Initial cleanup of Web server resources
|
@ -1,136 +0,0 @@
|
||||||
DIV#helpDialog
|
|
||||||
{
|
|
||||||
width: 300px;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#helpDialog H3
|
|
||||||
{
|
|
||||||
font-size: 1.2em;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#helpDialog DIV DIV
|
|
||||||
{
|
|
||||||
border: 0;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#helpDialog P.button
|
|
||||||
{
|
|
||||||
margin: 0;
|
|
||||||
padding: 0 0 5px 0;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#verticalDragHandle
|
|
||||||
{
|
|
||||||
cursor: e-resize;
|
|
||||||
top: 6em;
|
|
||||||
left: 15em;
|
|
||||||
width: 5px;
|
|
||||||
bottom: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.titlediv
|
|
||||||
{
|
|
||||||
vertical-align: bottom;
|
|
||||||
padding-top: 14px;
|
|
||||||
padding-left: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#administrationModules
|
|
||||||
{
|
|
||||||
position: absolute;
|
|
||||||
top: 9em;
|
|
||||||
left: 0;
|
|
||||||
width: 15em;
|
|
||||||
bottom: 2px;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#administrationModules UL
|
|
||||||
{
|
|
||||||
display: block;
|
|
||||||
list-style-type: none;
|
|
||||||
list-style-image: none;
|
|
||||||
clear: both;
|
|
||||||
cursor: default;
|
|
||||||
color: #000;
|
|
||||||
position: absolute; /* required for Safari & IE */
|
|
||||||
top: 0px;
|
|
||||||
bottom: 0px;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
width: auto;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
overflow: auto;
|
|
||||||
overflow-x: hidden;
|
|
||||||
border-top: 1px solid #909090;
|
|
||||||
border-left: 1px solid #909090;
|
|
||||||
border-bottom: 1px solid #FFFFFF;
|
|
||||||
border-right: 1px solid #FFFFFF;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-khtml-user-select: none;
|
|
||||||
}
|
|
||||||
DIV#administrationModules
|
|
||||||
{ background: #CCDDEC; }
|
|
||||||
|
|
||||||
DIV#administrationModules UL LI
|
|
||||||
{
|
|
||||||
cursor: pointer;
|
|
||||||
line-height: 20px;
|
|
||||||
height: 20px;
|
|
||||||
padding-left: 0.5em;
|
|
||||||
margin: 0px;
|
|
||||||
width: auto;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#rightPanel
|
|
||||||
{
|
|
||||||
position: absolute;
|
|
||||||
top: 80px;
|
|
||||||
left: 15em;
|
|
||||||
margin-left: 5px;
|
|
||||||
right: 0px;
|
|
||||||
bottom: 0px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#rightPanel > SPAN
|
|
||||||
{
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#rightPanel H1
|
|
||||||
{
|
|
||||||
font-size: 14px;
|
|
||||||
margin: 0.5em 0 5px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#filterPanel
|
|
||||||
{
|
|
||||||
n0padding-top: 5px;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#administrationContent
|
|
||||||
{
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
right: 1em;
|
|
||||||
top: 3em;
|
|
||||||
bottom: 2px;
|
|
||||||
background-color: #fff;
|
|
||||||
padding: .5em;
|
|
||||||
overflow: auto;
|
|
||||||
border-top: 1px solid #909090;
|
|
||||||
border-left: 1px solid #909090;
|
|
||||||
border-bottom: 1px solid #FFFFFF;
|
|
||||||
border-right: 1px solid #FFFFFF;
|
|
||||||
}
|
|
|
@ -1,221 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
var d;
|
|
||||||
var usersRightsWindowHeight = 220;
|
|
||||||
var usersRightsWindowWidth = 450;
|
|
||||||
|
|
||||||
/* ACLs module */
|
|
||||||
|
|
||||||
function onSearchFormSubmit(panel) {
|
|
||||||
var searchValue = panel.down('[name="search"]');
|
|
||||||
var encodedValue = encodeURI(searchValue.value);
|
|
||||||
|
|
||||||
if (encodedValue.blank()) {
|
|
||||||
checkAjaxRequestsState();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var url = (UserFolderURL
|
|
||||||
+ "usersSearch?search=" + encodedValue);
|
|
||||||
if (document.userFoldersRequest) {
|
|
||||||
document.userFoldersRequest.aborted = true;
|
|
||||||
document.userFoldersRequest.abort();
|
|
||||||
}
|
|
||||||
document.userFoldersRequest
|
|
||||||
= triggerAjaxRequest(url, usersSearchCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function usersSearchCallback(http) {
|
|
||||||
document.userFoldersRequest = null;
|
|
||||||
var div = $("administrationContent");
|
|
||||||
if (http.status == 200) {
|
|
||||||
var response = http.responseText.evalJSON();
|
|
||||||
buildUsersTree(div, response)
|
|
||||||
}
|
|
||||||
else if (http.status == 404)
|
|
||||||
div.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildUsersTree(treeDiv, response) {
|
|
||||||
d = new dTree("d");
|
|
||||||
d.config.hideRoot = true;
|
|
||||||
d.icon.root = ResourcesURL + '/tbtv_account_17x17.gif';
|
|
||||||
d.icon.folder = ResourcesURL + '/tbtv_leaf_corner_17x17.png';
|
|
||||||
d.icon.folderOpen = ResourcesURL + '/tbtv_leaf_corner_17x17.png';
|
|
||||||
d.icon.node = ResourcesURL + '/tbtv_leaf_corner_17x17.png';
|
|
||||||
d.icon.line = ResourcesURL + '/tbtv_line_17x22.png';
|
|
||||||
d.icon.join = ResourcesURL + '/tbtv_junction_17x22.png';
|
|
||||||
d.icon.joinBottom = ResourcesURL + '/tbtv_corner_17x22.png';
|
|
||||||
d.icon.plus = ResourcesURL + '/tbtv_plus_17x22.png';
|
|
||||||
d.icon.plusBottom = ResourcesURL + '/tbtv_corner_plus_17x22.png';
|
|
||||||
d.icon.minus = ResourcesURL + '/tbtv_minus_17x22.png';
|
|
||||||
d.icon.minusBottom = ResourcesURL + '/tbtv_corner_minus_17x22.png';
|
|
||||||
d.icon.nlPlus = ResourcesURL + '/tbtv_corner_plus_17x22.png';
|
|
||||||
d.icon.nlMinus = ResourcesURL + '/tbtv_corner_minus_17x22.png';
|
|
||||||
d.icon.empty = ResourcesURL + '/empty.gif';
|
|
||||||
d.preload ();
|
|
||||||
d.add(0, -1, '');
|
|
||||||
|
|
||||||
var isUserDialog = false;
|
|
||||||
var multiplier = ((isUserDialog) ? 1 : 2);
|
|
||||||
|
|
||||||
for (var i = 0; i < response.length; i++)
|
|
||||||
addUserLineToTree(d, 1 + i * multiplier, response[i]);
|
|
||||||
treeDiv.innerHTML = "";
|
|
||||||
treeDiv.appendChild(d.domObject());
|
|
||||||
treeDiv.clean = false;
|
|
||||||
for (var i = 0; i < response.length; i++) {
|
|
||||||
if (!isUserDialog) {
|
|
||||||
var toggle = $("tgd" + (1 + i * 2));
|
|
||||||
toggle.observe ("click", onUserNodeToggle);
|
|
||||||
}
|
|
||||||
var sd = $("sd" + (1 + i * multiplier));
|
|
||||||
sd.observe("click", onTreeItemClick);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function addUserLineToTree(tree, parent, line) {
|
|
||||||
var icon = ResourcesURL + '/busy.gif';
|
|
||||||
|
|
||||||
var email = line[1] + " <" + line[2] + ">";
|
|
||||||
if (line[4] && !line[4].empty())
|
|
||||||
email += ", " + line[4]; // extra contact info
|
|
||||||
tree.add(parent, 0, email, 0, '#', line[0], 'person',
|
|
||||||
'', '',
|
|
||||||
ResourcesURL + '/abcard.png',
|
|
||||||
ResourcesURL + '/abcard.png');
|
|
||||||
tree.add(parent + 1, parent, _("Please wait..."), 0, '#', null,
|
|
||||||
null, '', '', icon, icon);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onTreeItemClick(event) {
|
|
||||||
preventDefault(event);
|
|
||||||
|
|
||||||
var topNode = $("d");
|
|
||||||
if (topNode.selectedEntry)
|
|
||||||
topNode.selectedEntry.deselect();
|
|
||||||
this.selectElement();
|
|
||||||
topNode.selectedEntry = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onUserNodeToggle(event) {
|
|
||||||
this.stopObserving("click", onUserNodeToggle);
|
|
||||||
|
|
||||||
var person = this.parentNode.getAttribute("dataname");
|
|
||||||
var url = (UserFolderURLForUser(person) + "foldersSearch");
|
|
||||||
var nodeId = this.getAttribute("id").substr(3);
|
|
||||||
triggerAjaxRequest(url, foldersSearchCallback,
|
|
||||||
{ nodeId: nodeId, user: person });
|
|
||||||
}
|
|
||||||
|
|
||||||
function foldersSearchCallback(http) {
|
|
||||||
if (http.status == 200) {
|
|
||||||
var response = http.responseText;
|
|
||||||
var nodeId = parseInt(http.callbackData["nodeId"]);
|
|
||||||
|
|
||||||
var dd = $("dd" + (nodeId + 2));
|
|
||||||
var indentValue = (dd ? 1 : 0);
|
|
||||||
d.aIndent.push(indentValue);
|
|
||||||
|
|
||||||
var dd = $("dd" + nodeId);
|
|
||||||
if (response.length) {
|
|
||||||
var folders = response.evalJSON();
|
|
||||||
var user = http.callbackData["user"];
|
|
||||||
|
|
||||||
dd.innerHTML = '';
|
|
||||||
for (var i = 0; i < folders.length - 1; i++)
|
|
||||||
dd.appendChild(addFolderBranchToTree (d, user, folders[i], nodeId, i+1, false));
|
|
||||||
dd.appendChild (addFolderBranchToTree (d, user, folders[folders.length-1], nodeId,
|
|
||||||
(folders.length), true));
|
|
||||||
for (var i = 0; i < folders.length; i++) {
|
|
||||||
var sd = $("sd" + (nodeId + i + 1));
|
|
||||||
sd.observe("click", onTreeItemClick);
|
|
||||||
sd.observe("dblclick", onFolderOpen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dd.innerHTML = '';
|
|
||||||
dd.appendChild (addFolderNotFoundNode (d, nodeId, null));
|
|
||||||
var sd = $("sd" + (nodeId + 1));
|
|
||||||
sd.observe("click", onTreeItemClick);
|
|
||||||
}
|
|
||||||
|
|
||||||
d.aIndent.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function addFolderBranchToTree(tree, user, folder, nodeId, subId, isLast) {
|
|
||||||
var icon = ResourcesURL + '/';
|
|
||||||
if (folder.type == 'Contact')
|
|
||||||
icon += 'tb-mail-addressbook-flat-16x16.png';
|
|
||||||
else
|
|
||||||
icon += 'calendar-folder-16x16.png';
|
|
||||||
var folderId = user + ":" + folder.name.substr(1);
|
|
||||||
var name = folder.displayName.escapeHTML();
|
|
||||||
var node = new dTreeNode(subId, nodeId, name, 0, '#', folderId,
|
|
||||||
folder.type + '-folder', '', '', icon, icon);
|
|
||||||
node._ls = isLast;
|
|
||||||
var content = tree.node(node, (nodeId + subId), null);
|
|
||||||
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
function addFolderNotFoundNode (tree, nodeId) {
|
|
||||||
var icon = ResourcesURL + '/icon_unread.gif';
|
|
||||||
var node = new dTreeNode(1, nodeId, _("No possible subscription"), 0, '#',
|
|
||||||
null, null, '', '', icon, icon);
|
|
||||||
node._ls = true;
|
|
||||||
return tree.node(node, (nodeId + 1), null);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onFolderOpen(event) {
|
|
||||||
var obj = Event.element(event);
|
|
||||||
var node = obj.up("div.dTreeNode");
|
|
||||||
var folderID = node.readAttribute("dataname");
|
|
||||||
var urlstr = URLForFolderID(folderID) + "/acls";
|
|
||||||
openAclWindow(urlstr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Common functions */
|
|
||||||
|
|
||||||
function configureDragHandles() {
|
|
||||||
var handle = $("verticalDragHandle");
|
|
||||||
if (handle) {
|
|
||||||
handle.addInterface(SOGoDragHandlesInterface);
|
|
||||||
handle.leftBlock = $("administrationModules");
|
|
||||||
handle.rightBlock = $("rightPanel");
|
|
||||||
handle.leftMargin = 100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function help() {
|
|
||||||
var div = $("helpDialog");
|
|
||||||
var title = div.select('H3').first();
|
|
||||||
var description = div.select('DIV DIV')[0];
|
|
||||||
var module = $$("#administrationModules LI._selected").first();
|
|
||||||
|
|
||||||
var cellPosition = module.cumulativeOffset();
|
|
||||||
var cellDimensions = module.getDimensions();
|
|
||||||
var left = cellDimensions.width - 20;
|
|
||||||
var top = cellPosition.top + 3;
|
|
||||||
|
|
||||||
div.setStyle({ top: top + 'px',
|
|
||||||
left: left + 'px' });
|
|
||||||
title.update($("moduleTitle").innerHTML);
|
|
||||||
description.update($("moduleDescription").innerHTML);
|
|
||||||
|
|
||||||
div.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
function initAdministration() {
|
|
||||||
$("helpDialogClose").observe("click", function(event) {
|
|
||||||
$("helpDialog").hide();
|
|
||||||
});
|
|
||||||
|
|
||||||
var searchValue = $$('[data-search="admin"] [name="search"]').first();
|
|
||||||
searchValue.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
document.observe("dom:loaded", initAdministration);
|
|
|
@ -1,5 +0,0 @@
|
||||||
The default theme icons are derived from the icons provided as
|
|
||||||
part of the Mozilla Thunderbird application.
|
|
||||||
The licensing terms of Mozilla Thunderbird are available in the
|
|
||||||
LICENSE-thunderbird.txt file.
|
|
||||||
|
|
|
@ -1,426 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2005 SKYRIX Software AG
|
|
||||||
|
|
||||||
This file is part of OpenGroupware.org.
|
|
||||||
|
|
||||||
OGo is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU Lesser General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2, or (at your option) any
|
|
||||||
later version.
|
|
||||||
|
|
||||||
OGo is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
||||||
License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with OGo; see the file COPYING. If not, write to the
|
|
||||||
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|
||||||
02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
DIV#rightPanel
|
|
||||||
{ position: absolute;
|
|
||||||
top: 80px;
|
|
||||||
left: 15em;
|
|
||||||
margin-left: 5px;
|
|
||||||
right: 0px;
|
|
||||||
bottom: 0px;
|
|
||||||
overflow: hidden; }
|
|
||||||
|
|
||||||
/* top list */
|
|
||||||
DIV#contactsListContent
|
|
||||||
{ cursor: default;
|
|
||||||
position: absolute;
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
top: 27px;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
height: 15.5em;
|
|
||||||
border-left: 1px solid #9B9B9B;
|
|
||||||
overflow: auto;
|
|
||||||
overflow-x: hidden; }
|
|
||||||
|
|
||||||
.aptview_text
|
|
||||||
{
|
|
||||||
color: #000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.apt_other
|
|
||||||
{
|
|
||||||
color: #000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.apt_other_print
|
|
||||||
{
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
.foldercell
|
|
||||||
{
|
|
||||||
width: 25%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.titlediv
|
|
||||||
{ line-height: 18px;
|
|
||||||
vertical-align: middle;
|
|
||||||
padding-top: 8px;
|
|
||||||
padding-left: 6px; }
|
|
||||||
|
|
||||||
TABLE.titletable
|
|
||||||
{
|
|
||||||
height: 24px;
|
|
||||||
vertical-align: middle;
|
|
||||||
padding-top: 6px;
|
|
||||||
padding-left: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
TD.titlecell
|
|
||||||
{
|
|
||||||
height: 22px;
|
|
||||||
vertical-align: middle;
|
|
||||||
padding-bottom: 2px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
TABLE.titletable TD.titlecell SELECT
|
|
||||||
{
|
|
||||||
display: -moz-popup;
|
|
||||||
border-top: 1px solid #fff;
|
|
||||||
border-left: 1px solid #fff;
|
|
||||||
border-right: 2px solid #222;
|
|
||||||
border-bottom: 2px solid #222;
|
|
||||||
-moz-border-bottom-colors: #000 #9c9a94 transparent;
|
|
||||||
-moz-border-right-colors: #000 #9c9a94 transparent;
|
|
||||||
background-color: #DCDAD5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.whitesec_title
|
|
||||||
{
|
|
||||||
background-color: #DCDAD5;
|
|
||||||
padding: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#contactFoldersList
|
|
||||||
{ position: absolute;
|
|
||||||
top: 82px;
|
|
||||||
left: 0px;
|
|
||||||
width: 15em;
|
|
||||||
background-color: #CCDDEC;
|
|
||||||
bottom: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
overflow: auto;
|
|
||||||
overflow-x: hidden; }
|
|
||||||
|
|
||||||
DIV#abToolbar
|
|
||||||
{ padding-left: 6px; }
|
|
||||||
|
|
||||||
SPAN.toolbarButton
|
|
||||||
{ float: none;
|
|
||||||
padding: 14px 2px 0px 2px; }
|
|
||||||
|
|
||||||
A.toolbarButton
|
|
||||||
{ text-decoration: none; }
|
|
||||||
|
|
||||||
UL#contactFolders
|
|
||||||
{ list-style-type: none;
|
|
||||||
list-style-image: none;
|
|
||||||
clear: left;
|
|
||||||
cursor: default;
|
|
||||||
color: #000;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
overflow: auto;
|
|
||||||
overflow-x: hidden;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-khtml-user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
UL#contactFolders LI
|
|
||||||
{
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: 14px 2px;
|
|
||||||
cursor: pointer;
|
|
||||||
line-height: 2em;
|
|
||||||
padding-left: 34px;
|
|
||||||
margin: 0px;
|
|
||||||
width: auto;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#contactFoldersList LI.local
|
|
||||||
{
|
|
||||||
background-image: url('addrbook.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#contactFoldersList LI.remote
|
|
||||||
{
|
|
||||||
background-image: url('remote-addrbook.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
.treecell
|
|
||||||
{
|
|
||||||
color: black;
|
|
||||||
vertical-align: bottom;
|
|
||||||
padding-left: 4px; /* move away from the icon */
|
|
||||||
padding-right: 2px; /* move away from the right border */
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#folderTreeContent TABLE TD
|
|
||||||
{ height: 2em;
|
|
||||||
border-top: 1px solid #fff;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px; }
|
|
||||||
|
|
||||||
TABLE#contactsList
|
|
||||||
{ -moz-user-select: none;
|
|
||||||
-khtml-user-select: none;
|
|
||||||
width: 100%; }
|
|
||||||
|
|
||||||
TABLE#contactsList TBODY TD
|
|
||||||
{ cursor: pointer; }
|
|
||||||
|
|
||||||
TABLE#contactsList TD,
|
|
||||||
TABLE#contactsList TH
|
|
||||||
{ overflow: hidden;
|
|
||||||
line-height: 16px;
|
|
||||||
height: 18px;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap; } /* pre, normal, nowrap */
|
|
||||||
|
|
||||||
TABLE#contactsList TH
|
|
||||||
{ white-space: pre; }
|
|
||||||
|
|
||||||
TABLE#contactsList TR._deleted TD
|
|
||||||
{
|
|
||||||
text-decoration: line-through;
|
|
||||||
}
|
|
||||||
|
|
||||||
TABLE#contactsList TD.displayName
|
|
||||||
{ background-repeat: no-repeat;
|
|
||||||
background-position: 4px 1px;
|
|
||||||
padding-left: 24px; }
|
|
||||||
|
|
||||||
TABLE#contactsList TR.vcard TD.displayName
|
|
||||||
{
|
|
||||||
background-image: url('abcard.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
TABLE#contactsList TR.vlist TD.displayName
|
|
||||||
{
|
|
||||||
background-image: url('ablist.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#contactView
|
|
||||||
{
|
|
||||||
position: absolute;
|
|
||||||
background: #fff;
|
|
||||||
padding: .5em;
|
|
||||||
top: 18em;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
bottom: 0px;
|
|
||||||
overflow: auto;
|
|
||||||
margin-top: 5px;
|
|
||||||
border-top: 1px solid #aaa;
|
|
||||||
border-left: 1px solid #aaa;
|
|
||||||
line-height: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#contactView A
|
|
||||||
{ color: #00f;
|
|
||||||
text-decoration: none; }
|
|
||||||
|
|
||||||
DIV#contactView H3.contactCardTitle
|
|
||||||
{ margin: 0px;
|
|
||||||
padding: .2em 0px;
|
|
||||||
font-size: large;
|
|
||||||
font-weight: bold;
|
|
||||||
text-decoration: underline; }
|
|
||||||
|
|
||||||
DIV.contactColumn
|
|
||||||
{ width: 50%;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
float: left; }
|
|
||||||
|
|
||||||
DIV.contactColumn DIV
|
|
||||||
{ margin: 1em; }
|
|
||||||
|
|
||||||
DIV.contactColumn H4
|
|
||||||
{ margin: .2em 0px;
|
|
||||||
margin-left: 0;
|
|
||||||
font-size: 10pt;
|
|
||||||
font-weight: bold;
|
|
||||||
background: #9ABCD8;
|
|
||||||
color: #fff;
|
|
||||||
width: 100%;
|
|
||||||
padding: .1em .2em; }
|
|
||||||
|
|
||||||
dt {
|
|
||||||
color: #666;
|
|
||||||
line-height: 13px;
|
|
||||||
}
|
|
||||||
dd {
|
|
||||||
line-height: 14px;
|
|
||||||
}
|
|
||||||
.dl-horizontal dt {
|
|
||||||
width: 100px;
|
|
||||||
}
|
|
||||||
.dl-horizontal dd {
|
|
||||||
margin-left: 110px;
|
|
||||||
}
|
|
||||||
|
|
||||||
SPAN.photoFrame
|
|
||||||
{ cursor: pointer;
|
|
||||||
float: left;
|
|
||||||
background-color: #fff;
|
|
||||||
border: 1px solid #999;
|
|
||||||
padding: 8px;
|
|
||||||
margin: 8px;
|
|
||||||
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.2);
|
|
||||||
-moz-transform: rotate(-2deg);
|
|
||||||
-webkit-transform: rotate(-2deg);
|
|
||||||
-ms-transform: rotate(-2deg);
|
|
||||||
-moz-transition: all 0.2s ease-in-out;
|
|
||||||
-webkit-transition: all 0.2s ease-in-out; }
|
|
||||||
|
|
||||||
SPAN.photoFrame IMG.contactPhoto
|
|
||||||
{ max-width: 120px;
|
|
||||||
max-height: 120px;}
|
|
||||||
|
|
||||||
SPAN.photoFrame:hover {
|
|
||||||
-moz-transform: scale(3.0, 3.0) rotate(0deg) translate(33%, 33%);
|
|
||||||
-webkit-transform: scale(3.0, 3.0) rotate(0deg) translate(33%, 33%);
|
|
||||||
-ms-transform: rotate(0deg) scale(3.0, 3.0); }
|
|
||||||
|
|
||||||
/* drag handles */
|
|
||||||
DIV#dragHandle
|
|
||||||
{ cursor: e-resize;
|
|
||||||
border: 0px;
|
|
||||||
top: 81px;
|
|
||||||
left: 15em;
|
|
||||||
width: 5px;
|
|
||||||
bottom: 0px; }
|
|
||||||
|
|
||||||
DIV#rightDragHandle
|
|
||||||
{
|
|
||||||
cursor: n-resize;
|
|
||||||
top: 18em;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
height: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV.contactSelector
|
|
||||||
{
|
|
||||||
position: absolute;
|
|
||||||
top: 0px;
|
|
||||||
bottom: 0px;
|
|
||||||
right: 0px;
|
|
||||||
left: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
BODY.popup DIV#rightPanel
|
|
||||||
{ top: 4em; }
|
|
||||||
|
|
||||||
BODY.popup DIV#dragHandle
|
|
||||||
{ top: 7em; }
|
|
||||||
|
|
||||||
BODY.popup DIV#contactsListContent
|
|
||||||
{ height: 7em;
|
|
||||||
top: 34px; }
|
|
||||||
|
|
||||||
BODY.popup DIV#contactFoldersList
|
|
||||||
{ top: 50px; }
|
|
||||||
|
|
||||||
BODY.popup DIV#rightDragHandle
|
|
||||||
{ top: 10.2em; }
|
|
||||||
|
|
||||||
BODY.popup DIV#contactView
|
|
||||||
{ top: 10.2em; }
|
|
||||||
|
|
||||||
BODY.popup DIV#filterPanel
|
|
||||||
{ position: relative;
|
|
||||||
top: 7px;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV.contactSelection
|
|
||||||
{
|
|
||||||
z-index: 10;
|
|
||||||
background: inherit;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0em;
|
|
||||||
padding: 1em;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
height: 90px;
|
|
||||||
text-align: right;
|
|
||||||
background: #E6E7E6;
|
|
||||||
border-top: 1px solid #fff;
|
|
||||||
border-left: 0px;
|
|
||||||
border-right: 0px;
|
|
||||||
border-bottom: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV.contactSelection > DIV.calendar
|
|
||||||
{ text-align: center; }
|
|
||||||
|
|
||||||
DIV.contactSelection INPUT.button
|
|
||||||
{ font-size: 8pt;
|
|
||||||
margin-top: .25em;
|
|
||||||
padding: 0px; }
|
|
||||||
|
|
||||||
DIV.contactSelection SPAN#selectionLabel
|
|
||||||
{ float: left; }
|
|
||||||
|
|
||||||
DIV#dragDropVisual
|
|
||||||
{
|
|
||||||
background-image: url(abcard.png);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: 4px 2px;
|
|
||||||
width: 5px;
|
|
||||||
height: 20px;
|
|
||||||
padding-left: 24px;
|
|
||||||
padding-top: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV.copy
|
|
||||||
{
|
|
||||||
background-image: url(add-contact.gif) !important;
|
|
||||||
background-position: 1px -2px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media print
|
|
||||||
{
|
|
||||||
div#linkBanner,
|
|
||||||
div#contactFoldersList,
|
|
||||||
div#dragHandle,
|
|
||||||
div#rightDragHandle,
|
|
||||||
div.menu,
|
|
||||||
div#filterPanel,
|
|
||||||
div#contactsListContent
|
|
||||||
{
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
div#contactView,
|
|
||||||
div#rightPanel
|
|
||||||
{
|
|
||||||
color: black;
|
|
||||||
top: 0px;
|
|
||||||
left: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
border: none;
|
|
||||||
display: block;
|
|
||||||
visibility: visible;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.contactColumn h4 {
|
|
||||||
background: none;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,383 +0,0 @@
|
||||||
/* -*- Mode: js-mode; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
["HTMLCollection", "NodeList"].each(
|
|
||||||
function (className) {
|
|
||||||
if (className in window) {
|
|
||||||
var contClass = window[className];
|
|
||||||
var _each = contClass.prototype.forEach;
|
|
||||||
if (!_each) {
|
|
||||||
_each = function HTMLElement_each(iterator, context) {
|
|
||||||
for (var i = 0, length = this.length >>> 0; i < length; i++) {
|
|
||||||
if (i in this) iterator.call(context, this[i], i, this);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
contClass.prototype._each = _each;
|
|
||||||
Object.extend(contClass.prototype, Enumerable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
/* custom extensions to the DOM api */
|
|
||||||
Element.addMethods({
|
|
||||||
addInterface: function(element, objectInterface) {
|
|
||||||
element = $(element);
|
|
||||||
Object.extend(element, objectInterface);
|
|
||||||
if (element.bind)
|
|
||||||
element.bind();
|
|
||||||
},
|
|
||||||
|
|
||||||
allTextContent: function(element) {
|
|
||||||
var content = "";
|
|
||||||
for (var i = 0; i < element.childNodes.length; i++) {
|
|
||||||
var node = $(element.childNodes[i]);
|
|
||||||
if (node.nodeType == Node.TEXT_NODE) {
|
|
||||||
content += node.nodeValue;
|
|
||||||
}
|
|
||||||
else if (node.nodeType === Node.ELEMENT_NODE) {
|
|
||||||
content += Element.allTextContent(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return content;
|
|
||||||
},
|
|
||||||
|
|
||||||
childNodesWithTag: function(element, tagName) {
|
|
||||||
element = $(element);
|
|
||||||
|
|
||||||
var matchingNodes = new Array();
|
|
||||||
tagName = tagName.toUpperCase();
|
|
||||||
|
|
||||||
for (var i = 0; i < element.childNodes.length; i++) {
|
|
||||||
var childNode = $(element.childNodes[i]);
|
|
||||||
if (Object.isElement(childNode)
|
|
||||||
&& childNode.tagName
|
|
||||||
&& childNode.tagName.toUpperCase() == tagName)
|
|
||||||
matchingNodes.push(childNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
return matchingNodes;
|
|
||||||
},
|
|
||||||
|
|
||||||
getParentWithTagName: function(element, tagName) {
|
|
||||||
element = $(element);
|
|
||||||
var currentElement = element;
|
|
||||||
tagName = tagName.toUpperCase();
|
|
||||||
|
|
||||||
currentElement = currentElement.parentNode;
|
|
||||||
while (currentElement
|
|
||||||
&& currentElement.tagName != tagName) {
|
|
||||||
currentElement = currentElement.parentNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
return currentElement;
|
|
||||||
},
|
|
||||||
|
|
||||||
cascadeLeftOffset: function(element) {
|
|
||||||
element = $(element);
|
|
||||||
var currentElement = element;
|
|
||||||
|
|
||||||
var offset = 0;
|
|
||||||
while (currentElement) {
|
|
||||||
offset += currentElement.offsetLeft;
|
|
||||||
currentElement = $(currentElement).getParentWithTagName("div");
|
|
||||||
}
|
|
||||||
|
|
||||||
return offset;
|
|
||||||
},
|
|
||||||
|
|
||||||
cascadeTopOffset: function(element) {
|
|
||||||
element = $(element);
|
|
||||||
var currentElement = element;
|
|
||||||
var offset = 0;
|
|
||||||
|
|
||||||
var i = 0;
|
|
||||||
|
|
||||||
while (currentElement && currentElement.tagName) {
|
|
||||||
offset += currentElement.offsetTop;
|
|
||||||
currentElement = currentElement.parentNode;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return offset;
|
|
||||||
},
|
|
||||||
|
|
||||||
dump: function(element, additionalInfo, additionalKeys) {
|
|
||||||
element = $(element);
|
|
||||||
var id = element.getAttribute("id");
|
|
||||||
var nclass = element.getAttribute("class");
|
|
||||||
|
|
||||||
var str = element.tagName;
|
|
||||||
if (id)
|
|
||||||
str += "; id = " + id;
|
|
||||||
if (nclass)
|
|
||||||
str += "; class = " + nclass;
|
|
||||||
|
|
||||||
if (additionalInfo)
|
|
||||||
str += "; " + additionalInfo;
|
|
||||||
|
|
||||||
if (additionalKeys)
|
|
||||||
for (var i = 0; i < additionalKeys.length; i++) {
|
|
||||||
var value = element.readAttribute(additionalKeys[i]);
|
|
||||||
if (value)
|
|
||||||
str += "; " + additionalKeys[i] + " = " + value;
|
|
||||||
}
|
|
||||||
|
|
||||||
log (str);
|
|
||||||
},
|
|
||||||
|
|
||||||
getSelectedNodes: function(element) {
|
|
||||||
element = $(element);
|
|
||||||
|
|
||||||
if (!element.selectedElements)
|
|
||||||
element.selectedElements = new Array();
|
|
||||||
|
|
||||||
return element.selectedElements;
|
|
||||||
},
|
|
||||||
|
|
||||||
getSelectedNodesId: function(element) {
|
|
||||||
element = $(element);
|
|
||||||
|
|
||||||
var selArray = null;
|
|
||||||
if (element.selectedIds) {
|
|
||||||
selArray = element.selectedIds;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
selArray = [];
|
|
||||||
if (element.selectedElements) {
|
|
||||||
for (var i = 0; i < element.selectedElements.length; i++) {
|
|
||||||
var node = element.selectedElements[i];
|
|
||||||
selArray.push(node.getAttribute("id"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return selArray;
|
|
||||||
},
|
|
||||||
|
|
||||||
onContextMenu: function(element, event) {
|
|
||||||
element = $(element);
|
|
||||||
if (document.currentPopupMenu)
|
|
||||||
hideMenu(document.currentPopupMenu);
|
|
||||||
|
|
||||||
var popup = element.sogoContextMenu;
|
|
||||||
var menuTop = Event.pointerY(event);
|
|
||||||
var menuLeft = Event.pointerX(event);
|
|
||||||
var heightDiff = (window.height()
|
|
||||||
- (menuTop + popup.offsetHeight));
|
|
||||||
if (heightDiff < 0)
|
|
||||||
menuTop += heightDiff;
|
|
||||||
|
|
||||||
var leftDiff = (window.width()
|
|
||||||
- (menuLeft + popup.offsetWidth));
|
|
||||||
if (leftDiff < 0)
|
|
||||||
menuLeft -= popup.offsetWidth;
|
|
||||||
|
|
||||||
var isVisible = true;
|
|
||||||
if (popup.prepareVisibility)
|
|
||||||
isVisible = popup.prepareVisibility();
|
|
||||||
|
|
||||||
Event.stop(event);
|
|
||||||
|
|
||||||
if (isVisible) {
|
|
||||||
popup.setStyle( { top: menuTop + "px",
|
|
||||||
left: menuLeft + "px",
|
|
||||||
visibility: "visible" } );
|
|
||||||
document.currentPopupMenu = popup;
|
|
||||||
$(document.body).on("mousedown", onBodyClickMenuHandler);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
log ("Warning: not showing the contextual menu " + element.id);
|
|
||||||
},
|
|
||||||
|
|
||||||
attachMenu: function(element, menuName) {
|
|
||||||
element = $(element);
|
|
||||||
element.sogoContextMenu = $(menuName);
|
|
||||||
element.on("contextmenu", element.onContextMenu);
|
|
||||||
},
|
|
||||||
|
|
||||||
selectElement: function(element) {
|
|
||||||
element = $(element);
|
|
||||||
element.addClassName('_selected');
|
|
||||||
var parent = element.up();
|
|
||||||
if (!parent.selectedElements || !parent.selectedIds) {
|
|
||||||
// Selected nodes are kept in a array at the
|
|
||||||
// container level.
|
|
||||||
parent.selectedElements = new Array();
|
|
||||||
parent.selectedIds = new Array();
|
|
||||||
}
|
|
||||||
for (var i = 0; i < parent.selectedElements.length; i++)
|
|
||||||
if (parent.selectedElements[i] == element) return;
|
|
||||||
parent.selectedElements.push(element); // use index instead ?
|
|
||||||
if (element.id) {
|
|
||||||
for (var i = 0; i < parent.selectedIds.length; i++)
|
|
||||||
if (parent.selectedIds[i] == element.id) return;
|
|
||||||
parent.selectedIds.push(element.id);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
selectRange: function(element, startIndex, endIndex) {
|
|
||||||
element = $(element);
|
|
||||||
var s;
|
|
||||||
var e;
|
|
||||||
var rows;
|
|
||||||
|
|
||||||
if (startIndex > endIndex) {
|
|
||||||
s = endIndex;
|
|
||||||
e = startIndex;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
s = startIndex;
|
|
||||||
e = endIndex;
|
|
||||||
}
|
|
||||||
if (element.tagName == 'UL')
|
|
||||||
rows = element.getElementsByTagName('LI');
|
|
||||||
else
|
|
||||||
rows = element.getElementsByTagName('TR');
|
|
||||||
while (s <= e) {
|
|
||||||
if (rows[s].nodeType == 1)
|
|
||||||
$(rows[s]).selectElement();
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
selectAll: function(element) {
|
|
||||||
element = $(element);
|
|
||||||
if (element.tagName == 'UL')
|
|
||||||
rows = element.getElementsByTagName('LI');
|
|
||||||
else
|
|
||||||
rows = element.select('TBODY TR');
|
|
||||||
for (var i = 0; i < rows.length; i++) {
|
|
||||||
if (rows[i].nodeType == 1)
|
|
||||||
$(rows[i]).selectElement();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
deselect: function(element) {
|
|
||||||
element = $(element);
|
|
||||||
element.removeClassName('_selected');
|
|
||||||
var parent = element.parentNode;
|
|
||||||
if (parent) {
|
|
||||||
if (parent.selectedElements)
|
|
||||||
parent.selectedElements = parent.selectedElements.without(element);
|
|
||||||
if (parent.selectedIds)
|
|
||||||
parent.selectedIds = parent.selectedIds.without(element.id);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
deselectAll: function(element) {
|
|
||||||
if (element.tagName == 'TABLE') {
|
|
||||||
var tbody = element.tBodies[0];
|
|
||||||
if (tbody)
|
|
||||||
element = tbody;
|
|
||||||
}
|
|
||||||
element = $(element);
|
|
||||||
var s = element.select("._selected");
|
|
||||||
for (var i = 0; i < s.length; i++)
|
|
||||||
s[i].removeClassName("_selected");
|
|
||||||
|
|
||||||
element.selectedElements = null;
|
|
||||||
element.selectedIds = null;
|
|
||||||
},
|
|
||||||
|
|
||||||
refreshSelectionByIds: function(element, selectedIds) {
|
|
||||||
element = $(element);
|
|
||||||
var selectedCount = 0;
|
|
||||||
if (selectedIds)
|
|
||||||
element.selectedIds = selectedIds;
|
|
||||||
if (element.selectedIds) {
|
|
||||||
for (var i = 0; i < element.selectedIds.length; i++) {
|
|
||||||
//var e = element.down('#'+element.selectedIds[i]); // buggy with IE
|
|
||||||
var e = $(element.selectedIds[i]);
|
|
||||||
if (e) {
|
|
||||||
if (!e.hasClassName('_selected'))
|
|
||||||
e.addClassName('_selected');
|
|
||||||
selectedCount++;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
log ("refreshSelectionByIds Error: " + element.tagName
|
|
||||||
+ " select by ID " + element.selectedIds[i]
|
|
||||||
+ " not found (" + element.childNodes.length + " children)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return selectedCount;
|
|
||||||
},
|
|
||||||
|
|
||||||
setCaretTo: function(element, pos) {
|
|
||||||
element = $(element);
|
|
||||||
if (element.setSelectionRange) { // For Mozilla and Safari
|
|
||||||
element.focus();
|
|
||||||
element.setSelectionRange(pos, pos);
|
|
||||||
}
|
|
||||||
else if (element.createTextRange) { // For IE
|
|
||||||
var range = element.createTextRange();
|
|
||||||
range.move("character", pos);
|
|
||||||
range.select();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
selectText: function(element, start, end) {
|
|
||||||
element = $(element);
|
|
||||||
if (element.setSelectionRange) { // For Mozilla and Safari
|
|
||||||
element.setSelectionRange(start, end);
|
|
||||||
}
|
|
||||||
else if (element.createTextRange) { // For IE
|
|
||||||
var textRange = element.createTextRange();
|
|
||||||
textRange.moveStart("character", start);
|
|
||||||
textRange.moveEnd("character", end-element.value.length);
|
|
||||||
textRange.select();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
element.select();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getRadioValue: function(element, radioName) {
|
|
||||||
element = $(element);
|
|
||||||
var radioValue;
|
|
||||||
Form.getInputs(element, 'radio', radioName).each(function(input) {
|
|
||||||
if (input.checked)
|
|
||||||
radioValue = input.value;
|
|
||||||
});
|
|
||||||
return radioValue;
|
|
||||||
},
|
|
||||||
|
|
||||||
setRadioValue: function(element, radioName, value) {
|
|
||||||
element = $(element);
|
|
||||||
var i = 0;
|
|
||||||
|
|
||||||
Form.getInputs(element, 'radio', radioName).each(function(input) {
|
|
||||||
if (i == value)
|
|
||||||
input.checked = 1;
|
|
||||||
i++;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
getCheckBoxListValues: function(element, checkboxName) {
|
|
||||||
element = $(element);
|
|
||||||
var values = new Array();
|
|
||||||
var i = 0;
|
|
||||||
|
|
||||||
Form.getInputs(element, 'checkbox', checkboxName).each(function(input) {
|
|
||||||
if (input.checked)
|
|
||||||
values.push(i+1);
|
|
||||||
|
|
||||||
i++;
|
|
||||||
});
|
|
||||||
return values.join(",");
|
|
||||||
},
|
|
||||||
|
|
||||||
setCheckBoxListValues: function(element, checkboxName, values) {
|
|
||||||
element = $(element);
|
|
||||||
var v = values.split(',');
|
|
||||||
var i = 1;
|
|
||||||
|
|
||||||
Form.getInputs(element, 'checkbox', checkboxName).each(function(input) {
|
|
||||||
|
|
||||||
if ($(v).indexOf(i+"") != -1)
|
|
||||||
input.checked = 1;
|
|
||||||
i++;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,63 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
Form.Element.Methods._replicate = function(element) {
|
|
||||||
element = $(element);
|
|
||||||
if (element.replica) {
|
|
||||||
element.replica.value = $F(element);
|
|
||||||
var onReplicaChangeEvent = document.createEvent("UIEvents");
|
|
||||||
onReplicaChangeEvent.initEvent("change", true, true);
|
|
||||||
element.replica.dispatchEvent(onReplicaChangeEvent);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Form.Element.Methods.assignReplica = function(element, otherInput) {
|
|
||||||
element = $(element);
|
|
||||||
if (!element._onChangeBound) {
|
|
||||||
element.observe("change", element._replicate, false);
|
|
||||||
element._onChangeBound = true;
|
|
||||||
}
|
|
||||||
element.replica = otherInput;
|
|
||||||
};
|
|
||||||
|
|
||||||
Form.Element.Methods.inputAsDate = function(element) {
|
|
||||||
return $F(element).asDate();
|
|
||||||
};
|
|
||||||
|
|
||||||
Form.Element.Methods.setInputAsDate = function(element, dateValue) {
|
|
||||||
element = $(element);
|
|
||||||
if (!element.dateSeparator)
|
|
||||||
element._detectDateSeparator();
|
|
||||||
element.value = dateValue.stringWithSeparator(element.dateSeparator);
|
|
||||||
};
|
|
||||||
|
|
||||||
Form.Element.Methods.updateShadowValue = function(element) {
|
|
||||||
element = $(element);
|
|
||||||
element.setAttribute("shadow-value", $F(element));
|
|
||||||
};
|
|
||||||
|
|
||||||
Form.Element.Methods._detectDateSeparator = function(element) {
|
|
||||||
element = $(element);
|
|
||||||
var date = $F(element).split("/");
|
|
||||||
if (date.length == 3)
|
|
||||||
element.dateSeparator = "/";
|
|
||||||
else
|
|
||||||
element.dateSeparator = "-";
|
|
||||||
};
|
|
||||||
|
|
||||||
Form.Element.Methods.valueAsShortDateString = function(element) {
|
|
||||||
element = $(element);
|
|
||||||
var dateStr = '';
|
|
||||||
|
|
||||||
if (!element.dateSeparator)
|
|
||||||
element._detectDateSeparator();
|
|
||||||
|
|
||||||
var date = $F(element).split(element.dateSeparator);
|
|
||||||
if (element.dateSeparator == '/')
|
|
||||||
dateStr += date[2] + date[1] + date[0];
|
|
||||||
else
|
|
||||||
dateStr += date[0] + date[1] + date[2];
|
|
||||||
|
|
||||||
return dateStr;
|
|
||||||
};
|
|
||||||
|
|
||||||
Element.addMethods();
|
|
|
@ -1,46 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
Element.addMethods({
|
|
||||||
getSelectedRows: function(element) {
|
|
||||||
element = $(element);
|
|
||||||
if (element.tagName == 'TABLE') {
|
|
||||||
var tbody = (element.getElementsByTagName('tbody'))[0];
|
|
||||||
|
|
||||||
return $(tbody).getSelectedNodes();
|
|
||||||
}
|
|
||||||
else if (element.tagName == 'TBODY') {
|
|
||||||
return element.getSelectedNodes();
|
|
||||||
}
|
|
||||||
else if (element.tagName == 'UL') {
|
|
||||||
return element.getSelectedNodes();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getSelectedRowsId: function(element) {
|
|
||||||
element = $(element);
|
|
||||||
var rowsId = null;
|
|
||||||
if (element.tagName == 'TABLE') {
|
|
||||||
var tbody = (element.getElementsByTagName('tbody'))[0];
|
|
||||||
rowsId = $(tbody).getSelectedNodesId();
|
|
||||||
}
|
|
||||||
else if (element.tagName == 'UL') {
|
|
||||||
rowsId = element.getSelectedNodesId();
|
|
||||||
}
|
|
||||||
|
|
||||||
return rowsId;
|
|
||||||
},
|
|
||||||
|
|
||||||
selectRowsMatchingClass: function(element, className) {
|
|
||||||
element = $(element);
|
|
||||||
if (element.tagName == 'TABLE') {
|
|
||||||
var tbody = (element.getElementsByTagName('tbody'))[0];
|
|
||||||
var nodes = tbody.childNodes;
|
|
||||||
for (var i = 0; i < nodes.length; i++) {
|
|
||||||
var node = nodes.item(i);
|
|
||||||
if (node.tagName && node.hasClassName(className))
|
|
||||||
node.selectElement();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}); // Element.addMethods
|
|
|
@ -1,438 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
String.prototype.trim = function() {
|
|
||||||
return this.replace(/(^\s+|\s+$)/g, '');
|
|
||||||
};
|
|
||||||
|
|
||||||
String.prototype.formatted = function() {
|
|
||||||
var newString = this;
|
|
||||||
|
|
||||||
for (var i = 0; i < arguments.length; i++) {
|
|
||||||
newString = newString.replace("%{" + i + "}", arguments[i], "g");
|
|
||||||
}
|
|
||||||
|
|
||||||
return newString;
|
|
||||||
};
|
|
||||||
|
|
||||||
String.prototype.formatTime = function(hours, minutes) {
|
|
||||||
var newString = this;
|
|
||||||
|
|
||||||
// See http://www.gnustep.org/resources/documentation/Developer/Base/Reference/NSCalendarDate.html#method$NSCalendarDate-descriptionWithCalendarFormat$
|
|
||||||
var p = 'am', i = hours, m = minutes;
|
|
||||||
if (hours > 12) {
|
|
||||||
p = 'pm';
|
|
||||||
i = hours % 12;
|
|
||||||
}
|
|
||||||
if (minutes < 10) {
|
|
||||||
m = '0' + minutes;
|
|
||||||
}
|
|
||||||
|
|
||||||
// %H : hour as a decimal number using 24-hour clock
|
|
||||||
newString = newString.replace("%H", hours < 10 ? '0' + hours : hours);
|
|
||||||
// %I : hour as a decimal number using 12-hour clock
|
|
||||||
newString = newString.replace("%I", i < 10 ? '0' + i : i);
|
|
||||||
// %M : minute as decimal number
|
|
||||||
newString = newString.replace("%M", m);
|
|
||||||
// %p : 'am' or 'pm'
|
|
||||||
newString = newString.replace("%p", p);
|
|
||||||
|
|
||||||
return newString;
|
|
||||||
};
|
|
||||||
|
|
||||||
String.prototype.repeat = function(count) {
|
|
||||||
var newString = "";
|
|
||||||
for (var i = 0; i < count; i++) {
|
|
||||||
newString += this;
|
|
||||||
}
|
|
||||||
|
|
||||||
return newString;
|
|
||||||
};
|
|
||||||
|
|
||||||
String.prototype.capitalize = function() {
|
|
||||||
return this.replace(/\w+/g,
|
|
||||||
function(a) {
|
|
||||||
return ( a.charAt(0).toUpperCase()
|
|
||||||
+ a.substr(1).toLowerCase() );
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
String.prototype.cssIdToHungarianId = function() {
|
|
||||||
var parts = this.split("-");
|
|
||||||
var newId = parts[0];
|
|
||||||
for (var i = 1; i < parts.length; i++) {
|
|
||||||
newId += parts[i].capitalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
return newId;
|
|
||||||
}
|
|
||||||
|
|
||||||
String.prototype.decodeEntities = function() {
|
|
||||||
return this.replace(/&#(\d+);/g,
|
|
||||||
function(wholematch, parenmatch1) {
|
|
||||||
return String.fromCharCode(+parenmatch1);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
String.prototype.unescapeHTMLEntities = function() {
|
|
||||||
return this.unescapeHTML().replace(/"/g,'"');
|
|
||||||
};
|
|
||||||
|
|
||||||
String.prototype.asDate = function () {
|
|
||||||
var newDate;
|
|
||||||
var date = this.split("/");
|
|
||||||
if (date.length == 3)
|
|
||||||
newDate = new Date(date[2], date[1] - 1, date[0]); // dd/mm/yyyy
|
|
||||||
else {
|
|
||||||
date = this.split("-");
|
|
||||||
if (date.length == 3)
|
|
||||||
newDate = new Date(date[0], date[1] - 1, date[2]); // yyyy-mm-dd
|
|
||||||
else {
|
|
||||||
if (this.length == 8) {
|
|
||||||
newDate = new Date(this.substring(0, 4),
|
|
||||||
this.substring(4, 6) - 1,
|
|
||||||
this.substring(6, 8));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return newDate;
|
|
||||||
};
|
|
||||||
|
|
||||||
RegExp.escape = function(text) {
|
|
||||||
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
|
||||||
}
|
|
||||||
|
|
||||||
var css_invalid_characters = [ '_' , '.', '#' , '@' , '*', ':' , ';' , ',' , ' ',
|
|
||||||
'(', ')', '[', ']', '{', '}',
|
|
||||||
"'", '"', '&', '+' ];
|
|
||||||
var css_escape_characters = [ '_U_', '_D_', '_H_', '_A_', '_S_', '_C_', '_SC_', '_CO_', '_SP_',
|
|
||||||
'_LP_', '_RP_', '_LS_', '_RQ_', '_LC_', '_RC_',
|
|
||||||
'_SQ_', '_DQ_', '_AM_', '_P_' ];
|
|
||||||
|
|
||||||
String.prototype.asCSSIdentifier = function() {
|
|
||||||
var newString = this;
|
|
||||||
for (var i = 0; i < css_invalid_characters.length; i++) {
|
|
||||||
var re = new RegExp(RegExp.escape(css_invalid_characters[i]), 'g');
|
|
||||||
newString = newString.replace(re, css_escape_characters[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (/^\d/.test(newString))
|
|
||||||
newString = '_' + newString;
|
|
||||||
|
|
||||||
return newString;
|
|
||||||
};
|
|
||||||
|
|
||||||
String.prototype.fromCSSIdentifier = function() {
|
|
||||||
var newString = this;
|
|
||||||
|
|
||||||
if (/^_\d/.test(newString))
|
|
||||||
newString = newString.substring(1);
|
|
||||||
|
|
||||||
for (var i = 0; i < css_escape_characters.length; i++) {
|
|
||||||
var re = new RegExp(css_escape_characters[i], 'g');
|
|
||||||
newString = newString.replace(re, css_invalid_characters[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return newString;
|
|
||||||
};
|
|
||||||
|
|
||||||
Date.prototype.clone = function() {
|
|
||||||
var newDate = new Date();
|
|
||||||
|
|
||||||
newDate.setTime(this.getTime());
|
|
||||||
|
|
||||||
return newDate;
|
|
||||||
};
|
|
||||||
|
|
||||||
Date.prototype.deltaDays = function(otherDate) {
|
|
||||||
var day1 = this.getTime();
|
|
||||||
var day2 = otherDate.getTime();
|
|
||||||
if (day1 > day2) {
|
|
||||||
var tmp = day2;
|
|
||||||
day2 = day1;
|
|
||||||
day1 = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Math.round((day2 - day1) / 86400000);
|
|
||||||
};
|
|
||||||
|
|
||||||
Date.prototype.daysUpTo = function(otherDate) {
|
|
||||||
var days = new Array();
|
|
||||||
|
|
||||||
var day1 = this.getTime();
|
|
||||||
var day2 = otherDate.getTime();
|
|
||||||
if (day1 > day2) {
|
|
||||||
var tmp = day1;
|
|
||||||
day1 = day2;
|
|
||||||
day2 = tmp;
|
|
||||||
}
|
|
||||||
// var day1Date = new Date();
|
|
||||||
// day1Date.setTime(this.getTime());
|
|
||||||
// day1Date.setHours(0, 0, 0, 0);
|
|
||||||
// var day2Date = new Date();
|
|
||||||
// day2Date.setTime(otherDate.getTime());
|
|
||||||
// day2Date.setHours(23, 59, 59, 999);
|
|
||||||
// var day1 = day1Date.getTime();
|
|
||||||
// var day2 = day2Date.getTime();
|
|
||||||
|
|
||||||
var nbrDays = Math.round((day2 - day1) / 86400000) + 1;
|
|
||||||
for (var i = 0; i < nbrDays; i++) {
|
|
||||||
var newDate = new Date();
|
|
||||||
newDate.setTime(day1 + (i * 86400000));
|
|
||||||
days.push(newDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return days;
|
|
||||||
};
|
|
||||||
|
|
||||||
Date.prototype.getDayString = function() {
|
|
||||||
var newString = this.getYear();
|
|
||||||
if (newString < 1000) newString += 1900;
|
|
||||||
var month = '' + (this.getMonth() + 1);
|
|
||||||
if (month.length == 1)
|
|
||||||
month = '0' + month;
|
|
||||||
newString += month;
|
|
||||||
var day = '' + this.getDate();
|
|
||||||
if (day.length == 1)
|
|
||||||
day = '0' + day;
|
|
||||||
newString += day;
|
|
||||||
|
|
||||||
return newString;
|
|
||||||
};
|
|
||||||
|
|
||||||
Date.prototype.getHourString = function() {
|
|
||||||
var newString = this.getHours() + '00';
|
|
||||||
if (newString.length == 3)
|
|
||||||
newString = '0' + newString;
|
|
||||||
|
|
||||||
return newString;
|
|
||||||
};
|
|
||||||
|
|
||||||
Date.prototype.getDisplayHoursString = function() {
|
|
||||||
var hoursString = "" + this.getHours();
|
|
||||||
if (hoursString.length == 1)
|
|
||||||
hoursString = '0' + hoursString;
|
|
||||||
|
|
||||||
var minutesString = "" + this.getMinutes();
|
|
||||||
if (minutesString.length == 1)
|
|
||||||
minutesString = '0' + minutesString;
|
|
||||||
|
|
||||||
return hoursString + ":" + minutesString;
|
|
||||||
};
|
|
||||||
|
|
||||||
Date.prototype.stringWithSeparator = function(separator) {
|
|
||||||
var month = '' + (this.getMonth() + 1);
|
|
||||||
var day = '' + this.getDate();
|
|
||||||
var year = this.getYear();
|
|
||||||
if (year < 1000)
|
|
||||||
year = '' + (year + 1900);
|
|
||||||
if (month.length == 1)
|
|
||||||
month = '0' + month;
|
|
||||||
if (day.length == 1)
|
|
||||||
day = '0' + day;
|
|
||||||
|
|
||||||
if (separator == '-')
|
|
||||||
str = year + '-' + month + '-' + day;
|
|
||||||
else
|
|
||||||
str = day + '/' + month + '/' + year;
|
|
||||||
|
|
||||||
return str;
|
|
||||||
};
|
|
||||||
|
|
||||||
Date.prototype.addDays = function(nbrDays) {
|
|
||||||
var dat = new Date(this.valueOf());
|
|
||||||
this.setDate(dat.getDate() + Math.round(nbrDays));
|
|
||||||
};
|
|
||||||
|
|
||||||
Date.prototype.earlierDate = function(otherDate) {
|
|
||||||
var workDate = new Date();
|
|
||||||
workDate.setTime(otherDate.getTime());
|
|
||||||
workDate.setHours(0);
|
|
||||||
return ((this.getTime() < workDate.getTime())
|
|
||||||
? this : otherDate);
|
|
||||||
};
|
|
||||||
|
|
||||||
Date.prototype.laterDate = function(otherDate) {
|
|
||||||
var workDate = new Date();
|
|
||||||
workDate.setTime(otherDate.getTime());
|
|
||||||
workDate.setHours(23);
|
|
||||||
workDate.setMinutes(59);
|
|
||||||
workDate.setSeconds(59);
|
|
||||||
workDate.setMilliseconds(999);
|
|
||||||
return ((this.getTime() < workDate.getTime())
|
|
||||||
? otherDate : this);
|
|
||||||
};
|
|
||||||
|
|
||||||
Date.prototype.beginOfDay = function() {
|
|
||||||
var beginOfDay = new Date(this.getTime());
|
|
||||||
beginOfDay.setHours(0);
|
|
||||||
beginOfDay.setMinutes(0);
|
|
||||||
beginOfDay.setSeconds(0);
|
|
||||||
beginOfDay.setMilliseconds(0);
|
|
||||||
|
|
||||||
return beginOfDay;
|
|
||||||
};
|
|
||||||
|
|
||||||
Date.prototype.beginOfWeek = function() {
|
|
||||||
var offset = firstDayOfWeek - this.getDay();
|
|
||||||
if (offset > 0)
|
|
||||||
offset -= 7;
|
|
||||||
|
|
||||||
var beginOfWeek = this.beginOfDay();
|
|
||||||
beginOfWeek.setHours(12);
|
|
||||||
beginOfWeek.addDays(offset);
|
|
||||||
|
|
||||||
return beginOfWeek;
|
|
||||||
};
|
|
||||||
|
|
||||||
Date.prototype.endOfWeek = function() {
|
|
||||||
var endOfWeek = this.beginOfWeek();
|
|
||||||
endOfWeek.addDays(6);
|
|
||||||
|
|
||||||
endOfWeek.setHours(23);
|
|
||||||
endOfWeek.setMinutes(59);
|
|
||||||
endOfWeek.setSeconds(59);
|
|
||||||
endOfWeek.setMilliseconds(999);
|
|
||||||
|
|
||||||
return endOfWeek;
|
|
||||||
};
|
|
||||||
|
|
||||||
String.prototype._base64_keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
|
||||||
String.prototype.base64encode = function () {
|
|
||||||
var output = "";
|
|
||||||
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
|
|
||||||
var i = 0;
|
|
||||||
|
|
||||||
var input = this.utf8encode();
|
|
||||||
|
|
||||||
while (i < input.length) {
|
|
||||||
chr1 = input.charCodeAt(i++);
|
|
||||||
chr2 = input.charCodeAt(i++);
|
|
||||||
chr3 = input.charCodeAt(i++);
|
|
||||||
|
|
||||||
enc1 = chr1 >> 2;
|
|
||||||
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
|
|
||||||
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
|
|
||||||
enc4 = chr3 & 63;
|
|
||||||
|
|
||||||
if (isNaN(chr2)) {
|
|
||||||
enc3 = enc4 = 64;
|
|
||||||
} else if (isNaN(chr3)) {
|
|
||||||
enc4 = 64;
|
|
||||||
}
|
|
||||||
|
|
||||||
output = output +
|
|
||||||
this._base64_keyStr.charAt(enc1) + this._base64_keyStr.charAt(enc2) +
|
|
||||||
this._base64_keyStr.charAt(enc3) + this._base64_keyStr.charAt(enc4);
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
};
|
|
||||||
|
|
||||||
String.prototype.base64decode = function() {
|
|
||||||
var output = "";
|
|
||||||
var chr1, chr2, chr3;
|
|
||||||
var enc1, enc2, enc3, enc4;
|
|
||||||
var i = 0;
|
|
||||||
|
|
||||||
var input = "" + this; // .replace(/[^A-Za-z0-9\+\/\=]/g, "")
|
|
||||||
while (i < input.length) {
|
|
||||||
enc1 = this._base64_keyStr.indexOf(input.charAt(i++));
|
|
||||||
enc2 = this._base64_keyStr.indexOf(input.charAt(i++));
|
|
||||||
enc3 = this._base64_keyStr.indexOf(input.charAt(i++));
|
|
||||||
enc4 = this._base64_keyStr.indexOf(input.charAt(i++));
|
|
||||||
|
|
||||||
chr1 = (enc1 << 2) | (enc2 >> 4);
|
|
||||||
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
|
|
||||||
chr3 = ((enc3 & 3) << 6) | enc4;
|
|
||||||
|
|
||||||
output = output + String.fromCharCode(chr1);
|
|
||||||
|
|
||||||
if (enc3 != 64) {
|
|
||||||
output = output + String.fromCharCode(chr2);
|
|
||||||
}
|
|
||||||
if (enc4 != 64) {
|
|
||||||
output = output + String.fromCharCode(chr3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
};
|
|
||||||
|
|
||||||
String.prototype.utf8encode = function() {
|
|
||||||
var string = this.replace(/\r\n/g,"\n");
|
|
||||||
var utftext = "";
|
|
||||||
|
|
||||||
for (var n = 0; n < this.length; n++) {
|
|
||||||
var c = this.charCodeAt(n);
|
|
||||||
|
|
||||||
if (c < 128) {
|
|
||||||
utftext += String.fromCharCode(c);
|
|
||||||
}
|
|
||||||
else if((c > 127) && (c < 2048)) {
|
|
||||||
utftext += String.fromCharCode((c >> 6) | 192);
|
|
||||||
utftext += String.fromCharCode((c & 63) | 128);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
utftext += String.fromCharCode((c >> 12) | 224);
|
|
||||||
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
|
|
||||||
utftext += String.fromCharCode((c & 63) | 128);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return utftext;
|
|
||||||
};
|
|
||||||
|
|
||||||
String.prototype.utf8decode = function() {
|
|
||||||
var string = "";
|
|
||||||
var i = 0;
|
|
||||||
var c = c1 = c2 = 0;
|
|
||||||
|
|
||||||
while (i < string.length) {
|
|
||||||
c = utftext.charCodeAt(i);
|
|
||||||
|
|
||||||
if (c < 128) {
|
|
||||||
string += String.fromCharCode(c);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
else if((c > 191) && (c < 224)) {
|
|
||||||
c2 = this.charCodeAt(i+1);
|
|
||||||
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
|
|
||||||
i += 2;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
c2 = this.charCodeAt(i+1);
|
|
||||||
c3 = this.charCodeAt(i+2);
|
|
||||||
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
|
|
||||||
i += 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return string;
|
|
||||||
};
|
|
||||||
|
|
||||||
String.prototype.cssSafeString = function() {
|
|
||||||
var newString = this.replace("#", "_", "g");
|
|
||||||
newString = newString.replace(".", "_", "g");
|
|
||||||
newString = newString.replace("@", "_", "g");
|
|
||||||
|
|
||||||
return newString;
|
|
||||||
};
|
|
||||||
|
|
||||||
window.width = function() {
|
|
||||||
if (window.innerWidth)
|
|
||||||
return window.innerWidth;
|
|
||||||
else if (document.body && document.body.offsetWidth)
|
|
||||||
return document.body.offsetWidth;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
window.height = function() {
|
|
||||||
if (window.innerHeight)
|
|
||||||
return window.innerHeight;
|
|
||||||
else if (document.body && document.body.offsetHeight)
|
|
||||||
return document.body.offsetHeight;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
};
|
|
|
@ -1,567 +0,0 @@
|
||||||
MOZILLA PUBLIC LICENSE
|
|
||||||
Version 1.1
|
|
||||||
|
|
||||||
---------------
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
1.0.1. "Commercial Use" means distribution or otherwise making the
|
|
||||||
Covered Code available to a third party.
|
|
||||||
|
|
||||||
1.1. "Contributor" means each entity that creates or contributes to
|
|
||||||
the creation of Modifications.
|
|
||||||
|
|
||||||
1.2. "Contributor Version" means the combination of the Original
|
|
||||||
Code, prior Modifications used by a Contributor, and the Modifications
|
|
||||||
made by that particular Contributor.
|
|
||||||
|
|
||||||
1.3. "Covered Code" means the Original Code or Modifications or the
|
|
||||||
combination of the Original Code and Modifications, in each case
|
|
||||||
including portions thereof.
|
|
||||||
|
|
||||||
1.4. "Electronic Distribution Mechanism" means a mechanism generally
|
|
||||||
accepted in the software development community for the electronic
|
|
||||||
transfer of data.
|
|
||||||
|
|
||||||
1.5. "Executable" means Covered Code in any form other than Source
|
|
||||||
Code.
|
|
||||||
|
|
||||||
1.6. "Initial Developer" means the individual or entity identified
|
|
||||||
as the Initial Developer in the Source Code notice required by Exhibit
|
|
||||||
A.
|
|
||||||
|
|
||||||
1.7. "Larger Work" means a work which combines Covered Code or
|
|
||||||
portions thereof with code not governed by the terms of this License.
|
|
||||||
|
|
||||||
1.8. "License" means this document.
|
|
||||||
|
|
||||||
1.8.1. "Licensable" means having the right to grant, to the maximum
|
|
||||||
extent possible, whether at the time of the initial grant or
|
|
||||||
subsequently acquired, any and all of the rights conveyed herein.
|
|
||||||
|
|
||||||
1.9. "Modifications" means any addition to or deletion from the
|
|
||||||
substance or structure of either the Original Code or any previous
|
|
||||||
Modifications. When Covered Code is released as a series of files, a
|
|
||||||
Modification is:
|
|
||||||
A. Any addition to or deletion from the contents of a file
|
|
||||||
containing Original Code or previous Modifications.
|
|
||||||
|
|
||||||
B. Any new file that contains any part of the Original Code or
|
|
||||||
previous Modifications.
|
|
||||||
|
|
||||||
1.10. "Original Code" means Source Code of computer software code
|
|
||||||
which is described in the Source Code notice required by Exhibit A as
|
|
||||||
Original Code, and which, at the time of its release under this
|
|
||||||
License is not already Covered Code governed by this License.
|
|
||||||
|
|
||||||
1.10.1. "Patent Claims" means any patent claim(s), now owned or
|
|
||||||
hereafter acquired, including without limitation, method, process,
|
|
||||||
and apparatus claims, in any patent Licensable by grantor.
|
|
||||||
|
|
||||||
1.11. "Source Code" means the preferred form of the Covered Code for
|
|
||||||
making modifications to it, including all modules it contains, plus
|
|
||||||
any associated interface definition files, scripts used to control
|
|
||||||
compilation and installation of an Executable, or source code
|
|
||||||
differential comparisons against either the Original Code or another
|
|
||||||
well known, available Covered Code of the Contributor's choice. The
|
|
||||||
Source Code can be in a compressed or archival form, provided the
|
|
||||||
appropriate decompression or de-archiving software is widely available
|
|
||||||
for no charge.
|
|
||||||
|
|
||||||
1.12. "You" (or "Your") means an individual or a legal entity
|
|
||||||
exercising rights under, and complying with all of the terms of, this
|
|
||||||
License or a future version of this License issued under Section 6.1.
|
|
||||||
For legal entities, "You" includes any entity which controls, is
|
|
||||||
controlled by, or is under common control with You. For purposes of
|
|
||||||
this definition, "control" means (a) the power, direct or indirect,
|
|
||||||
to cause the direction or management of such entity, whether by
|
|
||||||
contract or otherwise, or (b) ownership of more than fifty percent
|
|
||||||
(50%) of the outstanding shares or beneficial ownership of such
|
|
||||||
entity.
|
|
||||||
|
|
||||||
2. Source Code License.
|
|
||||||
|
|
||||||
2.1. The Initial Developer Grant.
|
|
||||||
The Initial Developer hereby grants You a world-wide, royalty-free,
|
|
||||||
non-exclusive license, subject to third party intellectual property
|
|
||||||
claims:
|
|
||||||
(a) under intellectual property rights (other than patent or
|
|
||||||
trademark) Licensable by Initial Developer to use, reproduce,
|
|
||||||
modify, display, perform, sublicense and distribute the Original
|
|
||||||
Code (or portions thereof) with or without Modifications, and/or
|
|
||||||
as part of a Larger Work; and
|
|
||||||
|
|
||||||
(b) under Patents Claims infringed by the making, using or
|
|
||||||
selling of Original Code, to make, have made, use, practice,
|
|
||||||
sell, and offer for sale, and/or otherwise dispose of the
|
|
||||||
Original Code (or portions thereof).
|
|
||||||
|
|
||||||
(c) the licenses granted in this Section 2.1(a) and (b) are
|
|
||||||
effective on the date Initial Developer first distributes
|
|
||||||
Original Code under the terms of this License.
|
|
||||||
|
|
||||||
(d) Notwithstanding Section 2.1(b) above, no patent license is
|
|
||||||
granted: 1) for code that You delete from the Original Code; 2)
|
|
||||||
separate from the Original Code; or 3) for infringements caused
|
|
||||||
by: i) the modification of the Original Code or ii) the
|
|
||||||
combination of the Original Code with other software or devices.
|
|
||||||
|
|
||||||
2.2. Contributor Grant.
|
|
||||||
Subject to third party intellectual property claims, each Contributor
|
|
||||||
hereby grants You a world-wide, royalty-free, non-exclusive license
|
|
||||||
|
|
||||||
(a) under intellectual property rights (other than patent or
|
|
||||||
trademark) Licensable by Contributor, to use, reproduce, modify,
|
|
||||||
display, perform, sublicense and distribute the Modifications
|
|
||||||
created by such Contributor (or portions thereof) either on an
|
|
||||||
unmodified basis, with other Modifications, as Covered Code
|
|
||||||
and/or as part of a Larger Work; and
|
|
||||||
|
|
||||||
(b) under Patent Claims infringed by the making, using, or
|
|
||||||
selling of Modifications made by that Contributor either alone
|
|
||||||
and/or in combination with its Contributor Version (or portions
|
|
||||||
of such combination), to make, use, sell, offer for sale, have
|
|
||||||
made, and/or otherwise dispose of: 1) Modifications made by that
|
|
||||||
Contributor (or portions thereof); and 2) the combination of
|
|
||||||
Modifications made by that Contributor with its Contributor
|
|
||||||
Version (or portions of such combination).
|
|
||||||
|
|
||||||
(c) the licenses granted in Sections 2.2(a) and 2.2(b) are
|
|
||||||
effective on the date Contributor first makes Commercial Use of
|
|
||||||
the Covered Code.
|
|
||||||
|
|
||||||
(d) Notwithstanding Section 2.2(b) above, no patent license is
|
|
||||||
granted: 1) for any code that Contributor has deleted from the
|
|
||||||
Contributor Version; 2) separate from the Contributor Version;
|
|
||||||
3) for infringements caused by: i) third party modifications of
|
|
||||||
Contributor Version or ii) the combination of Modifications made
|
|
||||||
by that Contributor with other software (except as part of the
|
|
||||||
Contributor Version) or other devices; or 4) under Patent Claims
|
|
||||||
infringed by Covered Code in the absence of Modifications made by
|
|
||||||
that Contributor.
|
|
||||||
|
|
||||||
3. Distribution Obligations.
|
|
||||||
|
|
||||||
3.1. Application of License.
|
|
||||||
The Modifications which You create or to which You contribute are
|
|
||||||
governed by the terms of this License, including without limitation
|
|
||||||
Section 2.2. The Source Code version of Covered Code may be
|
|
||||||
distributed only under the terms of this License or a future version
|
|
||||||
of this License released under Section 6.1, and You must include a
|
|
||||||
copy of this License with every copy of the Source Code You
|
|
||||||
distribute. You may not offer or impose any terms on any Source Code
|
|
||||||
version that alters or restricts the applicable version of this
|
|
||||||
License or the recipients' rights hereunder. However, You may include
|
|
||||||
an additional document offering the additional rights described in
|
|
||||||
Section 3.5.
|
|
||||||
|
|
||||||
3.2. Availability of Source Code.
|
|
||||||
Any Modification which You create or to which You contribute must be
|
|
||||||
made available in Source Code form under the terms of this License
|
|
||||||
either on the same media as an Executable version or via an accepted
|
|
||||||
Electronic Distribution Mechanism to anyone to whom you made an
|
|
||||||
Executable version available; and if made available via Electronic
|
|
||||||
Distribution Mechanism, must remain available for at least twelve (12)
|
|
||||||
months after the date it initially became available, or at least six
|
|
||||||
(6) months after a subsequent version of that particular Modification
|
|
||||||
has been made available to such recipients. You are responsible for
|
|
||||||
ensuring that the Source Code version remains available even if the
|
|
||||||
Electronic Distribution Mechanism is maintained by a third party.
|
|
||||||
|
|
||||||
3.3. Description of Modifications.
|
|
||||||
You must cause all Covered Code to which You contribute to contain a
|
|
||||||
file documenting the changes You made to create that Covered Code and
|
|
||||||
the date of any change. You must include a prominent statement that
|
|
||||||
the Modification is derived, directly or indirectly, from Original
|
|
||||||
Code provided by the Initial Developer and including the name of the
|
|
||||||
Initial Developer in (a) the Source Code, and (b) in any notice in an
|
|
||||||
Executable version or related documentation in which You describe the
|
|
||||||
origin or ownership of the Covered Code.
|
|
||||||
|
|
||||||
3.4. Intellectual Property Matters
|
|
||||||
(a) Third Party Claims.
|
|
||||||
If Contributor has knowledge that a license under a third party's
|
|
||||||
intellectual property rights is required to exercise the rights
|
|
||||||
granted by such Contributor under Sections 2.1 or 2.2,
|
|
||||||
Contributor must include a text file with the Source Code
|
|
||||||
distribution titled "LEGAL" which describes the claim and the
|
|
||||||
party making the claim in sufficient detail that a recipient will
|
|
||||||
know whom to contact. If Contributor obtains such knowledge after
|
|
||||||
the Modification is made available as described in Section 3.2,
|
|
||||||
Contributor shall promptly modify the LEGAL file in all copies
|
|
||||||
Contributor makes available thereafter and shall take other steps
|
|
||||||
(such as notifying appropriate mailing lists or newsgroups)
|
|
||||||
reasonably calculated to inform those who received the Covered
|
|
||||||
Code that new knowledge has been obtained.
|
|
||||||
|
|
||||||
(b) Contributor APIs.
|
|
||||||
If Contributor's Modifications include an application programming
|
|
||||||
interface and Contributor has knowledge of patent licenses which
|
|
||||||
are reasonably necessary to implement that API, Contributor must
|
|
||||||
also include this information in the LEGAL file.
|
|
||||||
|
|
||||||
(c) Representations.
|
|
||||||
Contributor represents that, except as disclosed pursuant to
|
|
||||||
Section 3.4(a) above, Contributor believes that Contributor's
|
|
||||||
Modifications are Contributor's original creation(s) and/or
|
|
||||||
Contributor has sufficient rights to grant the rights conveyed by
|
|
||||||
this License.
|
|
||||||
|
|
||||||
3.5. Required Notices.
|
|
||||||
You must duplicate the notice in Exhibit A in each file of the Source
|
|
||||||
Code. If it is not possible to put such notice in a particular Source
|
|
||||||
Code file due to its structure, then You must include such notice in a
|
|
||||||
location (such as a relevant directory) where a user would be likely
|
|
||||||
to look for such a notice. If You created one or more Modification(s)
|
|
||||||
You may add your name as a Contributor to the notice described in
|
|
||||||
Exhibit A. You must also duplicate this License in any documentation
|
|
||||||
for the Source Code where You describe recipients' rights or ownership
|
|
||||||
rights relating to Covered Code. You may choose to offer, and to
|
|
||||||
charge a fee for, warranty, support, indemnity or liability
|
|
||||||
obligations to one or more recipients of Covered Code. However, You
|
|
||||||
may do so only on Your own behalf, and not on behalf of the Initial
|
|
||||||
Developer or any Contributor. You must make it absolutely clear than
|
|
||||||
any such warranty, support, indemnity or liability obligation is
|
|
||||||
offered by You alone, and You hereby agree to indemnify the Initial
|
|
||||||
Developer and every Contributor for any liability incurred by the
|
|
||||||
Initial Developer or such Contributor as a result of warranty,
|
|
||||||
support, indemnity or liability terms You offer.
|
|
||||||
|
|
||||||
3.6. Distribution of Executable Versions.
|
|
||||||
You may distribute Covered Code in Executable form only if the
|
|
||||||
requirements of Section 3.1-3.5 have been met for that Covered Code,
|
|
||||||
and if You include a notice stating that the Source Code version of
|
|
||||||
the Covered Code is available under the terms of this License,
|
|
||||||
including a description of how and where You have fulfilled the
|
|
||||||
obligations of Section 3.2. The notice must be conspicuously included
|
|
||||||
in any notice in an Executable version, related documentation or
|
|
||||||
collateral in which You describe recipients' rights relating to the
|
|
||||||
Covered Code. You may distribute the Executable version of Covered
|
|
||||||
Code or ownership rights under a license of Your choice, which may
|
|
||||||
contain terms different from this License, provided that You are in
|
|
||||||
compliance with the terms of this License and that the license for the
|
|
||||||
Executable version does not attempt to limit or alter the recipient's
|
|
||||||
rights in the Source Code version from the rights set forth in this
|
|
||||||
License. If You distribute the Executable version under a different
|
|
||||||
license You must make it absolutely clear that any terms which differ
|
|
||||||
from this License are offered by You alone, not by the Initial
|
|
||||||
Developer or any Contributor. You hereby agree to indemnify the
|
|
||||||
Initial Developer and every Contributor for any liability incurred by
|
|
||||||
the Initial Developer or such Contributor as a result of any such
|
|
||||||
terms You offer.
|
|
||||||
|
|
||||||
3.7. Larger Works.
|
|
||||||
You may create a Larger Work by combining Covered Code with other code
|
|
||||||
not governed by the terms of this License and distribute the Larger
|
|
||||||
Work as a single product. In such a case, You must make sure the
|
|
||||||
requirements of this License are fulfilled for the Covered Code.
|
|
||||||
|
|
||||||
4. Inability to Comply Due to Statute or Regulation.
|
|
||||||
|
|
||||||
If it is impossible for You to comply with any of the terms of this
|
|
||||||
License with respect to some or all of the Covered Code due to
|
|
||||||
statute, judicial order, or regulation then You must: (a) comply with
|
|
||||||
the terms of this License to the maximum extent possible; and (b)
|
|
||||||
describe the limitations and the code they affect. Such description
|
|
||||||
must be included in the LEGAL file described in Section 3.4 and must
|
|
||||||
be included with all distributions of the Source Code. Except to the
|
|
||||||
extent prohibited by statute or regulation, such description must be
|
|
||||||
sufficiently detailed for a recipient of ordinary skill to be able to
|
|
||||||
understand it.
|
|
||||||
|
|
||||||
5. Application of this License.
|
|
||||||
|
|
||||||
This License applies to code to which the Initial Developer has
|
|
||||||
attached the notice in Exhibit A and to related Covered Code.
|
|
||||||
|
|
||||||
6. Versions of the License.
|
|
||||||
|
|
||||||
6.1. New Versions.
|
|
||||||
Netscape Communications Corporation ("Netscape") may publish revised
|
|
||||||
and/or new versions of the License from time to time. Each version
|
|
||||||
will be given a distinguishing version number.
|
|
||||||
|
|
||||||
6.2. Effect of New Versions.
|
|
||||||
Once Covered Code has been published under a particular version of the
|
|
||||||
License, You may always continue to use it under the terms of that
|
|
||||||
version. You may also choose to use such Covered Code under the terms
|
|
||||||
of any subsequent version of the License published by Netscape. No one
|
|
||||||
other than Netscape has the right to modify the terms applicable to
|
|
||||||
Covered Code created under this License.
|
|
||||||
|
|
||||||
6.3. Derivative Works.
|
|
||||||
If You create or use a modified version of this License (which you may
|
|
||||||
only do in order to apply it to code which is not already Covered Code
|
|
||||||
governed by this License), You must (a) rename Your license so that
|
|
||||||
the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
|
|
||||||
"MPL", "NPL" or any confusingly similar phrase do not appear in your
|
|
||||||
license (except to note that your license differs from this License)
|
|
||||||
and (b) otherwise make it clear that Your version of the license
|
|
||||||
contains terms which differ from the Mozilla Public License and
|
|
||||||
Netscape Public License. (Filling in the name of the Initial
|
|
||||||
Developer, Original Code or Contributor in the notice described in
|
|
||||||
Exhibit A shall not of themselves be deemed to be modifications of
|
|
||||||
this License.)
|
|
||||||
|
|
||||||
7. DISCLAIMER OF WARRANTY.
|
|
||||||
|
|
||||||
COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
|
|
||||||
WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
|
|
||||||
DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
|
|
||||||
THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
|
|
||||||
IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
|
|
||||||
YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
|
|
||||||
COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
|
|
||||||
OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
|
|
||||||
ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
|
|
||||||
|
|
||||||
8. TERMINATION.
|
|
||||||
|
|
||||||
8.1. This License and the rights granted hereunder will terminate
|
|
||||||
automatically if You fail to comply with terms herein and fail to cure
|
|
||||||
such breach within 30 days of becoming aware of the breach. All
|
|
||||||
sublicenses to the Covered Code which are properly granted shall
|
|
||||||
survive any termination of this License. Provisions which, by their
|
|
||||||
nature, must remain in effect beyond the termination of this License
|
|
||||||
shall survive.
|
|
||||||
|
|
||||||
8.2. If You initiate litigation by asserting a patent infringement
|
|
||||||
claim (excluding declatory judgment actions) against Initial Developer
|
|
||||||
or a Contributor (the Initial Developer or Contributor against whom
|
|
||||||
You file such action is referred to as "Participant") alleging that:
|
|
||||||
|
|
||||||
(a) such Participant's Contributor Version directly or indirectly
|
|
||||||
infringes any patent, then any and all rights granted by such
|
|
||||||
Participant to You under Sections 2.1 and/or 2.2 of this License
|
|
||||||
shall, upon 60 days notice from Participant terminate prospectively,
|
|
||||||
unless if within 60 days after receipt of notice You either: (i)
|
|
||||||
agree in writing to pay Participant a mutually agreeable reasonable
|
|
||||||
royalty for Your past and future use of Modifications made by such
|
|
||||||
Participant, or (ii) withdraw Your litigation claim with respect to
|
|
||||||
the Contributor Version against such Participant. If within 60 days
|
|
||||||
of notice, a reasonable royalty and payment arrangement are not
|
|
||||||
mutually agreed upon in writing by the parties or the litigation claim
|
|
||||||
is not withdrawn, the rights granted by Participant to You under
|
|
||||||
Sections 2.1 and/or 2.2 automatically terminate at the expiration of
|
|
||||||
the 60 day notice period specified above.
|
|
||||||
|
|
||||||
(b) any software, hardware, or device, other than such Participant's
|
|
||||||
Contributor Version, directly or indirectly infringes any patent, then
|
|
||||||
any rights granted to You by such Participant under Sections 2.1(b)
|
|
||||||
and 2.2(b) are revoked effective as of the date You first made, used,
|
|
||||||
sold, distributed, or had made, Modifications made by that
|
|
||||||
Participant.
|
|
||||||
|
|
||||||
8.3. If You assert a patent infringement claim against Participant
|
|
||||||
alleging that such Participant's Contributor Version directly or
|
|
||||||
indirectly infringes any patent where such claim is resolved (such as
|
|
||||||
by license or settlement) prior to the initiation of patent
|
|
||||||
infringement litigation, then the reasonable value of the licenses
|
|
||||||
granted by such Participant under Sections 2.1 or 2.2 shall be taken
|
|
||||||
into account in determining the amount or value of any payment or
|
|
||||||
license.
|
|
||||||
|
|
||||||
8.4. In the event of termination under Sections 8.1 or 8.2 above,
|
|
||||||
all end user license agreements (excluding distributors and resellers)
|
|
||||||
which have been validly granted by You or any distributor hereunder
|
|
||||||
prior to termination shall survive termination.
|
|
||||||
|
|
||||||
9. LIMITATION OF LIABILITY.
|
|
||||||
|
|
||||||
UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
|
|
||||||
(INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
|
|
||||||
DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
|
|
||||||
OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
|
|
||||||
ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
|
|
||||||
CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
|
|
||||||
WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
|
|
||||||
COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
|
|
||||||
INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
|
|
||||||
LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
|
|
||||||
RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
|
|
||||||
PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
|
|
||||||
EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
|
|
||||||
THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
|
|
||||||
|
|
||||||
10. U.S. GOVERNMENT END USERS.
|
|
||||||
|
|
||||||
The Covered Code is a "commercial item," as that term is defined in
|
|
||||||
48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
|
|
||||||
software" and "commercial computer software documentation," as such
|
|
||||||
terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
|
|
||||||
C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
|
|
||||||
all U.S. Government End Users acquire Covered Code with only those
|
|
||||||
rights set forth herein.
|
|
||||||
|
|
||||||
11. MISCELLANEOUS.
|
|
||||||
|
|
||||||
This License represents the complete agreement concerning subject
|
|
||||||
matter hereof. If any provision of this License is held to be
|
|
||||||
unenforceable, such provision shall be reformed only to the extent
|
|
||||||
necessary to make it enforceable. This License shall be governed by
|
|
||||||
California law provisions (except to the extent applicable law, if
|
|
||||||
any, provides otherwise), excluding its conflict-of-law provisions.
|
|
||||||
With respect to disputes in which at least one party is a citizen of,
|
|
||||||
or an entity chartered or registered to do business in the United
|
|
||||||
States of America, any litigation relating to this License shall be
|
|
||||||
subject to the jurisdiction of the Federal Courts of the Northern
|
|
||||||
District of California, with venue lying in Santa Clara County,
|
|
||||||
California, with the losing party responsible for costs, including
|
|
||||||
without limitation, court costs and reasonable attorneys' fees and
|
|
||||||
expenses. The application of the United Nations Convention on
|
|
||||||
Contracts for the International Sale of Goods is expressly excluded.
|
|
||||||
Any law or regulation which provides that the language of a contract
|
|
||||||
shall be construed against the drafter shall not apply to this
|
|
||||||
License.
|
|
||||||
|
|
||||||
12. RESPONSIBILITY FOR CLAIMS.
|
|
||||||
|
|
||||||
As between Initial Developer and the Contributors, each party is
|
|
||||||
responsible for claims and damages arising, directly or indirectly,
|
|
||||||
out of its utilization of rights under this License and You agree to
|
|
||||||
work with Initial Developer and Contributors to distribute such
|
|
||||||
responsibility on an equitable basis. Nothing herein is intended or
|
|
||||||
shall be deemed to constitute any admission of liability.
|
|
||||||
|
|
||||||
13. MULTIPLE-LICENSED CODE.
|
|
||||||
|
|
||||||
Initial Developer may designate portions of the Covered Code as
|
|
||||||
"Multiple-Licensed". "Multiple-Licensed" means that the Initial
|
|
||||||
Developer permits you to utilize portions of the Covered Code under
|
|
||||||
Your choice of the NPL or the alternative licenses, if any, specified
|
|
||||||
by the Initial Developer in the file described in Exhibit A.
|
|
||||||
|
|
||||||
EXHIBIT A -Mozilla Public License.
|
|
||||||
|
|
||||||
``The contents of this file are subject to the Mozilla Public License
|
|
||||||
Version 1.1 (the "License"); you may not use this file except in
|
|
||||||
compliance with the License. You may obtain a copy of the License at
|
|
||||||
http://www.mozilla.org/MPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS"
|
|
||||||
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
|
||||||
License for the specific language governing rights and limitations
|
|
||||||
under the License.
|
|
||||||
|
|
||||||
The Original Code is ______________________________________.
|
|
||||||
|
|
||||||
The Initial Developer of the Original Code is ________________________.
|
|
||||||
Portions created by ______________________ are Copyright (C) ______
|
|
||||||
_______________________. All Rights Reserved.
|
|
||||||
|
|
||||||
Contributor(s): ______________________________________.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms
|
|
||||||
of the _____ license (the "[___] License"), in which case the
|
|
||||||
provisions of [______] License are applicable instead of those
|
|
||||||
above. If you wish to allow use of your version of this file only
|
|
||||||
under the terms of the [____] License and not to allow others to use
|
|
||||||
your version of this file under the MPL, indicate your decision by
|
|
||||||
deleting the provisions above and replace them with the notice and
|
|
||||||
other provisions required by the [___] License. If you do not delete
|
|
||||||
the provisions above, a recipient may use your version of this file
|
|
||||||
under either the MPL or the [___] License."
|
|
||||||
|
|
||||||
[NOTE: The text of this Exhibit A may differ slightly from the text of
|
|
||||||
the notices in the Source Code files of the Original Code. You should
|
|
||||||
use the text of this Exhibit A rather than the text found in the
|
|
||||||
Original Code Source Code for Your Modifications.]
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
|
|
||||||
AMENDMENTS
|
|
||||||
|
|
||||||
The Netscape Public License Version 1.1 ("NPL") consists of the
|
|
||||||
Mozilla Public License Version 1.1 with the following Amendments,
|
|
||||||
including Exhibit A-Netscape Public License. Files identified with
|
|
||||||
"Exhibit A-Netscape Public License" are governed by the Netscape
|
|
||||||
Public License Version 1.1.
|
|
||||||
|
|
||||||
Additional Terms applicable to the Netscape Public License.
|
|
||||||
I. Effect.
|
|
||||||
These additional terms described in this Netscape Public
|
|
||||||
License -- Amendments shall apply to the Mozilla Communicator
|
|
||||||
client code and to all Covered Code under this License.
|
|
||||||
|
|
||||||
II. "Netscape's Branded Code" means Covered Code that Netscape
|
|
||||||
distributes and/or permits others to distribute under one or more
|
|
||||||
trademark(s) which are controlled by Netscape but which are not
|
|
||||||
licensed for use under this License.
|
|
||||||
|
|
||||||
III. Netscape and logo.
|
|
||||||
This License does not grant any rights to use the trademarks
|
|
||||||
"Netscape", the "Netscape N and horizon" logo or the "Netscape
|
|
||||||
lighthouse" logo, "Netcenter", "Gecko", "Java" or "JavaScript",
|
|
||||||
"Smart Browsing" even if such marks are included in the Original
|
|
||||||
Code or Modifications.
|
|
||||||
|
|
||||||
IV. Inability to Comply Due to Contractual Obligation.
|
|
||||||
Prior to licensing the Original Code under this License, Netscape
|
|
||||||
has licensed third party code for use in Netscape's Branded Code.
|
|
||||||
To the extent that Netscape is limited contractually from making
|
|
||||||
such third party code available under this License, Netscape may
|
|
||||||
choose to reintegrate such code into Covered Code without being
|
|
||||||
required to distribute such code in Source Code form, even if
|
|
||||||
such code would otherwise be considered "Modifications" under
|
|
||||||
this License.
|
|
||||||
|
|
||||||
V. Use of Modifications and Covered Code by Initial Developer.
|
|
||||||
V.1. In General.
|
|
||||||
The obligations of Section 3 apply to Netscape, except to
|
|
||||||
the extent specified in this Amendment, Section V.2 and V.3.
|
|
||||||
|
|
||||||
V.2. Other Products.
|
|
||||||
Netscape may include Covered Code in products other than the
|
|
||||||
Netscape's Branded Code which are released by Netscape
|
|
||||||
during the two (2) years following the release date of the
|
|
||||||
Original Code, without such additional products becoming
|
|
||||||
subject to the terms of this License, and may license such
|
|
||||||
additional products on different terms from those contained
|
|
||||||
in this License.
|
|
||||||
|
|
||||||
V.3. Alternative Licensing.
|
|
||||||
Netscape may license the Source Code of Netscape's Branded
|
|
||||||
Code, including Modifications incorporated therein, without
|
|
||||||
such Netscape Branded Code becoming subject to the terms of
|
|
||||||
this License, and may license such Netscape Branded Code on
|
|
||||||
different terms from those contained in this License.
|
|
||||||
|
|
||||||
VI. Litigation.
|
|
||||||
Notwithstanding the limitations of Section 11 above, the
|
|
||||||
provisions regarding litigation in Section 11(a), (b) and (c) of
|
|
||||||
the License shall apply to all disputes relating to this License.
|
|
||||||
|
|
||||||
EXHIBIT A-Netscape Public License.
|
|
||||||
|
|
||||||
"The contents of this file are subject to the Netscape Public
|
|
||||||
License Version 1.1 (the "License"); you may not use this file
|
|
||||||
except in compliance with the License. You may obtain a copy of
|
|
||||||
the License at http://www.mozilla.org/NPL/
|
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS
|
|
||||||
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
||||||
implied. See the License for the specific language governing
|
|
||||||
rights and limitations under the License.
|
|
||||||
|
|
||||||
The Original Code is Mozilla Communicator client code, released
|
|
||||||
March 31, 1998.
|
|
||||||
|
|
||||||
The Initial Developer of the Original Code is Netscape
|
|
||||||
Communications Corporation. Portions created by Netscape are
|
|
||||||
Copyright (C) 1998-1999 Netscape Communications Corporation. All
|
|
||||||
Rights Reserved.
|
|
||||||
|
|
||||||
Contributor(s): ______________________________________.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the
|
|
||||||
terms of the _____ license (the "[___] License"), in which case
|
|
||||||
the provisions of [______] License are applicable instead of
|
|
||||||
those above. If you wish to allow use of your version of this
|
|
||||||
file only under the terms of the [____] License and not to allow
|
|
||||||
others to use your version of this file under the NPL, indicate
|
|
||||||
your decision by deleting the provisions above and replace them
|
|
||||||
with the notice and other provisions required by the [___]
|
|
||||||
License. If you do not delete the provisions above, a recipient
|
|
||||||
may use your version of this file under either the NPL or the
|
|
||||||
[___] License."
|
|
|
@ -1,897 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2005-2013 Inverse inc.
|
|
||||||
Copyright (C) 2005 SKYRIX Software AG
|
|
||||||
|
|
||||||
This file is part of SOGo.
|
|
||||||
|
|
||||||
SOGo is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU Lesser General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2, or (at your option) any
|
|
||||||
later version.
|
|
||||||
|
|
||||||
SOGo is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
||||||
License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with OGo; see the file COPYING. If not, write toge the
|
|
||||||
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|
||||||
02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
DIV#leftPanel
|
|
||||||
{
|
|
||||||
position: absolute;
|
|
||||||
top: 85px;
|
|
||||||
left: 0px;
|
|
||||||
width: 15em;
|
|
||||||
bottom: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#rightPanel
|
|
||||||
{ position: absolute;
|
|
||||||
top: 80px;
|
|
||||||
left: 15em;
|
|
||||||
right: 0px;
|
|
||||||
bottom: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
margin-left: 5px;
|
|
||||||
padding: 0px;
|
|
||||||
overflow: hidden; }
|
|
||||||
|
|
||||||
/* top list */
|
|
||||||
DIV#mailboxContent
|
|
||||||
{ cursor: default;
|
|
||||||
position: absolute;
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
top: 2.5em;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
height: 15.5em;
|
|
||||||
border-left: 1px solid #9B9B9B;
|
|
||||||
overflow: hidden; }
|
|
||||||
|
|
||||||
DIV#mailboxList
|
|
||||||
{ overflow: auto;
|
|
||||||
overflow-x: hidden; }
|
|
||||||
|
|
||||||
DIV#messageContent
|
|
||||||
{ position: absolute;
|
|
||||||
overflow: hidden;
|
|
||||||
top: 18em;
|
|
||||||
bottom: 0px;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
margin-top: 5px;
|
|
||||||
padding: 0px;
|
|
||||||
border: 0px;
|
|
||||||
border-top: 1px solid #aaa;
|
|
||||||
border-left: 1px solid #aaa;
|
|
||||||
background: #fff; }
|
|
||||||
|
|
||||||
DIV#messageContent P IMG
|
|
||||||
{ border: 0px;
|
|
||||||
vertical-align: middle;
|
|
||||||
margin-right: 1em; }
|
|
||||||
|
|
||||||
DIV#folderTreeContent
|
|
||||||
{ border-top: 1px solid #909090;
|
|
||||||
border-left: 1px solid #909090;
|
|
||||||
border-bottom: 1px solid #FFFFFF;
|
|
||||||
border-right: 1px solid #FFFFFF;
|
|
||||||
position: absolute;
|
|
||||||
background: #CCDDEC;
|
|
||||||
color: #535D6D;
|
|
||||||
width: auto;
|
|
||||||
top: 2em;
|
|
||||||
bottom: 0px;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
overflow: auto; }
|
|
||||||
|
|
||||||
.aptview_title
|
|
||||||
{
|
|
||||||
color: #000000;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.aptview_text
|
|
||||||
{
|
|
||||||
color: #000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.apt_other
|
|
||||||
{
|
|
||||||
color: #000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.apt_other_print
|
|
||||||
{
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* new stuff for Thunderbird like mailer */
|
|
||||||
|
|
||||||
.vertframerow
|
|
||||||
{
|
|
||||||
border-top-color: white;
|
|
||||||
border-top-width: 1px;
|
|
||||||
border-top-style: solid;
|
|
||||||
border-bottom-color: #808080;
|
|
||||||
border-bottom-width: 1px;
|
|
||||||
border-bottom-style: solid;
|
|
||||||
background-color: #dcdad5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.foldercell
|
|
||||||
{
|
|
||||||
width: 25%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contentcell
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
.embedwhite_out
|
|
||||||
{
|
|
||||||
border-width: 1px;
|
|
||||||
border-style: solid;
|
|
||||||
border-top-color: #808080;
|
|
||||||
border-left-color: #808080;
|
|
||||||
border-bottom-color: white;
|
|
||||||
border-right-color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.embedwhite_in
|
|
||||||
{
|
|
||||||
border-width: 1px;
|
|
||||||
border-style: solid;
|
|
||||||
border-top-color: #808080; /* TODO */
|
|
||||||
border-left-color: #808080; /* TODO */
|
|
||||||
border-bottom-color: #808080;
|
|
||||||
border-right-color: #808080;
|
|
||||||
|
|
||||||
background-color: white;
|
|
||||||
/* height: 300px; */
|
|
||||||
/* height: 100%; */
|
|
||||||
}
|
|
||||||
|
|
||||||
.titlediv
|
|
||||||
{
|
|
||||||
height: 2em;
|
|
||||||
line-height: 18px;
|
|
||||||
vertical-align: middle;
|
|
||||||
padding-top: 0px;
|
|
||||||
padding-left: 6px; }
|
|
||||||
|
|
||||||
TABLE.titletable
|
|
||||||
{
|
|
||||||
height: 24px;
|
|
||||||
vertical-align: middle;
|
|
||||||
padding-top: 6px;
|
|
||||||
padding-left: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
TABLE.titletable TD.titlecell SELECT
|
|
||||||
{
|
|
||||||
display: -moz-popup;
|
|
||||||
border-top: 1px solid #fff;
|
|
||||||
border-left: 1px solid #fff;
|
|
||||||
border-right: 2px solid #222;
|
|
||||||
border-bottom: 2px solid #222;
|
|
||||||
-moz-border-bottom-colors: #000 #9c9a94 transparent;
|
|
||||||
-moz-border-right-colors: #000 #9c9a94 transparent;
|
|
||||||
background: #dcdad5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.whitesec_title
|
|
||||||
{
|
|
||||||
background-color: #dcdad5;
|
|
||||||
padding: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.treecell
|
|
||||||
{
|
|
||||||
color: black;
|
|
||||||
vertical-align: bottom;
|
|
||||||
padding-left: 4px; /* move away from the icon */
|
|
||||||
padding-right: 2px; /* move away from the right border */
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#folderTreeContent
|
|
||||||
{ -khtml-user-select: none;}
|
|
||||||
|
|
||||||
/* mailbox tree (dtree) */
|
|
||||||
DIV.dTreeNode SPAN.unseen
|
|
||||||
{ font-weight: bold; }
|
|
||||||
|
|
||||||
/* mail tableview */
|
|
||||||
|
|
||||||
/* messages table with fixed headers */
|
|
||||||
|
|
||||||
TABLE.messageList
|
|
||||||
{ width: 100%;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-khtml-user-select: none; }
|
|
||||||
|
|
||||||
TABLE.messageList TH,
|
|
||||||
TABLE.messageList TD
|
|
||||||
{ height: 20px;
|
|
||||||
min-height: 20px;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
padding: 0px 3px;
|
|
||||||
min-width: 22px;
|
|
||||||
margin: 0;
|
|
||||||
white-space: nowrap; }
|
|
||||||
|
|
||||||
TABLE.messageList TH,
|
|
||||||
TR#messageCountHeader TH
|
|
||||||
{ height: 22px;
|
|
||||||
min-height: 22px; }
|
|
||||||
|
|
||||||
TR#messageCountHeader TH
|
|
||||||
{ border-top: 0px; }
|
|
||||||
|
|
||||||
TABLE.messageList TD
|
|
||||||
{ border-right: 1px solid transparent; }
|
|
||||||
|
|
||||||
TABLE.messageList .messageThreadColumn,
|
|
||||||
TABLE.messageList .messageFlagColumn,
|
|
||||||
TABLE.messageList .messageAttachmentColumn,
|
|
||||||
TABLE.messageList .messageUnreadColumn
|
|
||||||
{ width: 22px;
|
|
||||||
max-width: 22px;
|
|
||||||
text-align: center; }
|
|
||||||
|
|
||||||
TABLE.messageList .messageSubjectColumn
|
|
||||||
{ max-width: 30%;
|
|
||||||
width: 30%; }
|
|
||||||
|
|
||||||
TABLE.messageList .messageSubjectColumn SPAN
|
|
||||||
{ padding-left: 20px; }
|
|
||||||
|
|
||||||
TABLE.messageList TR.openedThread TD,
|
|
||||||
TABLE.messageList TR.closedThread TD,
|
|
||||||
TABLE.messageList TR.thread .messageThreadColumn
|
|
||||||
{ background-color: #DDD; }
|
|
||||||
|
|
||||||
TABLE.messageList TR.thread TD
|
|
||||||
{ background-color: #EEE; }
|
|
||||||
|
|
||||||
TABLE.messageList TR.thread1 .messageSubjectColumn
|
|
||||||
{ background-position: 20px 0px !important;
|
|
||||||
padding-left: 20px; }
|
|
||||||
TABLE.messageList TR.thread2 .messageSubjectColumn
|
|
||||||
{ background-position: 40px 0px !important;
|
|
||||||
padding-left: 40px; }
|
|
||||||
TABLE.messageList TR.thread3 .messageSubjectColumn
|
|
||||||
{ background-position: 60px 0px !important;
|
|
||||||
padding-left: 60px; }
|
|
||||||
TABLE.messageList TR.thread4 .messageSubjectColumn
|
|
||||||
{ background-position: 80px 0px !important;
|
|
||||||
padding-left: 80px; }
|
|
||||||
TABLE.messageList TR.thread5 .messageSubjectColumn
|
|
||||||
{ background-position: 100px 0px !important;
|
|
||||||
padding-left: 100px; }
|
|
||||||
TABLE.messageList TR.thread6 .messageSubjectColumn
|
|
||||||
{ background-position: 120px 0px !important;
|
|
||||||
padding-left: 120px; }
|
|
||||||
TABLE.messageList TR.thread7 .messageSubjectColumn
|
|
||||||
{ background-position: 140px 0px !important;
|
|
||||||
padding-left: 140px; }
|
|
||||||
TABLE.messageList TR.thread8 .messageSubjectColumn
|
|
||||||
{ background-position: 160px 0px !important;
|
|
||||||
padding-left: 160px; }
|
|
||||||
TABLE.messageList TR.thread9 .messageSubjectColumn
|
|
||||||
{ background-position: 180px 0px !important;
|
|
||||||
padding-left: 180px; }
|
|
||||||
TABLE.messageList TR.thread10 .messageSubjectColumn
|
|
||||||
{ background-position: 200px 0px !important;
|
|
||||||
padding-left: 200px; }
|
|
||||||
|
|
||||||
TABLE.messageList .messageAddressColumn
|
|
||||||
{ max-width: 18%;
|
|
||||||
width: 18%; }
|
|
||||||
|
|
||||||
TABLE.messageList .messageDateColumn
|
|
||||||
{ max-width: 22%;
|
|
||||||
width: 22%; }
|
|
||||||
|
|
||||||
TABLE.messageList .messagePriorityColumn
|
|
||||||
{ width: 60px;
|
|
||||||
max-width: 60px; }
|
|
||||||
|
|
||||||
TABLE.messageList .messageSizeColumn
|
|
||||||
{ min-width: 40px; }
|
|
||||||
|
|
||||||
TR#rowTop TD
|
|
||||||
{ height: 0;
|
|
||||||
min-height: 0;
|
|
||||||
padding-top: 0;
|
|
||||||
padding-bottom: 0; }
|
|
||||||
|
|
||||||
TABLE.messageList TR._selected TD
|
|
||||||
{ background-color: #9ABCD8;
|
|
||||||
color: #fff; }
|
|
||||||
|
|
||||||
TABLE.messageList TR._deleted TD
|
|
||||||
{ text-decoration: line-through; }
|
|
||||||
|
|
||||||
TABLE.messageList TR.mailer_unreadmail TD,
|
|
||||||
TR.mailer_unreadmail TD.messageSubjectColumn
|
|
||||||
{ font-weight: bold !important; }
|
|
||||||
|
|
||||||
TR.mailer_repliedmailsubject TD.messageSubjectColumn
|
|
||||||
{ background-image: url(icon-replied.png) !important;
|
|
||||||
background-repeat: no-repeat !important;
|
|
||||||
background-position: 0px 0px !important; }
|
|
||||||
|
|
||||||
TR.mailer_forwardedmailsubject TD.messageSubjectColumn
|
|
||||||
{ background-image: url(icon-forwarded.png) !important;
|
|
||||||
background-repeat: no-repeat !important;
|
|
||||||
background-position: 0px 0px !important; }
|
|
||||||
|
|
||||||
TR.mailer_forwardedrepliedmailsubject TD.messageSubjectColumn
|
|
||||||
{
|
|
||||||
background-image: url(icon-forwarded-replied.png) !important;
|
|
||||||
background-repeat: no-repeat !important;
|
|
||||||
background-position: 0px 0px !important; }
|
|
||||||
|
|
||||||
TR.mailer_deletedmailsubject TD.messageSubjectColumn
|
|
||||||
{
|
|
||||||
background-image: url(icon-deleted.png) !important;
|
|
||||||
background-repeat: no-repeat !important;
|
|
||||||
background-position: 0px 0px !important; }
|
|
||||||
|
|
||||||
TD.mailer_readmailsubject A
|
|
||||||
{
|
|
||||||
color: black;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
TD.mailer_unreadmailsubject A
|
|
||||||
{
|
|
||||||
color: black;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
TR.mailer_listcell_deleted TD
|
|
||||||
{
|
|
||||||
text-decoration: line-through;
|
|
||||||
}
|
|
||||||
|
|
||||||
TR.mailer_listcell_regular TD A
|
|
||||||
{
|
|
||||||
color: black;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* mail viewer */
|
|
||||||
#actionButtons
|
|
||||||
{
|
|
||||||
position: absolute;
|
|
||||||
top: 2.5em;
|
|
||||||
right: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup #actionButtons
|
|
||||||
{
|
|
||||||
top: 7.0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#editDraftButton,
|
|
||||||
#loadImagesButton
|
|
||||||
{
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#signedImage
|
|
||||||
{
|
|
||||||
position: absolute;
|
|
||||||
top: 5px;
|
|
||||||
right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup #signedImage
|
|
||||||
{
|
|
||||||
top: 54px;
|
|
||||||
right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
TABLE.mailer_fieldtable
|
|
||||||
{ top: 0px;
|
|
||||||
left: 0px;
|
|
||||||
padding-top: .5em;
|
|
||||||
padding-bottom: .5em;
|
|
||||||
overflow-y: auto;
|
|
||||||
overflow-x: hidden;
|
|
||||||
border-bottom: 1px solid #808080;
|
|
||||||
background: #DDDDDD;
|
|
||||||
width: 100%; }
|
|
||||||
|
|
||||||
DIV.mailer_mailcontent
|
|
||||||
{ background-color: #fff;
|
|
||||||
padding: .5em;
|
|
||||||
position: absolute;
|
|
||||||
top: 7.5em;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
bottom: 0px;
|
|
||||||
overflow: auto; }
|
|
||||||
|
|
||||||
DIV.mailer_mailcontent TABLE
|
|
||||||
{
|
|
||||||
table-layout: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* collapsable header */
|
|
||||||
TD.mailer_fieldname IMG.collapse,
|
|
||||||
TD.mailer_fieldname IMG.expand
|
|
||||||
{ cursor: pointer;
|
|
||||||
padding-right: 5px; }
|
|
||||||
TD.mailer_fieldvalue SPAN.collapse
|
|
||||||
{ white-space: nowrap; }
|
|
||||||
TD.mailer_fieldvalue SPAN.expand
|
|
||||||
{ white-space: normal; }
|
|
||||||
|
|
||||||
TD.mailer_fieldname
|
|
||||||
{
|
|
||||||
white-space: nowrap;
|
|
||||||
padding: 0 1em;
|
|
||||||
text-align: right;
|
|
||||||
font-weight: bold;
|
|
||||||
vertical-align: top;
|
|
||||||
width: 9em;
|
|
||||||
}
|
|
||||||
|
|
||||||
TD.mailer_fieldvalue
|
|
||||||
{ vertical-align: top; }
|
|
||||||
|
|
||||||
TD.mailer_subjectfieldvalue
|
|
||||||
{
|
|
||||||
font-weight: bold;
|
|
||||||
white-space: pre;
|
|
||||||
white-space: pre-wrap; /* css-3 */
|
|
||||||
white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */
|
|
||||||
white-space: -pre-wrap; /* Opera 4-6 */
|
|
||||||
white-space: -o-pre-wrap; /* Opera 7 */
|
|
||||||
white-space: pre-wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
TD.mailer_fieldvalue a
|
|
||||||
{
|
|
||||||
text-decoration: underline;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
TR.deleted TD
|
|
||||||
{ /* text-decoration: line-through; -- alternative display */ }
|
|
||||||
|
|
||||||
img.mailer_imagecontent
|
|
||||||
{
|
|
||||||
border: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV.mailer_plaincontent
|
|
||||||
{
|
|
||||||
position: relative;
|
|
||||||
clear: left;
|
|
||||||
font-family: monospace, fixed;
|
|
||||||
white-space: pre;
|
|
||||||
white-space: pre-wrap; /* css-3 */
|
|
||||||
white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */
|
|
||||||
white-space: -pre-wrap; /* Opera 4-6 */
|
|
||||||
white-space: -o-pre-wrap; /* Opera 7 */
|
|
||||||
word-wrap: break-word; /* Internet Explorer 5.5+ */
|
|
||||||
width: 99%;
|
|
||||||
font-size: inherit;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV.mailer_plaincontent P
|
|
||||||
{
|
|
||||||
line-height: 3em;
|
|
||||||
height: auto;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV.mailer_htmlcontent P
|
|
||||||
{
|
|
||||||
white-space: normal;
|
|
||||||
font-family: sans-serif;
|
|
||||||
font-size: inherit;
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* attachment editor */
|
|
||||||
|
|
||||||
form#attachment_form
|
|
||||||
{
|
|
||||||
background-color: #dcdad5;
|
|
||||||
padding: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div#attachment_list
|
|
||||||
{
|
|
||||||
border-top-color: white;
|
|
||||||
border-top-width: 1px;
|
|
||||||
border-top-style: solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
div#attachment_upload
|
|
||||||
{
|
|
||||||
border-bottom-color: #808080;
|
|
||||||
border-bottom-width: 1px;
|
|
||||||
border-bottom-style: solid;
|
|
||||||
padding: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
TD.attachment_uplabel
|
|
||||||
{
|
|
||||||
width: 15%;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* attachment link viewer */
|
|
||||||
|
|
||||||
DIV.linked_attachment_frame
|
|
||||||
{
|
|
||||||
border: 0px;
|
|
||||||
clear: left;
|
|
||||||
margin: 0px;
|
|
||||||
margin-top: 10px;
|
|
||||||
padding: 5px;
|
|
||||||
/*background: #F0F0F0;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV.linked_attachment_frame fieldset
|
|
||||||
{
|
|
||||||
-webkit-border-radius: 4px;
|
|
||||||
-moz-border-radius: 4px;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV.linked_attachment_frame.file
|
|
||||||
{ display: inline;
|
|
||||||
clear: none;
|
|
||||||
float: left; }
|
|
||||||
|
|
||||||
DIV.linked_attachment_body
|
|
||||||
{
|
|
||||||
border: 0px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV.linked_attachment_meta
|
|
||||||
{
|
|
||||||
color: #444444;
|
|
||||||
border-width: 0;
|
|
||||||
padding: 2px 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
TABLE.linked_attachment_meta
|
|
||||||
{
|
|
||||||
color: #444444;
|
|
||||||
}
|
|
||||||
|
|
||||||
.linked_attachment_body a:hover
|
|
||||||
{
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.linked_attachment_body a:hover .linked_attachment_meta
|
|
||||||
{
|
|
||||||
background-color: #9ABCD8;
|
|
||||||
color: #fff;
|
|
||||||
-webkit-border-radius: 5px;
|
|
||||||
-moz-border-radius: 5px;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.linked_attachment_body a:hover .muted
|
|
||||||
{
|
|
||||||
color: #fff !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV.linked_attachment_body HR
|
|
||||||
{
|
|
||||||
border: 0px;
|
|
||||||
border-top: 1px solid #ddd;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV.bodyFields
|
|
||||||
{
|
|
||||||
background: #eee;
|
|
||||||
line-height: 1.5em;
|
|
||||||
margin: 0.5em 0px;
|
|
||||||
padding-bottom: 0.5em;
|
|
||||||
padding-top: 0.5em;
|
|
||||||
text-align: left;
|
|
||||||
-webkit-border-radius: 4px;
|
|
||||||
-moz-border-radius: 4px;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV.bodyFields SPAN.fieldName
|
|
||||||
{
|
|
||||||
float: left;
|
|
||||||
font-weight: bold;
|
|
||||||
padding-right: 1em;
|
|
||||||
text-align: right;
|
|
||||||
width: 9em;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV.bodyAdditionalFields
|
|
||||||
{
|
|
||||||
color: #777;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV.bodyMailContent
|
|
||||||
{ margin: 0.5em;
|
|
||||||
text-align: left; }
|
|
||||||
|
|
||||||
DIV[datatype~="additional"] > A.node > SPAN.nodeName
|
|
||||||
{ color: #777;
|
|
||||||
font-style: italic; }
|
|
||||||
|
|
||||||
DIV[datatype~="additional"] > A.node._selected > SPAN.nodeName
|
|
||||||
{ color: #fff; }
|
|
||||||
|
|
||||||
/* drag-n-drop */
|
|
||||||
IMG.dragMessage
|
|
||||||
{ position: absolute;
|
|
||||||
visibility: hidden;
|
|
||||||
border: 0px;
|
|
||||||
-moz-opacity: 0.7;
|
|
||||||
opacity: 0.7; }
|
|
||||||
|
|
||||||
TABLE#addr_table
|
|
||||||
{
|
|
||||||
margin-left: 30%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* quota indicator */
|
|
||||||
DIV.quota
|
|
||||||
{ border-bottom: 1px solid #ccc;
|
|
||||||
margin: 2px 4px 2px 2px; }
|
|
||||||
DIV.quota DIV.level
|
|
||||||
{ background-image: url(quota-level.png);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
background-position: 25% 0;
|
|
||||||
border-left: 1px solid #999;
|
|
||||||
border-right: 1px solid #999;
|
|
||||||
/*height: 20px;*/ }
|
|
||||||
DIV.quota DIV.marks DIV
|
|
||||||
{ float: left;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
width: 25%;
|
|
||||||
border: 0;
|
|
||||||
border-right: 1px solid #999;
|
|
||||||
height: 3px; }
|
|
||||||
DIV.quota DIV.level DIV.value
|
|
||||||
{ background-repeat: repeat-x;
|
|
||||||
border-left: 1px solid transparent;
|
|
||||||
height: 9px;
|
|
||||||
margin: 0;
|
|
||||||
position: relative; }
|
|
||||||
DIV.quota DIV.level DIV.value.ok
|
|
||||||
{ background-image: url(quota-level-ok.png); }
|
|
||||||
DIV.quota DIV.level DIV.value.warn
|
|
||||||
{ background-image: url(quota-level-warn.png); }
|
|
||||||
DIV.quota DIV.level DIV.value.alert
|
|
||||||
{ background-image: url(quota-level-alert.png); }
|
|
||||||
DIV.quota DIV.level P
|
|
||||||
{ margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
clear: both;
|
|
||||||
color: #555;
|
|
||||||
font-size: 1em;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
DIV#quotaDialog
|
|
||||||
{ background-image: url("dialog-left.png");
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: top left;
|
|
||||||
position: absolute;
|
|
||||||
top: 100px;
|
|
||||||
left: 75px;
|
|
||||||
width: 200px;
|
|
||||||
z-index: 50; }
|
|
||||||
DIV#quotaDialog DIV
|
|
||||||
{ border: 1px solid #444;
|
|
||||||
background-color: #fff;
|
|
||||||
padding: 5px; }
|
|
||||||
DIV#quotaDialog DIV
|
|
||||||
{ border-left: 0;
|
|
||||||
margin-left: 19px;
|
|
||||||
text-align: left; }
|
|
||||||
DIV#quotaDialog H1,
|
|
||||||
DIV#quotaDialog P
|
|
||||||
{ font-size: 10px;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0; }
|
|
||||||
|
|
||||||
/* drag handles */
|
|
||||||
DIV#verticalDragHandle
|
|
||||||
{ cursor: e-resize;
|
|
||||||
border: 0px;
|
|
||||||
top: 81px;
|
|
||||||
left: 15em;
|
|
||||||
width: 5px;
|
|
||||||
bottom: 0px; }
|
|
||||||
|
|
||||||
DIV#rightDragHandle
|
|
||||||
{ cursor: n-resize;
|
|
||||||
top: 18em;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
height: 5px; }
|
|
||||||
|
|
||||||
@media print
|
|
||||||
{
|
|
||||||
DIV#leftPanel,
|
|
||||||
DIV#verticalDragHandle,
|
|
||||||
DIV#filterPanel,
|
|
||||||
DIV#mailboxContent,
|
|
||||||
DIV.dragHandle
|
|
||||||
{ display: none; }
|
|
||||||
|
|
||||||
DIV#rightPanel
|
|
||||||
{ position: static;
|
|
||||||
overflow: visible;
|
|
||||||
margin: 0px; }
|
|
||||||
|
|
||||||
DIV#messageContent
|
|
||||||
{ position: static;
|
|
||||||
border: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
overflow: visible; }
|
|
||||||
|
|
||||||
TABLE.mailer_fieldtable
|
|
||||||
{ border: 0px;
|
|
||||||
font-family: serif;
|
|
||||||
height: auto;
|
|
||||||
overflow: visible; }
|
|
||||||
|
|
||||||
TD.mailer_fieldname
|
|
||||||
{ text-align: left; }
|
|
||||||
|
|
||||||
TD.mailer_fieldname IMG
|
|
||||||
{ display: none; }
|
|
||||||
|
|
||||||
TD.mailer_fieldvalue,
|
|
||||||
TD.mailer_fieldvalue SPAN.collapse
|
|
||||||
{ white-space: normal; }
|
|
||||||
|
|
||||||
TD.mailer_fieldvalue A
|
|
||||||
{ text-decoration: none;
|
|
||||||
white-space: nowrap;
|
|
||||||
color: #000; }
|
|
||||||
|
|
||||||
A:visited
|
|
||||||
{ color: #00f; }
|
|
||||||
|
|
||||||
DIV.mailer_mailcontent
|
|
||||||
{ position: static;
|
|
||||||
overflow: visible; }
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#dragDropVisual
|
|
||||||
{
|
|
||||||
background-image: url(message.gif);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: 4px 2px;
|
|
||||||
width: 5px;
|
|
||||||
height: 20px;
|
|
||||||
padding-left: 24px;
|
|
||||||
padding-top: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV.copy
|
|
||||||
{
|
|
||||||
background-image: url(message-copy.gif) !important;
|
|
||||||
background-position: 1px -2px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#signatureFlagMessage DIV
|
|
||||||
{ text-align: left !important; }
|
|
||||||
|
|
||||||
DIV#signatureFlagMessage H1,
|
|
||||||
DIV#signatureFlagMessage P
|
|
||||||
{ font-size: 10px;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0; }
|
|
||||||
|
|
||||||
TR#messageCountHeader TD
|
|
||||||
{ border-top: none; }
|
|
||||||
|
|
||||||
/* UIxMailPartICalViewer */
|
|
||||||
#iCalAttendees
|
|
||||||
{ padding: 0; }
|
|
||||||
|
|
||||||
#iCalAttendees dt
|
|
||||||
{ font-weight: bold; }
|
|
||||||
|
|
||||||
#iCalAttendees SPAN
|
|
||||||
{ line-height: 19px; }
|
|
||||||
|
|
||||||
#iCalAttendees DIV.status-icon
|
|
||||||
{ background-repeat: no-repeat;
|
|
||||||
float: left;
|
|
||||||
padding: 0px;
|
|
||||||
clear: both;
|
|
||||||
width: 12px;
|
|
||||||
height: 18px;
|
|
||||||
margin-top: 1px;
|
|
||||||
margin-left: 4px;
|
|
||||||
margin-right: 4px;
|
|
||||||
background-image: url("attendee-partstats.png"); }
|
|
||||||
|
|
||||||
#iCalAttendees .accepted DIV.status-icon
|
|
||||||
{ background-position: 0px 0px; }
|
|
||||||
|
|
||||||
#iCalAttendees .declined DIV.status-icon
|
|
||||||
{ background-position: -12px 0px; }
|
|
||||||
|
|
||||||
#iCalAttendees .needs-action DIV.status-icon
|
|
||||||
{ background-position: -24px 0px; }
|
|
||||||
|
|
||||||
#iCalAttendees .tentative DIV.status-icon
|
|
||||||
{ background-position: -36px 0px; }
|
|
||||||
|
|
||||||
#iCalAttendees .delegated DIV.status-icon
|
|
||||||
{ background-position: -48px 0px; }
|
|
||||||
|
|
||||||
#iCalAttendees .attendeeUser,
|
|
||||||
#iCalAttendees .attendeeUser A
|
|
||||||
{ font-weight: bold; }
|
|
||||||
|
|
||||||
#delegateEditor
|
|
||||||
{ padding-left: 5px; }
|
|
||||||
|
|
||||||
#delegatedTo
|
|
||||||
{ width: 220px; }
|
|
||||||
|
|
||||||
#delegatedTo
|
|
||||||
{ background-image: url("abcard.png");
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: 4px center;
|
|
||||||
padding: 2px 2px 2px 24px;
|
|
||||||
width: 220px; }
|
|
||||||
|
|
||||||
DIV#iCalendarToolbar A.button
|
|
||||||
{ float: left;
|
|
||||||
vertical-align: middle;}
|
|
||||||
|
|
||||||
DIV#iCalendarToolbar
|
|
||||||
{ padding: 0; }
|
|
||||||
|
|
||||||
SPAN#delegateEditor
|
|
||||||
{ line-height: 23px;
|
|
||||||
vertical-align: middle; }
|
|
||||||
|
|
||||||
INPUT#delegatedTo
|
|
||||||
{ float: left; }
|
|
||||||
|
|
||||||
SPAN.floatLeft
|
|
||||||
{ float: left;
|
|
||||||
padding: 0 5px; }
|
|
||||||
|
|
||||||
A#iCalendarDeleteFromCalendar
|
|
||||||
{ float: left; }
|
|
||||||
|
|
||||||
A#iCalendarAddToCalendar
|
|
||||||
{ border-left: 2px solid #E6E7E6;
|
|
||||||
margin-left: 5px;}
|
|
|
@ -1,71 +0,0 @@
|
||||||
var MailerUIdTreeExtension = {
|
|
||||||
elementCounter: 1,
|
|
||||||
folderIcons: { account: "tbtv_account_17x17.png",
|
|
||||||
inbox: "tbtv_inbox_17x17.png",
|
|
||||||
sent: "tbtv_sent_17x17.png",
|
|
||||||
draft: "tbtv_drafts_17x17.png",
|
|
||||||
trash: "tbtv_trash_17x17.png" },
|
|
||||||
folderNames: { inbox: _("InboxFolderName"),
|
|
||||||
sent: _("SentFolderName"),
|
|
||||||
draft: _("DraftsFolderName"),
|
|
||||||
trash: _("TrashFolderName") },
|
|
||||||
_addFolderNode: function (parent, name, fullName, type, unseen) {
|
|
||||||
var icon = this.folderIcons[type];
|
|
||||||
if (icon)
|
|
||||||
icon = ResourcesURL + "/" + icon;
|
|
||||||
else
|
|
||||||
icon = "";
|
|
||||||
var displayName = this.folderNames[type];
|
|
||||||
if (!displayName)
|
|
||||||
displayName = name;
|
|
||||||
displayName += "<span class=\"unseenCount hidden\"> (" + parseInt(unseen) + ")</span>";
|
|
||||||
this.add(this.elementCounter, parent, displayName, 1, '#', fullName,
|
|
||||||
type, '', '', icon, icon, true);
|
|
||||||
this.elementCounter++;
|
|
||||||
},
|
|
||||||
_addFolder: function (parent, folder) {
|
|
||||||
var thisCounter = this.elementCounter;
|
|
||||||
this._addFolderNode(parent, folder.displayName, folder.fullName(), folder.type, folder.unseen);
|
|
||||||
for (var i = 0; i < folder.children.length; i++)
|
|
||||||
this._addFolder(thisCounter, folder.children[i]);
|
|
||||||
},
|
|
||||||
addMailAccount: function (mailAccount) {
|
|
||||||
this._addFolder(0, mailAccount);
|
|
||||||
},
|
|
||||||
setCookie: function(cookieName, cookieValue, expires, path, domain, secure) {
|
|
||||||
|
|
||||||
},
|
|
||||||
getCookie: function(cookieName) {
|
|
||||||
return ("");
|
|
||||||
},
|
|
||||||
updateCookie: function () {
|
|
||||||
if (Mailer.foldersStateTimer)
|
|
||||||
clearTimeout(Mailer.foldersStateTimer);
|
|
||||||
Mailer.foldersStateTimer = setTimeout('saveFoldersState()', 3000); // 3 seconds
|
|
||||||
},
|
|
||||||
getFoldersState: function () {
|
|
||||||
var expandedFolders = new Array();
|
|
||||||
for (var n = 0; n < this.aNodes.length; n++) {
|
|
||||||
if (this.aNodes[n]._io && this.aNodes[n].pid != this.root.id) {
|
|
||||||
expandedFolders.push(this.aNodes[n].dataname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Object.toJSON(expandedFolders);
|
|
||||||
},
|
|
||||||
autoSync: function() {
|
|
||||||
this.config.useCookies = true;
|
|
||||||
},
|
|
||||||
getMailboxNode: function(mailbox) {
|
|
||||||
var childNode = null;
|
|
||||||
for (var i = 0; (childNode == null) && (i < this.aNodes.length); i++) {
|
|
||||||
var aNode = this.aNodes[i];
|
|
||||||
if (aNode.dataname == mailbox) {
|
|
||||||
childNode = $("smailboxTree" + aNode.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((childNode) ? childNode.parentNode : null);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Object.extend(dTree.prototype, MailerUIdTreeExtension);
|
|
|
@ -1,98 +0,0 @@
|
||||||
var PolicyPasswordChangeUnsupported = -3;
|
|
||||||
var PolicyPasswordSystemUnknown = -2;
|
|
||||||
var PolicyPasswordUnknown = -1;
|
|
||||||
var PolicyPasswordExpired = 0;
|
|
||||||
var PolicyAccountLocked = 1;
|
|
||||||
var PolicyChangeAfterReset = 2;
|
|
||||||
var PolicyPasswordModNotAllowed = 3;
|
|
||||||
var PolicyMustSupplyOldPassword = 4;
|
|
||||||
var PolicyInsufficientPasswordQuality = 5;
|
|
||||||
var PolicyPasswordTooShort = 6;
|
|
||||||
var PolicyPasswordTooYoung = 7;
|
|
||||||
var PolicyPasswordInHistory = 8;
|
|
||||||
var PolicyNoError = 65535;
|
|
||||||
|
|
||||||
function _passwordPolicyAjaxCallback(http) {
|
|
||||||
if (http.readyState == 4) {
|
|
||||||
var policy = http.callbackData;
|
|
||||||
policy.callback(http);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function PasswordPolicy(userName, password) {
|
|
||||||
this.userName = userName;
|
|
||||||
this.password = password;
|
|
||||||
}
|
|
||||||
|
|
||||||
PasswordPolicy.prototype = {
|
|
||||||
userName: null,
|
|
||||||
password: null,
|
|
||||||
successCallback: null,
|
|
||||||
failureCallback: null,
|
|
||||||
|
|
||||||
setCallbacks: function(successCallback, failureCallback) {
|
|
||||||
this.successCallback = successCallback;
|
|
||||||
this.failureCallback = failureCallback;
|
|
||||||
},
|
|
||||||
|
|
||||||
changePassword: function (newPassword) {
|
|
||||||
var content = Object.toJSON({ userName: this.userName,
|
|
||||||
password: this.password,
|
|
||||||
newPassword: newPassword });
|
|
||||||
var urlParts = ApplicationBaseURL.split("/");
|
|
||||||
var url = "/" + urlParts[1] + "/so/changePassword";
|
|
||||||
triggerAjaxRequest(url, _passwordPolicyAjaxCallback, this,
|
|
||||||
content, {"content-type": "application/json"} );
|
|
||||||
},
|
|
||||||
|
|
||||||
callback: function(http) {
|
|
||||||
if (isHttpStatus204(http.status)) {
|
|
||||||
if (this.successCallback)
|
|
||||||
this.successCallback(_("The password was changed successfully."));
|
|
||||||
} else {
|
|
||||||
if (this.failureCallback) {
|
|
||||||
var perr = PolicyPasswordUnknown;
|
|
||||||
var error = "";
|
|
||||||
switch (http.status) {
|
|
||||||
case 403:
|
|
||||||
if (http.getResponseHeader("content-type")
|
|
||||||
== "application/json") {
|
|
||||||
var jsonResponse = http.responseText.evalJSON(false);
|
|
||||||
perr = jsonResponse["LDAPPasswordPolicyError"];
|
|
||||||
|
|
||||||
// Normal password change failed
|
|
||||||
if (perr == PolicyNoError) {
|
|
||||||
error = _("Password change failed");
|
|
||||||
} else if (perr == PolicyPasswordModNotAllowed) {
|
|
||||||
error = _("Password change failed - Permission denied");
|
|
||||||
} else if (perr == PolicyInsufficientPasswordQuality) {
|
|
||||||
error = _("Password change failed - Insufficient password quality");
|
|
||||||
} else if (perr == PolicyPasswordTooShort) {
|
|
||||||
error = _("Password change failed - Password is too short");
|
|
||||||
} else if (perr == PolicyPasswordTooYoung) {
|
|
||||||
error = _("Password change failed - Password is too young");
|
|
||||||
} else if (perr == PolicyPasswordInHistory) {
|
|
||||||
error = _("Password change failed - Password is in history");
|
|
||||||
} else {
|
|
||||||
error = _("Unhandled policy error: %{0}").formatted(perr);
|
|
||||||
perr = PolicyPasswordUnknown;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
perr = PolicyPasswordSystemUnknown;
|
|
||||||
error = _("Unhandled error response");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 404:
|
|
||||||
perr = PolicyPasswordChangeUnsupported;
|
|
||||||
error = _("Password change is not supported.");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
perr = PolicyPasswordSystemUnknown;
|
|
||||||
error = _("Unhandled HTTP error code: %{0}").formatted(http.status);
|
|
||||||
}
|
|
||||||
this.failureCallback(perr, error);
|
|
||||||
// showPasswordMessage(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,130 +0,0 @@
|
||||||
/* bind method: attachToRowElement(row: TD or LI)
|
|
||||||
* callback methods:
|
|
||||||
notifyStartEditingCallback(this)
|
|
||||||
notifyEndEditingCallback(this)
|
|
||||||
notifyNewValueCallback(this, newValue),
|
|
||||||
*/
|
|
||||||
|
|
||||||
function RowEditionController() {
|
|
||||||
}
|
|
||||||
|
|
||||||
RowEditionController.prototype = {
|
|
||||||
initialValue: null,
|
|
||||||
rowElement: null,
|
|
||||||
textField: null,
|
|
||||||
|
|
||||||
/* notification callbacks */
|
|
||||||
notifyStartEditingCallback: null,
|
|
||||||
notifyEndEditingCallback: null,
|
|
||||||
notifyNewValueCallback: null,
|
|
||||||
|
|
||||||
/* bind method */
|
|
||||||
attachToRowElement: function REC_attachToRowElement(rowElement) {
|
|
||||||
var onRowDblClickBound = this.onRowDblClick.bindAsEventListener(this);
|
|
||||||
rowElement.observe("dblclick", onRowDblClickBound);
|
|
||||||
this.rowElement = rowElement;
|
|
||||||
rowElement.editionController = this;
|
|
||||||
},
|
|
||||||
|
|
||||||
/* internal */
|
|
||||||
emptyRow: function REC_emptyRow() {
|
|
||||||
var rowElement = this.rowElement;
|
|
||||||
while (rowElement.firstChild) {
|
|
||||||
rowElement.removeChild(rowElement.firstChild);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
startEditing: function REC_startEditing() {
|
|
||||||
var rowElement = this.rowElement;
|
|
||||||
rowElement.addClassName("editing");
|
|
||||||
|
|
||||||
var value = "";
|
|
||||||
for (var i = 0; i < rowElement.childNodes.length; i++) {
|
|
||||||
var child = rowElement.childNodes[i];
|
|
||||||
if (child.nodeType == Node.TEXT_NODE) {
|
|
||||||
value += child.nodeValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.initialValue = value;
|
|
||||||
this.emptyRow();
|
|
||||||
|
|
||||||
this.showInputField(value);
|
|
||||||
|
|
||||||
this.onBodyMouseDownBound = this.onBodyMouseDown.bindAsEventListener(this);
|
|
||||||
$(document.body).observe("mousedown", this.onBodyMouseDownBound);
|
|
||||||
|
|
||||||
if (this.notifyStartEditingCallback) {
|
|
||||||
this.notifyStartEditingCallback(this);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
showInputField: function REC_showInputField(value) {
|
|
||||||
var textField = createElement("input", null, null, {"type": "text"});
|
|
||||||
this.textField = textField;
|
|
||||||
if (value) {
|
|
||||||
textField.value = value;
|
|
||||||
}
|
|
||||||
this.rowElement.appendChild(textField);
|
|
||||||
var onInputKeyDownBound = this.onInputKeyDown.bindAsEventListener(this);
|
|
||||||
textField.observe("keydown", onInputKeyDownBound);
|
|
||||||
textField.focus();
|
|
||||||
textField.select();
|
|
||||||
},
|
|
||||||
|
|
||||||
stopEditing: function REC_stopEditing(accept) {
|
|
||||||
var displayValue = (accept ? this.textField.value : this.initialValue);
|
|
||||||
this.textField = null;
|
|
||||||
this.emptyRow();
|
|
||||||
var rowElement = this.rowElement;
|
|
||||||
rowElement.removeClassName("editing");
|
|
||||||
rowElement.appendChild(document.createTextNode(displayValue));
|
|
||||||
this.initialValue = null;
|
|
||||||
|
|
||||||
$(document.body).stopObserving("mousedown", this.onBodyMouseDownBound);
|
|
||||||
this.onBodyMouseDownBound = null;
|
|
||||||
|
|
||||||
if (this.notifyEndEditingCallback) {
|
|
||||||
this.notifyEndEditingCallback(this);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
acceptEdition: function REC_acceptEdition() {
|
|
||||||
var newValue = this.textField.value;
|
|
||||||
var isValid = (newValue && newValue.length > 0);
|
|
||||||
if (this.initialValue != newValue
|
|
||||||
&& isValid
|
|
||||||
&& this.notifyNewValueCallback) {
|
|
||||||
this.notifyNewValueCallback(this, newValue);
|
|
||||||
}
|
|
||||||
this.stopEditing(isValid);
|
|
||||||
},
|
|
||||||
cancelEdition: function REC_acceptEdition() {
|
|
||||||
this.stopEditing(false);
|
|
||||||
},
|
|
||||||
|
|
||||||
/* event handlers */
|
|
||||||
onRowDblClick: function REC_onRowDblClick(event) {
|
|
||||||
if (!this.textField) {
|
|
||||||
this.startEditing();
|
|
||||||
event.stop();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onInputKeyDown: function REC_onInputKeyDown(event) {
|
|
||||||
if (event.keyCode == Event.KEY_ESC) {
|
|
||||||
this.cancelEdition();
|
|
||||||
event.stop();
|
|
||||||
}
|
|
||||||
else if (event.keyCode == Event.KEY_RETURN) {
|
|
||||||
this.acceptEdition();
|
|
||||||
event.stop();
|
|
||||||
}
|
|
||||||
else if (event.keyCode == Event.KEY_TAB) {
|
|
||||||
this.acceptEdition();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onBodyMouseDown: function REC_onBodyMouseDown(event) {
|
|
||||||
if (event.target != this.textField) {
|
|
||||||
this.acceptEdition();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,385 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
// NOTE: The popup menu with id "contactsMenu" must exist before
|
|
||||||
// using this interface.
|
|
||||||
//
|
|
||||||
// This interface fires two events:
|
|
||||||
// - autocompletion:changed : fired when a new contact is selected
|
|
||||||
// - autocompletion:changedlist : fired when a new list is selected
|
|
||||||
//
|
|
||||||
var SOGoAutoCompletionInterface = {
|
|
||||||
|
|
||||||
// Attributes that could be changed from the object
|
|
||||||
// inheriting the inteface
|
|
||||||
uidField: "c_name",
|
|
||||||
addressBook: null,
|
|
||||||
SOGoUsersSearch: false,
|
|
||||||
excludeGroups: false,
|
|
||||||
excludeLists: false,
|
|
||||||
|
|
||||||
// Internal attributes
|
|
||||||
animationParent: null,
|
|
||||||
selectedIndex: -1,
|
|
||||||
delay: 0.750,
|
|
||||||
delayedSearch: false,
|
|
||||||
menu: null,
|
|
||||||
|
|
||||||
bind: function () {
|
|
||||||
this.menu = $('contactsMenu');
|
|
||||||
this.writeAttribute("autocomplete", "off");
|
|
||||||
this.writeAttribute("container", null);
|
|
||||||
this.confirmedValue = null;
|
|
||||||
this.observe("keydown", this.onKeydown.bindAsEventListener(this));
|
|
||||||
this.observe("blur", this.onBlur.bindAsEventListener(this));
|
|
||||||
},
|
|
||||||
|
|
||||||
onKeydown: function (event) {
|
|
||||||
if (event.ctrlKey || event.metaKey) {
|
|
||||||
this.focussed = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (event.keyCode == Event.KEY_TAB) {
|
|
||||||
if (this.confirmedValue)
|
|
||||||
this.value = this.confirmedValue;
|
|
||||||
else
|
|
||||||
this.writeAttribute("uid", null);
|
|
||||||
if (document.currentPopupMenu)
|
|
||||||
hideMenu(document.currentPopupMenu);
|
|
||||||
}
|
|
||||||
else if (event.keyCode == 0
|
|
||||||
|| event.keyCode == Event.KEY_BACKSPACE
|
|
||||||
|| event.keyCode == Event.KEY_DELETE
|
|
||||||
|| event.keyCode == 32 // Space
|
|
||||||
|| event.keyCode > 47) {
|
|
||||||
this.confirmedValue = null;
|
|
||||||
this.selectedIndex = -1;
|
|
||||||
if (this.delayedSearch)
|
|
||||||
window.clearTimeout(this.delayedSearch);
|
|
||||||
this.delayedSearch = this.performSearch.delay(this.delay, this);
|
|
||||||
}
|
|
||||||
else if (event.keyCode == Event.KEY_RETURN) {
|
|
||||||
preventDefault(event);
|
|
||||||
if (this.confirmedValue)
|
|
||||||
this.value = this.confirmedValue;
|
|
||||||
else
|
|
||||||
this.writeAttribute("uid", null);
|
|
||||||
if (document.currentPopupMenu)
|
|
||||||
hideMenu(document.currentPopupMenu);
|
|
||||||
this.selectedIndex = -1;
|
|
||||||
if (this.readAttribute("container")) {
|
|
||||||
this.confirmedValue = null;
|
|
||||||
this.fire("autocompletion:changedlist", this.readAttribute("container"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
this.fire("autocompletion:changed", event.keyCode);
|
|
||||||
}
|
|
||||||
else if (this.menu.getStyle('visibility') == 'visible') {
|
|
||||||
if (event.keyCode == Event.KEY_UP) { // Up arrow
|
|
||||||
if (this.selectedIndex > 0) {
|
|
||||||
var contacts = this.menu.select("li");
|
|
||||||
contacts[this.selectedIndex--].removeClassName("selected");
|
|
||||||
this.value = contacts[this.selectedIndex].readAttribute("address");
|
|
||||||
this.confirmedValue = this.value;
|
|
||||||
this.writeAttribute("uid", contacts[this.selectedIndex].readAttribute("uid"));
|
|
||||||
contacts[this.selectedIndex].addClassName("selected");
|
|
||||||
var container = contacts[this.selectedIndex].readAttribute("container");
|
|
||||||
if (container)
|
|
||||||
this.writeAttribute("container", container);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (event.keyCode == Event.KEY_DOWN) { // Down arrow
|
|
||||||
var contacts = this.menu.select("li");
|
|
||||||
if (contacts.size() - 1 > this.selectedIndex) {
|
|
||||||
if (this.selectedIndex >= 0)
|
|
||||||
contacts[this.selectedIndex].removeClassName("selected");
|
|
||||||
this.selectedIndex++;
|
|
||||||
this.value = contacts[this.selectedIndex].readAttribute("address");
|
|
||||||
this.confirmedValue = this.value;
|
|
||||||
this.writeAttribute("uid", contacts[this.selectedIndex].readAttribute("uid"));
|
|
||||||
contacts[this.selectedIndex].addClassName("selected");
|
|
||||||
var container = contacts[this.selectedIndex].readAttribute("container");
|
|
||||||
if (container)
|
|
||||||
this.writeAttribute("container", container);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onBlur: function (event) {
|
|
||||||
if (this.delayedSearch)
|
|
||||||
window.clearTimeout(this.delayedSearch);
|
|
||||||
if (this.confirmedValue) {
|
|
||||||
this.value = this.confirmedValue;
|
|
||||||
if (this.readAttribute("container"))
|
|
||||||
this.fire("autocompletion:changedlist", this.readAttribute("container"));
|
|
||||||
else
|
|
||||||
this.fire("autocompletion:changed", event.keyCode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
this.writeAttribute("uid", null);
|
|
||||||
},
|
|
||||||
|
|
||||||
performSearch: function (input) {
|
|
||||||
// Perform address completion
|
|
||||||
if (document.contactLookupAjaxRequest) {
|
|
||||||
// Abort any pending request
|
|
||||||
document.contactLookupAjaxRequest.aborted = true;
|
|
||||||
document.contactLookupAjaxRequest.abort();
|
|
||||||
}
|
|
||||||
if (input.value.trim().length > minimumSearchLength) {
|
|
||||||
if (input.SOGoUsersSearch) {
|
|
||||||
var urlstr = UserFolderURL + "usersSearch?search=" + encodeURIComponent(input.value);
|
|
||||||
document.contactLookupAjaxRequest =
|
|
||||||
triggerAjaxRequest(urlstr, input.performUsersSearchCallback.bind(input), input);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var urlstr = UserFolderURL + "Contacts/";
|
|
||||||
if (input.addressBook)
|
|
||||||
urlstr += input.addressBook + "/contact";
|
|
||||||
else
|
|
||||||
urlstr += "allContact";
|
|
||||||
urlstr += "Search?search=" + encodeURIComponent(input.value);
|
|
||||||
if (input.excludeGroups)
|
|
||||||
urlstr += "&excludeGroups=1";
|
|
||||||
if (input.excludeLists)
|
|
||||||
urlstr += "&excludeLists=1";
|
|
||||||
if (input.animationParent)
|
|
||||||
startAnimation(input.animationParent);
|
|
||||||
document.contactLookupAjaxRequest =
|
|
||||||
triggerAjaxRequest(urlstr, input.performSearchCallback.bind(input), input);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (document.currentPopupMenu)
|
|
||||||
hideMenu(document.currentPopupMenu);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
performSearchCallback: function (http) {
|
|
||||||
if (http.readyState == 4) {
|
|
||||||
var list = this.menu.down("ul");
|
|
||||||
|
|
||||||
var input = http.callbackData;
|
|
||||||
|
|
||||||
if (http.status == 200) {
|
|
||||||
var start = input.value.length;
|
|
||||||
var data = http.responseText.evalJSON(true);
|
|
||||||
|
|
||||||
if (data.contacts.length > 1) {
|
|
||||||
list.select("li").each(function(item) {
|
|
||||||
item.stopObserving("mousedown");
|
|
||||||
item.remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Populate popup menu
|
|
||||||
for (var i = 0; i < data.contacts.length; i++) {
|
|
||||||
var contact = data.contacts[i];
|
|
||||||
var completeEmail = contact["c_cn"];
|
|
||||||
var uid = "" + contact[this.uidField];
|
|
||||||
var c_name = "" + contact['c_name'];
|
|
||||||
if (contact["c_mail"])
|
|
||||||
completeEmail += " <" + contact["c_mail"] + ">";
|
|
||||||
var node = new Element('li', { 'address': completeEmail,
|
|
||||||
'uid': uid });
|
|
||||||
var matchPosition = completeEmail.toLowerCase().indexOf(data.searchText.toLowerCase());
|
|
||||||
if (matchPosition > -1) {
|
|
||||||
var matchBefore = completeEmail.substring(0, matchPosition);
|
|
||||||
var matchText = completeEmail.substring(matchPosition, matchPosition + data.searchText.length);
|
|
||||||
var matchAfter = completeEmail.substring(matchPosition + data.searchText.length);
|
|
||||||
node.appendChild(document.createTextNode(matchBefore));
|
|
||||||
node.appendChild(new Element('strong').update(matchText));
|
|
||||||
node.appendChild(document.createTextNode(matchAfter));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
node.appendChild(document.createTextNode(completeEmail));
|
|
||||||
}
|
|
||||||
list.appendChild(node);
|
|
||||||
if (c_name.endsWith(".vlf")) {
|
|
||||||
// Keep track of list containers
|
|
||||||
node.writeAttribute("container", contact['container']);
|
|
||||||
}
|
|
||||||
if (contact["contactInfo"])
|
|
||||||
node.appendChild(document.createTextNode(" (" + contact["contactInfo"] + ")"));
|
|
||||||
$(node).observe("mousedown", this.onAddressResultClick.bindAsEventListener(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show popup menu
|
|
||||||
var offsetScroll = Element.cumulativeScrollOffset(input);
|
|
||||||
var offset = Element.positionedOffset(input);
|
|
||||||
if ($(document.body).hasClassName("popup") && typeof initPopupMailer == 'undefined')
|
|
||||||
// Hack for some situations where the offset must be computed differently
|
|
||||||
offset = Element.cumulativeOffset(input);
|
|
||||||
var top = offset.top - offsetScroll.top + node.offsetHeight + 3;
|
|
||||||
var height = 'auto';
|
|
||||||
var heightDiff = window.height() - offset[1];
|
|
||||||
var nodeHeight = node.getHeight();
|
|
||||||
|
|
||||||
if ((data.contacts.length * nodeHeight) > heightDiff)
|
|
||||||
// Limit the size of the popup to the window height, minus 12 pixels
|
|
||||||
height = parseInt(heightDiff/nodeHeight) * nodeHeight - 12 + 'px';
|
|
||||||
|
|
||||||
this.menu.setStyle({ top: top + "px",
|
|
||||||
left: offset[0] + "px",
|
|
||||||
height: height,
|
|
||||||
maxWidth: (window.width() - offset[0] - 12) + "px",
|
|
||||||
visibility: "visible" });
|
|
||||||
this.menu.scrollTop = 0;
|
|
||||||
|
|
||||||
document.currentPopupMenu = this.menu;
|
|
||||||
$(document.body).stopObserving("click");
|
|
||||||
$(document.body).observe("click", onBodyClickMenuHandler);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (document.currentPopupMenu)
|
|
||||||
hideMenu(document.currentPopupMenu);
|
|
||||||
|
|
||||||
if (data.contacts.length == 1) {
|
|
||||||
// Single result
|
|
||||||
var contact = data.contacts[0];
|
|
||||||
var uid = "" + contact[this.uidField];
|
|
||||||
var c_name = "" + contact['c_name'];
|
|
||||||
input.writeAttribute("uid", uid);
|
|
||||||
if (c_name.endsWith(".vlf")) {
|
|
||||||
this.writeAttribute("container", contact['container']);
|
|
||||||
}
|
|
||||||
var completeEmail = contact["c_cn"];
|
|
||||||
if (contact["c_mail"])
|
|
||||||
completeEmail += " <" + contact["c_mail"] + ">";
|
|
||||||
if (contact["c_cn"].substring(0, input.value.length).toUpperCase()
|
|
||||||
== input.value.toUpperCase())
|
|
||||||
input.value = completeEmail;
|
|
||||||
else
|
|
||||||
// The result matches email address, not user name
|
|
||||||
input.value += ' >> ' + completeEmail;
|
|
||||||
input.confirmedValue = completeEmail;
|
|
||||||
|
|
||||||
var end = input.value.length;
|
|
||||||
$(input).selectText(start, end);
|
|
||||||
|
|
||||||
this.selectedIndex = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (document.currentPopupMenu)
|
|
||||||
hideMenu(document.currentPopupMenu);
|
|
||||||
document.contactLookupAjaxRequest = null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
performUsersSearchCallback: function (http) {
|
|
||||||
if (http.readyState == 4) {
|
|
||||||
var list = this.menu.down("ul");
|
|
||||||
var input = http.callbackData;
|
|
||||||
if (http.status == 200) {
|
|
||||||
var response = http.responseText.evalJSON();
|
|
||||||
|
|
||||||
if (response.length > 1) {
|
|
||||||
list.select("li").each(function(item) {
|
|
||||||
item.stopObserving("mousedown");
|
|
||||||
item.remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Populate popup menu
|
|
||||||
for (var i = 0; i < response.length; i++) {
|
|
||||||
var c_name = response[i][1];
|
|
||||||
var completeEmail = c_name;
|
|
||||||
var c_mail = response[i][2];
|
|
||||||
var uid = response[i][3];
|
|
||||||
if (c_mail)
|
|
||||||
completeEmail += " <" + c_mail + ">";
|
|
||||||
var node = new Element('li', { 'address': completeEmail,
|
|
||||||
'uid': uid });
|
|
||||||
var matchPosition = completeEmail.toLowerCase().indexOf(input.getValue().toLowerCase());
|
|
||||||
if (matchPosition > -1) {
|
|
||||||
var matchBefore = completeEmail.substring(0, matchPosition);
|
|
||||||
var matchText = completeEmail.substring(matchPosition, matchPosition + input.getValue().length);
|
|
||||||
var matchAfter = completeEmail.substring(matchPosition + input.getValue().length);
|
|
||||||
node.appendChild(document.createTextNode(matchBefore));
|
|
||||||
node.appendChild(new Element('strong').update(matchText));
|
|
||||||
node.appendChild(document.createTextNode(matchAfter));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
node.appendChild(document.createTextNode(completeEmail));
|
|
||||||
}
|
|
||||||
list.appendChild(node);
|
|
||||||
$(node).observe("mousedown", this.onAddressResultClick.bindAsEventListener(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show popup menu
|
|
||||||
var offsetScroll = Element.cumulativeScrollOffset(input);
|
|
||||||
var offset = Element.positionedOffset(input);
|
|
||||||
if ($(document.body).hasClassName("popup") && typeof initPopupMailer == 'undefined')
|
|
||||||
// Hack for some situations where the offset must be computed differently
|
|
||||||
offset = Element.cumulativeOffset(input);
|
|
||||||
var top = offset.top - offsetScroll.top + node.offsetHeight + 3;
|
|
||||||
var height = 'auto';
|
|
||||||
var heightDiff = window.height() - offset[1];
|
|
||||||
var nodeHeight = node.getHeight();
|
|
||||||
|
|
||||||
if ((response.length * nodeHeight) > heightDiff)
|
|
||||||
// Limit the size of the popup to the window height, minus 12 pixels
|
|
||||||
height = parseInt(heightDiff/nodeHeight) * nodeHeight - 12 + 'px';
|
|
||||||
|
|
||||||
this.menu.setStyle({ top: top + "px",
|
|
||||||
left: offset[0] + "px",
|
|
||||||
height: height,
|
|
||||||
maxWidth: (window.width() - offset[0] - 12) + "px",
|
|
||||||
visibility: "visible" });
|
|
||||||
this.menu.scrollTop = 0;
|
|
||||||
|
|
||||||
document.currentPopupMenu = this.menu;
|
|
||||||
$(document.body).stopObserving("click");
|
|
||||||
$(document.body).observe("click", onBodyClickMenuHandler);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (document.currentPopupMenu)
|
|
||||||
hideMenu(document.currentPopupMenu);
|
|
||||||
|
|
||||||
if (response.length == 1) {
|
|
||||||
// Single result
|
|
||||||
var c_name = response[0][1];
|
|
||||||
var completeEmail = c_name;
|
|
||||||
var c_mail = response[0][2];
|
|
||||||
var c_uid = response[0][0];
|
|
||||||
input.writeAttribute("uid", c_uid);
|
|
||||||
if (c_mail)
|
|
||||||
completeEmail += " <" + c_mail + ">";
|
|
||||||
if (c_uid.substring(0, input.getValue().length).toUpperCase() == input.getValue().toUpperCase())
|
|
||||||
input.value = completeEmail;
|
|
||||||
else
|
|
||||||
// The result matches email address, not user name
|
|
||||||
input.value += ' >> ' + completeEmail;
|
|
||||||
input.confirmedValue = completeEmail;
|
|
||||||
|
|
||||||
var end = input.getValue().length;
|
|
||||||
$(input).selectText(start, end);
|
|
||||||
|
|
||||||
this.selectedIndex = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (document.currentPopupMenu)
|
|
||||||
hideMenu(document.currentPopupMenu);
|
|
||||||
document.contactLookupAjaxRequest = null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onAddressResultClick: function(event) {
|
|
||||||
var e = Event.element(event);
|
|
||||||
if (e.tagName != 'LI')
|
|
||||||
e = e.up('LI');
|
|
||||||
if (e) {
|
|
||||||
preventDefault(event);
|
|
||||||
this.value = e.readAttribute("address");
|
|
||||||
this.writeAttribute("uid", e.readAttribute("uid"));
|
|
||||||
if (e.readAttribute("container"))
|
|
||||||
this.fire("autocompletion:changedlist", e.readAttribute("container"));
|
|
||||||
else {
|
|
||||||
this.confirmedValue = this.value;
|
|
||||||
this.fire("autocompletion:changed", Event.KEY_RETURN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,345 +0,0 @@
|
||||||
/* -*- Mode: js2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Data table interface to be added to a DIV (this!)
|
|
||||||
*
|
|
||||||
* Available events:
|
|
||||||
* datatable:rendered -- fired once the view rendering is completed
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
var SOGoDataTableInterface = {
|
|
||||||
|
|
||||||
// Object variables initialized with "bind"
|
|
||||||
columnsCount: null,
|
|
||||||
rowModel: null,
|
|
||||||
rowHeight: 0,
|
|
||||||
body: null,
|
|
||||||
|
|
||||||
// Object variables
|
|
||||||
dataSource: null,
|
|
||||||
rowTop: null,
|
|
||||||
rowBottom: null,
|
|
||||||
renderedIndex: -1,
|
|
||||||
renderedCount: 0,
|
|
||||||
rowRenderCallback: null,
|
|
||||||
|
|
||||||
// Constants
|
|
||||||
overflow: 30, // must be lower than the overflow of the data source class
|
|
||||||
renderDelay: 0.1, // delay (in seconds) before which the table is rendered upon scrolling
|
|
||||||
|
|
||||||
bind: function() {
|
|
||||||
this.observe("scroll" , this.render.bind(this));
|
|
||||||
|
|
||||||
this.body = this.down("tbody");
|
|
||||||
this.rowModel = this.body.down("tr");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Overrided methods from HTMLElement.js
|
|
||||||
* Handle selection based on rows ID.
|
|
||||||
*/
|
|
||||||
this.body.selectRange = function(startIndex, endIndex) {
|
|
||||||
var s;
|
|
||||||
var e;
|
|
||||||
var rows;
|
|
||||||
var div = this.up('div');
|
|
||||||
var uid = lastClickedRowId.substr(4);
|
|
||||||
|
|
||||||
startIndex = div.dataSource.indexOf(uid);
|
|
||||||
uid = div.down('tr', endIndex).id.substr(4);
|
|
||||||
endIndex = div.dataSource.indexOf(uid);
|
|
||||||
|
|
||||||
if (startIndex > endIndex) {
|
|
||||||
s = endIndex;
|
|
||||||
e = startIndex;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
s = startIndex;
|
|
||||||
e = endIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (s <= e) {
|
|
||||||
uid = "row_" + div.dataSource.uidAtIndex(s);
|
|
||||||
if (this.selectedIds.indexOf(uid) < 0)
|
|
||||||
this.selectedIds.push(uid);
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
this.refreshSelectionByIds();
|
|
||||||
};
|
|
||||||
|
|
||||||
this.body.selectAll = function() {
|
|
||||||
var div = this.up('div');
|
|
||||||
this.selectedIds = new Array();
|
|
||||||
for (var i = 0; i < div.dataSource.uids.length; i++)
|
|
||||||
this.selectedIds.push("row_" + div.dataSource.uidAtIndex(i));
|
|
||||||
this.refreshSelectionByIds();
|
|
||||||
},
|
|
||||||
|
|
||||||
// Since we use the fixed table layout, the first row must have the
|
|
||||||
// proper CSS classes that will define the columns width.
|
|
||||||
this.rowTop = new Element('tr', {'id': 'rowTop'});
|
|
||||||
this.body.insertBefore(this.rowTop, this.rowModel); // IE requires the element to be inside the DOM before appending new children
|
|
||||||
var cells = this.rowModel.select('TD');
|
|
||||||
for (var i = 0; i < cells.length; i++) {
|
|
||||||
var cell = cells[i];
|
|
||||||
var td = new Element('td', {'class': cell.className});
|
|
||||||
this.rowTop.appendChild(td);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.rowBottom = new Element('tr', {'id': 'rowBottom'}).update(new Element('td'));
|
|
||||||
this.body.insertBefore(this.rowBottom, this.rowModel);
|
|
||||||
|
|
||||||
this.columnsCount = this.rowModel.select("td").length;
|
|
||||||
this.rowHeight = this.rowModel.getHeight();
|
|
||||||
// log ("DataTable.bind() row height = " + this.rowHeight + "px");
|
|
||||||
},
|
|
||||||
|
|
||||||
setRowRenderCallback: function(callbackFunction) {
|
|
||||||
// Each time a row is created or updated with new data, this callback
|
|
||||||
// function will be called.
|
|
||||||
this.rowRenderCallback = callbackFunction;
|
|
||||||
},
|
|
||||||
|
|
||||||
setSource: function(ds) {
|
|
||||||
this.dataSource = ds;
|
|
||||||
this.currentRenderID = "";
|
|
||||||
this._emptyTable();
|
|
||||||
this.scrollTop = 0;
|
|
||||||
},
|
|
||||||
|
|
||||||
initSource: function(dataSourceClass, url, params) {
|
|
||||||
// log ("DataTable.setSource() " + url);
|
|
||||||
if (this.dataSource) this.dataSource.destroy();
|
|
||||||
this._emptyTable();
|
|
||||||
this.dataSource = new window[dataSourceClass](this, url);
|
|
||||||
this.scrollTop = 0;
|
|
||||||
this.load(params);
|
|
||||||
},
|
|
||||||
|
|
||||||
load: function(urlParams) {
|
|
||||||
if (!this.dataSource) return;
|
|
||||||
// log ("DataTable.load() with parameters [" + urlParams.keys().join(' ') + "]");
|
|
||||||
this.dataSource.load(urlParams);
|
|
||||||
},
|
|
||||||
|
|
||||||
visibleRowCount: function() {
|
|
||||||
var divHeight = this.getHeight();
|
|
||||||
var visibleRowCount = Math.ceil(divHeight/this.rowHeight);
|
|
||||||
|
|
||||||
return visibleRowCount;
|
|
||||||
},
|
|
||||||
|
|
||||||
firstVisibleRowIndex: function() {
|
|
||||||
var firstRowIndex = Math.floor(this.scrollTop/this.rowHeight);
|
|
||||||
|
|
||||||
return firstRowIndex;
|
|
||||||
},
|
|
||||||
|
|
||||||
refresh: function() {
|
|
||||||
this.render(true);
|
|
||||||
},
|
|
||||||
|
|
||||||
render: function(refresh) {
|
|
||||||
// Setting "refresh" to true will force the call to getData which
|
|
||||||
// recomputes the top and bottom padding with respect to the total
|
|
||||||
// number of rows.
|
|
||||||
var index = this.firstVisibleRowIndex();
|
|
||||||
var count = this.visibleRowCount();
|
|
||||||
// Overflow the query to the maximum defined in the class variable overflow
|
|
||||||
var start = index - (this.overflow/2);
|
|
||||||
if (start < 0) start = 0;
|
|
||||||
var end = index + count + this.overflow - (index - start);
|
|
||||||
// log ("DataTable.render() from " + index + " to " + (index + count) + " boosted from " + start + " to " + end);
|
|
||||||
|
|
||||||
// Don't overflow above the maximum number of entries from the data source
|
|
||||||
//if (this.dataSource.uids && this.dataSource.uids.length < end) end = this.dataSource.uids.length;
|
|
||||||
|
|
||||||
index = start;
|
|
||||||
count = end - start;
|
|
||||||
|
|
||||||
this.currentRenderID = this.dataSource.id + "/" + index + "-" + count;
|
|
||||||
|
|
||||||
// Query the data source only if at least one row is not loaded
|
|
||||||
if (refresh === true ||
|
|
||||||
this.renderedIndex < 0 ||
|
|
||||||
this.renderedIndex > index ||
|
|
||||||
this.renderedCount < count ||
|
|
||||||
(index + count) > (this.renderedIndex + this.renderedCount)) {
|
|
||||||
this.dataSource.getData(this.currentRenderID,
|
|
||||||
index,
|
|
||||||
count,
|
|
||||||
(refresh === true)?this._refresh.bind(this):this._render.bind(this),
|
|
||||||
this.renderDelay);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_refresh: function(renderID, start, max, data) {
|
|
||||||
this._render(renderID, start, max, data, true);
|
|
||||||
},
|
|
||||||
|
|
||||||
_render: function(renderID, start, max, data, refresh) {
|
|
||||||
if (this.currentRenderID != renderID) {
|
|
||||||
// log ("DataTable._render() ignore render for " + renderID + " (current is " + this.currentRenderID + ")");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// log("DataTable._render() for " + data.length + " uids (from " + start + ", max " + max + ")");
|
|
||||||
|
|
||||||
var h, i, j;
|
|
||||||
var rows = this.body.select("tr");
|
|
||||||
var scroll;
|
|
||||||
|
|
||||||
scroll = this.scrollTop;
|
|
||||||
|
|
||||||
h = start * this.rowHeight;
|
|
||||||
if (Prototype.Browser.IE)
|
|
||||||
this.rowTop.setStyle({ 'height': h + 'px', 'line-height': h + 'px' });
|
|
||||||
this.rowTop.firstChild.setStyle({ 'height': h + 'px', 'line-height': h + 'px' });
|
|
||||||
|
|
||||||
h = (max - start - data.length) * this.rowHeight;
|
|
||||||
if (Prototype.Browser.IE)
|
|
||||||
this.rowBottom.setStyle({ 'height': h + 'px', 'line-height': h + 'px' });
|
|
||||||
this.rowBottom.firstChild.setStyle({ 'height': h + 'px', 'line-height': h + 'px' });
|
|
||||||
|
|
||||||
if (this.renderedIndex < 0) {
|
|
||||||
this.renderedIndex = 0;
|
|
||||||
this.renderedCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (refresh === true ||
|
|
||||||
start > (this.renderedIndex + this.renderedCount) ||
|
|
||||||
start + data.length < this.renderedIndex) {
|
|
||||||
// No reusable row in the viewport;
|
|
||||||
// refresh the complete view port
|
|
||||||
for (i = 0, j = start;
|
|
||||||
i < this.renderedCount && i < data.length;
|
|
||||||
i++, j++) {
|
|
||||||
// Render all existing rows with new data
|
|
||||||
var row = rows[i+1]; // must skip the first row (this.rowTop)
|
|
||||||
this.rowRenderCallback(row, data[i], false);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = this.renderedCount;
|
|
||||||
i < data.length;
|
|
||||||
i++, j++) {
|
|
||||||
// Add new rows, if necessary
|
|
||||||
var row = this.rowModel.cloneNode(true);
|
|
||||||
this.rowRenderCallback(row, data[i], true);
|
|
||||||
row.show();
|
|
||||||
this.body.insertBefore(row, this.rowBottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = this.renderedCount;
|
|
||||||
i > data.length;
|
|
||||||
i--) {
|
|
||||||
// Delete extra rows, if necessary
|
|
||||||
this.body.removeChild(rows[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (start >= this.renderedIndex) {
|
|
||||||
// Scrolling down
|
|
||||||
|
|
||||||
// Delete top rows
|
|
||||||
for (i = start; i > this.renderedIndex; i--) {
|
|
||||||
this.body.removeChild(rows[i - this.renderedIndex]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add bottom rows
|
|
||||||
for (j = this.renderedIndex + this.renderedCount - start, i = this.renderedIndex + this.renderedCount;
|
|
||||||
j < data.length;
|
|
||||||
j++, i++) {
|
|
||||||
var row = this.rowModel.cloneNode(true);
|
|
||||||
this.rowRenderCallback(row, data[j], true);
|
|
||||||
this.body.insertBefore(row, this.rowBottom);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Scrolling up
|
|
||||||
|
|
||||||
// Delete bottom rows
|
|
||||||
for (i = this.renderedIndex + this.renderedCount, j = this.renderedCount;
|
|
||||||
i > (start + data.length);
|
|
||||||
i--, j--) {
|
|
||||||
this.body.removeChild(rows[j]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add top rows
|
|
||||||
for (i = 0, j = start;
|
|
||||||
j < this.renderedIndex;
|
|
||||||
i++, j++) {
|
|
||||||
var row = this.rowModel.cloneNode(true);
|
|
||||||
this.rowRenderCallback(row, data[i], true);
|
|
||||||
row.show();
|
|
||||||
this.body.insertBefore(row, rows[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update references to selected rows
|
|
||||||
this.body.refreshSelectionByIds();
|
|
||||||
// log ("DataTable._render() top gap/bottom gap/total rows = " + this.rowTop.getStyle('height') + "/" + this.rowBottom.getStyle('height') + "/" + this.body.select("tr").length + " (height = " + this.down("table").getHeight() + "px)");
|
|
||||||
|
|
||||||
// Save current rendered view index and count
|
|
||||||
this.renderedIndex = start;
|
|
||||||
this.renderedCount = data.length;
|
|
||||||
|
|
||||||
// Restore scroll position (necessary in certain cases)
|
|
||||||
this.scrollTop = scroll;
|
|
||||||
|
|
||||||
Event.fire(this, "datatable:rendered", max);
|
|
||||||
},
|
|
||||||
|
|
||||||
invalidate: function(uid, withoutRefresh) {
|
|
||||||
// Refetch the data for uid. Only refresh the data table if
|
|
||||||
// necessary.
|
|
||||||
// log ("DataTable.invalidate(" + uid + ", with" + (withoutRefresh?"out":"") + " refresh)");
|
|
||||||
var index = this.dataSource.invalidate(uid);
|
|
||||||
this.currentRenderID = index + "-" + 1;
|
|
||||||
this.dataSource.getData(this.currentRenderID,
|
|
||||||
index,
|
|
||||||
1,
|
|
||||||
(withoutRefresh?false:this._invalidate.bind(this)),
|
|
||||||
0);
|
|
||||||
},
|
|
||||||
|
|
||||||
_invalidate: function(renderID, start, max, data) {
|
|
||||||
if (renderID == this.currentRenderID) {
|
|
||||||
var rows = this.body.select("TR#" + data[0]['rowID']);
|
|
||||||
if (rows.length > 0)
|
|
||||||
this.rowRenderCallback(rows[0], data[0], false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
remove: function(uid) {
|
|
||||||
var rows = this.body.select("TR#row_" + uid);
|
|
||||||
if (rows.length == 1) {
|
|
||||||
var row = rows.first();
|
|
||||||
row.deselect();
|
|
||||||
row.parentNode.removeChild(row);
|
|
||||||
}
|
|
||||||
var index = this.dataSource.remove(uid);
|
|
||||||
// log ("DataTable.remove(" + uid + ") at index " + index);
|
|
||||||
if (index >= 0) {
|
|
||||||
if (this.renderedIndex > index)
|
|
||||||
this.renderedIndex--;
|
|
||||||
else if ((this.renderedIndex + this.renderedCount) > index)
|
|
||||||
this.renderedCount--;
|
|
||||||
}
|
|
||||||
return index;
|
|
||||||
},
|
|
||||||
|
|
||||||
_emptyTable: function() {
|
|
||||||
var rows = this.body.select("tr");
|
|
||||||
var currentCount = rows.length;
|
|
||||||
|
|
||||||
for (var i = currentCount - 1; i >= 0; i--) {
|
|
||||||
if (rows[i] != this.rowModel &&
|
|
||||||
rows[i] != this.rowTop &&
|
|
||||||
rows[i] != this.rowBottom)
|
|
||||||
this.body.removeChild(rows[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.body.deselectAll();
|
|
||||||
this.renderedIndex = -1;
|
|
||||||
this.renderedCount = 0;
|
|
||||||
this.rowTop.firstChild.setStyle({ 'height': '0px', 'line-height': '0px' });
|
|
||||||
this.rowBottom.firstChild.setStyle({ 'height': '0px', 'line-height': '0px' });
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,203 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Drag handle widget interface to be added to a DIV (the drag handle)
|
|
||||||
*
|
|
||||||
* Available events:
|
|
||||||
* handle:dragged -- fired once the handle has been dropped
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
var SOGoDragHandlesInterface = {
|
|
||||||
leftMargin: 180,
|
|
||||||
topMargin: 180,
|
|
||||||
dhType: null,
|
|
||||||
dhLimit: -1,
|
|
||||||
origX: -1,
|
|
||||||
origLeft: -1,
|
|
||||||
origRight: -1,
|
|
||||||
origY: -1,
|
|
||||||
origUpper: -1,
|
|
||||||
origLower: -1,
|
|
||||||
delta: -1,
|
|
||||||
btn: null,
|
|
||||||
leftBlock: null,
|
|
||||||
rightBlock: null,
|
|
||||||
upperBlock: null,
|
|
||||||
lowerBlock: null,
|
|
||||||
rightSafetyBlock: null,
|
|
||||||
startHandleDraggingBound: null,
|
|
||||||
stopHandleDraggingBound: null,
|
|
||||||
moveBound: null,
|
|
||||||
delayedSave: null,
|
|
||||||
bind: function () {
|
|
||||||
this.startHandleDraggingBound = this.startHandleDragging.bindAsEventListener(this);
|
|
||||||
this.observe("mousedown", this.startHandleDraggingBound, false);
|
|
||||||
},
|
|
||||||
enableRightSafety: function () {
|
|
||||||
this.rightSafetyBlock = new Element('div', {'class': 'safetyBlock'});
|
|
||||||
this.rightSafetyBlock.hide();
|
|
||||||
document.body.appendChild(this.rightSafetyBlock);
|
|
||||||
},
|
|
||||||
adjust: function () {
|
|
||||||
if (!this.dhType)
|
|
||||||
this._determineType();
|
|
||||||
if (this.dhType == 'horizontal') {
|
|
||||||
this.dhLimit = window.width() - 20;
|
|
||||||
if (parseInt(this.getStyle("left")) > this.dhLimit) {
|
|
||||||
this.setStyle({ left: this.dhLimit + "px" });
|
|
||||||
this.rightBlock.setStyle({ left: (this.dhLimit) + 'px' });
|
|
||||||
this.leftBlock.setStyle({ width: (this.dhLimit) + 'px' });
|
|
||||||
if (this.delayedSave) window.clearTimeout(this.delayedSave);
|
|
||||||
this.delayedSave = this.saveDragHandleState.delay(3, this.dhType, this.dhLimit, this.saveDragHandleStateCallback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (this.dhType == 'vertical') {
|
|
||||||
var windowHeight = window.height();
|
|
||||||
this.dhLimit = windowHeight - 20 - this.upperBlock.cumulativeOffset().top + this.upperBlock.offsetTop;
|
|
||||||
if (parseInt(this.getStyle("top")) > this.dhLimit &&
|
|
||||||
windowHeight > this.topMargin) {
|
|
||||||
this.setStyle({ top: this.dhLimit + 'px' });
|
|
||||||
this.lowerBlock.setStyle({ top: this.dhLimit + 'px' });
|
|
||||||
this.upperBlock.setStyle({ height: (this.dhLimit - this.upperBlock.offsetTop) + 'px' });
|
|
||||||
if (this.delayedSave) window.clearTimeout(this.delayedSave);
|
|
||||||
this.delayedSave = this.saveDragHandleState.delay(3, this.dhType, this.dhLimit, this.saveDragHandleStateCallback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_determineType: function () {
|
|
||||||
if (this.leftBlock && this.rightBlock)
|
|
||||||
this.dhType = 'horizontal';
|
|
||||||
else if (this.upperBlock && this.lowerBlock)
|
|
||||||
this.dhType = 'vertical';
|
|
||||||
},
|
|
||||||
startHandleDragging: function (event) {
|
|
||||||
this.btn = event.button;
|
|
||||||
if (!this.dhType)
|
|
||||||
this._determineType();
|
|
||||||
var targ = getTarget(event);
|
|
||||||
if (targ.nodeType == 1) {
|
|
||||||
if (this.dhType == 'horizontal') {
|
|
||||||
this.dhLimit = window.width() - 20;
|
|
||||||
this.origX = this.offsetLeft;
|
|
||||||
this.origLeft = this.leftBlock.offsetWidth;
|
|
||||||
this.delta = 0;
|
|
||||||
this.origRight = this.rightBlock.offsetLeft - 5;
|
|
||||||
document.body.setStyle({ cursor: "e-resize" });
|
|
||||||
if (this.rightSafetyBlock) {
|
|
||||||
this.rightSafetyBlock.setStyle({
|
|
||||||
top: this.rightBlock.getStyle('top'),
|
|
||||||
left: this.rightBlock.getStyle('left') });
|
|
||||||
this.rightSafetyBlock.show();
|
|
||||||
}
|
|
||||||
} else if (this.dhType == 'vertical') {
|
|
||||||
this.dhLimit = window.height() - 20;
|
|
||||||
this.origY = this.offsetTop;
|
|
||||||
this.origUpper = this.upperBlock.offsetHeight;
|
|
||||||
var pointY = Event.pointerY(event);
|
|
||||||
this.delta = pointY - this.offsetTop - 5;
|
|
||||||
this.origLower = this.lowerBlock.offsetTop - 5;
|
|
||||||
document.body.setStyle({ cursor: "n-resize" });
|
|
||||||
}
|
|
||||||
this.stopHandleDraggingBound = this.stopHandleDragging.bindAsEventListener(this);
|
|
||||||
if (Prototype.Browser.IE)
|
|
||||||
Event.observe(document.body, "mouseup", this.stopHandleDraggingBound);
|
|
||||||
else
|
|
||||||
Event.observe(window, "mouseup", this.stopHandleDraggingBound);
|
|
||||||
this.moveBound = this.move.bindAsEventListener(this);
|
|
||||||
Event.observe(document.body, "mousemove", this.moveBound);
|
|
||||||
this.move(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
stopHandleDragging: function (event) {
|
|
||||||
if (!this.dhType)
|
|
||||||
this._determineType();
|
|
||||||
if (this.dhType == 'horizontal') {
|
|
||||||
var pointerX = Event.pointerX(event);
|
|
||||||
if (pointerX <= this.leftMargin) {
|
|
||||||
this.rightBlock.setStyle({ left: (this.leftMargin) + 'px' });
|
|
||||||
this.leftBlock.setStyle({ width: (this.leftMargin) + 'px' });
|
|
||||||
}
|
|
||||||
else if (pointerX >= this.dhLimit) {
|
|
||||||
this.rightBlock.setStyle({ left: (this.dhLimit) + 'px' });
|
|
||||||
this.leftBlock.setStyle({ width: (this.dhLimit) + 'px' });
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var deltaX = Math.floor(pointerX - this.origX - (this.offsetWidth / 2));
|
|
||||||
this.rightBlock.setStyle({ left: (this.origRight + deltaX) + 'px' });
|
|
||||||
this.leftBlock.setStyle({ width: (this.origLeft + deltaX) + 'px' });
|
|
||||||
}
|
|
||||||
this.saveDragHandleState(this.dhType, parseInt(this.leftBlock.getStyle("width")));
|
|
||||||
if (this.rightSafetyBlock)
|
|
||||||
this.rightSafetyBlock.hide();
|
|
||||||
}
|
|
||||||
else if (this.dhType == 'vertical') {
|
|
||||||
var pointerY = Event.pointerY(event);
|
|
||||||
var deltaY;
|
|
||||||
if (pointerY <= this.topMargin)
|
|
||||||
deltaY = Math.floor(this.topMargin - this.origY - (this.offsetHeight / 2));
|
|
||||||
else if (pointerY >= this.dhLimit)
|
|
||||||
deltaY = Math.floor(this.dhLimit - this.origY - (this.offsetHeight / 2));
|
|
||||||
else
|
|
||||||
deltaY = Math.floor(pointerY - this.origY - (this.offsetHeight / 2));
|
|
||||||
this.lowerBlock.setStyle({ top: (this.origLower + deltaY - this.delta) + 'px' });
|
|
||||||
this.upperBlock.setStyle({ height: (this.origUpper + deltaY - this.delta) + 'px' });
|
|
||||||
this.saveDragHandleState(this.dhType, parseInt(this.lowerBlock.getStyle("top")));
|
|
||||||
}
|
|
||||||
if (Prototype.Browser.IE)
|
|
||||||
Event.stopObserving(document.body, "mouseup", this.stopHandleDraggingBound);
|
|
||||||
else
|
|
||||||
Event.stopObserving(window, "mouseup", this.stopHandleDraggingBound);
|
|
||||||
Event.stopObserving(document.body, "mousemove", this.moveBound);
|
|
||||||
|
|
||||||
document.body.setAttribute('style', '');
|
|
||||||
document.body.setStyle({ cursor: "default" });
|
|
||||||
this.fire("handle:dragged");
|
|
||||||
|
|
||||||
Event.stop(event);
|
|
||||||
},
|
|
||||||
move: function (event) {
|
|
||||||
if (!this.dhType)
|
|
||||||
this._determineType();
|
|
||||||
if (this.dhType == 'horizontal') {
|
|
||||||
var hX = Event.pointerX(event);
|
|
||||||
var width = this.offsetWidth;
|
|
||||||
if (hX < this.leftMargin)
|
|
||||||
hX = this.leftMargin + Math.floor(width / 2);
|
|
||||||
else if (hX > this.dhLimit)
|
|
||||||
hX = this.dhLimit + Math.floor(width / 2);
|
|
||||||
var newLeft = Math.floor(hX - (width / 2));
|
|
||||||
this.setStyle({ left: newLeft + 'px' });
|
|
||||||
} else if (this.dhType == 'vertical') {
|
|
||||||
var hY = Event.pointerY(event);
|
|
||||||
var height = this.offsetHeight;
|
|
||||||
if (hY < this.topMargin)
|
|
||||||
hY = this.topMargin;
|
|
||||||
else if (hY > this.dhLimit)
|
|
||||||
hY = this.dhLimit;
|
|
||||||
|
|
||||||
var newTop = Math.floor(hY - (height / 2)) - this.delta;
|
|
||||||
this.setStyle({ top: newTop + 'px' });
|
|
||||||
}
|
|
||||||
Event.stop(event);
|
|
||||||
if (Prototype.Browser.IE && event.button != this.btn)
|
|
||||||
this.stopHandleDragging(event);
|
|
||||||
},
|
|
||||||
saveDragHandleState: function (type, position, fcn) {
|
|
||||||
if (!$(document.body).hasClassName("popup")) {
|
|
||||||
var urlstr = ApplicationBaseURL + "/saveDragHandleState"
|
|
||||||
+ "?" + type + "=" + position;
|
|
||||||
var callbackFunction = fcn || this.saveDragHandleStateCallback;
|
|
||||||
triggerAjaxRequest(urlstr, callbackFunction);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
saveDragHandleStateCallback: function (http) {
|
|
||||||
if (isHttpStatus204(http.status)) {
|
|
||||||
log ("Drag handle state saved");
|
|
||||||
}
|
|
||||||
else if (http.readyState == 4) {
|
|
||||||
log ("Can't save handle state");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,244 +0,0 @@
|
||||||
/* -*- Mode: js2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
SOGoMailDataSource = Class.create({
|
|
||||||
|
|
||||||
initialize: function(dataTable, url) {
|
|
||||||
// Instance variables
|
|
||||||
this.dataTable = dataTable;
|
|
||||||
this.id = url;
|
|
||||||
this.url = url;
|
|
||||||
|
|
||||||
this.uids = new Array();
|
|
||||||
this.threaded = false;
|
|
||||||
this.cache = new Hash();
|
|
||||||
|
|
||||||
this.loaded = false;
|
|
||||||
this.delayedGetData = false;
|
|
||||||
this.ajaxGetData = false;
|
|
||||||
|
|
||||||
// Constants
|
|
||||||
this.overflow = 50; // must be higher or equal to the overflow of the data table class
|
|
||||||
},
|
|
||||||
|
|
||||||
destroy: function() {
|
|
||||||
this.uids.clear();
|
|
||||||
var keys = this.cache.keys();
|
|
||||||
for (var i = 0; i < keys.length; i++)
|
|
||||||
this.cache.unset(keys[i]);
|
|
||||||
},
|
|
||||||
|
|
||||||
invalidate: function(uid) {
|
|
||||||
this.cache.unset(uid);
|
|
||||||
var index = this.indexOf(uid);
|
|
||||||
// log ("MailDataSource.invalidate(" + uid + ") at index " + index);
|
|
||||||
|
|
||||||
return index;
|
|
||||||
},
|
|
||||||
|
|
||||||
remove: function(uid) {
|
|
||||||
// log ("MailDataSource.remove(" + uid + ")");
|
|
||||||
var index = this.invalidate(uid);
|
|
||||||
if (index >= 0) {
|
|
||||||
this.uids.splice(index, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return index;
|
|
||||||
},
|
|
||||||
|
|
||||||
init: function(uids, threaded, headers, quotas) {
|
|
||||||
this.uids = uids;
|
|
||||||
if (typeof threaded != "undefined") {
|
|
||||||
this.threaded = threaded;
|
|
||||||
if (threaded)
|
|
||||||
this.uids.shift(); // drop key fields
|
|
||||||
}
|
|
||||||
// log ("MailDataSource.init() " + this.uids.length + " uids loaded");
|
|
||||||
|
|
||||||
if (quotas && Object.isFunction(updateQuotas))
|
|
||||||
updateQuotas(quotas);
|
|
||||||
|
|
||||||
if (headers) {
|
|
||||||
var keys = headers[0];
|
|
||||||
for (var i = 1; i < headers.length; i++) {
|
|
||||||
var header = [];
|
|
||||||
for (var j = 0; j < keys.length; j++)
|
|
||||||
header[keys[j]] = headers[i][j];
|
|
||||||
this.cache.set(header["uid"], header);
|
|
||||||
}
|
|
||||||
// log ("MailDataSource.init() " + this.cache.keys().length + " headers loaded");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.loaded = true;
|
|
||||||
// log ("MailDataSource.init() " + this.uids.length + " UIDs, " + this.cache.keys().length + " headers");
|
|
||||||
},
|
|
||||||
|
|
||||||
load: function(content) {
|
|
||||||
this.loaded = false;
|
|
||||||
triggerAjaxRequest(this.url + "/uids",
|
|
||||||
this._loadCallback.bind(this),
|
|
||||||
null,
|
|
||||||
content,
|
|
||||||
{ "content-type": "application/json" });
|
|
||||||
},
|
|
||||||
|
|
||||||
_loadCallback: function(http) {
|
|
||||||
if (http.status == 200) {
|
|
||||||
if (http.responseText.length > 0) {
|
|
||||||
var data = http.responseText.evalJSON(true);
|
|
||||||
if (data.uids)
|
|
||||||
this.init(data.uids, data.threaded, data.headers, data.quotas);
|
|
||||||
else
|
|
||||||
this.init(data);
|
|
||||||
if (this.delayedGetData) {
|
|
||||||
this.delayedGetData();
|
|
||||||
this.delayedGetData = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
log("SOGoMailDataSource._loadCallback Error " + http.status + ": " + http.responseText);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getData: function(id, index, count, callbackFunction, delay) {
|
|
||||||
if (this.loaded == false) {
|
|
||||||
// UIDs are not yet loaded -- delay the call until loading the data is completed.
|
|
||||||
// log ("MailDataSource.getData() delaying data fetching while waiting for UIDs");
|
|
||||||
this.delayedGetData = this.getData.bind(this, id, index, count, callbackFunction, delay);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var start, end;
|
|
||||||
|
|
||||||
if (count > 1) {
|
|
||||||
// Compute last index depending on number of UIDs
|
|
||||||
start = index - (this.overflow/2);
|
|
||||||
if (start < 0) start = 0;
|
|
||||||
end = index + count + this.overflow - (index - start);
|
|
||||||
if (end > this.uids.length) {
|
|
||||||
start -= end - this.uids.length;
|
|
||||||
end = this.uids.length;
|
|
||||||
if (start < 0) start = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Count is 1; don't fetch more data since the caller is
|
|
||||||
// SOGoDataTable.invalide() and asks for only one data row.
|
|
||||||
start = index;
|
|
||||||
end = index + count;
|
|
||||||
}
|
|
||||||
// log ("MailDataSource._getData() from " + index + " to " + (index + count) + " boosted from " + start + " to " + end);
|
|
||||||
|
|
||||||
var missingUids = [];
|
|
||||||
for (var j = start; j < end; j++) {
|
|
||||||
var uid = this.threaded? this.uids[j][0] : this.uids[j];
|
|
||||||
if (!this.cache.get(uid)) {
|
|
||||||
// log ("MailDataSource._getData missing headers of uid " + uid + " at index " + j + (this.threaded? " (":" (non-") + "threaded)");
|
|
||||||
missingUids.push(uid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.delayed_getRemoteData) window.clearTimeout(this.delayed_getRemoteData);
|
|
||||||
if (missingUids.length > 0) {
|
|
||||||
var params = "uids=" + missingUids.join(",");
|
|
||||||
this.delayed_getRemoteData = this._getRemoteData.bind(this,
|
|
||||||
{ callbackFunction: callbackFunction,
|
|
||||||
start: start, end: end,
|
|
||||||
id: id },
|
|
||||||
params).delay(delay);
|
|
||||||
}
|
|
||||||
else if (callbackFunction)
|
|
||||||
this._returnData(callbackFunction, id, start, end);
|
|
||||||
},
|
|
||||||
|
|
||||||
_getRemoteData: function(callbackData, urlParams) {
|
|
||||||
if (this.ajaxGetData) {
|
|
||||||
this.ajaxGetData.aborted = true;
|
|
||||||
this.ajaxGetData.abort();
|
|
||||||
// log ("MailDataSource._getRemoteData() aborted previous AJAX request");
|
|
||||||
}
|
|
||||||
// log ("MailDataSource._getRemoteData() fetching headers of " + urlParams);
|
|
||||||
this.ajaxGetData = triggerAjaxRequest(this.url + "/headers",
|
|
||||||
this._getRemoteDataCallback.bind(this),
|
|
||||||
callbackData,
|
|
||||||
urlParams,
|
|
||||||
{ "Content-type": "application/x-www-form-urlencoded" });
|
|
||||||
},
|
|
||||||
|
|
||||||
_getRemoteDataCallback: function(http) {
|
|
||||||
if (http.status == 200) {
|
|
||||||
if (http.responseText.length > 0) {
|
|
||||||
// We receives an array of hashes
|
|
||||||
var headers = $A(http.responseText.evalJSON(true));
|
|
||||||
var data = http.callbackData;
|
|
||||||
var keys = headers[0];
|
|
||||||
for (var i = 1; i < headers.length; i++) {
|
|
||||||
var header = [];
|
|
||||||
for (var j = 0; j < keys.length; j++)
|
|
||||||
header[keys[j]] = headers[i][j];
|
|
||||||
this.cache.set(header["uid"], header);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data["callbackFunction"])
|
|
||||||
this._returnData(data["callbackFunction"], data["id"], data["start"], data["end"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
log("SOGoMailDataSource._getRemoteDataCallback Error " + http.status + ": " + http.responseText);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_returnData: function(callbackFunction, id, start, end) {
|
|
||||||
var i, j;
|
|
||||||
var data = new Array();
|
|
||||||
for (i = start, j = 0; i < end; i++, j++) {
|
|
||||||
if (this.threaded) {
|
|
||||||
data[j] = this.cache.get(this.uids[i][0]);
|
|
||||||
|
|
||||||
// Add thread-related data
|
|
||||||
if (parseInt(this.uids[i][2]) > 0) {
|
|
||||||
var mailbox = Mailer.currentMailbox;
|
|
||||||
if ((UserSettings.Mail.threadsCollapsed != undefined) &&
|
|
||||||
(UserSettings.Mail.threadsCollapsed[Mailer.currentMailbox] != undefined) &&
|
|
||||||
(UserSettings.Mail.threadsCollapsed[Mailer.currentMailbox].indexOf((this.uids[i][0]).toString())) != -1) {
|
|
||||||
data[j]['Thread'] = '<img class="messageThread" src="' + ResourcesURL + '/arrow-right.png">';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
data[j]['Thread'] = '<img class="messageThread" src="' + ResourcesURL + '/arrow-down.png">';
|
|
||||||
}
|
|
||||||
else if (data[j]['Thread'])
|
|
||||||
delete data[j]['Thread'];
|
|
||||||
if (parseInt(this.uids[i][1]) > -1)
|
|
||||||
data[j]['ThreadLevel'] = this.uids[i][1];
|
|
||||||
else
|
|
||||||
delete data[j]['ThreadLevel'];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
data[j] = this.cache.get(this.uids[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
callbackFunction(id, start, this.uids.length, data);
|
|
||||||
},
|
|
||||||
|
|
||||||
indexOf: function(uid) {
|
|
||||||
var index = -1;
|
|
||||||
if (this.threaded) {
|
|
||||||
for (var i = 0; i < this.uids.length; i++)
|
|
||||||
if (this.uids[i][0] == uid) {
|
|
||||||
index = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
index = this.uids.indexOf(parseInt(uid));
|
|
||||||
|
|
||||||
return index;
|
|
||||||
},
|
|
||||||
|
|
||||||
uidAtIndex: function(index) {
|
|
||||||
if (this.threaded)
|
|
||||||
return this.uids[index][0];
|
|
||||||
else
|
|
||||||
return this.uids[index];
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,286 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Resizable table interface to be added to a TABLE (this!)
|
|
||||||
*
|
|
||||||
* Columns with the class resizable will be .. resizable.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
var SOGoResizableTableInterface = {
|
|
||||||
|
|
||||||
delayedResize: null,
|
|
||||||
ratios: null,
|
|
||||||
|
|
||||||
bind: function() {
|
|
||||||
var i;
|
|
||||||
var cells = $(this).down('tr').childElements();
|
|
||||||
for (i = 0; i < cells.length; i++) {
|
|
||||||
var cell = cells[i];
|
|
||||||
if (Prototype.Browser.IE)
|
|
||||||
cell.observe("selectstart", Event.stop);
|
|
||||||
if (cell.hasClassName('resizable')) {
|
|
||||||
Event.observe(cell, 'mouseover', SOGoResizableTable.initDetect);
|
|
||||||
Event.observe(cell, 'mouseout', SOGoResizableTable.killDetect);
|
|
||||||
}
|
|
||||||
SOGoResizableTable._resize(this, $(cell), i, null, cell.getWidth());
|
|
||||||
}
|
|
||||||
this.computeColumnsWidths();
|
|
||||||
Event.observe(window, "resize", this.resize.bind(this));
|
|
||||||
},
|
|
||||||
|
|
||||||
resize: function(e) {
|
|
||||||
// Only resize the columns after a certain delay, otherwise it slows
|
|
||||||
// down the interface.
|
|
||||||
if (this.delayedResize) window.clearTimeout(this.delayedResize);
|
|
||||||
this.delayedResize = this._resize.bind(this).delay(0.2);
|
|
||||||
},
|
|
||||||
|
|
||||||
_resize: function() {
|
|
||||||
this.restore();
|
|
||||||
},
|
|
||||||
|
|
||||||
restore: function(relativeWidths) {
|
|
||||||
if (SOGoResizableTable._stylesheet != null)
|
|
||||||
if (Prototype.Browser.IE)
|
|
||||||
while (SOGoResizableTable._stylesheet.styleSheet.rules.length)
|
|
||||||
SOGoResizableTable._stylesheet.styleSheet.removeRule(0);
|
|
||||||
else
|
|
||||||
while (SOGoResizableTable._stylesheet.firstChild)
|
|
||||||
SOGoResizableTable._stylesheet.removeChild(SOGoResizableTable._stylesheet.firstChild);
|
|
||||||
|
|
||||||
if (relativeWidths)
|
|
||||||
this.ratios = relativeWidths;
|
|
||||||
var tableWidth = this.getWidth()/100;
|
|
||||||
var cells = $(this).down('tr').select('.resizable');
|
|
||||||
for (i = 0; i < cells.length; i++) {
|
|
||||||
var cell = cells[i];
|
|
||||||
var ratio = this.ratios.get(cell.id);
|
|
||||||
SOGoResizableTable._resize(this, $(cell), i, null, ratio*tableWidth);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
computeColumnsWidths: function() {
|
|
||||||
this.ratios = new Hash();
|
|
||||||
var tableWidth = 100/this.getWidth();
|
|
||||||
var cells = $(this).down('tr').childElements();
|
|
||||||
for (i = 0; i < cells.length; i++) {
|
|
||||||
var cell = cells[i];
|
|
||||||
if (cell.hasClassName('resizable'))
|
|
||||||
this.ratios.set(cell.id, Math.round(cell.getWidth()*tableWidth));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
saveColumnsState: function() {
|
|
||||||
this.computeColumnsWidths();
|
|
||||||
if (!$(document.body).hasClassName("popup")) {
|
|
||||||
var url = ApplicationBaseURL + "/saveColumnsState";
|
|
||||||
var data = this.ratios;
|
|
||||||
var columns = data.keys();
|
|
||||||
var params = "columns=" + columns.join(",")
|
|
||||||
+ "&widths=" + columns.collect(function(c) { return data.get(c); }).join(",");
|
|
||||||
triggerAjaxRequest(url,
|
|
||||||
this.saveColumnsStateCallback,
|
|
||||||
null,
|
|
||||||
params,
|
|
||||||
{ "Content-type": "application/x-www-form-urlencoded" });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
saveColumnsStateCallback: function(http) {
|
|
||||||
if (isHttpStatus204(http.status)) {
|
|
||||||
log ("ResizableTable.saveColumnsStateCallback() Columns state saved");
|
|
||||||
}
|
|
||||||
else if (http.readyState == 4) {
|
|
||||||
log ("ResizableTable.saveColumnsStateCallback() Can't save columns state");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
SOGoResizableTable = {
|
|
||||||
|
|
||||||
_onHandle: false,
|
|
||||||
_cell: null,
|
|
||||||
_tbl: null,
|
|
||||||
_handle: null,
|
|
||||||
_stylesheet: null,
|
|
||||||
|
|
||||||
resize: function(table, index, w) {
|
|
||||||
var cell;
|
|
||||||
if (typeof index === 'number') {
|
|
||||||
if (!table || (table.tagName && table.tagName !== "TABLE")) { return; }
|
|
||||||
table = $(table);
|
|
||||||
index = Math.min(table.rows[0].cells.length, index);
|
|
||||||
index = Math.max(1, index);
|
|
||||||
index -= 1;
|
|
||||||
cell = $(table.rows[0].cells[index]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cell = $(index);
|
|
||||||
table = table ? $(table) : cell.up('table');
|
|
||||||
index = SOGoResizableTable.getCellIndex(cell);
|
|
||||||
}
|
|
||||||
|
|
||||||
var cells = table.down('tr').childElements();
|
|
||||||
var nextResizableCell = null;
|
|
||||||
for (var i = index + 1; i < cells.length; i++) {
|
|
||||||
var c = cells[i];
|
|
||||||
if (c.hasClassName('resizable')) {
|
|
||||||
nextResizableCell = c;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var delta = SOGoResizableTable._resize(table, cell, index, nextResizableCell, w, false);
|
|
||||||
if (delta != 0 && nextResizableCell != null) {
|
|
||||||
var w = nextResizableCell.getWidth() - delta;
|
|
||||||
SOGoResizableTable._resize(table, nextResizableCell, i, null, w, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
table.saveColumnsState();
|
|
||||||
},
|
|
||||||
|
|
||||||
_resize: function(table, cell, index, nextResizableCell, w, isAdjustment) {
|
|
||||||
var pad = 0;
|
|
||||||
if (!Prototype.Browser.WebKit) {
|
|
||||||
pad = parseInt(cell.getStyle('paddingLeft'),10) + parseInt(cell.getStyle('paddingRight'),10);
|
|
||||||
pad += parseInt(cell.getStyle('borderLeftWidth'),10) + parseInt(cell.getStyle('borderRightWidth'),10);
|
|
||||||
}
|
|
||||||
|
|
||||||
var cells = table.down('tr').childElements();
|
|
||||||
if ((index + 1) == cells.length) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isAdjustment && cell.getWidth() < w) {
|
|
||||||
if (nextResizableCell == null && (index + 2) == cells.length)
|
|
||||||
// The next cell is the last cell; respect its minimum width
|
|
||||||
// event if it's not resizable.
|
|
||||||
nextResizableCell = cells[index + 1];
|
|
||||||
if (nextResizableCell != null) {
|
|
||||||
// Respect the minimum width of the next resizable cell.
|
|
||||||
var max = cells[index].getWidth()
|
|
||||||
+ nextResizableCell.getWidth()
|
|
||||||
- parseInt(nextResizableCell.getStyle('minWidth'))
|
|
||||||
- pad;
|
|
||||||
w = Math.min(max, w);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Respect the minimum width of the cell.
|
|
||||||
w = Math.max(Math.round(w) - pad, parseInt(cell.getStyle('minWidth')));
|
|
||||||
|
|
||||||
var delta = w - cell.getWidth() + pad;
|
|
||||||
|
|
||||||
var cssSelector = ' TABLE.' + $w(table.className).first() + ' .' + $w(cell.className).first();
|
|
||||||
|
|
||||||
if (SOGoResizableTable._stylesheet == null) {
|
|
||||||
SOGoResizableTable._stylesheet = document.createElement("style");
|
|
||||||
SOGoResizableTable._stylesheet.type = "text/css";
|
|
||||||
document.getElementsByTagName("head")[0].appendChild(SOGoResizableTable._stylesheet);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SOGoResizableTable._stylesheet.styleSheet && SOGoResizableTable._stylesheet.styleSheet.addRule) {
|
|
||||||
// IE
|
|
||||||
SOGoResizableTable._stylesheet.styleSheet.addRule(cssSelector,
|
|
||||||
' { width: ' + w + 'px; max-width: ' + w + 'px; }');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Mozilla + Safari
|
|
||||||
SOGoResizableTable._stylesheet.appendChild(document.createTextNode(cssSelector +
|
|
||||||
' { width: ' + w + 'px; max-width: ' + w + 'px; }'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return delta;
|
|
||||||
},
|
|
||||||
|
|
||||||
initDetect: function(e) {
|
|
||||||
var cell = Event.element(e);
|
|
||||||
if (cell.tagName != "TH") { return; }
|
|
||||||
Event.observe(cell, 'mousemove', SOGoResizableTable.detectHandle);
|
|
||||||
Event.observe(cell, 'mousedown', SOGoResizableTable.startResize);
|
|
||||||
},
|
|
||||||
|
|
||||||
detectHandle: function(e) {
|
|
||||||
var cell = Event.element(e);
|
|
||||||
if (SOGoResizableTable.pointerPos(cell, Event.pointerX(e), Event.pointerY(e))) {
|
|
||||||
cell.addClassName('resize-handle-active');
|
|
||||||
SOGoResizableTable._onHandle = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cell.removeClassName('resize-handle-active');
|
|
||||||
SOGoResizableTable._onHandle = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
killDetect: function(e) {
|
|
||||||
SOGoResizableTable._onHandle = false;
|
|
||||||
var cell = Event.element(e);
|
|
||||||
Event.stopObserving(cell, 'mousemove', SOGoResizableTable.detectHandle);
|
|
||||||
Event.stopObserving(cell, 'mousedown', SOGoResizableTable.startResize);
|
|
||||||
cell.removeClassName('resize-handle-active');
|
|
||||||
},
|
|
||||||
|
|
||||||
startResize: function(e) {
|
|
||||||
if (!SOGoResizableTable._onHandle) { return; }
|
|
||||||
var cell = Event.element(e);
|
|
||||||
Event.stopObserving(cell, 'mousemove', SOGoResizableTable.detectHandle);
|
|
||||||
Event.stopObserving(cell, 'mousedown', SOGoResizableTable.startResize);
|
|
||||||
Event.stopObserving(cell, 'mouseout', SOGoResizableTable.killDetect);
|
|
||||||
SOGoResizableTable._cell = cell;
|
|
||||||
var table = cell.up('table');
|
|
||||||
SOGoResizableTable._tbl = table;
|
|
||||||
SOGoResizableTable._handle = $(document.createElement('div')).addClassName('resize-handle').setStyle({
|
|
||||||
'top' : table.cumulativeOffset()[1] + 'px',
|
|
||||||
'left' : Event.pointerX(e) + 'px',
|
|
||||||
'height' : table.getHeight() + 'px',
|
|
||||||
'max-height' : table.getHeight() + 'px'
|
|
||||||
});
|
|
||||||
document.body.appendChild(SOGoResizableTable._handle);
|
|
||||||
|
|
||||||
Event.observe(document, 'mousemove', SOGoResizableTable.drag);
|
|
||||||
Event.observe(document, 'mouseup', SOGoResizableTable.endResize);
|
|
||||||
Event.stop(e);
|
|
||||||
},
|
|
||||||
|
|
||||||
endResize: function(e) {
|
|
||||||
var cell = SOGoResizableTable._cell;
|
|
||||||
if (!cell) { return; }
|
|
||||||
SOGoResizableTable.resize(null, cell, (Event.pointerX(e) - cell.cumulativeOffset()[0]));
|
|
||||||
Event.stopObserving(document, 'mousemove', SOGoResizableTable.drag);
|
|
||||||
Event.stopObserving(document, 'mouseup', SOGoResizableTable.endResize);
|
|
||||||
$$('div.resize-handle').each(function(elm){
|
|
||||||
document.body.removeChild(elm);
|
|
||||||
});
|
|
||||||
Event.observe(cell, 'mouseout', SOGoResizableTable.killDetect);
|
|
||||||
SOGoResizableTable._tbl = SOGoResizableTable._handle = SOGoResizableTable._cell = null;
|
|
||||||
Event.stop(e);
|
|
||||||
},
|
|
||||||
|
|
||||||
drag: function(e) {
|
|
||||||
e = $(e);
|
|
||||||
if (SOGoResizableTable._handle === null) {
|
|
||||||
try {
|
|
||||||
SOGoResizableTable.resize(SOGoResizableTable._tbl, SOGoResizableTable._cell, (Event.pointerX(e) - SOGoResizableTable._cell.cumulativeOffset()[0]));
|
|
||||||
}
|
|
||||||
catch(e) {}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SOGoResizableTable._handle.setStyle({'left' : Event.pointerX(e) + 'px'});
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
pointerPos: function(element, x, y) {
|
|
||||||
var offset = $(element).cumulativeOffset();
|
|
||||||
return (y >= offset[1] &&
|
|
||||||
y < offset[1] + element.offsetHeight &&
|
|
||||||
x >= offset[0] + element.offsetWidth - 5 &&
|
|
||||||
x < offset[0] + element.offsetWidth);
|
|
||||||
},
|
|
||||||
|
|
||||||
getCellIndex : function(cell) {
|
|
||||||
return $A(cell.parentNode.cells).indexOf(cell);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
|
@ -1,138 +0,0 @@
|
||||||
BODY
|
|
||||||
{ background-color: #E6E7E6;
|
|
||||||
text-align: center; }
|
|
||||||
|
|
||||||
IMG#preparedAnimation
|
|
||||||
{ width: 0px;
|
|
||||||
height: 0px; }
|
|
||||||
|
|
||||||
DIV.linkbanner A#about
|
|
||||||
{ float: right;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px .5em; }
|
|
||||||
|
|
||||||
DIV#aboutBox
|
|
||||||
{ position: absolute;
|
|
||||||
z-index: 1000;
|
|
||||||
left: 0px;
|
|
||||||
top: 30px;
|
|
||||||
width: 100%;
|
|
||||||
text-align: center; }
|
|
||||||
|
|
||||||
DIV#aboutBox DIV
|
|
||||||
{ background-color: #fff;
|
|
||||||
border: 1px solid #222;
|
|
||||||
margin: auto;
|
|
||||||
padding-bottom: 20px;
|
|
||||||
width: 550px; }
|
|
||||||
|
|
||||||
DIV#aboutBox SPAN.buildDate
|
|
||||||
{ color: #666; }
|
|
||||||
|
|
||||||
A#aboutClose
|
|
||||||
{ position: relative;
|
|
||||||
margin-right: 10px;
|
|
||||||
top: -10px; }
|
|
||||||
|
|
||||||
A,
|
|
||||||
A:link,
|
|
||||||
A:visited
|
|
||||||
{ color: #54b948; }
|
|
||||||
|
|
||||||
DIV A.button
|
|
||||||
{ color: #000; }
|
|
||||||
|
|
||||||
DIV#aboutBox P.logo
|
|
||||||
{ background-color: #222;
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 10px; }
|
|
||||||
|
|
||||||
DIV#aboutBox P.scroll
|
|
||||||
{ border: 1px solid #222;
|
|
||||||
height: 120px;
|
|
||||||
margin: auto;
|
|
||||||
padding: 5px;
|
|
||||||
width: 350px;
|
|
||||||
text-align: left;
|
|
||||||
overflow-y: auto; }
|
|
||||||
|
|
||||||
DIV#aboutBox P.links
|
|
||||||
{ margin: 0 0 20px 0; }
|
|
||||||
|
|
||||||
DIV.linkbanner
|
|
||||||
{ text-align: right; }
|
|
||||||
|
|
||||||
DIV.linkbanner A
|
|
||||||
{ padding-right: .5em; }
|
|
||||||
|
|
||||||
DIV#loginScreen
|
|
||||||
{ clear: both;
|
|
||||||
margin: 0px auto;
|
|
||||||
padding-top: 5em;
|
|
||||||
border: 2px solid transparent;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#loginScreen TABLE
|
|
||||||
{ margin: auto; }
|
|
||||||
|
|
||||||
DIV#loginScreen TABLE TD
|
|
||||||
{ text-align: right; }
|
|
||||||
|
|
||||||
DIV#loginScreen TABLE TD#loginCell
|
|
||||||
{ border-left: 1px solid #fff;
|
|
||||||
padding-left: 10px;
|
|
||||||
vertical-align: top; }
|
|
||||||
|
|
||||||
LABEL
|
|
||||||
{ display: inline-block;
|
|
||||||
padding: 10px; }
|
|
||||||
|
|
||||||
DIV#loginScreen LABEL
|
|
||||||
{ display: block;
|
|
||||||
padding: 5px; }
|
|
||||||
|
|
||||||
#animation
|
|
||||||
{ margin: 0px auto;
|
|
||||||
padding: 0px; }
|
|
||||||
|
|
||||||
IMG#splash
|
|
||||||
{ border: 0;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px 0px 0px 0px; }
|
|
||||||
|
|
||||||
DIV#loginScreen INPUT.textField
|
|
||||||
{ width: 187px; }
|
|
||||||
|
|
||||||
DIV#loginScreen A#submit,
|
|
||||||
DIV#loginScreen A#submit SPAN
|
|
||||||
{ color: #535D6D; }
|
|
||||||
|
|
||||||
IMG#progressIndicator
|
|
||||||
{ width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
margin-top: 20px;
|
|
||||||
margin-left: 5px; }
|
|
||||||
|
|
||||||
#errorMessage
|
|
||||||
{ color: #f00;
|
|
||||||
width: 400px;
|
|
||||||
margin: 0px auto;
|
|
||||||
text-align: center; }
|
|
||||||
|
|
||||||
P.browser
|
|
||||||
{ background-color: #fff;
|
|
||||||
border-top: 1px solid #888;
|
|
||||||
border-left: 1px solid #888;
|
|
||||||
border-right: 1px solid #eee;
|
|
||||||
border-bottom: 1px solid #eee;
|
|
||||||
line-height: 32px;
|
|
||||||
padding-right: 5px; }
|
|
||||||
|
|
||||||
P.browser IMG
|
|
||||||
{ padding: 0 2px;
|
|
||||||
margin: 0;
|
|
||||||
vertical-align: middle; }
|
|
||||||
|
|
||||||
#passwordChangeDialog INPUT
|
|
||||||
{ width: 150px; }
|
|
|
@ -1,350 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
var dialogs = {};
|
|
||||||
|
|
||||||
function initLogin() {
|
|
||||||
var date = new Date();
|
|
||||||
date.setTime(date.getTime() - 86400000);
|
|
||||||
|
|
||||||
var href = $("connectForm").action.split("/");
|
|
||||||
var appName = href[href.length-2];
|
|
||||||
|
|
||||||
document.cookie = ("0xHIGHFLYxSOGo=discarded"
|
|
||||||
+ "; expires=" + date.toGMTString()
|
|
||||||
+ "; path=/" + appName + "/");
|
|
||||||
|
|
||||||
var about = $("about");
|
|
||||||
if (about) {
|
|
||||||
about.observe("click", function(event) {
|
|
||||||
jQuery('#aboutBox').slideToggle('fast');
|
|
||||||
event.stop(); });
|
|
||||||
var aboutClose = $("aboutClose");
|
|
||||||
aboutClose.observe("click", function(event) {
|
|
||||||
jQuery('#aboutBox').slideUp('fast');
|
|
||||||
event.stop() });
|
|
||||||
}
|
|
||||||
|
|
||||||
var submit = $("submit");
|
|
||||||
submit.observe("click", onLoginClick);
|
|
||||||
|
|
||||||
var userName = $("userName");
|
|
||||||
userName.observe("keydown", onFieldKeyDown);
|
|
||||||
|
|
||||||
var passw = $("password");
|
|
||||||
passw.observe("keydown", onFieldKeyDown);
|
|
||||||
|
|
||||||
var image = $("preparedAnimation");
|
|
||||||
image.parentNode.removeChild(image);
|
|
||||||
|
|
||||||
var submitBtn = $("submit");
|
|
||||||
submitBtn.disabled = false;
|
|
||||||
|
|
||||||
if (userName.value.empty())
|
|
||||||
userName.focus();
|
|
||||||
else
|
|
||||||
passw.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onFieldKeyDown(event) {
|
|
||||||
if (event.keyCode == Event.KEY_RETURN) {
|
|
||||||
if ($("password").value.length > 0
|
|
||||||
&& $("userName").value.length > 0)
|
|
||||||
return onLoginClick(event);
|
|
||||||
else
|
|
||||||
Event.stop(event);
|
|
||||||
} else if (IsCharacterKey(event.keyCode)
|
|
||||||
|| event.keyCode == Event.KEY_BACKSPACE) {
|
|
||||||
SetLogMessage("errorMessage", null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onLoginClick(event) {
|
|
||||||
var userNameField = $("userName");
|
|
||||||
var userName = userNameField.value;
|
|
||||||
var password = $("password").value;
|
|
||||||
var language = $("language");
|
|
||||||
var domain = $("domain");
|
|
||||||
|
|
||||||
SetLogMessage("errorMessage");
|
|
||||||
|
|
||||||
if (userName.length > 0 && password.length > 0) {
|
|
||||||
this.disabled = true;
|
|
||||||
startAnimation($("animation"));
|
|
||||||
|
|
||||||
if (typeof(loginSuffix) != "undefined"
|
|
||||||
&& loginSuffix.length > 0
|
|
||||||
&& !userName.endsWith(loginSuffix))
|
|
||||||
userName += loginSuffix;
|
|
||||||
|
|
||||||
var url = $("connectForm").getAttribute("action");
|
|
||||||
var parameters = ("userName=" + encodeURIComponent(userName)
|
|
||||||
+ "&password=" + encodeURIComponent(password));
|
|
||||||
if (language)
|
|
||||||
parameters += ((language.value == "WONoSelectionString")
|
|
||||||
? ""
|
|
||||||
: ("&language=" + language.value));
|
|
||||||
if (domain)
|
|
||||||
parameters += "&domain=" + domain.value;
|
|
||||||
var rememberLogin = $("rememberLogin");
|
|
||||||
if (rememberLogin && rememberLogin.checked)
|
|
||||||
parameters += "&rememberLogin=1";
|
|
||||||
|
|
||||||
/// Discarded as it seems to create a cookie for nothing. To discard
|
|
||||||
// a cookie in JS, have a look here: http://www.quirksmode.org/js/cookies.html
|
|
||||||
//document.cookie = "";\
|
|
||||||
triggerAjaxRequest(url, onLoginCallback, null, (parameters),
|
|
||||||
{ "Content-type": "application/x-www-form-urlencoded",
|
|
||||||
"Content-length": parameters.length,
|
|
||||||
"Connection": "close" });
|
|
||||||
}
|
|
||||||
else
|
|
||||||
userNameField.focus();
|
|
||||||
|
|
||||||
preventDefault(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onLoginCallback(http) {
|
|
||||||
if (http.readyState == 4) {
|
|
||||||
var submitBtn = $("submit");
|
|
||||||
|
|
||||||
if (http.status == 200) {
|
|
||||||
// Make sure browser's cookies are enabled
|
|
||||||
var loginCookie = readLoginCookie();
|
|
||||||
|
|
||||||
if (!loginCookie) {
|
|
||||||
SetLogMessage("errorMessage", _("cookiesNotEnabled"));
|
|
||||||
submitBtn.disabled = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var jsonResponse = http.responseText.evalJSON(false);
|
|
||||||
if (jsonResponse
|
|
||||||
&& typeof(jsonResponse["expire"]) != "undefined"
|
|
||||||
&& typeof(jsonResponse["grace"]) != "undefined") {
|
|
||||||
|
|
||||||
if (jsonResponse["expire"] < 0 && jsonResponse["grace"] > 0)
|
|
||||||
showPasswordDialog("grace", createPasswordGraceDialog, jsonResponse["grace"]);
|
|
||||||
else if (jsonResponse["expire"] > 0 && jsonResponse["grace"] == -1)
|
|
||||||
showPasswordDialog("expiration", createPasswordExpirationDialog, jsonResponse["expire"]);
|
|
||||||
else {
|
|
||||||
redirectToUserPage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
redirectToUserPage();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (http.status == 403
|
|
||||||
&& http.getResponseHeader("content-type")
|
|
||||||
== "application/json") {
|
|
||||||
var jsonResponse = http.responseText.evalJSON(false);
|
|
||||||
handlePasswordError(jsonResponse);
|
|
||||||
} else {
|
|
||||||
SetLogMessage("errorMessage", _("An unhandled error occurred."));
|
|
||||||
}
|
|
||||||
submitBtn.disabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function redirectToUserPage() {
|
|
||||||
// Redirect to proper page
|
|
||||||
var userName = $("userName").value;
|
|
||||||
var domain = $("domain");
|
|
||||||
if (domain)
|
|
||||||
userName += '@' + domain.value;
|
|
||||||
else if (typeof(loginSuffix) != "undefined"
|
|
||||||
&& loginSuffix.length > 0
|
|
||||||
&& !userName.endsWith(loginSuffix))
|
|
||||||
userName += loginSuffix;
|
|
||||||
var address = "" + window.location.href;
|
|
||||||
var baseAddress = ApplicationBaseURL + "/" + encodeURIComponent(userName);
|
|
||||||
var altBaseAddress;
|
|
||||||
if (baseAddress[0] == "/") {
|
|
||||||
var parts = address.split("/");
|
|
||||||
var hostpart = parts[2];
|
|
||||||
var protocol = parts[0];
|
|
||||||
baseAddress = protocol + "//" + hostpart + baseAddress;
|
|
||||||
}
|
|
||||||
var altBaseAddress;
|
|
||||||
var parts = baseAddress.split("/");
|
|
||||||
parts.splice(3, 0);
|
|
||||||
altBaseAddress = parts.join("/");
|
|
||||||
|
|
||||||
var newAddress;
|
|
||||||
if ((address.startsWith(baseAddress)
|
|
||||||
|| address.startsWith(altBaseAddress))
|
|
||||||
&& !address.endsWith("/logoff"))
|
|
||||||
newAddress = address;
|
|
||||||
else
|
|
||||||
newAddress = baseAddress;
|
|
||||||
window.location.href = newAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handlePasswordError(jsonResponse) {
|
|
||||||
var perr = jsonResponse["LDAPPasswordPolicyError"];
|
|
||||||
if (perr == PolicyNoError) {
|
|
||||||
SetLogMessage("errorMessage", _("Wrong username or password."));
|
|
||||||
} else if (perr == PolicyAccountLocked) {
|
|
||||||
SetLogMessage("errorMessage",
|
|
||||||
_("Your account was locked due to too many failed attempts."));
|
|
||||||
} else if (perr == PolicyChangeAfterReset) {
|
|
||||||
showPasswordDialog("change", createPasswordChangeDialog, 5);
|
|
||||||
} else if (perr == PolicyPasswordExpired) {
|
|
||||||
SetLogMessage("errorMessage",
|
|
||||||
_("Your account was locked due to an expired password."));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
SetLogMessage("errorMessage",
|
|
||||||
_("Login failed due to unhandled error case: " + perr));
|
|
||||||
}
|
|
||||||
|
|
||||||
function showPasswordDialog(dialogType, constructor, parameters) {
|
|
||||||
var dialog = dialogs[dialogType];
|
|
||||||
if (!dialog) {
|
|
||||||
dialog = constructor(parameters);
|
|
||||||
var form = $("connectForm");
|
|
||||||
form.appendChild(dialog);
|
|
||||||
dialogs[dialogType] = dialog;
|
|
||||||
}
|
|
||||||
var password = $("password");
|
|
||||||
var offsets = password.positionedOffset();
|
|
||||||
dialog.show();
|
|
||||||
var top = offsets[1] - 2;
|
|
||||||
var left = offsets[0] + 10 - dialog.clientWidth;
|
|
||||||
dialog.setStyle({ "top": top + "px", "left": left + "px"});
|
|
||||||
}
|
|
||||||
|
|
||||||
function createPasswordChangeDialog() {
|
|
||||||
var fields = createElement("p");
|
|
||||||
createElement("span", "passwordError", null, null, null, fields);
|
|
||||||
|
|
||||||
var fieldNames = [ "newPassword", "newPassword2" ];
|
|
||||||
var fieldLabels = [ _("New password:"), _("Confirmation:") ];
|
|
||||||
for (var i = 0; i < fieldNames.length; i++) {
|
|
||||||
var label = createElement("label", null, null, null, null, fields);
|
|
||||||
label.appendChild(document.createTextNode(fieldLabels[i]));
|
|
||||||
createElement("input", fieldNames[i], "textField",
|
|
||||||
{ "name": fieldNames[i], "type": "password" },
|
|
||||||
null, label);
|
|
||||||
createElement("br", null, null, null, null, fields);
|
|
||||||
}
|
|
||||||
|
|
||||||
var button = createButton("passwordOKButton", _("OK"), passwordDialogOK);
|
|
||||||
button.addClassName("actionButton");
|
|
||||||
fields.appendChild(button);
|
|
||||||
fields.appendChild(document.createTextNode(" "));
|
|
||||||
button = createButton("passwordCancelButton",
|
|
||||||
_("Cancel"), passwordDialogCancel);
|
|
||||||
fields.appendChild(button);
|
|
||||||
|
|
||||||
var dialog = createDialog("passwordChangeDialog",
|
|
||||||
_("Change your Password"),
|
|
||||||
_("Your password has expired, please enter a new one below:"),
|
|
||||||
fields,
|
|
||||||
"right");
|
|
||||||
|
|
||||||
return dialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
function passwordDialogOK(event) {
|
|
||||||
var field = $("newPassword");
|
|
||||||
var confirmationField = $("newPassword2");
|
|
||||||
if (field && confirmationField) {
|
|
||||||
var newPassword = field.value;
|
|
||||||
if (newPassword == confirmationField.value) {
|
|
||||||
if (newPassword.length > 0) {
|
|
||||||
var userName = $("userName");
|
|
||||||
var password = $("password");
|
|
||||||
var policy = new PasswordPolicy(userName.value,
|
|
||||||
password.value);
|
|
||||||
policy.setCallbacks(onPasswordChangeSuccess,
|
|
||||||
onPasswordChangeFailure);
|
|
||||||
policy.changePassword(newPassword);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
SetLogMessage("passwordError",
|
|
||||||
_("Password must not be empty."));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SetLogMessage("passwordError",
|
|
||||||
_("The passwords do not match. Please try again."));
|
|
||||||
field.focus();
|
|
||||||
field.select();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
event.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPasswordChangeSuccess() {
|
|
||||||
SetLogMessage("passwordError", _("Please wait..."));
|
|
||||||
redirectToUserPage();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPasswordChangeFailure(code, message) {
|
|
||||||
SetLogMessage("passwordError", message);
|
|
||||||
}
|
|
||||||
|
|
||||||
function passwordDialogCancel(event) {
|
|
||||||
var dialog = $("passwordChangeDialog");
|
|
||||||
dialog.hide();
|
|
||||||
event.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
function createPasswordGraceDialog(tries) {
|
|
||||||
var button = createButton("graceOKButton", _("OK"));
|
|
||||||
button.observe("click", passwordGraceDialogOK);
|
|
||||||
button.addClassName("actionButton");
|
|
||||||
|
|
||||||
return createDialog("passwordGraceDialog",
|
|
||||||
_("Password Grace Period"),
|
|
||||||
_("You have %{0} logins remaining before your account is locked. Please change your password in the preference dialog.").formatted(tries),
|
|
||||||
button,
|
|
||||||
"right");
|
|
||||||
}
|
|
||||||
|
|
||||||
function passwordGraceDialogOK(event) {
|
|
||||||
var dialog = $("passwordGraceDialog");
|
|
||||||
dialog.hide();
|
|
||||||
event.stop();
|
|
||||||
redirectToUserPage();
|
|
||||||
}
|
|
||||||
|
|
||||||
function createPasswordExpirationDialog(expire) {
|
|
||||||
var button = createButton("expirationOKButton", _("OK"));
|
|
||||||
button.observe("click", passwordExpirationDialogOK);
|
|
||||||
button.addClassName("actionButton");
|
|
||||||
|
|
||||||
var value, string;
|
|
||||||
|
|
||||||
if (expire > 86400) {
|
|
||||||
value = Math.round(expire/86400);
|
|
||||||
string = _("days");
|
|
||||||
}
|
|
||||||
else if (expire > 3600) {
|
|
||||||
value = Math.round(expire/3600);
|
|
||||||
string = _("hours");
|
|
||||||
}
|
|
||||||
else if (expire > 60) {
|
|
||||||
value = Math.round(expire/60);
|
|
||||||
string = _("minutes");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
value = expire;
|
|
||||||
string = _("seconds");
|
|
||||||
}
|
|
||||||
return createDialog("passwordExpirationDialog",
|
|
||||||
_("Password about to expire"),
|
|
||||||
_("Your password is going to expire in %{0} %{1}.").formatted(value, string),
|
|
||||||
button,
|
|
||||||
"right");
|
|
||||||
}
|
|
||||||
|
|
||||||
function passwordExpirationDialogOK(event) {
|
|
||||||
var dialog = $("passwordExpirationDialog");
|
|
||||||
dialog.hide();
|
|
||||||
event.stop();
|
|
||||||
redirectToUserPage();
|
|
||||||
}
|
|
||||||
|
|
||||||
document.observe("dom:loaded", initLogin);
|
|
|
@ -1,169 +0,0 @@
|
||||||
/* -*- Mode: java; tab-width: 2; c-label-minimum-indentation: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
function SOGoTabsController() {
|
|
||||||
}
|
|
||||||
|
|
||||||
SOGoTabsController.prototype = {
|
|
||||||
container: null,
|
|
||||||
firstTab: null,
|
|
||||||
activeTab: null,
|
|
||||||
|
|
||||||
list: null,
|
|
||||||
offset: 0,
|
|
||||||
|
|
||||||
createScrollButtons: function STC_createScrollButtons() {
|
|
||||||
var scrollToolbar = createElement("div", null, "scrollToolbar");
|
|
||||||
scrollToolbar.hide();
|
|
||||||
var lnk = createElement("a", null,
|
|
||||||
[ "leftScrollButton",
|
|
||||||
"scrollButton", "smallToolbarButton"],
|
|
||||||
{ href: "#" },
|
|
||||||
null, scrollToolbar);
|
|
||||||
var span = createElement("span");
|
|
||||||
lnk.appendChild(span);
|
|
||||||
span.appendChild(document.createTextNode("<"));
|
|
||||||
this.onScrollLeftBound = this.onScrollLeft.bindAsEventListener(this);
|
|
||||||
lnk.observe("click", this.onScrollLeftBound, false);
|
|
||||||
|
|
||||||
var lnk = createElement("a", null,
|
|
||||||
[ "rightScrollButton",
|
|
||||||
"scrollButton", "smallToolbarButton"],
|
|
||||||
{ href: "#" },
|
|
||||||
null, scrollToolbar);
|
|
||||||
var span = createElement("span");
|
|
||||||
lnk.appendChild(span);
|
|
||||||
span.appendChild(document.createTextNode(">"));
|
|
||||||
this.onScrollRightBound = this.onScrollRight.bindAsEventListener(this);
|
|
||||||
lnk.observe("click", this.onScrollRightBound, false);
|
|
||||||
|
|
||||||
this.container.appendChild(scrollToolbar);
|
|
||||||
this.scrollToolbar = scrollToolbar;
|
|
||||||
},
|
|
||||||
|
|
||||||
onScrollLeft: function(event) {
|
|
||||||
if (this.offset < 0) {
|
|
||||||
var offset = this.offset + 20;
|
|
||||||
if (offset > 0) {
|
|
||||||
offset = 0;
|
|
||||||
}
|
|
||||||
this.list.setStyle("margin-left: " + offset + "px;");
|
|
||||||
// log("offset: " + offset);
|
|
||||||
this.offset = offset;
|
|
||||||
}
|
|
||||||
event.stop();
|
|
||||||
},
|
|
||||||
onScrollRight: function(event) {
|
|
||||||
if (this.offset > this.minOffset) {
|
|
||||||
var offset = this.offset - 20;
|
|
||||||
if (offset < this.minOffset) {
|
|
||||||
offset = this.minOffset;
|
|
||||||
}
|
|
||||||
this.list.setStyle("margin-left: " + offset + "px;");
|
|
||||||
// log("offset: " + offset);
|
|
||||||
this.offset = offset;
|
|
||||||
}
|
|
||||||
event.stop();
|
|
||||||
},
|
|
||||||
|
|
||||||
attachToTabsContainer: function STC_attachToTabsContainer(container) {
|
|
||||||
this.container = container;
|
|
||||||
container.controller = this;
|
|
||||||
this.onTabMouseDownBound = this.onTabMouseDown.bindAsEventListener(this);
|
|
||||||
this.onTabClickBound = this.onTabClick.bindAsEventListener(this);
|
|
||||||
|
|
||||||
var list = container.childNodesWithTag("ul");
|
|
||||||
if (list.length > 0) {
|
|
||||||
this.list = $(list[0]);
|
|
||||||
var nodes = this.list.childNodesWithTag("li");
|
|
||||||
if (nodes.length > 0) {
|
|
||||||
this.firstTab = $(nodes[0]);
|
|
||||||
for (var i = 0; i < nodes.length; i++) {
|
|
||||||
var currentNode = $(nodes[i]);
|
|
||||||
currentNode.observe("mousedown", this.onTabMouseDownBound, false);
|
|
||||||
currentNode.observe("click", this.onTabClickBound, false);
|
|
||||||
if (currentNode.hasClassName("active"))
|
|
||||||
this.activeTab = currentNode;
|
|
||||||
//$(currentNode.getAttribute("target")).hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.firstTab.addClassName("first");
|
|
||||||
if (this.activeTab == null) {
|
|
||||||
this.activeTab = this.firstTab;
|
|
||||||
this.activeTab.addClassName("active");
|
|
||||||
}
|
|
||||||
var last = nodes.length - 1;
|
|
||||||
this.lastTab = $(nodes[last]);
|
|
||||||
|
|
||||||
var target = $(this.activeTab.getAttribute("target"));
|
|
||||||
target.addClassName("active");
|
|
||||||
}
|
|
||||||
this.onWindowResizeBound = this.onWindowResize.bindAsEventListener(this);
|
|
||||||
Event.observe(window, "resize", this.onWindowResizeBound, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.createScrollButtons();
|
|
||||||
this.recomputeMinOffset();
|
|
||||||
},
|
|
||||||
|
|
||||||
onWindowResize: function STC_onWindowResize(event) {
|
|
||||||
this.recomputeMinOffset();
|
|
||||||
},
|
|
||||||
|
|
||||||
recomputeMinOffset: function() {
|
|
||||||
var tabsWidth = (this.lastTab.offsetLeft + this.lastTab.clientWidth
|
|
||||||
- this.firstTab.offsetLeft
|
|
||||||
+ 4);
|
|
||||||
this.minOffset = (this.container.clientWidth - tabsWidth - 40);
|
|
||||||
if (this.minOffset < -40) {
|
|
||||||
this.scrollToolbar.show();
|
|
||||||
} else {
|
|
||||||
this.scrollToolbar.hide();
|
|
||||||
if (this.offset < 0) {
|
|
||||||
this.list.setStyle("margin-left: 0px;");
|
|
||||||
this.offset = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onTabMouseDown: function STC_onTabMouseDown(event) {
|
|
||||||
event.stop();
|
|
||||||
},
|
|
||||||
|
|
||||||
onTabClick: function STC_onTabClick(event) {
|
|
||||||
var clickedTab = getTarget(event);
|
|
||||||
if (clickedTab.nodeType == 1) {
|
|
||||||
while (clickedTab.tagName.toLowerCase() != "li") {
|
|
||||||
clickedTab = $(clickedTab.parentNode);
|
|
||||||
}
|
|
||||||
var content = $(clickedTab.getAttribute("target"));
|
|
||||||
var oldContent = $(this.activeTab.getAttribute("target"));
|
|
||||||
oldContent.removeClassName("active");
|
|
||||||
this.activeTab.removeClassName("active"); // previous LI
|
|
||||||
this.activeTab = $(clickedTab);
|
|
||||||
this.activeTab.addClassName("active"); // current LI
|
|
||||||
content.addClassName("active");
|
|
||||||
this.activeTab.fire("tabs:click", content.id);
|
|
||||||
|
|
||||||
content.select('.tabsContainer').each(function(c) {
|
|
||||||
// When the tab contains an inner tabs container,
|
|
||||||
// show or hide the tabs navigation arrows of this
|
|
||||||
// inner container
|
|
||||||
c.controller.recomputeMinOffset();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Prototype alternative
|
|
||||||
|
|
||||||
//oldContent.removeClassName("active");
|
|
||||||
//container.activeTab.removeClassName("active"); // previous LI
|
|
||||||
//container.activeTab = node;
|
|
||||||
//container.activeTab.addClassName("active"); // current LI
|
|
||||||
|
|
||||||
//container.activeTab.hide();
|
|
||||||
//oldContent.hide();
|
|
||||||
//content.show();
|
|
||||||
|
|
||||||
//container.activeTab = node;
|
|
||||||
//container.activeTab.show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,134 +0,0 @@
|
||||||
.SOGoTimePickerMenu
|
|
||||||
{ position: absolute;
|
|
||||||
z-index: 1000;
|
|
||||||
background-color: #fff;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
|
||||||
-webkit-border-radius: 5px;
|
|
||||||
-moz-border-radius: 5px;
|
|
||||||
border-radius: 5px;
|
|
||||||
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
|
|
||||||
-moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
|
|
||||||
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
|
|
||||||
-webkit-background-clip: padding-box;
|
|
||||||
-moz-background-clip: padding;
|
|
||||||
background-clip: padding-box;
|
|
||||||
*border-right-width: 2px;
|
|
||||||
*border-bottom-width: 2px;
|
|
||||||
color: #000;
|
|
||||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
||||||
font-size: 11px;
|
|
||||||
line-height: 18px;
|
|
||||||
text-align: center; }
|
|
||||||
|
|
||||||
.SOGoTimePickerMenu > DIV
|
|
||||||
{ padding: 5px; }
|
|
||||||
|
|
||||||
.SOGoTimePickerMenu.bellow > DIV:before {
|
|
||||||
content: '';
|
|
||||||
display: inline-block;
|
|
||||||
border-left: 7px solid transparent;
|
|
||||||
border-right: 7px solid transparent;
|
|
||||||
border-bottom: 7px solid #ccc;
|
|
||||||
border-bottom-color: rgba(0, 0, 0, 0.2);
|
|
||||||
position: absolute;
|
|
||||||
top: -7px;
|
|
||||||
left: 6px;
|
|
||||||
left: 35px;
|
|
||||||
}
|
|
||||||
.SOGoTimePickerMenu.bellow > DIV:after {
|
|
||||||
content: '';
|
|
||||||
display: inline-block;
|
|
||||||
border-left: 6px solid transparent;
|
|
||||||
border-right: 6px solid transparent;
|
|
||||||
border-bottom: 6px solid #ffffff;
|
|
||||||
position: absolute;
|
|
||||||
top: -6px;
|
|
||||||
left: 7px;
|
|
||||||
left: 36px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SOGoTimePickerMenu.above > DIV:before {
|
|
||||||
content: '';
|
|
||||||
display: inline-block;
|
|
||||||
border-left: 7px solid transparent;
|
|
||||||
border-right: 7px solid transparent;
|
|
||||||
border-top: 7px solid #ccc;
|
|
||||||
border-top-color: rgba(0, 0, 0, 0.2);
|
|
||||||
position: absolute;
|
|
||||||
bottom: -7px;
|
|
||||||
right: 35px;
|
|
||||||
}
|
|
||||||
.SOGoTimePickerMenu.above > DIV:after {
|
|
||||||
content: '';
|
|
||||||
display: inline-block;
|
|
||||||
border-left: 6px solid transparent;
|
|
||||||
border-right: 6px solid transparent;
|
|
||||||
border-top: 6px solid #ffffff;
|
|
||||||
position: absolute;
|
|
||||||
bottom: -6px;
|
|
||||||
right: 36px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SOGoTimePickerMenu .hours,
|
|
||||||
.SOGoTimePickerMenu .minutes,
|
|
||||||
.SOGoTimePickerMenu .button
|
|
||||||
{ clear: both; /* Opera fix */ }
|
|
||||||
|
|
||||||
.SOGoTimePickerMenu SPAN DIV
|
|
||||||
{ padding: 2px; }
|
|
||||||
|
|
||||||
.SOGoTimePickerMenu DIV.hours SPAN
|
|
||||||
{ float: left;
|
|
||||||
width: 25px; }
|
|
||||||
|
|
||||||
.SOGoTimePickerMenu DIV.hours SPAN DIV
|
|
||||||
{ -webkit-border-radius: 4px;
|
|
||||||
-moz-border-radius: 4px;
|
|
||||||
border-radius: 4px; }
|
|
||||||
|
|
||||||
.SOGoTimePickerMenu DIV.min5 SPAN
|
|
||||||
{ float: left;
|
|
||||||
width: 50px; }
|
|
||||||
|
|
||||||
.SOGoTimePickerMenu DIV.min1 SPAN
|
|
||||||
{ float: left;
|
|
||||||
width: 60px; }
|
|
||||||
|
|
||||||
.SOGoTimePickerMenu DIV.minutes SPAN DIV
|
|
||||||
{ -webkit-border-radius: 4px;
|
|
||||||
-moz-border-radius: 4px;
|
|
||||||
border-radius: 4px; }
|
|
||||||
|
|
||||||
.SOGoTimePickerMenu DIV.hours SPAN DIV:hover,
|
|
||||||
.SOGoTimePickerMenu DIV.minutes SPAN DIV:hover
|
|
||||||
{ background-color: #eee;
|
|
||||||
color: #333;
|
|
||||||
cursor: pointer; }
|
|
||||||
|
|
||||||
.SOGoTimePickerMenu DIV.hours SPAN DIV.selected,
|
|
||||||
.SOGoTimePickerMenu DIV.minutes SPAN DIV.selected,
|
|
||||||
.SOGoTimePickerMenu DIV.hours SPAN DIV.selected:hover,
|
|
||||||
.SOGoTimePickerMenu DIV.minutes SPAN DIV.selected:hover
|
|
||||||
{ background-color: #006dcc;
|
|
||||||
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
|
|
||||||
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
|
|
||||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
|
|
||||||
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
|
|
||||||
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
|
|
||||||
background-image: linear-gradient(top, #0088cc, #0044cc);
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
|
|
||||||
border-color: #0044cc #0044cc #002a80;
|
|
||||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
|
||||||
filter: progid:dximagetransform.microsoft.gradient(enabled=false);
|
|
||||||
color: #fff;
|
|
||||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); }
|
|
||||||
|
|
||||||
.SOGoTimePickerMenu HR
|
|
||||||
{ clear: both;
|
|
||||||
height: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
color: #fff;
|
|
||||||
border: 0px; }
|
|
|
@ -1,241 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Time picker widget interface to be added to an INPUT (this!)
|
|
||||||
*
|
|
||||||
* Available events:
|
|
||||||
* time:change -- fired once the value of the input has changed
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
var SOGoTimePickerInterface = {
|
|
||||||
|
|
||||||
div: null,
|
|
||||||
extendedButton: null,
|
|
||||||
|
|
||||||
pos: 'bellow',
|
|
||||||
|
|
||||||
minutes: '00',
|
|
||||||
hours: '00',
|
|
||||||
extended: false,
|
|
||||||
|
|
||||||
mouseInside: false,
|
|
||||||
disposeHandler: null,
|
|
||||||
|
|
||||||
bind: function () {
|
|
||||||
// Build widget
|
|
||||||
this.div = new Element("div", {'class': 'SOGoTimePickerMenu ' + this.pos});
|
|
||||||
this.div.hide();
|
|
||||||
document.body.appendChild(this.div);
|
|
||||||
var inner = new Element("div");
|
|
||||||
this.div.appendChild(inner);
|
|
||||||
|
|
||||||
var hours = new Element("div", {'class': 'hours'});
|
|
||||||
inner.appendChild(hours);
|
|
||||||
for (var i = 0; i < 24; i++) {
|
|
||||||
var v = (i < 10)? '0' + i : i;
|
|
||||||
var content = new Element("div", {'class': 'SOGoTimePickerHour_'+v}).update(v);
|
|
||||||
content.on("click", this.onHourClick.bindAsEventListener(this));
|
|
||||||
var span = new Element("span", {'class': 'cell'});
|
|
||||||
span.appendChild(content);
|
|
||||||
hours.appendChild(span);
|
|
||||||
if (i == 11) {
|
|
||||||
hours = new Element("div", {'class': 'hours'});
|
|
||||||
inner.appendChild(hours);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var minutes = new Element("div", {'class': 'minutes min5'});
|
|
||||||
inner.appendChild(minutes);
|
|
||||||
for (var i = 0; i < 60; i += 5) {
|
|
||||||
var v = (i < 10)? '0' + i : i;
|
|
||||||
var content = new Element("div", {'class': 'SOGoTimePickerMinute_'+v}).update(":"+v);
|
|
||||||
content.on("click", this.onMinuteClick.bindAsEventListener(this));
|
|
||||||
var span = new Element("span", {'class': 'cell'});
|
|
||||||
span.appendChild(content);
|
|
||||||
minutes.appendChild(span);
|
|
||||||
if (i == 25) {
|
|
||||||
minutes = new Element("div", {'class': 'minutes min5'});
|
|
||||||
inner.appendChild(minutes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var minutes = new Element("div", {'class': 'minutes min1'});
|
|
||||||
minutes.hide();
|
|
||||||
inner.appendChild(minutes);
|
|
||||||
for (var i = 0; i < 60;) {
|
|
||||||
var v = (i < 10)? '0' + i : i;
|
|
||||||
var content = new Element("div", {'class': 'SOGoTimePickerMinute_'+v}).update(":"+v);
|
|
||||||
content.on("click", this.onMinuteClick.bindAsEventListener(this));
|
|
||||||
var span = new Element("span", {'class': 'cell'});
|
|
||||||
span.appendChild(content);
|
|
||||||
minutes.appendChild(span);
|
|
||||||
i++;
|
|
||||||
if (i % 5 == 0) {
|
|
||||||
minutes = new Element("div", {'class': 'minutes min1'});
|
|
||||||
minutes.hide();
|
|
||||||
inner.appendChild(minutes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var a = new Element("a", {'class': 'button'});
|
|
||||||
a.on("click", this.toggleExtendedView.bindAsEventListener(this));
|
|
||||||
this.extendedButton = new Element("span").update('>>');
|
|
||||||
a.appendChild(this.extendedButton);
|
|
||||||
inner.appendChild(a);
|
|
||||||
|
|
||||||
inner.appendChild(new Element("hr"));
|
|
||||||
|
|
||||||
// Compute position
|
|
||||||
this.position();
|
|
||||||
|
|
||||||
// Register observers
|
|
||||||
this.on("click", this.toggleVisibility.bindAsEventListener(this));
|
|
||||||
this.on("change", this.onChange.bindAsEventListener(this));
|
|
||||||
this.on("keydown", this.onKeydown.bindAsEventListener(this));
|
|
||||||
this.div.on("mouseenter", this.onEnter.bindAsEventListener(this));
|
|
||||||
this.div.on("mouseleave", this.onLeave.bindAsEventListener(this));
|
|
||||||
this.disposeHandler = $(document.body).on("click", this.onDispose.bindAsEventListener(this));
|
|
||||||
this.disposeHandler.stop();
|
|
||||||
|
|
||||||
// Apply current input value if defined
|
|
||||||
this.onChange();
|
|
||||||
},
|
|
||||||
|
|
||||||
setPosition: function (newPos) {
|
|
||||||
if (newPos == 'bellow' || newPos == 'above') {
|
|
||||||
this.div.removeClassName(this.pos);
|
|
||||||
this.div.addClassName(newPos);
|
|
||||||
this.pos = newPos;
|
|
||||||
this.position();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
position: function () {
|
|
||||||
var inputPosition = this.cumulativeOffset();
|
|
||||||
var inputDimensions = this.getDimensions();
|
|
||||||
var divWidth = this.div.getWidth();
|
|
||||||
var windowWidth = window.width();
|
|
||||||
var left = inputPosition[0];
|
|
||||||
var arrow = -1000 + inputDimensions['width'] - 10;
|
|
||||||
if (left + divWidth > windowWidth) {
|
|
||||||
left = windowWidth - divWidth - 4;
|
|
||||||
arrow += (inputPosition[0] - left);
|
|
||||||
}
|
|
||||||
var top = inputPosition[1];
|
|
||||||
if (this.pos == 'bellow')
|
|
||||||
top += 22;
|
|
||||||
else
|
|
||||||
top -= this.div.getHeight();
|
|
||||||
this.div.setStyle({ top: top+"px",
|
|
||||||
left: left+"px",
|
|
||||||
backgroundPosition: arrow+'px top'});
|
|
||||||
},
|
|
||||||
|
|
||||||
onHourClick: function (event) {
|
|
||||||
this.div.down('.SOGoTimePickerHour_' + this.hours).removeClassName("selected");
|
|
||||||
this.hours = Event.findElement(event).className.substring(19);
|
|
||||||
this.div.down('.SOGoTimePickerHour_' + this.hours).addClassName("selected");
|
|
||||||
this._updateValue();
|
|
||||||
},
|
|
||||||
|
|
||||||
onMinuteClick: function (event) {
|
|
||||||
this.div.select('.SOGoTimePickerMinute_' + this.minutes).each(function(e) { e.removeClassName("selected") });
|
|
||||||
this.minutes = Event.findElement(event).className.substring(21);
|
|
||||||
this.div.select('.SOGoTimePickerMinute_' + this.minutes).each(function(e) { e.addClassName("selected") });
|
|
||||||
this._updateValue();
|
|
||||||
this.div.hide();
|
|
||||||
},
|
|
||||||
|
|
||||||
toggleExtendedView: function (event) {
|
|
||||||
this.extended = !this.extended;
|
|
||||||
if (this.extended) {
|
|
||||||
this.extendedButton.update('<<');
|
|
||||||
this.div.select("DIV.min5").invoke('hide');
|
|
||||||
this.div.select("DIV.min1").invoke('show');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.extendedButton.update('>>');
|
|
||||||
this.div.select("DIV.min1").invoke('hide');
|
|
||||||
this.div.select("DIV.min5").invoke('show');
|
|
||||||
}
|
|
||||||
if (this.pos == 'above')
|
|
||||||
this.position();
|
|
||||||
},
|
|
||||||
|
|
||||||
toggleVisibility: function (event) {
|
|
||||||
if (this.div.visible())
|
|
||||||
this.div.hide();
|
|
||||||
else {
|
|
||||||
$$('DIV.SOGoTimePickerMenu').invoke('hide');
|
|
||||||
this.div.show();
|
|
||||||
this.disposeHandler.start();
|
|
||||||
}
|
|
||||||
Event.stop(event);
|
|
||||||
},
|
|
||||||
|
|
||||||
onChange: function (event) {
|
|
||||||
this.div.down('.SOGoTimePickerHour_' + this.hours).removeClassName("selected");
|
|
||||||
this.div.select('.SOGoTimePickerMinute_' + this.minutes).each(function(e) { e.removeClassName("selected") });
|
|
||||||
|
|
||||||
var matches = this.value.match(/([0-9]{1,2}):?([0-9]{2})/);
|
|
||||||
if (matches) {
|
|
||||||
this.hours = matches[1];
|
|
||||||
this.minutes = matches[2] || '0';
|
|
||||||
if (parseInt(this.hours, 10) > 23) this.hours = 23;
|
|
||||||
if (parseInt(this.minutes, 10) > 59) this.minutes = 59;
|
|
||||||
if (this.minutes % 5 == 0) {
|
|
||||||
if (this.extended)
|
|
||||||
this.toggleExtendedView();
|
|
||||||
}
|
|
||||||
else if (!this.extended)
|
|
||||||
this.toggleExtendedView();
|
|
||||||
|
|
||||||
if (this.hours.length < 2) this.hours = '0' + this.hours;
|
|
||||||
if (this.minutes.length < 2) this.minutes = '0' + this.minutes;
|
|
||||||
this.div.down('.SOGoTimePickerHour_' + this.hours).addClassName("selected");
|
|
||||||
this.div.select('.SOGoTimePickerMinute_' + this.minutes).each(function(e) { e.addClassName("selected") });
|
|
||||||
}
|
|
||||||
|
|
||||||
this._updateValue(true);
|
|
||||||
},
|
|
||||||
|
|
||||||
onKeydown: function (event) {
|
|
||||||
this.div.hide();
|
|
||||||
this.disposeHandler.stop();
|
|
||||||
if (event.metaKey == 1 || event.ctrlKey == 1 ||
|
|
||||||
event.keyCode == Event.KEY_TAB ||
|
|
||||||
event.keyCode == Event.KEY_BACKSPACE)
|
|
||||||
return true;
|
|
||||||
if (event.keyCode > 57 && // ignore non-numeric characters
|
|
||||||
(event.keyCode < 96 || event.keyCode > 105) && // but allow entries from keypad
|
|
||||||
event.keyCode != 186 && event.keyCode != 59 ||
|
|
||||||
(event.keyCode == 186 || event.keyCode == 59) && this.value.indexOf(":") >= 0)
|
|
||||||
Event.stop(event);
|
|
||||||
},
|
|
||||||
|
|
||||||
onEnter: function (event) {
|
|
||||||
this.mouseInside = true;
|
|
||||||
this.disposeHandler.stop();
|
|
||||||
},
|
|
||||||
|
|
||||||
onLeave: function (event) {
|
|
||||||
this.mouseInside = false;
|
|
||||||
this.disposeHandler.start();
|
|
||||||
},
|
|
||||||
|
|
||||||
onDispose: function (event) {
|
|
||||||
if (!this.mouseInside) {
|
|
||||||
this.div.hide();
|
|
||||||
this.disposeHandler.stop();
|
|
||||||
Event.stop(event);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateValue: function (force) {
|
|
||||||
var value = this.hours + ':' + this.minutes;
|
|
||||||
if (force || value != this.value) {
|
|
||||||
this.value = value;
|
|
||||||
this.fire("time:change");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
Before Width: | Height: | Size: 820 B |
|
@ -1,76 +0,0 @@
|
||||||
DIV.acls
|
|
||||||
{ position: absolute;
|
|
||||||
top: 0px;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
bottom: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
border: 0px;
|
|
||||||
margin: 0px; }
|
|
||||||
|
|
||||||
DIV.acls LABEL
|
|
||||||
{ white-space: nowrap;
|
|
||||||
width: 100%; }
|
|
||||||
|
|
||||||
#userRoles
|
|
||||||
{ position: absolute;
|
|
||||||
top: 5px;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
bottom: 0px; }
|
|
||||||
|
|
||||||
#userSelectorButtons
|
|
||||||
{ margin-left: 5px;
|
|
||||||
padding-bottom: 2px; }
|
|
||||||
|
|
||||||
UL#userList
|
|
||||||
{ position: absolute;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
top: 40px;
|
|
||||||
bottom: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: auto;
|
|
||||||
border-bottom: 1px solid #fff;
|
|
||||||
border-right: 1px solid #fff;
|
|
||||||
border-top: 1px solid #909090;
|
|
||||||
border-left: 1px solid #909090;
|
|
||||||
background-color: #CCDDEC;
|
|
||||||
list-style-type: none;
|
|
||||||
list-style-image: none; }
|
|
||||||
|
|
||||||
UL#userList LI
|
|
||||||
{ clear: both;
|
|
||||||
cursor: pointer;
|
|
||||||
height: 20px;
|
|
||||||
text-align: right;
|
|
||||||
margin-left: 0px;
|
|
||||||
padding-left: 24px;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: 4px center; }
|
|
||||||
|
|
||||||
UL#userList LI.normal-user,
|
|
||||||
UL#userList LI.normal-person
|
|
||||||
{ background-image: url("abcard.png"); }
|
|
||||||
|
|
||||||
UL#userList LI.normal-group
|
|
||||||
{ background-image: url("ablist.png"); }
|
|
||||||
|
|
||||||
UL#userList LI.any-user
|
|
||||||
{ background-image: url("abcard-anyone.png");
|
|
||||||
border-top: 1px dotted #555; }
|
|
||||||
|
|
||||||
UL#userList LI.anonymous-user
|
|
||||||
{ background-image: url("abcard-anonymous.png"); }
|
|
||||||
|
|
||||||
DIV#userSelectorButtons A.smallToolbarButton
|
|
||||||
{ float: left; }
|
|
||||||
|
|
||||||
SPAN.userFullName
|
|
||||||
{ float: left;
|
|
||||||
margin-top: 2px; }
|
|
||||||
|
|
||||||
LABEL.subscriptionArea
|
|
||||||
{ padding-right: 5px; }
|
|
|
@ -1,246 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
var contactSelectorAction = 'acls-contacts';
|
|
||||||
var defaultUserID = '';
|
|
||||||
var AclEditor = {
|
|
||||||
userRightsHeight: null,
|
|
||||||
userRightsWidth: null
|
|
||||||
};
|
|
||||||
|
|
||||||
var usersToSubscribe = [];
|
|
||||||
|
|
||||||
function addUser(userName, userID, type) {
|
|
||||||
var result = false;
|
|
||||||
if (!$(userID)) {
|
|
||||||
var ul = $("userList");
|
|
||||||
var lis = ul.childNodesWithTag("li");
|
|
||||||
var newNode = nodeForUser(userName, userID, canSubscribeUsers);
|
|
||||||
newNode.addClassName("normal-" + type);
|
|
||||||
|
|
||||||
var count = lis.length - 1;
|
|
||||||
var inserted = false;
|
|
||||||
while (count > -1 && !inserted) {
|
|
||||||
if ($(lis[count]).hasClassName("normal-user")) {
|
|
||||||
if ((count+1) < lis.length)
|
|
||||||
ul.insertBefore(newNode, lis[count+1]);
|
|
||||||
else
|
|
||||||
ul.appendChild(newNode);
|
|
||||||
inserted = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
count--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!inserted) {
|
|
||||||
if (lis.length > 0)
|
|
||||||
ul.insertBefore(newNode, lis[0]);
|
|
||||||
else
|
|
||||||
ul.appendChild(newNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
var url = window.location.href;
|
|
||||||
var elements = url.split("/");
|
|
||||||
elements[elements.length-1] = ("addUserInAcls?uid="
|
|
||||||
+ encodeURIComponent(userID.unescapeHTML()));
|
|
||||||
triggerAjaxRequest(elements.join("/"), addUserCallback, newNode);
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function addUserCallback(http) {
|
|
||||||
if (http.readyState == 4) {
|
|
||||||
if (!isHttpStatus204(http.status)) {
|
|
||||||
var node = http.callbackData;
|
|
||||||
node.parentNode.removeChild(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setEventsOnUserNode(node) {
|
|
||||||
var n = $(node);
|
|
||||||
n.observe("mousedown", listRowMouseDownHandler);
|
|
||||||
n.observe("selectstart", listRowMouseDownHandler);
|
|
||||||
n.observe("dblclick", onOpenUserRights);
|
|
||||||
n.observe("click", onRowClick);
|
|
||||||
|
|
||||||
var cbParents = n.childNodesWithTag("label");
|
|
||||||
if (cbParents && cbParents.length) {
|
|
||||||
var cbParent = $(cbParents[0]);
|
|
||||||
var checkbox = cbParent.childNodesWithTag("input")[0];
|
|
||||||
$(checkbox).observe("change", onSubscriptionChange);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onSubscriptionChange(event) {
|
|
||||||
var li = this.parentNode.parentNode;
|
|
||||||
var username = li.getAttribute("id");
|
|
||||||
var idx = usersToSubscribe.indexOf(username);
|
|
||||||
if (this.checked) {
|
|
||||||
if (idx < 0)
|
|
||||||
usersToSubscribe.push(username);
|
|
||||||
} else {
|
|
||||||
if (idx > -1)
|
|
||||||
usersToSubscribe.splice(idx, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function nodeForUser(userName, userId, canSubscribe) {
|
|
||||||
var node = createElement("li");
|
|
||||||
node.id = userId;
|
|
||||||
|
|
||||||
var span = createElement("span");
|
|
||||||
span.addClassName("userFullName");
|
|
||||||
span.appendChild(document.createTextNode(" " + userName.unescapeHTML()));
|
|
||||||
node.appendChild(span);
|
|
||||||
|
|
||||||
if (canSubscribe) {
|
|
||||||
var label = createElement("label");
|
|
||||||
label.addClassName("subscriptionArea");
|
|
||||||
var cb = createElement("input");
|
|
||||||
cb.type = "checkbox";
|
|
||||||
label.appendChild(cb);
|
|
||||||
label.appendChild(document.createTextNode(_("Subscribe User")));
|
|
||||||
node.appendChild(label);
|
|
||||||
}
|
|
||||||
|
|
||||||
setEventsOnUserNode(node);
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onUserAdd(event) {
|
|
||||||
openUserFolderSelector(null, "user");
|
|
||||||
|
|
||||||
preventDefault(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeUserCallback(http) {
|
|
||||||
var node = http.callbackData;
|
|
||||||
|
|
||||||
if (http.readyState == 4
|
|
||||||
&& isHttpStatus204(http.status))
|
|
||||||
node.parentNode.removeChild(node);
|
|
||||||
else
|
|
||||||
log("error deleting user: " + node.getAttribute("id"));
|
|
||||||
}
|
|
||||||
|
|
||||||
function onUserRemove(event) {
|
|
||||||
var userList = $("userList");
|
|
||||||
var nodes = userList.getSelectedRows();
|
|
||||||
|
|
||||||
var url = window.location.href;
|
|
||||||
var elements = url.split("/");
|
|
||||||
elements[elements.length-1] = "removeUserFromAcls?uid=";
|
|
||||||
var baseURL = elements.join("/");
|
|
||||||
|
|
||||||
for (var i = 0; i < nodes.length; i++) {
|
|
||||||
var userId = nodes[i].id.unescapeHTML();
|
|
||||||
if (userId != defaultUserID && userId != "anonymous") {
|
|
||||||
triggerAjaxRequest(baseURL + encodeURIComponent(userId), removeUserCallback,
|
|
||||||
nodes[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
preventDefault(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
function subscribeToFolder(refreshCallback, refreshCallbackData) {
|
|
||||||
var result = true;
|
|
||||||
if (UserLogin != refreshCallbackData["folder"]) {
|
|
||||||
result = addUser(refreshCallbackData["folderName"],
|
|
||||||
refreshCallbackData["folder"],
|
|
||||||
refreshCallbackData["type"]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
refreshCallbackData["window"].alert(_("You cannot subscribe to a folder that you own!"));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function openRightsForUserID(userID) {
|
|
||||||
var url = window.location.href;
|
|
||||||
var elements = url.split("/");
|
|
||||||
elements[elements.length-1] = "userRights?uid=" + encodeURIComponent(userID);
|
|
||||||
|
|
||||||
var height = AclEditor.userRightsHeight;
|
|
||||||
if (userID == "anonymous") {
|
|
||||||
height -= 42;
|
|
||||||
if (CurrentModule() == "Contacts") {
|
|
||||||
height -= 21;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
window.open(elements.join("/"), "",
|
|
||||||
"width=" + AclEditor.userRightsWidth
|
|
||||||
+ ",height=" + height
|
|
||||||
+ ",resizable=0,scrollbars=0,toolbar=0,"
|
|
||||||
+ "location=0,directories=0,status=0,menubar=0,copyhistory=0");
|
|
||||||
}
|
|
||||||
|
|
||||||
function openRightsForUser(button) {
|
|
||||||
var nodes = $("userList").getSelectedRows();
|
|
||||||
if (nodes.length > 0)
|
|
||||||
openRightsForUserID(nodes[0].id.unescapeHTML());
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onOpenUserRights(event) {
|
|
||||||
openRightsForUser();
|
|
||||||
preventDefault(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onAclLoadHandler() {
|
|
||||||
var ul = $("userList");
|
|
||||||
var lis = ul.childNodesWithTag("li");
|
|
||||||
for (var i = 0; i < lis.length; i++)
|
|
||||||
setEventsOnUserNode(lis[i]);
|
|
||||||
|
|
||||||
var input = $("defaultUserID");
|
|
||||||
if (input) {
|
|
||||||
defaultUserID = $("defaultUserID").value;
|
|
||||||
var userNode = nodeForUser(_("Any Authenticated User"),
|
|
||||||
defaultUserID.escapeHTML());
|
|
||||||
userNode.addClassName("any-user");
|
|
||||||
userNode.setAttribute("title",
|
|
||||||
_("Any user not listed above"));
|
|
||||||
ul.appendChild(userNode);
|
|
||||||
}
|
|
||||||
if (isPublicAccessEnabled && CurrentModule() != "Mail") {
|
|
||||||
userNode = nodeForUser(_("Public Access"), "anonymous");
|
|
||||||
userNode.addClassName("anonymous-user");
|
|
||||||
userNode.setAttribute("title",
|
|
||||||
_("Anybody accessing this resource from the public area"));
|
|
||||||
ul.appendChild(userNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
var buttonArea = $("userSelectorButtons");
|
|
||||||
if (buttonArea) {
|
|
||||||
var buttons = buttonArea.childNodesWithTag("a");
|
|
||||||
$("aclAddUser").stopObserving ("click");
|
|
||||||
$("aclDeleteUser").stopObserving ("click");
|
|
||||||
$("aclAddUser").observe("mousedown", onUserAdd);
|
|
||||||
$("aclDeleteUser").observe("mousedown", onUserRemove);
|
|
||||||
}
|
|
||||||
|
|
||||||
AclEditor['userRightsHeight'] = window.opener.getUsersRightsWindowHeight();
|
|
||||||
AclEditor['userRightsWidth'] = window.opener.getUsersRightsWindowWidth();
|
|
||||||
|
|
||||||
Event.observe(window, "unload", onAclCloseHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onAclCloseHandler(event) {
|
|
||||||
if (usersToSubscribe.length) {
|
|
||||||
var url = (URLForFolderID($("folderID").value)
|
|
||||||
+ "/subscribeUsers?uids=" + usersToSubscribe.join(","));
|
|
||||||
new Ajax.Request(url, {
|
|
||||||
asynchronous: false,
|
|
||||||
method: 'get',
|
|
||||||
onFailure: function(transport) {
|
|
||||||
log("Can't subscribe users: " + transport.status);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
document.observe("dom:loaded", onAclLoadHandler);
|
|
|
@ -1,168 +0,0 @@
|
||||||
DIV.appointmentLabel
|
|
||||||
{ display: block;
|
|
||||||
position: relative;
|
|
||||||
line-height: 1.8em;
|
|
||||||
text-align: right;
|
|
||||||
width: 3em; }
|
|
||||||
|
|
||||||
DIV#eventView
|
|
||||||
{ overflow: hidden;
|
|
||||||
position: absolute;
|
|
||||||
top: 0; bottom: 0; left: 0; right: 0; }
|
|
||||||
|
|
||||||
DIV#eventView > DIV
|
|
||||||
{ padding: 1em; }
|
|
||||||
|
|
||||||
DIV.appointmentRightLabel
|
|
||||||
{ display: inline;
|
|
||||||
vertical-align: middle; }
|
|
||||||
|
|
||||||
UL.contactList
|
|
||||||
{ display: block;
|
|
||||||
cursor: default;
|
|
||||||
list-style-type: none;
|
|
||||||
list-style-image: none;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
background: #fff;
|
|
||||||
border: 1px solid #000;
|
|
||||||
width: 15em;
|
|
||||||
height: 5em;
|
|
||||||
overflow: auto; }
|
|
||||||
|
|
||||||
UL.contactList LI IMG
|
|
||||||
{ vertical-align: middle; }
|
|
||||||
|
|
||||||
UL.contactList LI
|
|
||||||
{ width: 100%;
|
|
||||||
white-space: nowrap;
|
|
||||||
vertical-align: middle; }
|
|
||||||
|
|
||||||
UL.contactList LI._selected
|
|
||||||
{ background: #4b6983;
|
|
||||||
color: #fff; }
|
|
||||||
|
|
||||||
DIV.contactSelector
|
|
||||||
{ margin: 0px; }
|
|
||||||
|
|
||||||
LABEL, SPAN.checkBoxList
|
|
||||||
{ display: block;
|
|
||||||
position: relative;
|
|
||||||
line-height: 1.5em;
|
|
||||||
height: 1.5em;
|
|
||||||
margin-left: 0px;
|
|
||||||
margin-bottom: .5em;
|
|
||||||
width: 100%; }
|
|
||||||
|
|
||||||
SELECT
|
|
||||||
{ margin-left: 1px; }
|
|
||||||
|
|
||||||
n0LABEL#commentArea
|
|
||||||
{ height: 17em; }
|
|
||||||
|
|
||||||
LABEL#commentArea textarea
|
|
||||||
{ height: 15.5em; }
|
|
||||||
|
|
||||||
SPAN.checkBoxList#participantsCB
|
|
||||||
{ height: 7em; }
|
|
||||||
|
|
||||||
SPAN.checkBoxList#categoriesCB
|
|
||||||
{ height: 3em; }
|
|
||||||
|
|
||||||
DIV#participants UL.contactList
|
|
||||||
{ height: 4.5em; }
|
|
||||||
|
|
||||||
SPAN.checkBoxList SPAN.content LABEL
|
|
||||||
{ display: inline; }
|
|
||||||
|
|
||||||
SPAN.content A
|
|
||||||
{ line-height: 2em; }
|
|
||||||
|
|
||||||
A#detailsButton
|
|
||||||
{ position: absolute;
|
|
||||||
right: 1em;
|
|
||||||
z-index: 1; }
|
|
||||||
|
|
||||||
SPAN.contactSelectorButtons
|
|
||||||
{ vertical-align: top;
|
|
||||||
line-height: 2em; }
|
|
||||||
|
|
||||||
SPAN#cycleSelectionFirstLevel,
|
|
||||||
SPAN#cycleSelectionSecondLevel
|
|
||||||
{ visibility: hidden;
|
|
||||||
margin-left: 1em; }
|
|
||||||
|
|
||||||
SPAN#cycleSelectionSecondLevel SPAN.timeDateControl
|
|
||||||
{ position: static;
|
|
||||||
margin: 0px; }
|
|
||||||
|
|
||||||
SPAN#categoriesCB INPUT
|
|
||||||
{ border: 2px solid #000;
|
|
||||||
vertical-align: middle;
|
|
||||||
-moz-border-top-colors: #000 #fff;
|
|
||||||
-moz-border-left-colors: #000 #fff;
|
|
||||||
-moz-border-bottom-colors: #000 #fff;
|
|
||||||
-moz-border-right-colors: #000 #fff; }
|
|
||||||
|
|
||||||
SPAN#categoriesCB LABEL
|
|
||||||
{ margin-left: 0px;
|
|
||||||
margin-right: 1em; }
|
|
||||||
|
|
||||||
SPAN.content > INPUT.textField
|
|
||||||
{ n0width: 380px;
|
|
||||||
width: 97%; }
|
|
||||||
|
|
||||||
LABEL#urlArea INPUT
|
|
||||||
{ position: static; }
|
|
||||||
|
|
||||||
DIV#attendeesMenu LI
|
|
||||||
{ padding-left: 10px;
|
|
||||||
width: auto; }
|
|
||||||
|
|
||||||
DIV#attendeesMenu .attendeeUser
|
|
||||||
{ font-weight: bold; }
|
|
||||||
|
|
||||||
DIV#attendeesMenu .opt-participant
|
|
||||||
{ font-style: italic; }
|
|
||||||
|
|
||||||
DIV#attendeesMenu .non-participant A
|
|
||||||
{ color: #888; }
|
|
||||||
|
|
||||||
#attendeesLabel DIV#attendeesMenu > DIV
|
|
||||||
{ margin-left: 4px; }
|
|
||||||
|
|
||||||
#attendeesLabel DIV#attendeesMenu > DIV,
|
|
||||||
DIV#attendeesMenu .attendee
|
|
||||||
{ height: 18px; }
|
|
||||||
|
|
||||||
#attendeesLabel DIV#attendeesMenu .statusIcon
|
|
||||||
{ margin-top: 4px; }
|
|
||||||
|
|
||||||
DIV#attendeesMenu .statusIcon
|
|
||||||
{ background-repeat: no-repeat;
|
|
||||||
float: left;
|
|
||||||
width: 12px;
|
|
||||||
height: 14px;
|
|
||||||
margin-right: 4px;
|
|
||||||
background-image: url("attendee-partstats.png"); }
|
|
||||||
|
|
||||||
DIV#attendeesMenu .accepted .statusIcon
|
|
||||||
{ background-position: 0px 0px; }
|
|
||||||
|
|
||||||
DIV#attendeesMenu .declined .statusIcon
|
|
||||||
{ background-position: -12px 0px; }
|
|
||||||
|
|
||||||
DIV#attendeesMenu .needs-action .statusIcon
|
|
||||||
{ background-position: -24px 0px; }
|
|
||||||
|
|
||||||
DIV#attendeesMenu .tentative .statusIcon
|
|
||||||
{ background-position: -36px 0px; }
|
|
||||||
|
|
||||||
DIV#attendeesMenu .delegated .statusIcon
|
|
||||||
{ background-position: -48px 0px; }
|
|
||||||
|
|
||||||
DIV#attendeesMenu .no-partstat .statusIcon
|
|
||||||
{ background-position: -60px 0px; }
|
|
||||||
|
|
||||||
DIV#attendeesMenu .delegate
|
|
||||||
{ padding-left: 16px !important; }
|
|
|
@ -1,544 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright (C) 2006-2014 Inverse inc.
|
|
||||||
|
|
||||||
This file is part of SOGo.
|
|
||||||
|
|
||||||
SOGo is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU Lesser General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2, or (at your option) any
|
|
||||||
later version.
|
|
||||||
|
|
||||||
SOGo is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
||||||
License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with OGo; see the file COPYING. If not, write to the
|
|
||||||
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|
||||||
02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
var contactSelectorAction = 'calendars-contacts';
|
|
||||||
var AppointmentEditor = {
|
|
||||||
attendeesMenu: null,
|
|
||||||
timeRE: /(\d{1,2}):?(\d{1,2})/
|
|
||||||
};
|
|
||||||
|
|
||||||
function uixEarlierDate(date1, date2) {
|
|
||||||
// can this be done in a sane way?
|
|
||||||
if (date1.getYear() < date2.getYear()) return date1;
|
|
||||||
if (date1.getYear() > date2.getYear()) return date2;
|
|
||||||
// same year
|
|
||||||
if (date1.getMonth() < date2.getMonth()) return date1;
|
|
||||||
if (date1.getMonth() > date2.getMonth()) return date2;
|
|
||||||
// // same month
|
|
||||||
if (date1.getDate() < date2.getDate()) return date1;
|
|
||||||
if (date1.getDate() > date2.getDate()) return date2;
|
|
||||||
// same day
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function validateAptEditor() {
|
|
||||||
var e, startdate, enddate, tmpdate;
|
|
||||||
|
|
||||||
e = $('summary');
|
|
||||||
if (e.value.length == 0) {
|
|
||||||
if (!confirm(labels.validate_notitle))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
e = $('startTime_date');
|
|
||||||
if (e.value.length != 10) {
|
|
||||||
showAlertDialog(labels.validate_invalid_startdate);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
startdate = getStartDate();
|
|
||||||
if (startdate == null) {
|
|
||||||
showAlertDialog(labels.validate_invalid_startdate);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
e = $('endTime_date');
|
|
||||||
if (e.value.length != 10) {
|
|
||||||
showAlertDialog(labels.validate_invalid_enddate);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
enddate = getEndDate();
|
|
||||||
if (enddate == null) {
|
|
||||||
showAlertDialog(labels.validate_invalid_enddate);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
tmpdate = uixEarlierDate(startdate, enddate);
|
|
||||||
if (tmpdate == enddate) {
|
|
||||||
showAlertDialog(labels.validate_endbeforestart);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (tmpdate == null /* means: same date */) {
|
|
||||||
var startHour, startMinute, endHour, endMinute;
|
|
||||||
var matches;
|
|
||||||
|
|
||||||
matches = AppointmentEditor.timeRE.exec(window.timeWidgets['start']['time'].value);
|
|
||||||
if (matches) {
|
|
||||||
startHour = parseInt(matches[1], 10);
|
|
||||||
startMinute = parseInt(matches[2], 10);
|
|
||||||
matches = AppointmentEditor.timeRE.exec(window.timeWidgets['end']['time'].value);
|
|
||||||
if (matches) {
|
|
||||||
endHour = parseInt(matches[1], 10);
|
|
||||||
endMinute = parseInt(matches[2], 10);
|
|
||||||
|
|
||||||
if (startHour > endHour) {
|
|
||||||
showAlertDialog(labels.validate_endbeforestart);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (startHour == endHour) {
|
|
||||||
if (startMinute > endMinute) {
|
|
||||||
showAlertDialog(labels.validate_endbeforestart);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
showAlertDialog(labels.validate_invalid_enddate);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
showAlertDialog(labels.validate_invalid_startdate);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AIM.submit($(document.editform), {'onComplete' : onEventPostComplete});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onAttendeesMenuPrepareVisibility()
|
|
||||||
{
|
|
||||||
var composeToUndecidedAttendees = $('composeToUndecidedAttendees');
|
|
||||||
var attendeesStates = $('attendeesMenu').innerHTML;
|
|
||||||
|
|
||||||
if (attendeesStates.indexOf("needs-action") < 0)
|
|
||||||
composeToUndecidedAttendees.addClassName("disabled");
|
|
||||||
else
|
|
||||||
composeToUndecidedAttendees.removeClassName("disabled");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onComposeToAllAttendees()
|
|
||||||
{
|
|
||||||
var attendees = $$("DIV#attendeesMenu LI.attendee");
|
|
||||||
var addresses = new Array();
|
|
||||||
attendees.each(function(item) {
|
|
||||||
var textChild = null;
|
|
||||||
var childNodes = item.childNodes;
|
|
||||||
for (var i = 0; !textChild && i < childNodes.length; i++) {
|
|
||||||
if (childNodes[i].nodeType == 3) {
|
|
||||||
textChild = childNodes[i];
|
|
||||||
var address = textChild.nodeValue.trim() + " <" + item.readAttribute("email") + ">";
|
|
||||||
addresses.push(address);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (window.opener)
|
|
||||||
window.opener.openMailTo(addresses.join(";"));
|
|
||||||
}
|
|
||||||
|
|
||||||
function onComposeToUndecidedAttendees()
|
|
||||||
{
|
|
||||||
if ($(this).hasClassName("disabled"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
var attendees = $$("DIV#attendeesMenu LI.attendee.needs-action");
|
|
||||||
var addresses = new Array();
|
|
||||||
attendees.each(function(item) {
|
|
||||||
var textChild = null;
|
|
||||||
var childNodes = item.childNodes;
|
|
||||||
for (var i = 0; !textChild && i < childNodes.length; i++) {
|
|
||||||
if (childNodes[i].nodeType == 3) {
|
|
||||||
textChild = childNodes[i];
|
|
||||||
var address = textChild.nodeValue.trim() + " <" + item.readAttribute("email") + ">";
|
|
||||||
addresses.push(address);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (window.opener)
|
|
||||||
window.opener.openMailTo(addresses.join(";"));
|
|
||||||
}
|
|
||||||
|
|
||||||
function addContact(tag, fullContactName, contactId, contactName, contactEmail) {
|
|
||||||
var uids = $('uixselector-participants-uidList');
|
|
||||||
|
|
||||||
if (contactId)
|
|
||||||
{
|
|
||||||
var re = new RegExp("(^|,)" + contactId + "($|,)");
|
|
||||||
|
|
||||||
if (!re.test(uids.value))
|
|
||||||
{
|
|
||||||
if (uids.value.length > 0)
|
|
||||||
uids.value += ',' + contactId;
|
|
||||||
else
|
|
||||||
uids.value = contactId;
|
|
||||||
|
|
||||||
var names = $('uixselector-participants-display');
|
|
||||||
names.innerHTML += ('<li onmousedown="return false;"'
|
|
||||||
+ ' onclick="onRowClick(event);"><img src="'
|
|
||||||
+ ResourcesURL + '/abcard.png" />'
|
|
||||||
+ contactName + '</li>');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onEventPostComplete(response) {
|
|
||||||
if (response && response.length > 0) {
|
|
||||||
var jsonResponse = response.evalJSON();
|
|
||||||
if (jsonResponse["status"] == "success") {
|
|
||||||
if (window.opener)
|
|
||||||
window.opener.refreshEventsAndDisplay();
|
|
||||||
window.close();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var message = jsonResponse["message"];
|
|
||||||
showAlertDialog(jsonResponse["message"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveEvent(sender) {
|
|
||||||
if (validateAptEditor()) {
|
|
||||||
document.forms['editform'].attendees.value = Object.toJSON($(attendees));
|
|
||||||
document.forms['editform'].submit();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function startDayAsShortString() {
|
|
||||||
return $('startTime_date').valueAsShortDateString();
|
|
||||||
}
|
|
||||||
|
|
||||||
function endDayAsShortString() {
|
|
||||||
return $('endTime_date').valueAsShortDateString();
|
|
||||||
}
|
|
||||||
|
|
||||||
function _getDate(which) {
|
|
||||||
var date = window.timeWidgets[which]['date'].inputAsDate();
|
|
||||||
var time = AppointmentEditor.timeRE.exec(window.timeWidgets[which]['time'].value);
|
|
||||||
if (time) {
|
|
||||||
date.setHours(time[1]);
|
|
||||||
date.setMinutes(time[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isNaN(date.getTime()))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return date;
|
|
||||||
}
|
|
||||||
|
|
||||||
function _getShadowDate(which) {
|
|
||||||
var date = window.timeWidgets[which]['date'].getAttribute("shadow-value").asDate();
|
|
||||||
var time = AppointmentEditor.timeRE.exec(window.timeWidgets[which]['time'].getAttribute("shadow-value"));
|
|
||||||
if (time) {
|
|
||||||
date.setHours(time[1]);
|
|
||||||
date.setMinutes(time[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return date;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getStartDate() {
|
|
||||||
return this._getDate('start');
|
|
||||||
}
|
|
||||||
|
|
||||||
function getEndDate() {
|
|
||||||
return this._getDate('end');
|
|
||||||
}
|
|
||||||
|
|
||||||
function getShadowStartDate() {
|
|
||||||
return this._getShadowDate('start');
|
|
||||||
}
|
|
||||||
|
|
||||||
function getShadowEndDate() {
|
|
||||||
return this._getShadowDate('end');
|
|
||||||
}
|
|
||||||
|
|
||||||
function _setDate(which, newDate) {
|
|
||||||
if (newDate) {
|
|
||||||
window.timeWidgets[which]['date'].setInputAsDate(newDate);
|
|
||||||
window.timeWidgets[which]['time'].value = newDate.getDisplayHoursString();
|
|
||||||
}
|
|
||||||
// Update date picker
|
|
||||||
var dateComponent = jQuery(window.timeWidgets[which]['date']).closest('.date');
|
|
||||||
dateComponent.data('date', window.timeWidgets[which]['date'].value);
|
|
||||||
dateComponent.datepicker('update');
|
|
||||||
}
|
|
||||||
|
|
||||||
function setStartDate(newStartDate) {
|
|
||||||
this._setDate('start', newStartDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setEndDate(newEndDate) {
|
|
||||||
this._setDate('end', newEndDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onAdjustTime(event) {
|
|
||||||
var endDate = window.getEndDate();
|
|
||||||
var startDate = window.getStartDate();
|
|
||||||
var input = $(this);
|
|
||||||
if (input.tagName != 'INPUT')
|
|
||||||
input = input.down('input');
|
|
||||||
|
|
||||||
if (input.id.startsWith("start")) {
|
|
||||||
// Start date was changed
|
|
||||||
if (startDate == null) {
|
|
||||||
var oldStartDate = window.getShadowStartDate();
|
|
||||||
window.setStartDate(oldStartDate);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var delta = window.getShadowStartDate().valueOf() - startDate.valueOf();
|
|
||||||
window.setStartDate();
|
|
||||||
if (delta != 0) {
|
|
||||||
// Increment end date
|
|
||||||
var newEndDate = new Date(endDate.valueOf() - delta);
|
|
||||||
window.setEndDate(newEndDate);
|
|
||||||
|
|
||||||
window.timeWidgets['end']['date'].updateShadowValue();
|
|
||||||
window.timeWidgets['end']['time'].updateShadowValue();
|
|
||||||
window.timeWidgets['start']['date'].updateShadowValue();
|
|
||||||
window.timeWidgets['start']['time'].updateShadowValue();
|
|
||||||
if (window.timeWidgets['end']['time'].onChange)
|
|
||||||
window.timeWidgets['end']['time'].onChange(); // method from SOGoTimePicker
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// End date was changed
|
|
||||||
if (endDate == null) {
|
|
||||||
var oldEndDate = window.getShadowEndDate();
|
|
||||||
window.setEndDate(oldEndDate);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var delta = endDate.valueOf() - startDate.valueOf();
|
|
||||||
if (delta < 0) {
|
|
||||||
showAlertDialog(labels.validate_endbeforestart);
|
|
||||||
var oldEndDate = window.getShadowEndDate();
|
|
||||||
window.setEndDate(oldEndDate);
|
|
||||||
|
|
||||||
window.timeWidgets['end']['date'].updateShadowValue();
|
|
||||||
window.timeWidgets['end']['time'].updateShadowValue();
|
|
||||||
window.timeWidgets['end']['time'].onChange(); // method from SOGoTimePicker
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
window.setEndDate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onAllDayChanged(event) {
|
|
||||||
for (var type in window.timeWidgets)
|
|
||||||
window.timeWidgets[type]['time'].disabled = this.checked;
|
|
||||||
}
|
|
||||||
|
|
||||||
function initTimeWidgets(widgets) {
|
|
||||||
this.timeWidgets = widgets;
|
|
||||||
|
|
||||||
if (widgets['start']['date']) {
|
|
||||||
jQuery(widgets['start']['date']).closest('.date').datepicker({autoclose: true, weekStart: firstDayOfWeek})
|
|
||||||
.on('changeDate', onAdjustTime);
|
|
||||||
widgets['start']['time'].on("time:change", onAdjustTime);
|
|
||||||
widgets['start']['time'].addInterface(SOGoTimePickerInterface);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (widgets['end']['date']) {
|
|
||||||
jQuery(widgets['end']['date']).closest('.date').datepicker({autoclose: true, weekStart: firstDayOfWeek})
|
|
||||||
.on('changeDate', onAdjustTime);
|
|
||||||
widgets['end']['time'].on("time:change", onAdjustTime);
|
|
||||||
widgets['end']['time'].addInterface(SOGoTimePickerInterface);
|
|
||||||
}
|
|
||||||
|
|
||||||
var allDayLabel = $("allDay");
|
|
||||||
if (allDayLabel) {
|
|
||||||
var input = $(allDayLabel).childNodesWithTag("input")[0];
|
|
||||||
input.observe("change", onAllDayChanged.bindAsEventListener(input));
|
|
||||||
if (input.checked) {
|
|
||||||
for (var type in widgets)
|
|
||||||
widgets[type]['time'].disabled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function refreshAttendeesRO() {
|
|
||||||
var attendeesMenu = $("attendeesMenu");
|
|
||||||
var attendeesLabel = $("attendeesLabel");
|
|
||||||
var attendeesDiv = $("attendeesDiv");
|
|
||||||
|
|
||||||
if (attendeesLabel)
|
|
||||||
attendeesLabel.setStyle({display: "block"});
|
|
||||||
if (attendeesDiv)
|
|
||||||
attendeesDiv.setStyle({display: "block"});
|
|
||||||
|
|
||||||
if (attendeesMenu) {
|
|
||||||
// Register "click" event on each attendee's email
|
|
||||||
var attendees = attendeesMenu.getElementsByTagName('a');
|
|
||||||
$A(attendees).each(function(attendee) {
|
|
||||||
$(attendee).observe("click", onMailTo);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function refreshAttendees(newAttendees) {
|
|
||||||
var attendeesLabel = $("attendeesLabel");
|
|
||||||
var attendeesHref = $("attendeesHref");
|
|
||||||
var attendeesMenu = $("attendeesMenu");
|
|
||||||
|
|
||||||
if (!attendeesHref)
|
|
||||||
return refreshAttendeesRO();
|
|
||||||
|
|
||||||
if (attendeesMenu)
|
|
||||||
attendeesMenu = $("attendeesMenu").down("ul");
|
|
||||||
|
|
||||||
// Remove link of attendees
|
|
||||||
for (var i = 0; i < attendeesHref.childNodes.length; i++)
|
|
||||||
attendeesHref.removeChild(attendeesHref.childNodes[i]);
|
|
||||||
|
|
||||||
// Remove attendees from menu
|
|
||||||
var menuItems = $$("DIV#attendeesMenu LI.attendee");
|
|
||||||
if (menuItems && attendeesMenu)
|
|
||||||
for (var i = 0; i < menuItems.length; i++)
|
|
||||||
attendeesMenu.removeChild(menuItems[i]);
|
|
||||||
|
|
||||||
if (newAttendees)
|
|
||||||
// Update global variable
|
|
||||||
attendees = $H(newAttendees.evalJSON());
|
|
||||||
|
|
||||||
if (attendees.keys().length > 0) {
|
|
||||||
// Update attendees link and show label
|
|
||||||
var names = new Array();
|
|
||||||
attendees.values().each(function(attendee) {
|
|
||||||
attendee = $H(attendee);
|
|
||||||
var name = attendee.get('name') || attendee.get('email');
|
|
||||||
var delegatedTo = attendee.get('delegated-to');
|
|
||||||
if (!delegatedTo)
|
|
||||||
names.push(name);
|
|
||||||
|
|
||||||
if (attendeesMenu) {
|
|
||||||
if (!attendee.get('delegated-from') || delegatedTo) {
|
|
||||||
var node = createElement("li");
|
|
||||||
attendeesMenu.appendChild(node);
|
|
||||||
setupAttendeeNode(node, attendee);
|
|
||||||
}
|
|
||||||
if (delegatedTo) {
|
|
||||||
var delegate = attendees.get(delegatedTo);
|
|
||||||
var node = createElement("li");
|
|
||||||
attendeesMenu.appendChild(node);
|
|
||||||
setupAttendeeNode(node, $H(delegate), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
attendeesHref.appendChild(document.createTextNode(names.join(", ")));
|
|
||||||
attendeesLabel.setStyle({ display: "block" });
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Hide link of attendees
|
|
||||||
attendeesLabel.setStyle({ display: "none" });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recompute the position of the time picker widgets
|
|
||||||
window.timeWidgets['start']['time'].position();
|
|
||||||
window.timeWidgets['end']['time'].position();
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupAttendeeNode(aNode, aAttendee, isDelegate) {
|
|
||||||
// Construct the display string from common name and/or email address.
|
|
||||||
var name = aAttendee.get('name');
|
|
||||||
var email = aAttendee.get('email');
|
|
||||||
// if (name)
|
|
||||||
// name += ' <' + email + '>';
|
|
||||||
// else
|
|
||||||
// name = email;
|
|
||||||
name = name || email;
|
|
||||||
|
|
||||||
aNode.writeAttribute("email", email);
|
|
||||||
aNode.addClassName("attendee");
|
|
||||||
var partstat = aAttendee.get('partstat');
|
|
||||||
if (!partstat)
|
|
||||||
partstat = "no-partstat";
|
|
||||||
aNode.addClassName(partstat);
|
|
||||||
if (isDelegate)
|
|
||||||
aNode.addClassName("delegate");
|
|
||||||
var statusIconNode = createElement("div", null, "statusIcon");
|
|
||||||
aNode.appendChild(statusIconNode);
|
|
||||||
aNode.appendChild(document.createTextNode(name));
|
|
||||||
aNode.observe("click", onMailTo);
|
|
||||||
}
|
|
||||||
|
|
||||||
function initializeAttendeesHref() {
|
|
||||||
var attendeesHref = $("attendeesHref");
|
|
||||||
if (attendeesHref && !attendeesHref.hasClassName("nomenu"))
|
|
||||||
attendeesHref.observe("click", onAttendeesHrefClick, false);
|
|
||||||
refreshAttendees();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onAttendeesHrefClick(event) {
|
|
||||||
popupMenu(event, 'attendeesMenu', this);
|
|
||||||
preventDefault(event);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMailTo(event) {
|
|
||||||
var target = $(getTarget(event));
|
|
||||||
var address = target.lastChild.nodeValue.trim() + " <" + target.readAttribute("email") + ">";
|
|
||||||
openMailTo(address);
|
|
||||||
Event.stop(event);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getMenus() {
|
|
||||||
AppointmentEditor.attendeesMenu = new Array(onPopupAttendeesWindow,
|
|
||||||
"-",
|
|
||||||
onComposeToAllAttendees,
|
|
||||||
onComposeToUndecidedAttendees,
|
|
||||||
"-",
|
|
||||||
null);
|
|
||||||
|
|
||||||
var attendeesMenu = $('attendeesMenu');
|
|
||||||
if (attendeesMenu)
|
|
||||||
attendeesMenu.prepareVisibility = onAttendeesMenuPrepareVisibility;
|
|
||||||
|
|
||||||
return { "attendeesMenu": AppointmentEditor.attendeesMenu };
|
|
||||||
}
|
|
||||||
|
|
||||||
function onAppointmentEditorLoad() {
|
|
||||||
if (readOnly == false) {
|
|
||||||
var widgets = {'start': {'date': $("startTime_date"),
|
|
||||||
'time': $("startTime_time")},
|
|
||||||
'end': {'date': $("endTime_date"),
|
|
||||||
'time': $("endTime_time")}};
|
|
||||||
initTimeWidgets(widgets);
|
|
||||||
}
|
|
||||||
|
|
||||||
var organizer = $("organizerLabel");
|
|
||||||
if (organizer && organizer.down("a")) {
|
|
||||||
organizer.down("a").on("click", onMailTo);
|
|
||||||
}
|
|
||||||
|
|
||||||
var createdBy = $("createdByLabel");
|
|
||||||
if (createdBy && createdBy.down("a")) {
|
|
||||||
createdBy.down("a").on("click", onMailTo);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extend JSON representation of attendees
|
|
||||||
attendees = $H(attendees);
|
|
||||||
|
|
||||||
initializeAttendeesHref();
|
|
||||||
}
|
|
||||||
|
|
||||||
document.observe("dom:loaded", onAppointmentEditorLoad);
|
|
|
@ -1,276 +0,0 @@
|
||||||
DIV#attendeesMenu
|
|
||||||
{ overflow: auto;
|
|
||||||
overflow-x: hidden; }
|
|
||||||
|
|
||||||
DIV#attendeesView
|
|
||||||
{ position: absolute;
|
|
||||||
left: 1em;
|
|
||||||
right: 1em;
|
|
||||||
top: 1em;
|
|
||||||
bottom: 1em; }
|
|
||||||
|
|
||||||
DIV#freeBusyView
|
|
||||||
{ background-color: #fff;
|
|
||||||
position: absolute;
|
|
||||||
top: 30px;
|
|
||||||
bottom: 135px;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
overflow: hidden;
|
|
||||||
border-top: 1px solid #909090;
|
|
||||||
border-left: 1px solid #909090;
|
|
||||||
border-right: 1px solid #fff;
|
|
||||||
border-bottom: 1px solid #fff; }
|
|
||||||
|
|
||||||
SPAN.timeDateControl A:hover
|
|
||||||
{ text-decoration: none; }
|
|
||||||
|
|
||||||
TABLE
|
|
||||||
{ border-collapse: separate;
|
|
||||||
table-layout: auto;
|
|
||||||
border-spacing: 0px 0px; }
|
|
||||||
|
|
||||||
TABLE#freeBusyHeader TH
|
|
||||||
{ white-space: nowrap; }
|
|
||||||
|
|
||||||
TABLE#freeBusy TD,
|
|
||||||
TABLE#freeBusy TH
|
|
||||||
{ padding: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
border: 0px;
|
|
||||||
vertical-align: top; }
|
|
||||||
|
|
||||||
TABLE#freeBusy TD.freeBusyHeader DIV,
|
|
||||||
TABLE#freeBusy TD.freeBusyAttendees DIV
|
|
||||||
{ overflow: hidden; }
|
|
||||||
|
|
||||||
TABLE#freeBusy TD.freeBusyData DIV
|
|
||||||
{ overflow: scroll; }
|
|
||||||
|
|
||||||
TABLE#freeBusyAttendees TD.attendeeStatus
|
|
||||||
{ width: 24px;
|
|
||||||
min-width: 24px;
|
|
||||||
max-width: 24px; }
|
|
||||||
|
|
||||||
TABLE#freeBusyAttendees TD.attendeeStatus DIV
|
|
||||||
{ width: 12px;
|
|
||||||
min-width: 12px;
|
|
||||||
max-width: 24px;
|
|
||||||
background-image: none; }
|
|
||||||
|
|
||||||
UL.roles-legend SPAN.role-icon
|
|
||||||
{ display: block;
|
|
||||||
float: left; }
|
|
||||||
|
|
||||||
UL.roles-legend SPAN.role-icon,
|
|
||||||
TABLE#freeBusyAttendees TR.attendee-row TD.attendeeStatus DIV
|
|
||||||
{ background-repeat: no-repeat;
|
|
||||||
width: 24px;
|
|
||||||
height: 20px;
|
|
||||||
background-image: url("attendee-roles.png"); }
|
|
||||||
|
|
||||||
LI[role="req-participant"] > SPAN.role-icon,
|
|
||||||
TABLE#freeBusyAttendees TR[role="req-participant"].attendee-row TD.attendeeStatus DIV
|
|
||||||
{ background-position: 0px 4px; }
|
|
||||||
|
|
||||||
LI[role="opt-participant"] > SPAN.role-icon,
|
|
||||||
TABLE#freeBusyAttendees TR[role="opt-participant"].attendee-row TD.attendeeStatus DIV
|
|
||||||
{ background-position: -24px 4px; }
|
|
||||||
|
|
||||||
LI[role="non-participant"] > SPAN.role-icon,
|
|
||||||
TABLE#freeBusyAttendees TR[role="non-participant"].attendee-row TD.attendeeStatus DIV
|
|
||||||
{ background-position: -72px 4px; }
|
|
||||||
|
|
||||||
LI[role="chair"] > SPAN.role-icon,
|
|
||||||
TABLE#freeBusyAttendees TR[role="chair"].attendee-row TD.attendeeStatus DIV
|
|
||||||
{ background-position: -48px 4px; }
|
|
||||||
|
|
||||||
TABLE#freeBusyAttendees TR.organizer-row TD.attendeeStatus DIV
|
|
||||||
{ background-repeat: no-repeat;
|
|
||||||
width: 12px;
|
|
||||||
height: 18px;
|
|
||||||
margin-left: 6px;
|
|
||||||
background-image: url("attendee-partstats.png"); }
|
|
||||||
|
|
||||||
TABLE#freeBusyAttendees TR[partstat="accepted"].organizer-row TD.attendeeStatus DIV
|
|
||||||
{ background-position: 0px 4px; }
|
|
||||||
|
|
||||||
TABLE#freeBusyAttendees TR[partstat="declined"].organizer-row TD.attendeeStatus DIV
|
|
||||||
{ background-position: -12px 4px; }
|
|
||||||
|
|
||||||
TABLE#freeBusyAttendees TR[partstat="needs-action"].organizer-row TD.attendeeStatus DIV
|
|
||||||
{ background-position: -24px 4px; }
|
|
||||||
|
|
||||||
TABLE#freeBusyAttendees TR[partstat="tentative"].organizer-row TD.attendeeStatus DIV
|
|
||||||
{ background-position: -36px 4px; }
|
|
||||||
|
|
||||||
TABLE#freeBusyHeader TR.freeBusyHeader2 TH
|
|
||||||
{ font-weight: normal; }
|
|
||||||
|
|
||||||
TABLE#freeBusyHeader TR.freeBusyHeader1 TH,
|
|
||||||
TABLE#freeBusyHeader TR.freeBusyHeader2 TH,
|
|
||||||
TABLE#freeBusyHeader TR.freeBusyHeader3 TH
|
|
||||||
{ text-align: left;
|
|
||||||
color: #777;
|
|
||||||
background: #fff; }
|
|
||||||
|
|
||||||
TABLE#freeBusyHeader TR.freeBusyHeader2 TH
|
|
||||||
{ padding-right: 2em; }
|
|
||||||
|
|
||||||
TABLE#freeBusyHeader TR.freeBusyHeader3 TH
|
|
||||||
{ border-left: 1px solid #fff;
|
|
||||||
border-bottom: 1px solid #cecbff; }
|
|
||||||
|
|
||||||
TABLE#freeBusyAttendees TR.attendeeModel,
|
|
||||||
TABLE#freeBusyData TR.dataModel
|
|
||||||
{ display: none; }
|
|
||||||
|
|
||||||
TABLE#freeBusy TD.freeBusyHeader,
|
|
||||||
TABLE#freeBusy TD.freeBusyData
|
|
||||||
{ border-left: 2px solid #bbb; }
|
|
||||||
|
|
||||||
TABLE#freeBusyAttendees TD,
|
|
||||||
TABLE#freeBusyData TD
|
|
||||||
{ border-bottom: 1px solid #cecbff;
|
|
||||||
border-left: 1px solid #cecbff;
|
|
||||||
border-top: 0px;
|
|
||||||
border-right: 0px;
|
|
||||||
height: 24px;
|
|
||||||
background-color: #fff; }
|
|
||||||
|
|
||||||
TABLE#freeBusyAttendees TD
|
|
||||||
{ border-left: 1px solid #fff; }
|
|
||||||
|
|
||||||
TABLE#freeBusyData TR.futureData TD
|
|
||||||
{ border-left: none; }
|
|
||||||
|
|
||||||
TABLE#freeBusy TD.freeBusyAttendees DIV
|
|
||||||
{ width: 16em; }
|
|
||||||
|
|
||||||
TABLE#freeBusyAttendees TD.attendees INPUT
|
|
||||||
{ background-image: url("abcard.png");
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: 4px center;
|
|
||||||
border: 0px;
|
|
||||||
width: 12em;
|
|
||||||
padding-left: 24px; }
|
|
||||||
|
|
||||||
TABLE#freeBusyAttendees TR.futureAttendee INPUT
|
|
||||||
{ background-image: none;
|
|
||||||
color: #aaa; }
|
|
||||||
|
|
||||||
TABLE#freeBusyAttendees TR.futureAttendee TD,
|
|
||||||
TABLE#freeBusyData TR.futureData TD
|
|
||||||
{ border: 0px;
|
|
||||||
height: 3em;
|
|
||||||
line-height: 3em; }
|
|
||||||
|
|
||||||
SPAN.freeBusyZoneElement
|
|
||||||
{ display: block;
|
|
||||||
float: left;
|
|
||||||
clear: right;
|
|
||||||
width: 25%;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
border: 0px; }
|
|
||||||
|
|
||||||
TABLE#freeBusyHeader TR.freeBusyHeader3 SPAN.freeBusyZoneElement
|
|
||||||
{ height: 2px; }
|
|
||||||
|
|
||||||
TABLE#freeBusyHeader TR.freeBusyHeader3 SPAN.freeBusyZoneElement.busy
|
|
||||||
{ background-color: #f03 !important; }
|
|
||||||
|
|
||||||
TABLE#freeBusyData TD SPAN.freeBusyZoneElement
|
|
||||||
{ height: 24px; }
|
|
||||||
|
|
||||||
.colorBox.free,
|
|
||||||
TABLE#freeBusyData TD SPAN.freeBusyZoneElement
|
|
||||||
{ background-color: #ebebe4; }
|
|
||||||
|
|
||||||
DIV#freeBusyFooter
|
|
||||||
{ position: absolute;
|
|
||||||
height: 130px;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
bottom: 0px;
|
|
||||||
line-height: 2em;
|
|
||||||
text-align: right; }
|
|
||||||
|
|
||||||
DIV#legend
|
|
||||||
{ margin-left: 1em;
|
|
||||||
text-align: left; }
|
|
||||||
|
|
||||||
DIV#legend UL
|
|
||||||
{ cursor: default;
|
|
||||||
float: left;
|
|
||||||
margin: 0px;
|
|
||||||
margin-right: 10px;
|
|
||||||
padding: 0px;
|
|
||||||
list-style-type: none;
|
|
||||||
list-style-image: none; }
|
|
||||||
|
|
||||||
DIV#legend LI
|
|
||||||
{ height: 20px;
|
|
||||||
white-space: nowrap;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px; }
|
|
||||||
|
|
||||||
#legend .colorBox
|
|
||||||
{ border: 1px solid #fff;
|
|
||||||
cursor: default; }
|
|
||||||
|
|
||||||
.colorBox.busy,
|
|
||||||
SPAN.freeBusyZoneElement.busy
|
|
||||||
{ background-color: #35556b !important; }
|
|
||||||
|
|
||||||
.colorBox.maybe-busy,
|
|
||||||
SPAN.freeBusyZoneElement.maybe-busy
|
|
||||||
{ background-color: #adc0d0 !important; }
|
|
||||||
|
|
||||||
.colorBox.noFreeBusy,
|
|
||||||
TABLE#freeBusyData TD.noFreeBusy
|
|
||||||
{ background-color: #e09ebd; }
|
|
||||||
|
|
||||||
#freeBusyViewButtons
|
|
||||||
{ margin: 0px;
|
|
||||||
text-align: left; }
|
|
||||||
|
|
||||||
SPAN#freeBusyViewOptions
|
|
||||||
{ float: left; }
|
|
||||||
|
|
||||||
#freeBusyViewButtons SELECT
|
|
||||||
{ width: 50px; }
|
|
||||||
|
|
||||||
SPAN.hidden
|
|
||||||
{ display: none; }
|
|
||||||
|
|
||||||
DIV#freeBusyReplicas
|
|
||||||
{ position: absolute;
|
|
||||||
top: 2px;
|
|
||||||
right: 0px;
|
|
||||||
width: 30em;
|
|
||||||
height: 4em; }
|
|
||||||
|
|
||||||
DIV#freeBusyReplicas LABEL
|
|
||||||
{ line-height: 1.5em; }
|
|
||||||
|
|
||||||
DIV#windowButtons
|
|
||||||
{ position: absolute;
|
|
||||||
bottom: 0px;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
height: 24px;
|
|
||||||
text-align: right; }
|
|
||||||
|
|
||||||
.officeHour
|
|
||||||
{ color: #666 !important;
|
|
||||||
font-weight: bold !important; }
|
|
||||||
|
|
||||||
SPAN.content INPUT,
|
|
||||||
SPAN.content SELECT,
|
|
||||||
SPAN.content SPAN,
|
|
||||||
SPAN.timeDateControl INPUT,
|
|
||||||
SPAN.timeDateControl SELECT,
|
|
||||||
SPAN.timeDateControl SPAN,
|
|
||||||
DIV#freeBusyReplicas SPAN
|
|
||||||
{ vertical-align: top; }
|
|
|
@ -1,48 +0,0 @@
|
||||||
DIV.title
|
|
||||||
{ color: #000;
|
|
||||||
vertical-align: bottom;
|
|
||||||
padding-top: 8px;
|
|
||||||
padding-left: 1em;
|
|
||||||
padding: 5px;
|
|
||||||
background-color: #fff;
|
|
||||||
border-bottom: 1px solid #555; }
|
|
||||||
|
|
||||||
DIV.title SPAN
|
|
||||||
{ float: left;
|
|
||||||
line-height: 14px;
|
|
||||||
text-align: right;
|
|
||||||
width: 120px; }
|
|
||||||
|
|
||||||
DIV.title SPAN.value
|
|
||||||
{ float: none;
|
|
||||||
margin-left: 1em;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: bold; }
|
|
||||||
|
|
||||||
DIV.title LABEL
|
|
||||||
{ display: block;
|
|
||||||
clear: both; }
|
|
||||||
|
|
||||||
DIV.calendarUserRights,
|
|
||||||
DIV.basicUserRights
|
|
||||||
{ margin: 1em;}
|
|
||||||
|
|
||||||
DIV.calendarUserRights SPAN
|
|
||||||
{ float: left;
|
|
||||||
clear: both;
|
|
||||||
line-height: 2em;
|
|
||||||
margin-right: 1em;
|
|
||||||
text-align: right;
|
|
||||||
width: 120px; }
|
|
||||||
|
|
||||||
DIV.buttons
|
|
||||||
{ text-align: right;
|
|
||||||
margin: 1em;
|
|
||||||
margin-top: 0px; }
|
|
||||||
|
|
||||||
DIV.dialog.none
|
|
||||||
{ position: absolute;
|
|
||||||
top: 0px;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
margin: 25px auto; }
|
|
|
@ -1,71 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
function onUpdateACL(event) {
|
|
||||||
var uid = $('uid').value;
|
|
||||||
if (uid == '<default>' || uid == 'anonymous') {
|
|
||||||
var selects = $$('#userRightsForm select');
|
|
||||||
var enabled = false;
|
|
||||||
for (var i = 0; i < selects.length; i++) {
|
|
||||||
if (selects[i].value != 'None') {
|
|
||||||
enabled = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!enabled) {
|
|
||||||
var inputs = $$('#userRightsForm input[type="checkbox"]');
|
|
||||||
for (var i = 0; i < inputs.length; i++) {
|
|
||||||
if (inputs[i].checked) {
|
|
||||||
enabled = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (enabled) {
|
|
||||||
if (uid == '<default>')
|
|
||||||
showConfirmDialog(_("Warning"),
|
|
||||||
_("Any user with an account on this system will be able to access your calendar \"%{0}\". Are you certain you trust them all?").formatted($("folderName").allTextContent()),
|
|
||||||
onUpdateACLConfirm, onUpdateACLCancel,
|
|
||||||
"Give Access", "Keep Private");
|
|
||||||
else
|
|
||||||
showConfirmDialog(_("Warning"),
|
|
||||||
_("Potentially anyone on the Internet will be able to access your calendar \"%{0}\", even if they do not have an account on this system. Is this information suitable for the public Internet?").formatted($("folderName").allTextContent()),
|
|
||||||
onUpdateACLConfirm, onUpdateACLCancel,
|
|
||||||
"Give Access", "Keep Private");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return onUpdateACLConfirm(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onUpdateACLConfirm(event) {
|
|
||||||
disposeDialog();
|
|
||||||
|
|
||||||
$('userRightsForm').submit();
|
|
||||||
Event.stop(event);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onUpdateACLCancel(event) {
|
|
||||||
var options = $$('#userRightsForm option');
|
|
||||||
for (var i = 0; i < options.length; i++)
|
|
||||||
options[i].selected = (options[i].value == 'None');
|
|
||||||
var inputs = $$('#userRightsForm input[type="checkbox"]');
|
|
||||||
for (var i = 0; i < inputs.length; i++)
|
|
||||||
if (inputs[i].checked)
|
|
||||||
inputs[i].checked = false;
|
|
||||||
|
|
||||||
disposeDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onCancelACL(event) {
|
|
||||||
window.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
function initACLButtons() {
|
|
||||||
$("updateButton").observe("click", onUpdateACL);
|
|
||||||
$("cancelButton").observe("click", onCancelACL);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.observe("dom:loaded", initACLButtons);
|
|
|
@ -1,64 +0,0 @@
|
||||||
DIV
|
|
||||||
{ clear: both; }
|
|
||||||
|
|
||||||
FIELDSET
|
|
||||||
{ margin-bottom: 5px;
|
|
||||||
border: 1px solid #FFFFFF;
|
|
||||||
border-top: 1px solid #909090;
|
|
||||||
border-left: 1px solid #909090; }
|
|
||||||
|
|
||||||
FIELDSET DIV
|
|
||||||
{ margin-left: 20px;
|
|
||||||
margin-right: 10px; }
|
|
||||||
|
|
||||||
SPAN.label
|
|
||||||
{ cursor: default;
|
|
||||||
width: 55px;
|
|
||||||
text-align: right;
|
|
||||||
line-height: 2em;
|
|
||||||
float: left;
|
|
||||||
display: block; }
|
|
||||||
|
|
||||||
INPUT.checkBox
|
|
||||||
{ margin-left: 38px;
|
|
||||||
margin-right: 6px; }
|
|
||||||
|
|
||||||
SPAN.content
|
|
||||||
{ line-height: 1.5em;
|
|
||||||
vertical-align: middle;
|
|
||||||
margin-left: 4px; }
|
|
||||||
|
|
||||||
SPAN.content INPUT.textField
|
|
||||||
{ width: 160px; }
|
|
||||||
|
|
||||||
DIV.colorBox
|
|
||||||
{ margin: 5px 0;
|
|
||||||
-webkit-border-radius: 4px;
|
|
||||||
-moz-border-radius: 4px;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: 2px solid #eee; }
|
|
||||||
|
|
||||||
DIV.colorBox:hover
|
|
||||||
{ border-color: #fff; }
|
|
||||||
|
|
||||||
#colorPickerDialog
|
|
||||||
{ width: 146px;
|
|
||||||
height: 191px; }
|
|
||||||
|
|
||||||
DIV#buttons
|
|
||||||
{ position: absolute;
|
|
||||||
bottom: 5px;
|
|
||||||
right: 5px;
|
|
||||||
padding: 10px;
|
|
||||||
padding-top: 5px;
|
|
||||||
text-align: right; }
|
|
||||||
|
|
||||||
INPUT#calendarSyncTag
|
|
||||||
{ width: 7em; }
|
|
||||||
|
|
||||||
LABEL
|
|
||||||
{ white-space: nowrap; }
|
|
||||||
|
|
||||||
#webCalendarUrl SPAN.content
|
|
||||||
{ white-space: nowrap;
|
|
||||||
overflow: hidden; }
|
|
|
@ -1,121 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
function onLoadCalendarProperties() {
|
|
||||||
var tabsContainer = $("propertiesTabs");
|
|
||||||
var controller = new SOGoTabsController();
|
|
||||||
controller.attachToTabsContainer(tabsContainer);
|
|
||||||
|
|
||||||
var colorButton = $("colorButton");
|
|
||||||
var calendarColor = $("calendarColor");
|
|
||||||
colorButton.setStyle({ "backgroundColor": colorButton.readAttribute('data-color') });
|
|
||||||
colorButton.observe("click", onColorClick);
|
|
||||||
|
|
||||||
$('colorPickerDialog').on('click', 'span', onColorPickerChoice);
|
|
||||||
$(document.body).on("click", onBodyClickHandler);
|
|
||||||
|
|
||||||
var cancelButton = $("cancelButton");
|
|
||||||
cancelButton.observe("click", onCancelClick);
|
|
||||||
|
|
||||||
var okButton = $("okButton");
|
|
||||||
okButton.observe("click", onOKClick);
|
|
||||||
|
|
||||||
Event.observe(document, "keydown", onDocumentKeydown);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onDocumentKeydown(event) {
|
|
||||||
var target = Event.element(event);
|
|
||||||
if (target.tagName == "INPUT" || target.tagName == "SELECT") {
|
|
||||||
if (event.keyCode == Event.KEY_RETURN) {
|
|
||||||
onOKClick(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (event.keyCode == Event.KEY_ESC) {
|
|
||||||
onCancelClick();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onCancelClick(event) {
|
|
||||||
window.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onOKClick(event) {
|
|
||||||
var calendarName = $("calendarName");
|
|
||||||
var calendarColor = $("calendarColor");
|
|
||||||
var calendarID = $("calendarID");
|
|
||||||
var save = true;
|
|
||||||
var tag = $("calendarSyncTag");
|
|
||||||
var originalTag = $("originalCalendarSyncTag");
|
|
||||||
var allTags = $("allCalendarSyncTags");
|
|
||||||
|
|
||||||
if (calendarName.value.blank()) {
|
|
||||||
alert(_("Please specify a calendar name."));
|
|
||||||
save = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (save
|
|
||||||
&& allTags)
|
|
||||||
allTags = allTags.value.split(",");
|
|
||||||
|
|
||||||
if (save
|
|
||||||
&& tag
|
|
||||||
&& $("synchronizeCalendar").checked) {
|
|
||||||
if (tag.value.blank()) {
|
|
||||||
alert(_("tagNotDefined"));
|
|
||||||
save = false;
|
|
||||||
}
|
|
||||||
else if (allTags
|
|
||||||
&& allTags.indexOf(tag.value) > -1) {
|
|
||||||
alert(_("tagAlreadyExists"));
|
|
||||||
save = false;
|
|
||||||
}
|
|
||||||
else if (originalTag
|
|
||||||
&& !originalTag.value.blank()) {
|
|
||||||
if (tag.value != originalTag.value)
|
|
||||||
save = confirm(_("tagHasChanged"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
save = confirm(_("tagWasAdded"));
|
|
||||||
}
|
|
||||||
else if (save
|
|
||||||
&& originalTag
|
|
||||||
&& !originalTag.value.blank())
|
|
||||||
save = confirm(_("tagWasRemoved"));
|
|
||||||
|
|
||||||
if (save) {
|
|
||||||
window.opener.updateCalendarProperties(calendarID.value,
|
|
||||||
calendarName.value,
|
|
||||||
calendarColor.value);
|
|
||||||
$("propertiesform").submit();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Event.stop(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onBodyClickHandler(event) {
|
|
||||||
var target = getTarget(event);
|
|
||||||
if (!target.hasClassName('colorBox'))
|
|
||||||
$("colorPickerDialog").hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onColorClick(event) {
|
|
||||||
var cellPosition = this.cumulativeOffset();
|
|
||||||
var cellDimensions = this.getDimensions();
|
|
||||||
var div = $('colorPickerDialog');
|
|
||||||
var divDimensions = div.getDimensions();
|
|
||||||
var left = cellPosition[0] + cellDimensions["width"] + 4;
|
|
||||||
var top = cellPosition[1] - 5;
|
|
||||||
div.setStyle({ left: left + "px", top: top + "px" });
|
|
||||||
div.show();
|
|
||||||
|
|
||||||
preventDefault(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onColorPickerChoice(event) {
|
|
||||||
var span = getTarget(event);
|
|
||||||
var newColor = "#" + span.className.substr(4);
|
|
||||||
var colorButton = $("colorButton");
|
|
||||||
colorButton.setStyle({ "backgroundColor": newColor });
|
|
||||||
$("calendarColor").value = newColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
document.observe("dom:loaded", onLoadCalendarProperties);
|
|
|
@ -1,14 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
var type;
|
|
||||||
|
|
||||||
function onLoadColorPicker(event) {
|
|
||||||
showColorPicker();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onChooseColor(newColor) {
|
|
||||||
window.opener.onColorPickerChoice(newColor, type);
|
|
||||||
window.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
document.observe("dom:loaded", onLoadColorPicker);
|
|
|
@ -1,135 +0,0 @@
|
||||||
form[name="editform"]
|
|
||||||
{ position: absolute;
|
|
||||||
top: 48px;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0; }
|
|
||||||
|
|
||||||
form[name="editform"] #eventView
|
|
||||||
{ padding: 1em; }
|
|
||||||
|
|
||||||
SELECT#calendarList,
|
|
||||||
SELECT#categoryList,
|
|
||||||
SELECT#priorityList,
|
|
||||||
SELECT#repeatList,
|
|
||||||
SELECT#reminderList
|
|
||||||
{ width: 13em; }
|
|
||||||
|
|
||||||
#attendeesLabel
|
|
||||||
{ display: none; }
|
|
||||||
|
|
||||||
A#changeAttachButton
|
|
||||||
{ margin-left: 1em;
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
display: inline; }
|
|
||||||
|
|
||||||
SPAN.datePicker INPUT.textField,
|
|
||||||
SPAN.timeDateControl INPUT.textField
|
|
||||||
{ width: 7em; }
|
|
||||||
|
|
||||||
SPAN.timeDateControl A.button
|
|
||||||
{ border: 0; }
|
|
||||||
|
|
||||||
SPAN.timeDateControl A:hover
|
|
||||||
{ text-decoration: none; }
|
|
||||||
|
|
||||||
SPAN.content
|
|
||||||
{ position: absolute;
|
|
||||||
white-space: nowrap;
|
|
||||||
line-height: 2em;
|
|
||||||
top: -.25em;
|
|
||||||
left: 8em;
|
|
||||||
right: 0em;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
min-height: 22px; }
|
|
||||||
|
|
||||||
LABEL, SPAN.checkBoxList
|
|
||||||
{ display: block;
|
|
||||||
position: relative;
|
|
||||||
line-height: 1.5em;
|
|
||||||
height: 1.5em;
|
|
||||||
margin-left: 0px;
|
|
||||||
margin-bottom: .5em;
|
|
||||||
width: 100%; }
|
|
||||||
|
|
||||||
LABEL#commentArea textarea
|
|
||||||
{ width: 97%; }
|
|
||||||
|
|
||||||
SPAN.headerContent
|
|
||||||
{
|
|
||||||
width: 80%;
|
|
||||||
height: 1px;
|
|
||||||
top: 0.9em;
|
|
||||||
}
|
|
||||||
LABEL.title
|
|
||||||
{
|
|
||||||
margin-top: 1em;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
LABEL.titleNoSpace
|
|
||||||
{
|
|
||||||
margin-top: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#windowButtons
|
|
||||||
{ position: absolute;
|
|
||||||
bottom: 2em;
|
|
||||||
left: auto;
|
|
||||||
right: 2em; }
|
|
||||||
|
|
||||||
LABEL.calendarName
|
|
||||||
{ background-color: #fff;
|
|
||||||
border-bottom: 1px solid #555;
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: right;
|
|
||||||
margin: 0;
|
|
||||||
padding: 10px;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#attendeesMenu
|
|
||||||
{ overflow: auto; }
|
|
||||||
|
|
||||||
DIV.fakeTextArea
|
|
||||||
{ overflow: auto;
|
|
||||||
background: white;
|
|
||||||
border-width: 2px;
|
|
||||||
border-style: inset;
|
|
||||||
padding: 2px;
|
|
||||||
height: 100px; }
|
|
||||||
|
|
||||||
DIV#descriptionDiv,
|
|
||||||
DIV#attendeesDiv
|
|
||||||
{ height: 120px; }
|
|
||||||
|
|
||||||
DIV#descriptionDiv DIV.fakeTextArea
|
|
||||||
{ line-height: 1.5em;
|
|
||||||
padding: 2px 4px;
|
|
||||||
white-space: pre-wrap; }
|
|
||||||
|
|
||||||
/* #delegateEditor
|
|
||||||
{ padding-bottom: 1em; } */
|
|
||||||
|
|
||||||
#delegatedTo
|
|
||||||
{ background-image: url("abcard.png");
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: 4px center;
|
|
||||||
background-color: #CCDDEC;
|
|
||||||
padding: 2px 2px 2px 24px;
|
|
||||||
width: 260px; }
|
|
||||||
|
|
||||||
IMG#progressIndicator
|
|
||||||
{ float: none;
|
|
||||||
position: absolute;
|
|
||||||
right: 1em;
|
|
||||||
margin: 0 5px; }
|
|
||||||
|
|
||||||
SPAN.content INPUT,
|
|
||||||
SPAN.content SELECT,
|
|
||||||
SPAN.content SPAN,
|
|
||||||
SPAN.timeDateControl INPUT,
|
|
||||||
SPAN.timeDateControl SELECT,
|
|
||||||
SPAN.timeDateControl SPAN
|
|
||||||
{ vertical-align: top; }
|
|
|
@ -1,411 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
var ComponentEditor = {
|
|
||||||
attendeesWindow: null,
|
|
||||||
recurrenceWindow: null,
|
|
||||||
reminderWindow: null
|
|
||||||
};
|
|
||||||
|
|
||||||
function getOwnerLogin() {
|
|
||||||
return ownerLogin;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCalendarOwner() {
|
|
||||||
var ownerProfile;
|
|
||||||
|
|
||||||
if (typeof organizer == "undefined") {
|
|
||||||
var calendarIndex = $("calendarList").value;
|
|
||||||
var ownersList = owners[0];
|
|
||||||
var profiles = owners[1];
|
|
||||||
var ownerUid = ownersList[calendarIndex];
|
|
||||||
ownerProfile = profiles[ownerUid];
|
|
||||||
ownerProfile["uid"] = ownerUid;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ownerProfile = organizer;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ownerProfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPopupAttendeesWindow(event) {
|
|
||||||
if (event)
|
|
||||||
preventDefault(event);
|
|
||||||
if (ComponentEditor.attendeesWindow && ComponentEditor.attendeesWindow.open && !ComponentEditor.attendeesWindow.closed)
|
|
||||||
ComponentEditor.attendeesWindow.focus();
|
|
||||||
else
|
|
||||||
ComponentEditor.attendeesWindow = window.open(ApplicationBaseURL + "/editAttendees",
|
|
||||||
sanitizeWindowName(activeCalendar + activeComponent + "Attendees"),
|
|
||||||
"width=900,height=573");
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onSelectClassification(event) {
|
|
||||||
if (event.button == 0 || (isWebKit() && event.button == 1)) {
|
|
||||||
var node = getTarget(event);
|
|
||||||
if (node.tagName != 'A')
|
|
||||||
node = $(node).up("A");
|
|
||||||
popupToolbarMenu(node, "classification-menu");
|
|
||||||
Event.stop(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPopupAttachWindow(event) {
|
|
||||||
if (event)
|
|
||||||
preventDefault(event);
|
|
||||||
|
|
||||||
var attachInput = $("attach");
|
|
||||||
var newAttach = window.prompt(_("Target:"), attachInput.value || "http://");
|
|
||||||
if (newAttach != null) {
|
|
||||||
var documentHref = $("documentHref");
|
|
||||||
var documentLabel = $("documentLabel");
|
|
||||||
if (documentHref.childNodes.length > 0) {
|
|
||||||
documentHref.childNodes[0].nodeValue = newAttach;
|
|
||||||
if (newAttach.length > 0)
|
|
||||||
documentLabel.setStyle({ display: "block" });
|
|
||||||
else
|
|
||||||
documentLabel.setStyle({ display: "none" });
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
documentHref.appendChild(document.createTextNode(newAttach));
|
|
||||||
if (newAttach.length > 0)
|
|
||||||
documentLabel.setStyle({ display: "block" });
|
|
||||||
}
|
|
||||||
attachInput.value = newAttach;
|
|
||||||
}
|
|
||||||
onWindowResize(event);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPopupDocumentWindow(event) {
|
|
||||||
var documentUrl = $("attach");
|
|
||||||
|
|
||||||
preventDefault(event);
|
|
||||||
window.open(documentUrl.value, "SOGo_Document");
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMenuSetClassification(event) {
|
|
||||||
event.cancelBubble = true;
|
|
||||||
|
|
||||||
var classification = this.getAttribute("classification");
|
|
||||||
if (this.parentNode.chosenNode)
|
|
||||||
this.parentNode.chosenNode.removeClassName("_chosen");
|
|
||||||
this.addClassName("_chosen");
|
|
||||||
this.parentNode.chosenNode = this;
|
|
||||||
|
|
||||||
var classificationInput = $("classification");
|
|
||||||
classificationInput.value = classification;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onChangeCalendar(event) {
|
|
||||||
var calendars = $("calendarFoldersList").value.split(",");
|
|
||||||
var form = document.forms["editform"];
|
|
||||||
var urlElems = form.getAttribute("action").split("?");
|
|
||||||
var choice = calendars[this.value];
|
|
||||||
var urlParam = "moveToCalendar=" + choice;
|
|
||||||
if (urlElems.length == 1)
|
|
||||||
urlElems.push(urlParam);
|
|
||||||
else
|
|
||||||
urlElems[2] = urlParam;
|
|
||||||
|
|
||||||
while (urlElems.length > 2)
|
|
||||||
urlElems.pop();
|
|
||||||
|
|
||||||
form.setAttribute("action", urlElems.join("?"));
|
|
||||||
}
|
|
||||||
|
|
||||||
function initializeDocumentHref() {
|
|
||||||
var documentHref = $("documentHref");
|
|
||||||
var documentLabel = $("documentLabel");
|
|
||||||
var documentUrl = $("attach");
|
|
||||||
|
|
||||||
documentHref.on("click", onPopupDocumentWindow);
|
|
||||||
if (documentUrl.value.length > 0) {
|
|
||||||
documentHref.appendChild(document.createTextNode(documentUrl.value));
|
|
||||||
documentLabel.setStyle({ display: "block" });
|
|
||||||
}
|
|
||||||
|
|
||||||
var changeUrlButton = $("changeAttachButton");
|
|
||||||
if (changeUrlButton)
|
|
||||||
changeUrlButton.on("click", onPopupAttachWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
function initializeClassificationMenu() {
|
|
||||||
if ($("classification-menu")) {
|
|
||||||
var classification = $("classification").value.toUpperCase();
|
|
||||||
var classificationMenu = $("classification-menu").childNodesWithTag("ul")[0];
|
|
||||||
var menuEntries = $(classificationMenu).childNodesWithTag("li");
|
|
||||||
var chosenNode;
|
|
||||||
if (classification == "CONFIDENTIAL")
|
|
||||||
chosenNode = menuEntries[1];
|
|
||||||
else if (classification == "PRIVATE")
|
|
||||||
chosenNode = menuEntries[2];
|
|
||||||
else
|
|
||||||
chosenNode = menuEntries[0];
|
|
||||||
classificationMenu.chosenNode = chosenNode;
|
|
||||||
$(chosenNode).addClassName("_chosen");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function findAttendeeWithFieldValue(field, fieldValue) {
|
|
||||||
var foundAttendee = null;
|
|
||||||
|
|
||||||
var attendeesKeys = attendees.keys();
|
|
||||||
for (var i = 0; !foundAttendee && i < attendeesKeys.length; i++) {
|
|
||||||
var attendee = attendees.get(attendeesKeys[i]);
|
|
||||||
if (attendee[field] == fieldValue) {
|
|
||||||
foundAttendee = attendee;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return foundAttendee;
|
|
||||||
}
|
|
||||||
|
|
||||||
function findDelegateAddress() {
|
|
||||||
var delegateAddress = null;
|
|
||||||
|
|
||||||
var ownerAttendee = findAttendeeWithFieldValue("uid", ownerLogin);
|
|
||||||
if (ownerAttendee && ownerAttendee["delegated-to"]) {
|
|
||||||
var delegateAttendee
|
|
||||||
= findAttendeeWithFieldValue("email",
|
|
||||||
ownerAttendee["delegated-to"]);
|
|
||||||
if (delegateAttendee) {
|
|
||||||
if (delegateAttendee["name"]) {
|
|
||||||
delegateAddress = (delegateAttendee["name"]
|
|
||||||
+ " <" + delegateAttendee["email"] + ">");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
delegateAddress = delegateAttendee["email"];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return delegateAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onComponentEditorLoad(event) {
|
|
||||||
initializeDocumentHref();
|
|
||||||
initializeClassificationMenu();
|
|
||||||
var list = $("calendarList");
|
|
||||||
if (list) {
|
|
||||||
list.on("change", onChangeCalendar);
|
|
||||||
list.fire("mousedown");
|
|
||||||
}
|
|
||||||
|
|
||||||
var tmp = $("itemClassificationList");
|
|
||||||
if (tmp) {
|
|
||||||
var menuItems = tmp.childNodesWithTag("li");
|
|
||||||
for (var i = 0; i < menuItems.length; i++)
|
|
||||||
menuItems[i].on("mousedown", onMenuSetClassification);
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = $("replyList");
|
|
||||||
if (tmp) {
|
|
||||||
tmp.on("change", onReplyChange);
|
|
||||||
var isDelegated = (tmp.value == 4);
|
|
||||||
tmp = $("delegatedTo");
|
|
||||||
tmp.addInterface(SOGoAutoCompletionInterface);
|
|
||||||
tmp.uidField = "c_mail";
|
|
||||||
tmp.excludeGroups = true;
|
|
||||||
var delegateEditor = $("delegateEditor");
|
|
||||||
tmp.animationParent = delegateEditor;
|
|
||||||
if (isDelegated) {
|
|
||||||
var delegateAddress = findDelegateAddress();
|
|
||||||
if (delegateAddress) {
|
|
||||||
tmp.value = delegateAddress;
|
|
||||||
}
|
|
||||||
delegateEditor.show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = $("repeatHref");
|
|
||||||
if (tmp)
|
|
||||||
tmp.on("click", onPopupRecurrenceWindow);
|
|
||||||
tmp = $("repeatList");
|
|
||||||
if (tmp)
|
|
||||||
tmp.on("change", onPopupRecurrenceWindow);
|
|
||||||
tmp = $("reminderHref");
|
|
||||||
if (tmp)
|
|
||||||
tmp.on("click", onPopupReminderWindow);
|
|
||||||
tmp = $("reminderList");
|
|
||||||
if (tmp)
|
|
||||||
tmp.on("change", onPopupReminderWindow);
|
|
||||||
tmp = $("summary");
|
|
||||||
if (tmp)
|
|
||||||
tmp.on("keyup", onSummaryChange);
|
|
||||||
|
|
||||||
Event.on(window, "resize", onWindowResize);
|
|
||||||
Event.on(window, "beforeunload", onComponentEditorClose);
|
|
||||||
|
|
||||||
onPopupRecurrenceWindow(null);
|
|
||||||
onPopupReminderWindow(null);
|
|
||||||
onSummaryChange (null);
|
|
||||||
|
|
||||||
var summary = $("summary");
|
|
||||||
if (summary) {
|
|
||||||
summary.focus();
|
|
||||||
summary.selectText(0, summary.value.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = $("okButton");
|
|
||||||
if (tmp)
|
|
||||||
tmp.on ("click", onOkButtonClick);
|
|
||||||
tmp = $("cancelButton");
|
|
||||||
if (tmp)
|
|
||||||
tmp.on ("click", onCancelButtonClick);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onSummaryChange (e) {
|
|
||||||
if ($("summary"))
|
|
||||||
document.title = $("summary").value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onReplyChange(event) {
|
|
||||||
var delegateEditor = $("delegateEditor");
|
|
||||||
if (this.value == 4) {
|
|
||||||
// Delegated
|
|
||||||
delegateEditor.show();
|
|
||||||
$("delegatedTo").focus();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
delegateEditor.hide();
|
|
||||||
}
|
|
||||||
onWindowResize(null);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onComponentEditorClose(event) {
|
|
||||||
if (ComponentEditor.attendeesWindow && ComponentEditor.attendeesWindow.open && !ComponentEditor.attendeesWindow.closed)
|
|
||||||
ComponentEditor.attendeesWindow.close();
|
|
||||||
if (ComponentEditor.recurrenceWindow && ComponentEditor.recurrenceWindow.open && !ComponentEditor.recurrenceWindow.closed)
|
|
||||||
ComponentEditor.recurrenceWindow.close();
|
|
||||||
if (ComponentEditor.reminderWindow && ComponentEditor.reminderWindow.open && !ComponentEditor.reminderWindow.closed)
|
|
||||||
ComponentEditor.reminderWindow.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onWindowResize(event) {
|
|
||||||
var comment = $("commentArea");
|
|
||||||
if (comment) {
|
|
||||||
// Resize comment area of read-write component
|
|
||||||
var document = $("documentLabel");
|
|
||||||
var area = comment.select("textarea").first();
|
|
||||||
var offset = 6;
|
|
||||||
var height;
|
|
||||||
|
|
||||||
height = window.height() - comment.cumulativeOffset().top - offset;
|
|
||||||
|
|
||||||
if (document.visible()) {
|
|
||||||
// Component has an attachment
|
|
||||||
if ($("changeAttachButton"))
|
|
||||||
height -= $("changeAttachButton").getHeight();
|
|
||||||
else
|
|
||||||
height -= $("documentHref").getHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (area)
|
|
||||||
area.setStyle({ height: (height - offset*2) + "px" });
|
|
||||||
|
|
||||||
comment.setStyle({ height: (height - offset) + "px" });
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Resize attendees area of a read-only component
|
|
||||||
$("eventView").style.height = window.height () + "px";
|
|
||||||
var height = window.height() - 120;
|
|
||||||
var tmp = $("generalDiv");
|
|
||||||
if (tmp)
|
|
||||||
height -= tmp.offsetHeight;
|
|
||||||
tmp = $("descriptionDiv");
|
|
||||||
if (tmp)
|
|
||||||
height -= tmp.offsetHeight;
|
|
||||||
|
|
||||||
tmp = $("attendeesDiv");
|
|
||||||
if (tmp) {
|
|
||||||
tmp.style.height = height + "px";
|
|
||||||
$("attendeesMenu").style.height = (height - 20) + "px";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPopupRecurrenceWindow(event) {
|
|
||||||
if (event)
|
|
||||||
preventDefault(event);
|
|
||||||
|
|
||||||
var repeatHref = $("repeatHref");
|
|
||||||
|
|
||||||
var repeatList = $("repeatList");
|
|
||||||
if (repeatList && repeatList.value == 7) {
|
|
||||||
// Custom repeat rule
|
|
||||||
repeatHref.show();
|
|
||||||
if (event) {
|
|
||||||
if (ComponentEditor.recurrenceWindow && ComponentEditor.recurrenceWindow.open && !ComponentEditor.recurrenceWindow.closed)
|
|
||||||
ComponentEditor.recurrenceWindow.focus();
|
|
||||||
else
|
|
||||||
ComponentEditor.recurrenceWindow = window.open(ApplicationBaseURL + "/editRecurrence",
|
|
||||||
sanitizeWindowName(activeCalendar + activeComponent + "Recurrence"),
|
|
||||||
"width=500,height=400");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (repeatHref)
|
|
||||||
repeatHref.hide();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPopupReminderWindow(event) {
|
|
||||||
if (event)
|
|
||||||
preventDefault(event);
|
|
||||||
|
|
||||||
var reminderHref = $("reminderHref");
|
|
||||||
|
|
||||||
var reminderList = $("reminderList");
|
|
||||||
if (reminderList && reminderList.value == 15) {
|
|
||||||
reminderHref.show();
|
|
||||||
if (event) {
|
|
||||||
if (ComponentEditor.reminderWindow && ComponentEditor.reminderWindow.open && !ComponentEditor.reminderWindow.closed)
|
|
||||||
ComponentEditor.reminderWindow.focus();
|
|
||||||
else {
|
|
||||||
var height = (emailAlarmsEnabled ? 235 : 150);
|
|
||||||
ComponentEditor.reminderWindow
|
|
||||||
= window.open(ApplicationBaseURL + "/editReminder",
|
|
||||||
sanitizeWindowName(activeCalendar + activeComponent + "Reminder"),
|
|
||||||
"width=255,height=" + height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (reminderHref)
|
|
||||||
reminderHref.hide();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onOkButtonClick (e) {
|
|
||||||
|
|
||||||
var jsonData = Form.serialize(document.forms['rsvpform'], true);
|
|
||||||
|
|
||||||
var input = $("delegatedTo");
|
|
||||||
if (input && input.readAttribute("uid") != null) {
|
|
||||||
jsonData['delegatedTo'] = input.readAttribute("uid");
|
|
||||||
}
|
|
||||||
|
|
||||||
triggerAjaxRequest(document.forms['rsvpform'].readAttribute("action"),
|
|
||||||
modifyEventCallback,
|
|
||||||
null,
|
|
||||||
Object.toJSON(jsonData),
|
|
||||||
{ "content-type": "application/json"}
|
|
||||||
);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onCancelButtonClick (e) {
|
|
||||||
window.close ();
|
|
||||||
}
|
|
||||||
|
|
||||||
document.on("dom:loaded", onComponentEditorLoad);
|
|
|
@ -1,100 +0,0 @@
|
||||||
DIV#addressBookSelector
|
|
||||||
{ margin: .5em; }
|
|
||||||
|
|
||||||
DIV#addressBookSelector SELECT
|
|
||||||
{ width: 32em; }
|
|
||||||
|
|
||||||
SELECT
|
|
||||||
{ width: 8em; }
|
|
||||||
|
|
||||||
TR
|
|
||||||
{ width: 100% !important;
|
|
||||||
border: 2px solid #0ff; }
|
|
||||||
|
|
||||||
/********** Frame of the current tab **********/
|
|
||||||
|
|
||||||
DIV#editorTabs
|
|
||||||
{ position: absolute;
|
|
||||||
left: 5px;
|
|
||||||
right: 5px;
|
|
||||||
top: 5px;
|
|
||||||
bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV#editorTabs DIV.tab TD.titleCell
|
|
||||||
{ text-align: left;
|
|
||||||
font-weight: bold; }
|
|
||||||
|
|
||||||
DIV#buttons
|
|
||||||
{ color: #535D6D;
|
|
||||||
visibility: visible;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 12px;
|
|
||||||
right: 10px; }
|
|
||||||
|
|
||||||
/********** Contact **********/
|
|
||||||
|
|
||||||
INPUT.textField
|
|
||||||
{ width: 60%; }
|
|
||||||
|
|
||||||
TD#htmlMailFormat
|
|
||||||
{ text-align: left !important; }
|
|
||||||
|
|
||||||
TABLE#emailInfos TD.preferred
|
|
||||||
{ width: 10% !important;
|
|
||||||
overflow: visible;
|
|
||||||
text-align: center; }
|
|
||||||
|
|
||||||
/********** Categories **********/
|
|
||||||
|
|
||||||
#categoryContainer
|
|
||||||
{ max-height: 400px;
|
|
||||||
overflow: auto;
|
|
||||||
padding: 0px;
|
|
||||||
overflow-y: auto; }
|
|
||||||
|
|
||||||
#categoryContainer > DIV
|
|
||||||
{ margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
border: 0px;
|
|
||||||
height: 22px; }
|
|
||||||
|
|
||||||
INPUT.comboBoxField, #emptyCategory
|
|
||||||
{ width: 370px;
|
|
||||||
height: 16px;
|
|
||||||
padding-top: 0px;
|
|
||||||
padding-bottom: 0px;
|
|
||||||
margin-bottom: 0px;
|
|
||||||
margin-top: 0px; }
|
|
||||||
|
|
||||||
/********** Address **********/
|
|
||||||
|
|
||||||
DIV.tab TD.firstColumn INPUT.textField,
|
|
||||||
DIV.tab TD.secondColumn INPUT.textField
|
|
||||||
{ width: 35%; }
|
|
||||||
|
|
||||||
/********** Photos **********/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/********** OTHER **********/
|
|
||||||
|
|
||||||
#birthdayDate
|
|
||||||
{ width: auto;
|
|
||||||
vertical-align: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#birthdayLabel
|
|
||||||
{
|
|
||||||
vertical-align: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#otherInfos table td
|
|
||||||
{ text-align: left;
|
|
||||||
padding-bottom: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#otherInfos textarea
|
|
||||||
{ width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
|
@ -1,306 +0,0 @@
|
||||||
/* -*- Mode: js2-mode; tab-width: 4; c-label-minimum-indentation: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright (C) 2005 SKYRIX Software AG
|
|
||||||
Copyright (C) 2006-2011 Inverse
|
|
||||||
|
|
||||||
This file is part of OpenGroupware.org.
|
|
||||||
|
|
||||||
OGo is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU Lesser General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2, or (at your option) any
|
|
||||||
later version.
|
|
||||||
|
|
||||||
OGo is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
||||||
License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with OGo; see the file COPYING. If not, write to the
|
|
||||||
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|
||||||
02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
var dateRegex = /^(([0-9]{2})?[0-9])?[0-9]-[0-9]?[0-9]-[0-9]?[0-9]$/;
|
|
||||||
|
|
||||||
var displaynameChanged = false;
|
|
||||||
|
|
||||||
var tabIndex = 0;
|
|
||||||
|
|
||||||
function unescapeCallbackParameter(s) {
|
|
||||||
if(!s || s.length == 0)
|
|
||||||
return s;
|
|
||||||
s = s.replace(/'/g, "'");
|
|
||||||
s = s.replace(/"/g, '"');
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
function copyContact(type, email, uid, sn, displayname,
|
|
||||||
givenname, telephonenumber, facsimiletelephonenumber,
|
|
||||||
mobile, postalAddress, homePostalAddress, departmentnumber, l)
|
|
||||||
{
|
|
||||||
// var type = arguments[0];
|
|
||||||
// var email = arguments[1];
|
|
||||||
// var uid = arguments[2];
|
|
||||||
// var sn = arguments[3];
|
|
||||||
// var givenname = arguments[4];
|
|
||||||
// var telephonenumber = arguments[5];
|
|
||||||
// var facsimiletelephonenumber = arguments[6];
|
|
||||||
// var mobile = arguments[7];
|
|
||||||
// var postaladdress = arguments[8];
|
|
||||||
// var homepostaladdress = arguments[9];
|
|
||||||
// var departmentnumber = arguments[10];
|
|
||||||
// var l = arguments[11];
|
|
||||||
var e;
|
|
||||||
e = $('displayname');
|
|
||||||
e.setAttribute('value', unescapeCallbackParameter(displayname));
|
|
||||||
e = $('email');
|
|
||||||
e.setAttribute('value', email);
|
|
||||||
e = $('sn');
|
|
||||||
e.setAttribute('value', unescapeCallbackParameter(sn));
|
|
||||||
e = $('givenname');
|
|
||||||
e.setAttribute('value', unescapeCallbackParameter(givenname));
|
|
||||||
e = $('telephonenumber');
|
|
||||||
e.setAttribute('value', telephonenumber);
|
|
||||||
e = $('facsimiletelephonenumber');
|
|
||||||
e.setAttribute('value', facsimileTelephonenumber);
|
|
||||||
e = $('mobile');
|
|
||||||
e.setAttribute('value', mobile);
|
|
||||||
e = $('postaladdress');
|
|
||||||
e.setAttribute('value', unescapeCallbackParameter(postalAddress));
|
|
||||||
e = $('homepostaladdress');
|
|
||||||
e.setAttribute('value', unescapeCallbackParameter(homePostalAddress));
|
|
||||||
e = $('departmentnumber');
|
|
||||||
e.setAttribute('value', unescapeCallbackParameter(departmentnumber));
|
|
||||||
e = $('l');
|
|
||||||
e.setAttribute('value', unescapeCallbackParameter(l));
|
|
||||||
};
|
|
||||||
|
|
||||||
function validateContactEditor() {
|
|
||||||
var rc = true;
|
|
||||||
|
|
||||||
var e = $('mail');
|
|
||||||
if (e.value.length > 0
|
|
||||||
&& !emailRE.test(e.value)) {
|
|
||||||
alert(_("invalidemailwarn"));
|
|
||||||
rc = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
e = $('mozillasecondemail');
|
|
||||||
if (e.value.length > 0
|
|
||||||
&& !emailRE.test(e.value)) {
|
|
||||||
alert(_("invalidemailwarn"));
|
|
||||||
rc = false;
|
|
||||||
}
|
|
||||||
return rc
|
|
||||||
}
|
|
||||||
|
|
||||||
function initTimeWidget(input) {
|
|
||||||
var firstDay = new Date();
|
|
||||||
firstDay.setFullYear(1900,0,1);
|
|
||||||
var lastDay = new Date();
|
|
||||||
|
|
||||||
jQuery(input).closest('.date').datepicker({autoclose: true,
|
|
||||||
endDate: lastDay,
|
|
||||||
startDate: firstDay,
|
|
||||||
setStartDate: lastDay,
|
|
||||||
startView: 2})
|
|
||||||
}
|
|
||||||
|
|
||||||
function onDisplaynameKeyDown() {
|
|
||||||
var fn = $("displayname");
|
|
||||||
fn.onkeydown = null;
|
|
||||||
displaynameChanged = true;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onDisplaynameNewValue(event) {
|
|
||||||
if (!displaynameChanged) {
|
|
||||||
var sn = $("sn").value.trim();
|
|
||||||
var givenname = $("givenname").value.trim();
|
|
||||||
|
|
||||||
var fullname = givenname;
|
|
||||||
if (fullname && sn)
|
|
||||||
fullname += ' ';
|
|
||||||
fullname += sn;
|
|
||||||
|
|
||||||
$("displayname").value = fullname;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onEditorCancelClick(event) {
|
|
||||||
this.blur();
|
|
||||||
onCloseButtonClick(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onEditorSubmitClick(event) {
|
|
||||||
if (validateContactEditor()) {
|
|
||||||
saveCategories();
|
|
||||||
$('mainForm').submit();
|
|
||||||
}
|
|
||||||
this.blur();
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveCategories() {
|
|
||||||
var container = $("categoryContainer");
|
|
||||||
var catsInput = $("jsonContactCategories");
|
|
||||||
if (container && catsInput) {
|
|
||||||
var newCategories = $([]);
|
|
||||||
var inputs = container.select("INPUT");
|
|
||||||
for (var i = 0; i < inputs.length; i++) {
|
|
||||||
var newValue = inputs[i].value.trim();
|
|
||||||
if (newValue.length > 0 && newValue != _("New category")
|
|
||||||
&& newCategories.indexOf(newValue) == -1) {
|
|
||||||
newCategories.push(newValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var json = Object.toJSON(newCategories);
|
|
||||||
catsInput.value = json;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onDocumentKeydown(event) {
|
|
||||||
var target = Event.element(event);
|
|
||||||
if (target.tagName == "INPUT" || target.tagName == "SELECT") {
|
|
||||||
if (event.keyCode == Event.KEY_RETURN) {
|
|
||||||
var fdisplayname = onEditorSubmitClick.bind($("submitButton"));
|
|
||||||
fdisplayname();
|
|
||||||
Event.stop(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function appendCategoryInput(label) {
|
|
||||||
var container = $("categoryContainer");
|
|
||||||
|
|
||||||
var inputContainer = createElement("div");
|
|
||||||
var textInput = createElement("input", null, "comboBoxField", null,
|
|
||||||
{ type: "text"}, inputContainer);
|
|
||||||
textInput.observe("change", onCategoryInputChange);
|
|
||||||
textInput.observe("focus", onCategoryInputFocus);
|
|
||||||
textInput.value = label;
|
|
||||||
textInput.tabIndex = tabIndex;
|
|
||||||
tabIndex++;
|
|
||||||
var button = createElement("button", null, "comboBoxButton");
|
|
||||||
inputContainer.appendChild(button);
|
|
||||||
button.observe("click", onComboButtonClick);
|
|
||||||
button.textInput = textInput;
|
|
||||||
button.menuName = "categoriesMenu";
|
|
||||||
|
|
||||||
container.appendChild(inputContainer);
|
|
||||||
|
|
||||||
return textInput;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onComboButtonClick(event) {
|
|
||||||
var menu = $(this.menuName);
|
|
||||||
popupMenu(event, this.menuName, this.textInput);
|
|
||||||
var container = $("categoryContainer");
|
|
||||||
var menuTop = (container.cascadeTopOffset()
|
|
||||||
- container.scrollTop
|
|
||||||
+ this.textInput.offsetTop
|
|
||||||
+ this.textInput.clientHeight);
|
|
||||||
var menuLeft = this.textInput.cascadeLeftOffset() + 1;
|
|
||||||
var width = this.textInput.clientWidth;
|
|
||||||
menu.setStyle({ "top": menuTop + "px",
|
|
||||||
"left": menuLeft + "px",
|
|
||||||
"width": width + "px" });
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onCategoryInputChange(event) {
|
|
||||||
var newValue = this.value.trim();
|
|
||||||
if (newValue == "") {
|
|
||||||
var inputContainer = this.parentNode;
|
|
||||||
inputContainer.parentNode.removeChild(inputContainer);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (gCategories.indexOf(newValue) == -1) {
|
|
||||||
gCategories.push(newValue);
|
|
||||||
gCategories.sort(function (a, b)
|
|
||||||
{ return a.toLowerCase() > b.toLowerCase(); } );
|
|
||||||
regenerateCategoriesMenu();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onCategoryInputFocus(event) {
|
|
||||||
this.select();
|
|
||||||
}
|
|
||||||
|
|
||||||
function regenerateCategoriesMenu() {
|
|
||||||
var menu = $("categoriesMenu");
|
|
||||||
if (menu) {
|
|
||||||
while (menu.lastChild) {
|
|
||||||
menu.removeChild(menu.lastChild);
|
|
||||||
}
|
|
||||||
var list = createElement("ul");
|
|
||||||
for (var i = 0; i < gCategories.length; i++) {
|
|
||||||
var label = gCategories[i];
|
|
||||||
var entry = createElement("li");
|
|
||||||
entry.label = label;
|
|
||||||
entry.menuCallback = onCategoryMenuEntryClick;
|
|
||||||
entry.on("mousedown", onMenuClickHandler);
|
|
||||||
entry.appendChild(document.createTextNode(label));
|
|
||||||
list.appendChild(entry);
|
|
||||||
}
|
|
||||||
menu.appendChild(list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onCategoryMenuEntryClick(event) {
|
|
||||||
document.menuTarget.value = this.label;
|
|
||||||
document.menuTarget.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onEmptyCategoryClick(event) {
|
|
||||||
var textInput = appendCategoryInput(_("New category"));
|
|
||||||
window.setTimeout(function() {textInput.focus();},
|
|
||||||
100);
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
function initEditorForm() {
|
|
||||||
var tabsContainer = $("editorTabs");
|
|
||||||
var controller = new SOGoTabsController();
|
|
||||||
controller.attachToTabsContainer(tabsContainer);
|
|
||||||
|
|
||||||
displaynameChanged = ($("displayname").value.length > 0);
|
|
||||||
$("displayname").onkeydown = onDisplaynameKeyDown;
|
|
||||||
$("sn").onkeyup = onDisplaynameNewValue;
|
|
||||||
$("givenname").onkeyup = onDisplaynameNewValue;
|
|
||||||
|
|
||||||
$("cancelButton").observe("click", onEditorCancelClick);
|
|
||||||
var submitButton = $("submitButton");
|
|
||||||
if (submitButton) {
|
|
||||||
submitButton.observe("click", onEditorSubmitClick);
|
|
||||||
}
|
|
||||||
|
|
||||||
Event.observe(document, "keydown", onDocumentKeydown);
|
|
||||||
|
|
||||||
if (typeof(gCategories) != "undefined") {
|
|
||||||
regenerateCategoriesMenu();
|
|
||||||
}
|
|
||||||
var catsInput = $("jsonContactCategories");
|
|
||||||
if (catsInput && catsInput.value.length > 0) {
|
|
||||||
var contactCats = $(catsInput.value.evalJSON(false));
|
|
||||||
for (var i = 0; i < contactCats.length; i++) {
|
|
||||||
appendCategoryInput(contactCats[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var emptyCategory = $("emptyCategory");
|
|
||||||
if (emptyCategory) {
|
|
||||||
emptyCategory.tabIndex = 10000;
|
|
||||||
emptyCategory.observe("click", onEmptyCategoryClick);
|
|
||||||
}
|
|
||||||
|
|
||||||
initTimeWidget($("birthdayDate"));
|
|
||||||
}
|
|
||||||
|
|
||||||
document.observe("dom:loaded", initEditorForm);
|
|
|
@ -1,49 +0,0 @@
|
||||||
DIV.filterPanel
|
|
||||||
{ position: absolute;
|
|
||||||
text-align: center;
|
|
||||||
width: auto;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
padding: 3px 1em 0; }
|
|
||||||
|
|
||||||
SPAN.searchBox
|
|
||||||
{ float: none !important; }
|
|
||||||
|
|
||||||
IMG#progressIndicator
|
|
||||||
{ float: none;
|
|
||||||
position: absolute;
|
|
||||||
right: 1em;
|
|
||||||
margin: 7px 5px; }}
|
|
||||||
|
|
||||||
INPUT[name="search"]
|
|
||||||
{ margin: 0px; }
|
|
||||||
|
|
||||||
INPUT[name="search"].notfound
|
|
||||||
{ color: #f00 !important; }
|
|
||||||
|
|
||||||
|
|
||||||
DIV#folders
|
|
||||||
{ position: absolute;
|
|
||||||
left: 1em;
|
|
||||||
right: 1em;
|
|
||||||
top: 3em;
|
|
||||||
bottom: 3em;
|
|
||||||
background-color: #CCDDEC;
|
|
||||||
padding: .5em;
|
|
||||||
padding-top: 0px;
|
|
||||||
overflow: auto;
|
|
||||||
border-top: 1px solid #909090;
|
|
||||||
border-left: 1px solid #909090;
|
|
||||||
border-bottom: 1px solid #FFFFFF;
|
|
||||||
border-right: 1px solid #FFFFFF; }
|
|
||||||
|
|
||||||
DIV#folders DIV
|
|
||||||
{ width: auto; }
|
|
||||||
|
|
||||||
DIV#buttons
|
|
||||||
{ position: absolute;
|
|
||||||
text-align: center;
|
|
||||||
height: 1.5em;
|
|
||||||
left: 1em;
|
|
||||||
right: 1em;
|
|
||||||
bottom: 1em; }
|
|
|
@ -1,270 +0,0 @@
|
||||||
var d;
|
|
||||||
|
|
||||||
function onSearchFormSubmit(filterPanel) {
|
|
||||||
var searchValue = filterPanel.down('[name="search"]');
|
|
||||||
var encodedValue = encodeURI(searchValue.value);
|
|
||||||
|
|
||||||
if (encodedValue.blank()) {
|
|
||||||
checkAjaxRequestsState();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var url = (UserFolderURL
|
|
||||||
+ "usersSearch?search=" + encodedValue);
|
|
||||||
if (document.userFoldersRequest) {
|
|
||||||
document.userFoldersRequest.aborted = true;
|
|
||||||
document.userFoldersRequest.abort();
|
|
||||||
}
|
|
||||||
if (encodedValue.trim().length > minimumSearchLength) {
|
|
||||||
startAnimation($("pageContent"), filterPanel);
|
|
||||||
document.userFoldersRequest
|
|
||||||
= triggerAjaxRequest(url, usersSearchCallback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function usersSearchCallback(http) {
|
|
||||||
document.userFoldersRequest = null;
|
|
||||||
var div = $("folders");
|
|
||||||
if (http.status == 200) {
|
|
||||||
var response = http.responseText.evalJSON();
|
|
||||||
buildUsersTree(div, response);
|
|
||||||
}
|
|
||||||
else if (http.status == 404)
|
|
||||||
div.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
function addUserLineToTree(tree, parent, line) {
|
|
||||||
// line[0] = uid
|
|
||||||
// line[1] = cn
|
|
||||||
// line[2] = email
|
|
||||||
// line[3] = 1 if it's a group
|
|
||||||
// line[4] = contact info
|
|
||||||
var icon = ResourcesURL + '/busy.gif';
|
|
||||||
|
|
||||||
var email = line[1] + " <" + line[2] + ">";
|
|
||||||
if (line[4] && !line[4].empty())
|
|
||||||
email += ", " + line[4].split("\n").join("; "); // extra contact info
|
|
||||||
var icon_card = 'abcard.png';
|
|
||||||
var datatype = 'user';
|
|
||||||
if (line[3]) {
|
|
||||||
icon_card = 'ablist.png';
|
|
||||||
datatype = 'group';
|
|
||||||
}
|
|
||||||
tree.add(parent, 0, email, 0, '#', line[0], datatype,
|
|
||||||
'', '',
|
|
||||||
ResourcesURL + '/' + icon_card,
|
|
||||||
ResourcesURL + '/' + icon_card);
|
|
||||||
if (window.opener.userFolderType != "user") {
|
|
||||||
tree.add(parent + 1, parent, _("Please wait..."), 0, '#', null,
|
|
||||||
null, '', '', icon, icon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildUsersTree(treeDiv, response) {
|
|
||||||
if (!treeDiv.clean) {
|
|
||||||
var oldD = $("d"); // the folders tree
|
|
||||||
if (oldD) {
|
|
||||||
oldD.remove();
|
|
||||||
delete d;
|
|
||||||
}
|
|
||||||
treeDiv.clean = true;
|
|
||||||
$("addButton").addClassName("disabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
d = new dTree("d");
|
|
||||||
d.config.hideRoot = true;
|
|
||||||
d.icon.root = ResourcesURL + '/tbtv_account_17x17.gif';
|
|
||||||
d.icon.folder = ResourcesURL + '/tbtv_leaf_corner_17x17.png';
|
|
||||||
d.icon.folderOpen = ResourcesURL + '/tbtv_leaf_corner_17x17.png';
|
|
||||||
d.icon.node = ResourcesURL + '/tbtv_leaf_corner_17x17.png';
|
|
||||||
d.icon.line = ResourcesURL + '/tbtv_line_17x22.png';
|
|
||||||
d.icon.join = ResourcesURL + '/tbtv_junction_17x22.png';
|
|
||||||
d.icon.joinBottom = ResourcesURL + '/tbtv_corner_17x22.png';
|
|
||||||
d.icon.plus = ResourcesURL + '/tbtv_plus_17x22.png';
|
|
||||||
d.icon.plusBottom = ResourcesURL + '/tbtv_corner_plus_17x22.png';
|
|
||||||
d.icon.minus = ResourcesURL + '/tbtv_minus_17x22.png';
|
|
||||||
d.icon.minusBottom = ResourcesURL + '/tbtv_corner_minus_17x22.png';
|
|
||||||
d.icon.nlPlus = ResourcesURL + '/tbtv_corner_plus_17x22.png';
|
|
||||||
d.icon.nlMinus = ResourcesURL + '/tbtv_corner_minus_17x22.png';
|
|
||||||
d.icon.empty = ResourcesURL + '/empty.gif';
|
|
||||||
d.preload();
|
|
||||||
d.add(0, -1, '');
|
|
||||||
|
|
||||||
var isUserDialog = (window.opener.userFolderType == "user");
|
|
||||||
var multiplier = ((isUserDialog) ? 1 : 2);
|
|
||||||
|
|
||||||
if (response.length > 0) {
|
|
||||||
for (var i = 0; i < response.length; i++)
|
|
||||||
addUserLineToTree(d, 1 + i * multiplier, response[i]);
|
|
||||||
treeDiv.appendChild(d.domObject ());
|
|
||||||
treeDiv.clean = false;
|
|
||||||
for (var i = 0; i < response.length; i++) {
|
|
||||||
if (!isUserDialog) {
|
|
||||||
var toggle = $("tgd" + (1 + i * 2));
|
|
||||||
toggle.on("click", onUserNodeToggle);
|
|
||||||
}
|
|
||||||
var sd = $("sd" + (1 + i * multiplier));
|
|
||||||
sd.on("click", onTreeItemClick);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$$('[name="search"]').first().addClassName("notfound");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onUserNodeToggle(event) {
|
|
||||||
this.stopObserving("click", onUserNodeToggle);
|
|
||||||
|
|
||||||
var person = this.parentNode.getAttribute("dataname").unescapeHTML();
|
|
||||||
|
|
||||||
var url = (UserFolderURLForUser(person) + "foldersSearch"
|
|
||||||
+ "?type=" + window.opener.userFolderType);
|
|
||||||
var nodeId = this.getAttribute("id").substr(3);
|
|
||||||
triggerAjaxRequest(url, foldersSearchCallback,
|
|
||||||
{ nodeId: nodeId, user: person });
|
|
||||||
}
|
|
||||||
|
|
||||||
function onTreeItemClick(event) {
|
|
||||||
preventDefault(event);
|
|
||||||
|
|
||||||
var topNode = $("d");
|
|
||||||
if (topNode.selectedEntry)
|
|
||||||
topNode.selectedEntry.deselect();
|
|
||||||
this.selectElement();
|
|
||||||
topNode.selectedEntry = this;
|
|
||||||
|
|
||||||
if (window.opener.userFolderType == "user")
|
|
||||||
$("addButton").removeClassName("disabled");
|
|
||||||
else {
|
|
||||||
var dataname = this.parentNode.getAttribute("dataname");
|
|
||||||
if (!dataname)
|
|
||||||
dataname = "";
|
|
||||||
if (dataname.indexOf(":") == -1)
|
|
||||||
$("addButton").addClassName("disabled");
|
|
||||||
else
|
|
||||||
$("addButton").removeClassName("disabled");
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function foldersSearchCallback(http) {
|
|
||||||
if (http.status == 200) {
|
|
||||||
var response = http.responseText;
|
|
||||||
var nodeId = parseInt(http.callbackData["nodeId"]);
|
|
||||||
|
|
||||||
var dd = $("dd" + (nodeId + 2));
|
|
||||||
var indentValue = (dd ? 1 : 0);
|
|
||||||
d.aIndent.push(indentValue);
|
|
||||||
|
|
||||||
var dd = $("dd" + nodeId);
|
|
||||||
var folders = response.evalJSON();
|
|
||||||
if (folders.length) {
|
|
||||||
var user = http.callbackData["user"];
|
|
||||||
|
|
||||||
dd.innerHTML = '';
|
|
||||||
for (var i = 0; i < folders.length-1; i++)
|
|
||||||
dd.appendChild(addFolderBranchToTree(d, user, folders[i], nodeId, i+1, false));
|
|
||||||
dd.appendChild(addFolderBranchToTree(d, user, folders[folders.length-1], nodeId,
|
|
||||||
folders.length, true));
|
|
||||||
//dd.update(str);
|
|
||||||
for (var i = 0; i < folders.length; i++) {
|
|
||||||
var sd = $("sd" + (nodeId + i + 1));
|
|
||||||
sd.on("click", onTreeItemClick);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dd.innerHTML = '';
|
|
||||||
dd.appendChild(addFolderNotFoundNode(d, nodeId, null));
|
|
||||||
var sd = $("sd" + (nodeId + 1));
|
|
||||||
sd.on("click", onTreeItemClick);
|
|
||||||
}
|
|
||||||
|
|
||||||
d.aIndent.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function addFolderBranchToTree(tree, user, folder, nodeId, subId, isLast) {
|
|
||||||
var icon = ResourcesURL + '/';
|
|
||||||
if (folder.type == 'Contact')
|
|
||||||
icon += 'tb-mail-addressbook-flat-16x16.png';
|
|
||||||
else
|
|
||||||
icon += 'calendar-folder-16x16.png';
|
|
||||||
var folderId = user + ":" + folder.name.substr(1);
|
|
||||||
|
|
||||||
// We sanitize the value to avoid XSS issues
|
|
||||||
var name = folder.displayName.escapeHTML();
|
|
||||||
var node = new dTreeNode(subId, nodeId, name, 0, '#', folderId,
|
|
||||||
folder.type + '-folder', '', '', icon, icon);
|
|
||||||
node._ls = isLast;
|
|
||||||
|
|
||||||
var content = tree.node(node, (nodeId + subId), null);
|
|
||||||
content.displayName = folder.displayName;
|
|
||||||
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
function addFolderNotFoundNode(tree, nodeId) {
|
|
||||||
var icon = ResourcesURL + '/dot.png';
|
|
||||||
var node = new dTreeNode(1, nodeId, _("No possible subscription"), 0, '#',
|
|
||||||
null, null, '', '', icon, icon);
|
|
||||||
node._ls = true;
|
|
||||||
return tree.node(node, (nodeId + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
function onConfirmFolderSelection(event) {
|
|
||||||
if (!this.hasClassName("disabled")) {
|
|
||||||
var topNode = $("d");
|
|
||||||
if (topNode && topNode.selectedEntry) {
|
|
||||||
var node = topNode.selectedEntry.parentNode;
|
|
||||||
var folder = node.getAttribute("dataname");
|
|
||||||
var type = node.getAttribute("datatype");
|
|
||||||
var folderName;
|
|
||||||
if (window.opener.userFolderType == "user") {
|
|
||||||
var resource = $(topNode.selectedEntry).down("SPAN.nodeName");
|
|
||||||
var description = (resource.innerHTML
|
|
||||||
.replace("<", "<", "g")
|
|
||||||
.replace(">", ">", "g"));
|
|
||||||
folderName = description.replace(/>,.*$/, ">", "g");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
folderName = node.displayName;
|
|
||||||
}
|
|
||||||
var data = { folderName: folderName, folder: folder, type: type, window: window };
|
|
||||||
if (parent$(accessToSubscribedFolder(folder)))
|
|
||||||
window.alert(_("You have already subscribed to that folder!"));
|
|
||||||
else
|
|
||||||
window.opener.subscribeToFolder(window.opener.userFolderCallback, data);
|
|
||||||
this.blur(); // required by IE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onFolderSearchKeyDown(event) {
|
|
||||||
if (event.keyCode == Event.KEY_BACKSPACE
|
|
||||||
|| IsCharacterKey(event.keyCode)) {
|
|
||||||
$(this).removeClassName("notfound");
|
|
||||||
var div = $("folders");
|
|
||||||
if (!div.clean) {
|
|
||||||
var oldD = $("d"); // the folders tree
|
|
||||||
if (oldD) {
|
|
||||||
oldD.remove();
|
|
||||||
delete d;
|
|
||||||
}
|
|
||||||
div.clean = true;
|
|
||||||
$("addButton").addClassName("disabled");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function initUserFoldersWindow() {
|
|
||||||
var searchValue = $$('[name="search"]').first();
|
|
||||||
searchValue.on("keydown", onFolderSearchKeyDown);
|
|
||||||
|
|
||||||
$("addButton").on("click", onConfirmFolderSelection);
|
|
||||||
$("doneButton").on("click", onCloseButtonClick);
|
|
||||||
|
|
||||||
searchValue.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
document.observe("dom:loaded", initUserFoldersWindow);
|
|
|
@ -1,39 +0,0 @@
|
||||||
DIV.title
|
|
||||||
{ color: #000;
|
|
||||||
vertical-align: bottom;
|
|
||||||
padding-top: 8px;
|
|
||||||
padding-left: 1em;
|
|
||||||
padding: 5px;
|
|
||||||
background-color: #fff;
|
|
||||||
border-bottom: 1px solid #555; }
|
|
||||||
|
|
||||||
DIV.calendarUserRights,
|
|
||||||
DIV.basicUserRights
|
|
||||||
{ margin: 1em;}
|
|
||||||
|
|
||||||
DIV.title SPAN
|
|
||||||
{ float: left;
|
|
||||||
line-height: 14px;
|
|
||||||
text-align: right;
|
|
||||||
width: 120px; }
|
|
||||||
|
|
||||||
DIV.title SPAN.value
|
|
||||||
{ float: none;
|
|
||||||
margin-left: 1em;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: bold; }
|
|
||||||
|
|
||||||
DIV.title LABEL
|
|
||||||
{ display: block;
|
|
||||||
clear: both; }
|
|
||||||
|
|
||||||
DIV.buttons
|
|
||||||
{ text-align: right;
|
|
||||||
margin: 1em; }
|
|
||||||
|
|
||||||
DIV.dialog.none
|
|
||||||
{ position: absolute;
|
|
||||||
top: 0px;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
margin: 10px auto; }
|
|
|
@ -1,59 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
function onUpdateACL(event) {
|
|
||||||
var uid = $('uid').value;
|
|
||||||
if (uid == '<default>' || uid == 'anonymous') {
|
|
||||||
var inputs = $$('#userRightsForm input[type="checkbox"]');
|
|
||||||
var enabled = false;
|
|
||||||
for (var i = 0; i < inputs.length; i++) {
|
|
||||||
if (inputs[i].checked) {
|
|
||||||
enabled = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (enabled) {
|
|
||||||
if (uid == '<default>')
|
|
||||||
showConfirmDialog(_("Warning"),
|
|
||||||
_("Any user with an account on this system will be able to access your address book \"%{0}\". Are you certain you trust them all?").formatted($("folderName").allTextContent()),
|
|
||||||
onUpdateACLConfirm, onUpdateACLCancel,
|
|
||||||
"Give Access", "Keep Private");
|
|
||||||
else
|
|
||||||
showConfirmDialog(_("Warning"),
|
|
||||||
_("Potentially anyone on the Internet will be able to access your address book \"%{0}\", even if they do not have an account on this system. Is this information suitable for the public Internet?").formatted($("folderName").allTextContent()),
|
|
||||||
onUpdateACLConfirm, onUpdateACLCancel,
|
|
||||||
"Give Access", "Keep Private");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return onUpdateACLConfirm(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onUpdateACLConfirm(event) {
|
|
||||||
disposeDialog();
|
|
||||||
|
|
||||||
$('userRightsForm').submit();
|
|
||||||
Event.stop(event);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onUpdateACLCancel(event) {
|
|
||||||
var inputs = $$('#userRightsForm input[type="checkbox"]');
|
|
||||||
for (var i = 0; i < inputs.length; i++)
|
|
||||||
if (inputs[i].checked)
|
|
||||||
inputs[i].checked = false;
|
|
||||||
|
|
||||||
disposeDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onCancelACL(event) {
|
|
||||||
window.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
function initACLButtons() {
|
|
||||||
$("updateButton").observe("click", onUpdateACL);
|
|
||||||
$("cancelButton").observe("click", onCancelACL);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.observe("dom:loaded", initACLButtons);
|
|
|
@ -1,106 +0,0 @@
|
||||||
DIV#pageContent
|
|
||||||
{ padding: 10px;
|
|
||||||
padding-top: 15px; }
|
|
||||||
|
|
||||||
#splitter
|
|
||||||
{ cursor: n-resize;
|
|
||||||
top: 230px;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
height: 5px; }
|
|
||||||
|
|
||||||
LABEL
|
|
||||||
{ margin: 0px;
|
|
||||||
padding: 0px; }
|
|
||||||
|
|
||||||
#pageContent INPUT,
|
|
||||||
#pageContent SELECT
|
|
||||||
{ background-color: #ccddec;
|
|
||||||
padding: 1px;
|
|
||||||
margin: 1px;
|
|
||||||
border-width: 1px; }
|
|
||||||
|
|
||||||
#pageContent INPUT
|
|
||||||
{ padding-left: 2px; }
|
|
||||||
|
|
||||||
DIV.container
|
|
||||||
{ margin-bottom: 14px; }
|
|
||||||
|
|
||||||
DIV#filterRulesContainer,
|
|
||||||
DIV#filterActionsContainer
|
|
||||||
{ position: absolute;
|
|
||||||
margin: 0px;
|
|
||||||
border: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
left: 10px;
|
|
||||||
right: 10px; }
|
|
||||||
|
|
||||||
DIV#filterRulesContainer
|
|
||||||
{ top: 128px;
|
|
||||||
height: 102px; }
|
|
||||||
|
|
||||||
DIV#filterActionsContainer
|
|
||||||
{ top: 235px;
|
|
||||||
bottom: 0px; }
|
|
||||||
|
|
||||||
DIV#filterRules, DIV#filterActions
|
|
||||||
{ position: absolute;
|
|
||||||
cursor: default;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
bottom: 21px;
|
|
||||||
border-top: 1px solid #909090;
|
|
||||||
border-left: 1px solid #909090;
|
|
||||||
border-bottom: 1px solid #ffffff;
|
|
||||||
border-right: 1px solid #ffffff;
|
|
||||||
background: #ccddec;
|
|
||||||
overflow: hidden;
|
|
||||||
overflow-y: auto; }
|
|
||||||
|
|
||||||
DIV#filterRules
|
|
||||||
{ top: 0px; }
|
|
||||||
|
|
||||||
DIV#filterActions
|
|
||||||
{ top: 20px; }
|
|
||||||
|
|
||||||
DIV.bottomToolbar
|
|
||||||
{ position: absolute;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
bottom: 0px; }
|
|
||||||
|
|
||||||
DIV.rule,
|
|
||||||
DIV.action
|
|
||||||
{ overflow: hidden;
|
|
||||||
padding-left: 2px;
|
|
||||||
padding-right: 2px;
|
|
||||||
width: 100%;
|
|
||||||
border-bottom: 1px solid #9b9b9b; }
|
|
||||||
|
|
||||||
DIV.rule._selected,
|
|
||||||
DIV.action._selected
|
|
||||||
{ background-color: #9abcd8;
|
|
||||||
color: #fff; }
|
|
||||||
|
|
||||||
SPAN.fieldContainer
|
|
||||||
{ width: 100px; }
|
|
||||||
|
|
||||||
SPAN.operatorContainer
|
|
||||||
{ width: 300px; }
|
|
||||||
|
|
||||||
SPAN.valueContainer INPUT
|
|
||||||
{ width: 160px; }
|
|
||||||
|
|
||||||
SPAN.redirectArgument INPUT
|
|
||||||
{ width: 160px; }
|
|
||||||
|
|
||||||
SPAN.fileintoArgument SELECT
|
|
||||||
{ max-width: 250px; }
|
|
||||||
|
|
||||||
SPAN.rejectArgument TEXTAREA
|
|
||||||
{ height: 54px;
|
|
||||||
width: 90%;
|
|
||||||
margin-left: 5%;
|
|
||||||
padding-right: -50px; }
|
|
|
@ -1,802 +0,0 @@
|
||||||
/* -*- Mode: java; tab-width: 2; c-label-minimum-indentation: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
/* Cyrus: comparator-i;ascii-numeric fileinto reject vacation imapflags
|
|
||||||
notify envelope relational regex subaddress copy */
|
|
||||||
var sieveCapabilities = [];
|
|
||||||
|
|
||||||
var filter;
|
|
||||||
|
|
||||||
var selectedRuleDiv = null;
|
|
||||||
var selectedActionDiv = null;
|
|
||||||
|
|
||||||
var fieldLabels;
|
|
||||||
var methodLabels;
|
|
||||||
var operatorLabels;
|
|
||||||
var operatorRequirements;
|
|
||||||
var methodRequirements;
|
|
||||||
var flagLabels;
|
|
||||||
|
|
||||||
var mailboxes = [];
|
|
||||||
|
|
||||||
function onLoadHandler() {
|
|
||||||
setupConstants();
|
|
||||||
setupEventHandlers();
|
|
||||||
|
|
||||||
if (window.opener)
|
|
||||||
sieveCapabilities = window.opener.getSieveCapabilitiesFromEditor();
|
|
||||||
if (!window.opener || filterId == "new") {
|
|
||||||
setupNewFilterData();
|
|
||||||
} else {
|
|
||||||
filter = window.opener.getFilterFromEditor(filterId).evalJSON();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!window.opener || window.opener.userMailboxes) {
|
|
||||||
setupFilterViews();
|
|
||||||
} else {
|
|
||||||
loadMailboxes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadMailboxes() {
|
|
||||||
var url = ApplicationBaseURL + "/Mail/0/mailboxes";
|
|
||||||
triggerAjaxRequest(url, onLoadMailboxesCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onLoadMailboxesCallback(http) {
|
|
||||||
if (http.readyState == 4) {
|
|
||||||
// log("http.status: " + http.status);
|
|
||||||
if (http.status == 200) {
|
|
||||||
checkAjaxRequestsState();
|
|
||||||
if (http.responseText.length > 0) {
|
|
||||||
var jsonResponse = http.responseText.evalJSON(true);
|
|
||||||
window.opener.setupMailboxesFromJSON(jsonResponse);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setupFilterViews();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupConstants() {
|
|
||||||
fieldLabels = { "subject": _("Subject"),
|
|
||||||
"from": _("From"),
|
|
||||||
"to": _("To"),
|
|
||||||
"cc": _("Cc"),
|
|
||||||
"to_or_cc": _("To or Cc"),
|
|
||||||
"size": _("Size (Kb)"),
|
|
||||||
"header": _("Header"),
|
|
||||||
"body": _("Body") };
|
|
||||||
methodLabels = { "addflag": _("Flag the message with:"),
|
|
||||||
"discard": _("Discard the message"),
|
|
||||||
"fileinto": _("File the message in:"),
|
|
||||||
"keep": _("Keep the message"),
|
|
||||||
"redirect": _("Forward the message to:"),
|
|
||||||
"reject": _("Send a reject message:"),
|
|
||||||
"vacation": _("Send a vacation message"),
|
|
||||||
"stop": _("Stop processing filter rules") };
|
|
||||||
|
|
||||||
operatorLabels = { "under": _("is under"),
|
|
||||||
"over": _("is over"),
|
|
||||||
"is": _("is"),
|
|
||||||
"is_not": _("is not"),
|
|
||||||
"contains": _("contains"),
|
|
||||||
"contains_not": _("does not contain"),
|
|
||||||
"matches": _("matches"),
|
|
||||||
"matches_not": _("does not match"),
|
|
||||||
"regex": _("matches regex"),
|
|
||||||
"regex_not": _("does not match regex") };
|
|
||||||
|
|
||||||
flagLabels = { "seen": _("Seen"),
|
|
||||||
"deleted": _("Deleted"),
|
|
||||||
"answered": _("Answered"),
|
|
||||||
"flagged": _("Flagged"),
|
|
||||||
"junk": _("Junk"),
|
|
||||||
"not_junk": _("Not Junk") };
|
|
||||||
|
|
||||||
for (var name in mailTags) {
|
|
||||||
flagLabels[name] = _( mailTags[name][0] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupEventHandlers() {
|
|
||||||
var filterName = $($("mainForm").filterName);
|
|
||||||
if (filterName) {
|
|
||||||
filterName.on('change', onFilterNameChange);
|
|
||||||
}
|
|
||||||
var matchTypeSelect = $("matchType");
|
|
||||||
if (matchTypeSelect) {
|
|
||||||
matchTypeSelect.on('change', onMatchTypeChange);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filter rules
|
|
||||||
$("filterRules").on('click', onFilterRulesDivClick);
|
|
||||||
var ruleAdd = $("ruleAdd");
|
|
||||||
if (ruleAdd) {
|
|
||||||
ruleAdd.on('click', onRuleAddClick);
|
|
||||||
}
|
|
||||||
var ruleDelete = $("ruleDelete");
|
|
||||||
if (ruleDelete) {
|
|
||||||
ruleDelete.on('click', onRuleDeleteClick);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filter actions
|
|
||||||
$('filterActions').on('click', onFilterActionsDivClick);
|
|
||||||
var actionAdd = $("actionAdd");
|
|
||||||
if (actionAdd) {
|
|
||||||
actionAdd.on('click', onActionAddClick);
|
|
||||||
}
|
|
||||||
var actionDelete = $("actionDelete");
|
|
||||||
if (actionDelete) {
|
|
||||||
actionDelete.on('click', onActionDeleteClick);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onFilterNameChange(event) {
|
|
||||||
filter.name = this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMatchTypeChange() {
|
|
||||||
var matchType = this.value;
|
|
||||||
filter.match = matchType;
|
|
||||||
var container = $("filterRulesContainer");
|
|
||||||
var otherContainer = $("filterActionsContainer");
|
|
||||||
var otherContainerTop;
|
|
||||||
if (matchType == "allmessages") {
|
|
||||||
container.hide();
|
|
||||||
otherContainerTop = 130;
|
|
||||||
} else {
|
|
||||||
container.show();
|
|
||||||
otherContainerTop = 240;
|
|
||||||
}
|
|
||||||
otherContainer.setStyle({ top: otherContainerTop + "px" });
|
|
||||||
}
|
|
||||||
|
|
||||||
function onFilterRulesDivClick(event) {
|
|
||||||
setSelectedRuleDiv(null);
|
|
||||||
Event.stop(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onFilterActionsDivClick(event) {
|
|
||||||
setSelectedActionDiv(null);
|
|
||||||
Event.stop(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createFilterRule() {
|
|
||||||
return { field: "subject", operator: "contains", value: "" };
|
|
||||||
}
|
|
||||||
|
|
||||||
function createFilterAction() {
|
|
||||||
return { method: "fileinto", argument: "INBOX" };
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupNewFilterData() {
|
|
||||||
var newFilterTemplate = $({ name: _("Untitled Filter"),
|
|
||||||
match: "any",
|
|
||||||
active: true });
|
|
||||||
newFilterTemplate.rules = $([ createFilterRule() ]);
|
|
||||||
newFilterTemplate.actions = $([ createFilterAction() ]);
|
|
||||||
|
|
||||||
filter = newFilterTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupFilterViews() {
|
|
||||||
var filterName = $("mainForm").filterName;
|
|
||||||
if (filterName) {
|
|
||||||
filterName.value = filter.name;
|
|
||||||
if (filterId == "new") {
|
|
||||||
filterName.focus();
|
|
||||||
$(filterName).selectText(0, filterName.value.length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var matchTypeSelect = $("matchType");
|
|
||||||
if (matchTypeSelect) {
|
|
||||||
matchTypeSelect.value = filter.match;
|
|
||||||
}
|
|
||||||
if (filter.match != "allmessages") {
|
|
||||||
var filterRules = $("filterRules");
|
|
||||||
if (filterRules && filter.rules) {
|
|
||||||
for (var i = 0; i < filter.rules.length; i++) {
|
|
||||||
appendRule(filterRules, filter.rules[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onMatchTypeChange.apply(matchTypeSelect);
|
|
||||||
|
|
||||||
var filterActions = $("filterActions");
|
|
||||||
if (filterActions && filter.actions) {
|
|
||||||
for (var i = 0; i < filter.actions.length; i++) {
|
|
||||||
appendAction(filterActions, filter.actions[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function appendRule(container, rule) {
|
|
||||||
var ruleDiv = createElement("div", null, "rule",
|
|
||||||
{ rule: rule }, null,
|
|
||||||
container);
|
|
||||||
ruleDiv.on('click', onRuleDivClick);
|
|
||||||
ensureRuleRepresentation(ruleDiv);
|
|
||||||
|
|
||||||
return ruleDiv;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onRuleDivClick(event) {
|
|
||||||
setSelectedRuleDiv(this);
|
|
||||||
Event.stop(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setSelectedRuleDiv(newDiv) {
|
|
||||||
if (selectedRuleDiv) {
|
|
||||||
selectedRuleDiv.removeClassName("_selected");
|
|
||||||
}
|
|
||||||
selectedRuleDiv = newDiv;
|
|
||||||
if (selectedRuleDiv) {
|
|
||||||
selectedRuleDiv.addClassName("_selected");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureRuleRepresentation(container) {
|
|
||||||
ensureFieldRepresentation(container);
|
|
||||||
ensureOperatorRepresentation(container);
|
|
||||||
ensureValueRepresentation(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureFieldRepresentation(container) {
|
|
||||||
var fieldSpans = container.select("SPAN.fieldContainer");
|
|
||||||
var fieldSpan;
|
|
||||||
if (fieldSpans.length)
|
|
||||||
fieldSpan = fieldSpans[0];
|
|
||||||
else {
|
|
||||||
while (container.firstChild) {
|
|
||||||
container.removeChild(container.firstChild);
|
|
||||||
}
|
|
||||||
fieldSpan = createElement("span", null, "fieldContainer",
|
|
||||||
null, null, container);
|
|
||||||
}
|
|
||||||
ensureFieldSelectRepresentation(container, fieldSpan);
|
|
||||||
ensureFieldCustomHeaderRepresentation(container, fieldSpan);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureFieldSelectRepresentation(container, fieldSpan) {
|
|
||||||
var fields = [ "subject", "from", "to", "cc", "to_or_cc", "size", "header" ];
|
|
||||||
if (sieveCapabilities.indexOf("body") > -1) {
|
|
||||||
fields.push("body");
|
|
||||||
}
|
|
||||||
var selects = fieldSpan.select("SELECT");
|
|
||||||
var select;
|
|
||||||
if (selects.length)
|
|
||||||
select = selects[0];
|
|
||||||
else {
|
|
||||||
select = createElement("select");
|
|
||||||
select.rule = container.rule;
|
|
||||||
select.on('change', onFieldSelectChange);
|
|
||||||
for (var i = 0; i < fields.length; i++) {
|
|
||||||
var field = fields[i];
|
|
||||||
var fieldOption = createElement("option", null, null,
|
|
||||||
{ value: field }, null, select);
|
|
||||||
fieldOption.appendChild(document.createTextNode(fieldLabels[field]));
|
|
||||||
}
|
|
||||||
fieldSpan.appendChild(select);
|
|
||||||
}
|
|
||||||
select.value = container.rule.field;
|
|
||||||
container.rule.field = select.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onFieldSelectChange(event) {
|
|
||||||
this.rule.field = this.value;
|
|
||||||
var fieldSpan = this.parentNode;
|
|
||||||
var container = fieldSpan.parentNode;
|
|
||||||
ensureFieldCustomHeaderRepresentation(container, fieldSpan);
|
|
||||||
ensureOperatorRepresentation(container);
|
|
||||||
ensureValueRepresentation(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureFieldCustomHeaderRepresentation(container, fieldSpan) {
|
|
||||||
var headerInputs = fieldSpan.select("INPUT");
|
|
||||||
var headerInput = null;
|
|
||||||
if (headerInputs.length) {
|
|
||||||
headerInput = headerInputs[0];
|
|
||||||
}
|
|
||||||
if (container.rule.field == "header") {
|
|
||||||
if (!headerInput) {
|
|
||||||
headerInput = createElement("input", null, null,
|
|
||||||
{ type: "text" }, null, fieldSpan);
|
|
||||||
headerInput.rule = container.rule;
|
|
||||||
if (!container.rule.custom_header)
|
|
||||||
container.rule.custom_header = "";
|
|
||||||
headerInput.value = container.rule.custom_header;
|
|
||||||
headerInput.on('change', onFieldCustomHeaderChange);
|
|
||||||
headerInput.focus();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (headerInput) {
|
|
||||||
if (container.rule.custom_header)
|
|
||||||
container.rule.custom_header = null;
|
|
||||||
fieldSpan.removeChild(headerInput);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onFieldCustomHeaderChange(event) {
|
|
||||||
this.rule.custom_header = this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureOperatorRepresentation(container) {
|
|
||||||
var operatorSpans = container.select("SPAN.operatorContainer");
|
|
||||||
var operatorSpan;
|
|
||||||
if (operatorSpans.length)
|
|
||||||
operatorSpan = operatorSpans[0];
|
|
||||||
else
|
|
||||||
operatorSpan = createElement("span", null, "operatorContainer",
|
|
||||||
null, null, container);
|
|
||||||
ensureOperatorSelectRepresentation(container, operatorSpan);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureOperatorSelectRepresentation(container, operatorSpan) {
|
|
||||||
var operators = determineOperators(container.rule.field);
|
|
||||||
|
|
||||||
var ruleField = container.rule.field;
|
|
||||||
var selects = operatorSpan.select("SELECT");
|
|
||||||
var select = null;
|
|
||||||
if (selects.length) {
|
|
||||||
select = selects[0];
|
|
||||||
if ((ruleField == "size" && !select.sizeOperator)
|
|
||||||
|| (ruleField != "size" && select.sizeOperator)) {
|
|
||||||
operatorSpan.removeChild(select);
|
|
||||||
select = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!select) {
|
|
||||||
select = createElement("select");
|
|
||||||
select.rule = container.rule;
|
|
||||||
select.sizeOperator = (ruleField == "size");
|
|
||||||
select.on('change', onOperatorSelectChange);
|
|
||||||
for (var i = 0; i < operators.length; i++) {
|
|
||||||
var operator = operators[i];
|
|
||||||
var operatorOption = createElement("option", null, null,
|
|
||||||
{ value: operator }, null,
|
|
||||||
select);
|
|
||||||
operatorOption.appendChild(document.createTextNode(operatorLabels[operator]));
|
|
||||||
}
|
|
||||||
operatorSpan.appendChild(select);
|
|
||||||
}
|
|
||||||
if (container.rule.operator
|
|
||||||
&& operators.indexOf(container.rule.operator) == -1) {
|
|
||||||
container.rule.operator = operators[0];
|
|
||||||
}
|
|
||||||
select.value = container.rule.operator;
|
|
||||||
container.rule.operator = select.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onOperatorSelectChange(event) {
|
|
||||||
this.rule.operator = this.value;
|
|
||||||
var valueSpans = this.parentNode.parentNode.select("SPAN.valueContainer");
|
|
||||||
if (valueSpans.length) {
|
|
||||||
var valueInputs = valueSpans[0].select("INPUT");
|
|
||||||
if (valueInputs.length) {
|
|
||||||
valueInputs[0].focus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function determineOperators(field) {
|
|
||||||
var operators;
|
|
||||||
if (field == "size") {
|
|
||||||
operators = [ "under", "over" ];
|
|
||||||
} else {
|
|
||||||
var baseOperators = [ "is", "contains", "matches" ];
|
|
||||||
if (sieveCapabilities.indexOf("regex") > -1) {
|
|
||||||
baseOperators.push("regex");
|
|
||||||
}
|
|
||||||
operators = [];
|
|
||||||
for (var i = 0; i < baseOperators.length; i++) {
|
|
||||||
operators.push(baseOperators[i]);
|
|
||||||
operators.push(baseOperators[i] + "_not");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return operators;
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureValueRepresentation(container) {
|
|
||||||
var valueSpans = container.select("SPAN.valueContainer");
|
|
||||||
var valueSpan;
|
|
||||||
if (valueSpans.length)
|
|
||||||
valueSpan = valueSpans[0];
|
|
||||||
else
|
|
||||||
valueSpan = createElement("span", null, "valueContainer",
|
|
||||||
null, null, container);
|
|
||||||
ensureValueInputRepresentation(container, valueSpan);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureValueInputRepresentation(container, valueSpan) {
|
|
||||||
var inputs = valueSpan.select("INPUT");
|
|
||||||
var input;
|
|
||||||
if (inputs.length) {
|
|
||||||
input = inputs[0];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
input = createElement("input", null, "textField");
|
|
||||||
input.rule = container.rule;
|
|
||||||
input.on('change', onValueInputChange);
|
|
||||||
valueSpan.appendChild(input);
|
|
||||||
}
|
|
||||||
input.value = container.rule.value;
|
|
||||||
ensureFieldValidity(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureFieldValidity(input) {
|
|
||||||
var valid = ensureFieldIsNotEmpty(input);
|
|
||||||
if (valid && input.rule.field == "size") {
|
|
||||||
valid = ensureFieldIsNumerical(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
return valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onValueInputChange(event) {
|
|
||||||
if (ensureFieldValidity(this))
|
|
||||||
this.rule.value = this.value;
|
|
||||||
else
|
|
||||||
this.rule.value = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureFieldIsNumerical(input) {
|
|
||||||
var valid = !isNaN(input.value);
|
|
||||||
if (valid) {
|
|
||||||
input.removeClassName("_invalid");
|
|
||||||
} else {
|
|
||||||
input.addClassName("_invalid");
|
|
||||||
}
|
|
||||||
|
|
||||||
return valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureFieldIsNotEmpty(input) {
|
|
||||||
var valid = !input.value.blank();
|
|
||||||
if (valid) {
|
|
||||||
input.removeClassName("_invalid");
|
|
||||||
} else {
|
|
||||||
input.addClassName("_invalid");
|
|
||||||
}
|
|
||||||
|
|
||||||
return valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
function appendAction(container, action) {
|
|
||||||
var actionDiv = createElement("div", null, "action",
|
|
||||||
{ action: action }, null,
|
|
||||||
container);
|
|
||||||
actionDiv.on('click', onActionDivClick);
|
|
||||||
ensureActionRepresentation(actionDiv);
|
|
||||||
|
|
||||||
return actionDiv;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onActionDivClick(event) {
|
|
||||||
setSelectedActionDiv(this);
|
|
||||||
Event.stop(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setSelectedActionDiv(newSpan) {
|
|
||||||
if (selectedActionDiv) {
|
|
||||||
selectedActionDiv.removeClassName("_selected");
|
|
||||||
}
|
|
||||||
selectedActionDiv = newSpan;
|
|
||||||
if (selectedActionDiv) {
|
|
||||||
selectedActionDiv.addClassName("_selected");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureActionRepresentation(container) {
|
|
||||||
ensureMethodRepresentation(container);
|
|
||||||
ensureArgumentRepresentation(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureMethodRepresentation(container) {
|
|
||||||
var methodSpans = container.select("SPAN.methodContainer");
|
|
||||||
var methodSpan;
|
|
||||||
if (methodSpans.length)
|
|
||||||
methodSpan = methodSpans[0];
|
|
||||||
else {
|
|
||||||
while (container.firstChild) {
|
|
||||||
container.removeChild(container.firstChild);
|
|
||||||
}
|
|
||||||
methodSpan = createElement("span", null, "methodContainer",
|
|
||||||
null, null, container);
|
|
||||||
}
|
|
||||||
ensureMethodSelectRepresentation(container, methodSpan);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureMethodSelectRepresentation(container, methodSpan) {
|
|
||||||
var methods = [ "redirect", "discard", "keep" ];
|
|
||||||
if (sieveCapabilities.indexOf("reject") > -1) {
|
|
||||||
methods.push("reject");
|
|
||||||
}
|
|
||||||
if (sieveCapabilities.indexOf("fileinto") > -1) {
|
|
||||||
methods.push("fileinto");
|
|
||||||
}
|
|
||||||
if (sieveCapabilities.indexOf("imapflags") > -1 || sieveCapabilities.indexOf("imap4flags") > -1) {
|
|
||||||
methods.push("addflag");
|
|
||||||
}
|
|
||||||
methods.push("stop");
|
|
||||||
/* TODO: those are currently unimplemented */
|
|
||||||
// if (sieveCapabilities.indexOf("notify") > -1) {
|
|
||||||
// methods.push("notify");
|
|
||||||
// }
|
|
||||||
// if (sieveCapabilities.indexOf("vacation") > -1) {
|
|
||||||
// methods.push("vacation");
|
|
||||||
// }
|
|
||||||
|
|
||||||
var selects = methodSpan.select("SELECT");
|
|
||||||
var select;
|
|
||||||
if (selects.length)
|
|
||||||
select = selects[0];
|
|
||||||
else {
|
|
||||||
select = createElement("select");
|
|
||||||
select.action = container.action;
|
|
||||||
select.on('change', onMethodSelectChange);
|
|
||||||
for (var i = 0; i < methods.length; i++) {
|
|
||||||
var method = methods[i];
|
|
||||||
var methodOption = createElement("option", null, null,
|
|
||||||
{ value: method }, null, select);
|
|
||||||
methodOption.appendChild(document.createTextNode(methodLabels[method]));
|
|
||||||
}
|
|
||||||
methodSpan.appendChild(select);
|
|
||||||
}
|
|
||||||
select.value = container.action.method;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMethodSelectChange(event) {
|
|
||||||
this.action.method = this.value;
|
|
||||||
var methodSpan = this.parentNode;
|
|
||||||
var container = methodSpan.parentNode;
|
|
||||||
ensureArgumentRepresentation(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureArgumentRepresentation(container) {
|
|
||||||
var argumentWidgetMethods
|
|
||||||
= { "addflag": ensureFlagArgRepresentation,
|
|
||||||
"fileinto": ensureMailboxArgRepresentation,
|
|
||||||
"redirect": ensureRedirectArgRepresentation,
|
|
||||||
"reject": ensureRejectArgRepresentation,
|
|
||||||
"vacation": ensureVacationArgRepresentation };
|
|
||||||
|
|
||||||
var widgetMethod = argumentWidgetMethods[container.action.method];
|
|
||||||
var spanClass = container.action.method + "Argument";
|
|
||||||
|
|
||||||
var argumentSpans = container.select("SPAN.argumentContainer");
|
|
||||||
var argumentSpan;
|
|
||||||
if (argumentSpans.length) {
|
|
||||||
argumentSpan = argumentSpans[0];
|
|
||||||
if (argumentSpan
|
|
||||||
&& (!widgetMethod || !argumentSpan.hasClassName(spanClass))) {
|
|
||||||
container.removeChild(argumentSpan);
|
|
||||||
container.action.argument = null;
|
|
||||||
argumentSpan = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
argumentSpan = null;
|
|
||||||
|
|
||||||
if (!argumentSpan && widgetMethod) {
|
|
||||||
argumentSpan = createElement("span", null,
|
|
||||||
["argumentContainer", spanClass],
|
|
||||||
null, null, container);
|
|
||||||
widgetMethod(container, argumentSpan);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureFlagArgRepresentation(container, argumentSpan) {
|
|
||||||
var selects = argumentSpan.select("SELECT");
|
|
||||||
var select;
|
|
||||||
if (selects.length)
|
|
||||||
select = selects[0];
|
|
||||||
else {
|
|
||||||
select = createElement("select");
|
|
||||||
select.action = container.action;
|
|
||||||
select.on('change', onFlagArgumentSelectChange);
|
|
||||||
for (var flag in flagLabels) {
|
|
||||||
if (typeof flag != 'undefined') {
|
|
||||||
var flagOption = createElement("option", null, null,
|
|
||||||
{ value: flag }, null, select);
|
|
||||||
var label = flagLabels[flag];
|
|
||||||
flagOption.appendChild(document.createTextNode(label));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
argumentSpan.appendChild(select);
|
|
||||||
}
|
|
||||||
/* 1) initialize the value if null
|
|
||||||
2) set the SELECT to the corresponding value
|
|
||||||
3) if value was not null in 1, we must ensure the SELECT contains it */
|
|
||||||
if (!container.action.argument)
|
|
||||||
container.action.argument = "seen";
|
|
||||||
select.value = container.action.argument;
|
|
||||||
container.action.argument = select.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onFlagArgumentSelectChange(event) {
|
|
||||||
this.action.argument = this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureMailboxArgRepresentation(container, argumentSpan) {
|
|
||||||
var selects = argumentSpan.select("SELECT");
|
|
||||||
var select;
|
|
||||||
if (selects.length)
|
|
||||||
select = selects[0];
|
|
||||||
else {
|
|
||||||
select = createElement("select");
|
|
||||||
select.action = container.action;
|
|
||||||
if (!container.action.argument)
|
|
||||||
container.action.argument = "INBOX";
|
|
||||||
select.on('change', onMailboxArgumentSelectChange);
|
|
||||||
var mailboxes = (window.opener
|
|
||||||
? window.opener.userMailboxes
|
|
||||||
: {'displayName': 'INBOX', 'path': 'INBOX' });
|
|
||||||
for (var i = 0; i < mailboxes.length; i++) {
|
|
||||||
var mailbox = mailboxes[i];
|
|
||||||
var folderValue;
|
|
||||||
((sieveFolderEncoding == "UTF-8") ? folderValue = mailbox.displayName
|
|
||||||
: folderValue = mailbox.path);
|
|
||||||
|
|
||||||
var mboxOption = createElement("option", null, null,
|
|
||||||
{ value: folderValue }, null, select);
|
|
||||||
mboxOption.appendChild(document.createTextNode(mailbox.displayName));
|
|
||||||
}
|
|
||||||
argumentSpan.appendChild(select);
|
|
||||||
}
|
|
||||||
select.value = container.action.argument;
|
|
||||||
container.action.argument = select.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMailboxArgumentSelectChange(event) {
|
|
||||||
this.action.argument = this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureRedirectArgRepresentation(container, argumentSpan) {
|
|
||||||
var emailInputs = argumentSpan.select("INPUT");
|
|
||||||
var emailInput = null;
|
|
||||||
if (emailInputs.length) {
|
|
||||||
emailInput = emailInputs[0];
|
|
||||||
}
|
|
||||||
if (!emailInput) {
|
|
||||||
emailInput = createElement("input", null, "textField",
|
|
||||||
{ type: "text" }, null, argumentSpan);
|
|
||||||
emailInput.action = container.action;
|
|
||||||
if (!container.action.argument)
|
|
||||||
container.action.argument = "";
|
|
||||||
emailInput.on('change', onEmailArgumentChange);
|
|
||||||
emailInput.focus();
|
|
||||||
}
|
|
||||||
emailInput.value = container.action.argument;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onEmailArgumentChange(event) {
|
|
||||||
this.action.argument = this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureRejectArgRepresentation(container, argumentSpan) {
|
|
||||||
var msgAreas = argumentSpan.select("TEXTAREA");
|
|
||||||
var msgArea = null;
|
|
||||||
if (msgAreas.length) {
|
|
||||||
msgArea = msgAreas[0];
|
|
||||||
}
|
|
||||||
if (!msgArea) {
|
|
||||||
msgArea = createElement("textarea", null, null,
|
|
||||||
{ action: container.action }, null,
|
|
||||||
argumentSpan);
|
|
||||||
if (!container.action.argument)
|
|
||||||
container.action.argument = "";
|
|
||||||
msgArea.on('change', onMsgArgumentChange);
|
|
||||||
msgArea.focus();
|
|
||||||
}
|
|
||||||
msgArea.value = container.action.argument;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMsgArgumentChange(event) {
|
|
||||||
this.action.argument = this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureVacationArgRepresentation(container, argumentSpan) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function onRuleAddClick(event) {
|
|
||||||
var filterRules = $("filterRules");
|
|
||||||
if (filterRules) {
|
|
||||||
var newRule = createFilterRule();
|
|
||||||
if (!filter.rules)
|
|
||||||
filter.rules = [];
|
|
||||||
filter.rules.push(newRule);
|
|
||||||
var newRuleDiv = appendRule(filterRules, newRule);
|
|
||||||
setSelectedRuleDiv(newRuleDiv);
|
|
||||||
filterRules.scrollTop = newRuleDiv.offsetTop;
|
|
||||||
}
|
|
||||||
Event.stop(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onRuleDeleteClick(event) {
|
|
||||||
if (selectedRuleDiv) {
|
|
||||||
var ruleIndex = filter.rules.indexOf(selectedRuleDiv.rule);
|
|
||||||
filter.rules.splice(ruleIndex, 1);
|
|
||||||
var nextSelected = selectedRuleDiv.next();
|
|
||||||
if (!nextSelected)
|
|
||||||
nextSelected = selectedRuleDiv.previous();
|
|
||||||
selectedRuleDiv.parentNode.removeChild(selectedRuleDiv);
|
|
||||||
setSelectedRuleDiv(nextSelected);
|
|
||||||
}
|
|
||||||
|
|
||||||
Event.stop(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onActionAddClick(event) {
|
|
||||||
var filterActions = $("filterActions");
|
|
||||||
if (filterActions) {
|
|
||||||
var newAction = createFilterAction();
|
|
||||||
filter.actions.push(newAction);
|
|
||||||
var newActionDiv = appendAction(filterActions, newAction);
|
|
||||||
setSelectedActionDiv(newActionDiv);
|
|
||||||
filterActions.scrollTop = newActionDiv.offsetTop;
|
|
||||||
}
|
|
||||||
Event.stop(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onActionDeleteClick(event) {
|
|
||||||
if (selectedActionDiv) {
|
|
||||||
var actionIndex = filter.actions.indexOf(selectedActionDiv.action);
|
|
||||||
filter.actions.splice(actionIndex, 1);
|
|
||||||
var nextSelected = selectedActionDiv.next();
|
|
||||||
if (!nextSelected)
|
|
||||||
nextSelected = selectedActionDiv.previous();
|
|
||||||
selectedActionDiv.parentNode.removeChild(selectedActionDiv);
|
|
||||||
setSelectedActionDiv(nextSelected);
|
|
||||||
}
|
|
||||||
|
|
||||||
Event.stop(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
function savePreferences(event) {
|
|
||||||
var valid = true;
|
|
||||||
|
|
||||||
var container = $('filterRulesContainer');
|
|
||||||
if (container.visible()) {
|
|
||||||
var rules = container.select("DIV#filterRules DIV.rule");
|
|
||||||
if (rules.length == 0) {
|
|
||||||
onRuleAddClick(event);
|
|
||||||
valid = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var inputs = $$("DIV#filterRules input");
|
|
||||||
inputs.each(function(input) {
|
|
||||||
if (input.hasClassName("_invalid"))
|
|
||||||
valid = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var actions = $$("DIV#filterActions DIV.action");
|
|
||||||
if (actions.length == 0) {
|
|
||||||
onActionAddClick(event);
|
|
||||||
valid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (valid) {
|
|
||||||
if (window.opener) {
|
|
||||||
window.opener.updateFilterFromEditor(filterId, Object.toJSON(filter));
|
|
||||||
}
|
|
||||||
window.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// function configureDragHandles() {
|
|
||||||
// var handle = $("splitter");
|
|
||||||
// if (handle) {
|
|
||||||
// handle.addInterface(SOGoDragHandlesInterface);
|
|
||||||
// handle.upperBlock = $("filterRulesContainer");
|
|
||||||
// handle.lowerBlock = $("filterActionsContainer");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
document.observe("dom:loaded", onLoadHandler);
|
|
|
@ -1,90 +0,0 @@
|
||||||
TABLE.details
|
|
||||||
{ float: right;
|
|
||||||
margin-right: 14px;
|
|
||||||
text-align: right; }
|
|
||||||
|
|
||||||
TABLE.details TD
|
|
||||||
{ padding: 0; }
|
|
||||||
|
|
||||||
TABLE#referenceList
|
|
||||||
{ width: 100%; }
|
|
||||||
|
|
||||||
TABLE#referenceList THEAD TD
|
|
||||||
{ padding-right: 2px; }
|
|
||||||
|
|
||||||
TABLE#referenceList TBODY TD TR
|
|
||||||
{ background: #CCDDEC;
|
|
||||||
text-align: left;}
|
|
||||||
|
|
||||||
TD.referenceListCell
|
|
||||||
{ padding-left: 2em;
|
|
||||||
background: #CCDDEC;
|
|
||||||
text-align: left;}
|
|
||||||
|
|
||||||
DIV#referenceListWrapper
|
|
||||||
{ background: #CCDDEC;
|
|
||||||
overflow: auto;
|
|
||||||
position: relative;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
height: 300px;
|
|
||||||
border-left: 1px solid #9B9B9B;
|
|
||||||
margin: 2px; }
|
|
||||||
|
|
||||||
DIV#referenceListWrapper TR,
|
|
||||||
TR.referenceListRow
|
|
||||||
{ background: #CCDDEC;
|
|
||||||
line-height: 2em; }
|
|
||||||
|
|
||||||
TD.referenceListCell,
|
|
||||||
TD.editing
|
|
||||||
{ background-repeat: no-repeat;
|
|
||||||
background-position: 4px 50%;
|
|
||||||
background-image: url('abcard.png');
|
|
||||||
text-align: left;
|
|
||||||
-moz-user-select: none; }
|
|
||||||
|
|
||||||
TD.referenceListCell SPAN,
|
|
||||||
TD.editing INPUT
|
|
||||||
{ margin-left: 24px; }
|
|
||||||
|
|
||||||
TD.editing INPUT,
|
|
||||||
TABLE#referenceList TD INPUT
|
|
||||||
{ width: 90%; }
|
|
||||||
|
|
||||||
TR.notfound TD.referenceListCell
|
|
||||||
{ color: #f00 !important; }
|
|
||||||
|
|
||||||
DIV#windowButtons
|
|
||||||
{ position: fixed;
|
|
||||||
top: auto;
|
|
||||||
bottom: 5em;
|
|
||||||
left: 0px;
|
|
||||||
right: 25px;
|
|
||||||
height: 3.5em;
|
|
||||||
line-height: 2em;
|
|
||||||
vertical-align: middle;
|
|
||||||
text-align: right; }
|
|
||||||
|
|
||||||
INPUT.textField
|
|
||||||
{ width: 100%; }
|
|
||||||
|
|
||||||
DIV#buttons
|
|
||||||
{ position: fixed;
|
|
||||||
top: auto;
|
|
||||||
bottom: 0px;
|
|
||||||
left: 0px;
|
|
||||||
right: 25px;
|
|
||||||
height: 3.5em;
|
|
||||||
line-height: 2em;
|
|
||||||
color: #535D6D;
|
|
||||||
vertical-align: middle;
|
|
||||||
text-align: right; }
|
|
||||||
|
|
||||||
TD
|
|
||||||
{ color: #535D6D; }
|
|
||||||
|
|
||||||
DIV#listEditor
|
|
||||||
{ padding: 5px; }
|
|
||||||
|
|
|
@ -1,172 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
function validateListEditor () {
|
|
||||||
return serializeReferences();
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeEditable (element) {
|
|
||||||
element.addClassName("editing");
|
|
||||||
element.removeClassName("referenceListCell");
|
|
||||||
|
|
||||||
var span = element.down("SPAN");
|
|
||||||
span.update();
|
|
||||||
|
|
||||||
var textField = element.down("INPUT");
|
|
||||||
textField.show();
|
|
||||||
textField.focus();
|
|
||||||
textField.select();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function endEditable(event, textField) {
|
|
||||||
if (!textField)
|
|
||||||
textField = this;
|
|
||||||
|
|
||||||
var uid = textField.readAttribute("uid");
|
|
||||||
var cell = textField.up("TD");
|
|
||||||
var textSpan = cell.down("SPAN");
|
|
||||||
|
|
||||||
cell.removeClassName("editing");
|
|
||||||
cell.addClassName("referenceListCell");
|
|
||||||
textField.hide();
|
|
||||||
|
|
||||||
var tmp = textField.value;
|
|
||||||
tmp = tmp.replace (/</, "<");
|
|
||||||
tmp = tmp.replace (/>/, ">");
|
|
||||||
if (!uid)
|
|
||||||
cell.up("TR").addClassName("notfound");
|
|
||||||
if (tmp)
|
|
||||||
textSpan.update(tmp);
|
|
||||||
else
|
|
||||||
cell.up("TR").remove();
|
|
||||||
|
|
||||||
if (event)
|
|
||||||
Event.stop(event);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function endAllEditables (e) {
|
|
||||||
var r = $$("TABLE#referenceList TBODY TR TD");
|
|
||||||
for (var i = 0; i < r.length; i++) {
|
|
||||||
var element = $(r[i]);
|
|
||||||
if (r[i] != this && element.hasClassName("editing"))
|
|
||||||
endEditable(null, element.down("INPUT"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onNameEdit (e) {
|
|
||||||
endAllEditables();
|
|
||||||
if (!this.hasClassName("editing")) {
|
|
||||||
makeEditable (this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onReferenceAdd (e) {
|
|
||||||
var tablebody = $("referenceList").tBodies[0];
|
|
||||||
var row = new Element("tr");
|
|
||||||
var td = new Element("td");
|
|
||||||
var textField = new Element("input");
|
|
||||||
var span = new Element("span");
|
|
||||||
|
|
||||||
row.addClassName ("referenceListRow");
|
|
||||||
row.observe("mousedown", onRowClick);
|
|
||||||
td.addClassName ("referenceListCell");
|
|
||||||
td.observe("mousedown", endAllEditables);
|
|
||||||
td.observe("dblclick", onNameEdit);
|
|
||||||
textField.addInterface(SOGoAutoCompletionInterface);
|
|
||||||
textField.addressBook = activeAddressBook;
|
|
||||||
textField.excludeLists = true;
|
|
||||||
textField.observe("autocompletion:changed", endEditable);
|
|
||||||
textField.addClassName("textField");
|
|
||||||
|
|
||||||
td.appendChild(textField);
|
|
||||||
td.appendChild(span);
|
|
||||||
row.appendChild (td);
|
|
||||||
tablebody.appendChild(row);
|
|
||||||
$(tablebody).deselectAll();
|
|
||||||
row.selectElement();
|
|
||||||
|
|
||||||
makeEditable(td);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onReferenceDelete(e) {
|
|
||||||
var list = $('referenceList').down("TBODY");;
|
|
||||||
var rows = list.getSelectedNodes();
|
|
||||||
var count = rows.length;
|
|
||||||
|
|
||||||
for (var i = 0; i < count; i++) {
|
|
||||||
rows[i].remove();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function serializeReferences(e) {
|
|
||||||
var r = $$("TABLE#referenceList TBODY TR INPUT");
|
|
||||||
var cards = new Array();
|
|
||||||
for (var i = 0; i < r.length; i++) {
|
|
||||||
var uid = $(r[i]).readAttribute("uid");
|
|
||||||
if (uid)
|
|
||||||
cards.push(uid);
|
|
||||||
else {
|
|
||||||
var addresses = r[i].value.split(/[,;]/);
|
|
||||||
for (var j = 0; j < addresses.length; j++) {
|
|
||||||
var mailto = addresses[j].strip();
|
|
||||||
var email = extractEmailAddress(mailto);
|
|
||||||
var c_name = extractEmailName(mailto);
|
|
||||||
if (!email && !c_name)
|
|
||||||
c_name = mailto;
|
|
||||||
cards.push(email + '|' + c_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$("referencesValue").value = cards.join(",");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetTableActions() {
|
|
||||||
var r = $$("TABLE#referenceList TBODY TR");
|
|
||||||
for (var i = 0; i < r.length; i++) {
|
|
||||||
var row = $(r[i]);
|
|
||||||
row.observe("mousedown", onRowClick);
|
|
||||||
var td = row.down("TD");
|
|
||||||
td.observe("mousedown", endAllEditables);
|
|
||||||
td.observe("dblclick", onNameEdit);
|
|
||||||
var textField = td.down("INPUT");
|
|
||||||
textField.addInterface(SOGoAutoCompletionInterface);
|
|
||||||
textField.addressBook = activeAddressBook;
|
|
||||||
textField.excludeLists = true;
|
|
||||||
textField.confirmedValue = textField.value;
|
|
||||||
textField.observe("autocompletion:changed", endEditable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onEditorSubmitClick(event) {
|
|
||||||
if (validateListEditor())
|
|
||||||
$("mainForm").submit();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onDocumentKeydown(event) {
|
|
||||||
var target = Event.element(event);
|
|
||||||
if (target.tagName == "INPUT") {
|
|
||||||
if (event.keyCode == Event.KEY_RETURN && target.menu == null) {
|
|
||||||
onEditorSubmitClick(event);
|
|
||||||
Event.stop(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function initListEditor() {
|
|
||||||
var table = $("referenceList");
|
|
||||||
table.multiselect = true;
|
|
||||||
resetTableActions();
|
|
||||||
$("referenceAdd").observe("click", onReferenceAdd);
|
|
||||||
$("referenceDelete").observe("click", onReferenceDelete);
|
|
||||||
$("cancelButton").observe("click", onCloseButtonClick);
|
|
||||||
$("submitButton").observe("click", onEditorSubmitClick);
|
|
||||||
|
|
||||||
Event.observe(document, "keydown", onDocumentKeydown);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.observe("dom:loaded", initListEditor);
|
|
|
@ -1,274 +0,0 @@
|
||||||
/* CSS for compose panel */
|
|
||||||
|
|
||||||
DIV#leftPanel
|
|
||||||
{ top: 52px; }
|
|
||||||
|
|
||||||
DIV#rightPanel
|
|
||||||
{ top: 48px;
|
|
||||||
left: 0em; }
|
|
||||||
|
|
||||||
DIV#hiddenDragHandle
|
|
||||||
{ cursor: e-resize;
|
|
||||||
border: 0px;
|
|
||||||
top: 52px;
|
|
||||||
left: 15em;
|
|
||||||
width: 5px;
|
|
||||||
bottom: 0; }
|
|
||||||
|
|
||||||
div#compose_panel div table
|
|
||||||
{ padding: 2px; }
|
|
||||||
|
|
||||||
TABLE#compose_table, TABLE#compose_table DIV
|
|
||||||
{ width: 100%; }
|
|
||||||
|
|
||||||
TABLE#compose_label
|
|
||||||
{ text-align: right; }
|
|
||||||
|
|
||||||
DIV#addressList
|
|
||||||
{ clear: left;
|
|
||||||
height: 8em;
|
|
||||||
overflow: auto;
|
|
||||||
overflow-y: auto;
|
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIV.addressList
|
|
||||||
{ margin: 5px; }
|
|
||||||
|
|
||||||
TABLE#addressList
|
|
||||||
{ border-bottom: 1px solid #fff;
|
|
||||||
border-right: 1px solid #fff;
|
|
||||||
border-top: 1px solid #909090;
|
|
||||||
border-left: 1px solid #909090;
|
|
||||||
border-spacing: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
width: 100%; }
|
|
||||||
|
|
||||||
TABLE#addressList TD
|
|
||||||
{ background-color: #fff;
|
|
||||||
border: 0px;
|
|
||||||
border-bottom: 1px solid #C4C8FF;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 1px; }
|
|
||||||
|
|
||||||
TABLE#addressList TD.headerField
|
|
||||||
{ border-right: 1px solid #C4C8FF;
|
|
||||||
width: 120px; }
|
|
||||||
|
|
||||||
TABLE#addressList TD.headerField SELECT
|
|
||||||
{ border: 1px solid #eee; }
|
|
||||||
|
|
||||||
TABLE#addressList TD.headerInput
|
|
||||||
{ background-image: url('abcard.png');
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: 2px center;
|
|
||||||
padding-left: 24px;
|
|
||||||
padding-right: 4px; }
|
|
||||||
|
|
||||||
TABLE#addressList TD.headerInput INPUT
|
|
||||||
{ background: #fff !important;
|
|
||||||
border: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
width: 100%; }
|
|
||||||
|
|
||||||
SPAN.headerField
|
|
||||||
{ line-height: 2.0em;
|
|
||||||
padding-left: 0.5em; }
|
|
||||||
|
|
||||||
TABLE#addressList TR#lastRow SELECT
|
|
||||||
{ visibility: hidden; }
|
|
||||||
|
|
||||||
DIV#subjectRow SPAN.headerField
|
|
||||||
{ float: left; }
|
|
||||||
|
|
||||||
DIV#subjectRow INPUT
|
|
||||||
{ background: #fff;
|
|
||||||
margin-left: 2px;
|
|
||||||
padding: 0px 2px 0px 2px; }
|
|
||||||
|
|
||||||
div#compose_internetmarker
|
|
||||||
{ padding: 8px;
|
|
||||||
text-align: center;
|
|
||||||
background-color: white;
|
|
||||||
border-color: red;
|
|
||||||
border-width: 2px;
|
|
||||||
border-style: solid; }
|
|
||||||
|
|
||||||
div#headerArea
|
|
||||||
{ padding: 5px 0px; }
|
|
||||||
|
|
||||||
div#headerArea div.addressList
|
|
||||||
{ max-height: 10em;
|
|
||||||
overflow: auto;
|
|
||||||
overflow-x: hidden; }
|
|
||||||
|
|
||||||
input.currentAttachment
|
|
||||||
{ position: fixed;
|
|
||||||
top: 1em;
|
|
||||||
right: 1em; }
|
|
||||||
|
|
||||||
input.attachment
|
|
||||||
{ position: absolute;
|
|
||||||
left: -1000px; }
|
|
||||||
|
|
||||||
#dropZone
|
|
||||||
{ position: absolute;
|
|
||||||
background: #000 url('upload_document.png') no-repeat center center;
|
|
||||||
opacity: 0.6;
|
|
||||||
border: 4px dashed #fff;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
top: 0px;
|
|
||||||
bottom: 0px;
|
|
||||||
z-index: 999; }
|
|
||||||
|
|
||||||
#dropZone div
|
|
||||||
{ position: absolute;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 18px;
|
|
||||||
height: 100px;
|
|
||||||
width: 300px;
|
|
||||||
margin: 60px 0 0 -150px;
|
|
||||||
left: 50%;
|
|
||||||
top: 50%;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#fileupload {
|
|
||||||
margin-top: 5px;
|
|
||||||
clear: both;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button.fileinput-button
|
|
||||||
{ display: inline-block;
|
|
||||||
float: none; }
|
|
||||||
|
|
||||||
UL#attachments
|
|
||||||
{ cursor: default;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
list-style-type: none;
|
|
||||||
list-style-image: none;
|
|
||||||
overflow: auto;
|
|
||||||
overflow-x: hidden;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-khtml-user-select: none; }
|
|
||||||
|
|
||||||
UL#attachments LI
|
|
||||||
{ float: left; }
|
|
||||||
|
|
||||||
UL#attachments LI[data-filename]
|
|
||||||
{ white-space: nowrap;
|
|
||||||
line-height: 18px;
|
|
||||||
margin: 3px 6px; }
|
|
||||||
|
|
||||||
UL#attachments LI[data-filename] SPAN
|
|
||||||
{ margin-left: 5px; }
|
|
||||||
|
|
||||||
UL#attachments LI[data-filename] A,
|
|
||||||
UL#attachments LI[data-filename] SPAN
|
|
||||||
{ padding-left: 2px;
|
|
||||||
vertical-align: top; }
|
|
||||||
|
|
||||||
UL#attachments LI IMG
|
|
||||||
{ vertical-align: top; }
|
|
||||||
|
|
||||||
UL#attachments .icon-attachment
|
|
||||||
{ background: url('attachment.png') no-repeat top left;
|
|
||||||
display: inline-block;
|
|
||||||
width: 16px;
|
|
||||||
height: 16px; }
|
|
||||||
UL#attachments .progress0 .icon-attachment
|
|
||||||
{ background-position: 0px 0px; }
|
|
||||||
UL#attachments .progress1 .icon-attachment
|
|
||||||
{ background-position: -16px 0px; }
|
|
||||||
UL#attachments .progress2 .icon-attachment
|
|
||||||
{ background-position: -32px 0px; }
|
|
||||||
UL#attachments .progress3 .icon-attachment
|
|
||||||
{ background-position: -48px 0px; }
|
|
||||||
UL#attachments .progress4 .icon-attachment
|
|
||||||
{ background-position: -64px 0px; }
|
|
||||||
UL#attachments .progressDone .icon-attachment
|
|
||||||
{ background-position: -80px 0px; }
|
|
||||||
UL#attachments .progressDone .icon-attachment:hover
|
|
||||||
{ background-position: -96px 0px;
|
|
||||||
cursor: pointer; }
|
|
||||||
|
|
||||||
#pageContent TEXTAREA
|
|
||||||
{ width: 99%; }
|
|
||||||
|
|
||||||
TEXTAREA#text
|
|
||||||
{ background: #fff; }
|
|
||||||
|
|
||||||
#cke_text
|
|
||||||
{ clear: both; }
|
|
||||||
|
|
||||||
/* Contacts search pane */
|
|
||||||
|
|
||||||
DIV#contactsSearch
|
|
||||||
{ border-right: 1px solid #fff;
|
|
||||||
padding-top: 5px;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
margin-left: 5px; }
|
|
||||||
|
|
||||||
DIV#contactsSearch LABEL
|
|
||||||
{ display: block;
|
|
||||||
margin: 0 0 5px 0; }
|
|
||||||
|
|
||||||
SELECT#contactFolder
|
|
||||||
{ margin-bottom: 5px; }
|
|
||||||
|
|
||||||
INPUT[name="search"]
|
|
||||||
{ position: absolute;
|
|
||||||
top: 6.2em;
|
|
||||||
left: 5px;
|
|
||||||
right: 0px; /* doesn't work in FF */
|
|
||||||
display: block;
|
|
||||||
width: auto; }
|
|
||||||
|
|
||||||
DIV#contactsListContent
|
|
||||||
{ position: absolute;
|
|
||||||
top: 9em;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
bottom: 110px;
|
|
||||||
margin: 0;
|
|
||||||
border-right: 1px solid #fff;
|
|
||||||
background-color: #fff;
|
|
||||||
overflow-y: auto; }
|
|
||||||
|
|
||||||
TABLE#contactsList
|
|
||||||
{ width: 100%; }
|
|
||||||
|
|
||||||
TABLE#contactsList TD,
|
|
||||||
TABLE#contactsList TH
|
|
||||||
{ overflow: hidden;
|
|
||||||
line-height: 16px;
|
|
||||||
height: 18px;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap; }
|
|
||||||
|
|
||||||
TABLE#contactsList TD#nameHeader,
|
|
||||||
TABLE#contactsList TD#mailHeader
|
|
||||||
{ width: 50%;
|
|
||||||
max-width: 50%; }
|
|
||||||
|
|
||||||
DIV.contactSelection
|
|
||||||
{
|
|
||||||
z-index: 1;
|
|
||||||
background: inherit;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0em;
|
|
||||||
padding: 1em;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
height: 90px;
|
|
||||||
text-align: right;
|
|
||||||
background: #E6E7E6;
|
|
||||||
border-top: 1px solid #fff;
|
|
||||||
border-left: 0px;
|
|
||||||
border-right: 0px;
|
|
||||||
border-bottom: 0px;
|
|
||||||
}
|
|
|
@ -1,758 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
var contactSelectorAction = 'mailer-contacts';
|
|
||||||
var attachmentCount = 0;
|
|
||||||
var MailEditor = {
|
|
||||||
currentField: null,
|
|
||||||
selectedIndex: -1,
|
|
||||||
delay: 750,
|
|
||||||
delayedSearch: false,
|
|
||||||
signatureLength: 0,
|
|
||||||
textFirstFocus: true
|
|
||||||
};
|
|
||||||
|
|
||||||
var autoSaveTimer;
|
|
||||||
|
|
||||||
function refreshDraftsFolder() {
|
|
||||||
if (window.opener && window.opener.getUnseenCountForFolder) {
|
|
||||||
var nodes = window.opener.$("mailboxTree").select("DIV[datatype=draft]");
|
|
||||||
window.opener.getUnseenCountForFolder(nodes[0].readAttribute("dataname"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onContactAdd(button) {
|
|
||||||
var div = $("contacts");
|
|
||||||
if (div.visible()) {
|
|
||||||
div.hide();
|
|
||||||
$("rightPanel").setStyle({ left: "0px" });
|
|
||||||
$(button).removeClassName("active");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$("rightPanel").setStyle({ left: $("leftPanel").getStyle("width") });
|
|
||||||
div.show();
|
|
||||||
$(button).addClassName("active");
|
|
||||||
}
|
|
||||||
|
|
||||||
$("hiddenDragHandle").adjust();
|
|
||||||
onWindowResize(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
function addContact(tag, fullContactName, contactId, contactName, contactEmail) {
|
|
||||||
if (!mailIsRecipient(contactEmail)) {
|
|
||||||
var neededOptionValue = 0;
|
|
||||||
if (tag == "cc")
|
|
||||||
neededOptionValue = 1;
|
|
||||||
else if (tag == "bcc")
|
|
||||||
neededOptionValue = 2;
|
|
||||||
|
|
||||||
var stop = false;
|
|
||||||
var counter = 0;
|
|
||||||
var currentRow = $('row_' + counter);
|
|
||||||
while (currentRow && !stop) {
|
|
||||||
var currentValue = $(currentRow.childNodesWithTag("td")[1]).childNodesWithTag("input")[0].value;
|
|
||||||
if (currentValue == neededOptionValue) {
|
|
||||||
stop = true;
|
|
||||||
insertContact($("addr_" + counter), contactName, contactEmail);
|
|
||||||
}
|
|
||||||
counter++;
|
|
||||||
currentRow = $('row_' + counter);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!stop) {
|
|
||||||
fancyAddRow("");
|
|
||||||
var row = $("row_" + currentIndex);
|
|
||||||
var td = $(row.childNodesWithTag("td")[0]);
|
|
||||||
var select = $(td.childNodesWithTag("select")[0]);
|
|
||||||
select.value = neededOptionValue;
|
|
||||||
insertContact($("addr_" + currentIndex), contactName, contactEmail);
|
|
||||||
onWindowResize(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onContactFolderChange(event) {
|
|
||||||
initCriteria();
|
|
||||||
openContactsFolder(this.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function mailIsRecipient(mailto) {
|
|
||||||
var isRecipient = false;
|
|
||||||
|
|
||||||
var counter = 0;
|
|
||||||
var currentRow = $('row_' + counter);
|
|
||||||
|
|
||||||
var email = extractEmailAddress(mailto).toUpperCase();
|
|
||||||
|
|
||||||
while (currentRow && !isRecipient) {
|
|
||||||
var currentValue = $("addr_"+counter).value.toUpperCase();
|
|
||||||
if (currentValue.indexOf(email) > -1)
|
|
||||||
isRecipient = true;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
counter++;
|
|
||||||
currentRow = $('row_' + counter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return isRecipient;
|
|
||||||
}
|
|
||||||
|
|
||||||
function insertContact(inputNode, contactName, contactEmail) {
|
|
||||||
var value = '' + inputNode.value;
|
|
||||||
|
|
||||||
var newContact = contactName;
|
|
||||||
if (newContact.length > 0)
|
|
||||||
newContact += ' <' + contactEmail + '>';
|
|
||||||
else
|
|
||||||
newContact = contactEmail;
|
|
||||||
|
|
||||||
if (value.length > 0)
|
|
||||||
value += ", ";
|
|
||||||
value += newContact;
|
|
||||||
|
|
||||||
inputNode.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateWindowTitleFromSubject(event) {
|
|
||||||
if (this.value) {
|
|
||||||
document.title = this.value;
|
|
||||||
}else{
|
|
||||||
document.title = '(' + _("Untitled") + ')';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* mail editor */
|
|
||||||
|
|
||||||
function onValidate(onSuccess) {
|
|
||||||
if (document.pageform.action != "send") {
|
|
||||||
|
|
||||||
if (!hasRecipients()) {
|
|
||||||
showAlertDialog(_("error_missingrecipients"));
|
|
||||||
}
|
|
||||||
else if (document.pageform.subject.value == "") {
|
|
||||||
showConfirmDialog(_("Warning"), _("error_missingsubject"), onValidateDone.bind(this, onSuccess), null, _("Send Anyway"), _("Cancel"));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
onValidateDone(onSuccess);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onValidateDone(onSuccess) {
|
|
||||||
// Create "blocking" div to avoid double-clicking on send button
|
|
||||||
var safetyNet = createElement("div", "javascriptSafetyNet");
|
|
||||||
$('pageContent').insert({top: safetyNet});
|
|
||||||
|
|
||||||
if (!document.busyAnim) {
|
|
||||||
var toolbar = document.getElementById("toolbar");
|
|
||||||
document.busyAnim = startAnimation(toolbar);
|
|
||||||
}
|
|
||||||
|
|
||||||
var lastRow = $("lastRow");
|
|
||||||
lastRow.down("select").name = "popup_last";
|
|
||||||
|
|
||||||
window.shouldPreserve = true;
|
|
||||||
|
|
||||||
document.pageform.action = "send";
|
|
||||||
|
|
||||||
if (typeof onSuccess == 'function')
|
|
||||||
onSuccess();
|
|
||||||
|
|
||||||
disposeDialog();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPostComplete(http) {
|
|
||||||
var response = http.responseText;
|
|
||||||
if (response && response.length > 0) {
|
|
||||||
var jsonResponse = response.evalJSON();
|
|
||||||
if (jsonResponse["status"] == "success") {
|
|
||||||
var p;
|
|
||||||
if (window.frameElement && window.frameElement.id)
|
|
||||||
p = parent;
|
|
||||||
if (window.opener && window.opener.refreshMessage)
|
|
||||||
p = window.opener;
|
|
||||||
if (p && p.refreshMessage)
|
|
||||||
p.refreshMessage(jsonResponse["sourceFolder"],
|
|
||||||
jsonResponse["sourceMessageID"]);
|
|
||||||
|
|
||||||
refreshDraftsFolder();
|
|
||||||
onCloseButtonClick();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var message = jsonResponse["message"];
|
|
||||||
document.pageform.action = "";
|
|
||||||
var progressImage = $("progressIndicator");
|
|
||||||
if (progressImage) {
|
|
||||||
progressImage.parentNode.removeChild(progressImage);
|
|
||||||
}
|
|
||||||
showAlertDialog(jsonResponse["message"]);
|
|
||||||
// Remove "blocking" div
|
|
||||||
onFinalLoadHandler(); // from generic.js
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
onCloseButtonClick();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function clickedEditorSend() {
|
|
||||||
onValidate(function() {
|
|
||||||
if (CKEDITOR.instances.text) CKEDITOR.instances.text.updateElement();
|
|
||||||
triggerAjaxRequest(document.pageform.action,
|
|
||||||
onPostComplete,
|
|
||||||
null,
|
|
||||||
Form.serialize(document.pageform), // excludes the file input
|
|
||||||
{ "Content-type": "application/x-www-form-urlencoded" });
|
|
||||||
});
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatBytes(bytes, si) {
|
|
||||||
var thresh = si ? 1000 : 1024;
|
|
||||||
if (bytes < thresh) return bytes + ' B';
|
|
||||||
var units = si ? ['KiB','MiB','GiB'] : ['KB','MB','GB'];
|
|
||||||
var u = -1;
|
|
||||||
do {
|
|
||||||
bytes /= thresh;
|
|
||||||
++u;
|
|
||||||
} while (bytes >= thresh);
|
|
||||||
return bytes.toFixed(1) + ' ' + units[u];
|
|
||||||
}
|
|
||||||
|
|
||||||
function createAttachment(file) {
|
|
||||||
var list = $('attachments');
|
|
||||||
var attachment;
|
|
||||||
if (list.select('[data-filename="'+file.name+'"]').length == 0) {
|
|
||||||
// File is not already uploaded
|
|
||||||
var attachment = createElement('li', null, ['muted progress0'], null, { 'data-filename': file.name }, list);
|
|
||||||
attachment.appendChild(new Element('i', { 'class': 'icon-attachment' }));
|
|
||||||
var a = createElement('a', null, null, null, {'href': '#', 'target': '_new' }, attachment);
|
|
||||||
|
|
||||||
a.appendChild(document.createTextNode(file.name));
|
|
||||||
if (file.size)
|
|
||||||
attachment.appendChild(new Element('span', { 'class': 'muted' }).update('(' + formatBytes(file.size, true) + ')'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return attachment;
|
|
||||||
}
|
|
||||||
|
|
||||||
function clickedEditorSave() {
|
|
||||||
var lastRow = $("lastRow");
|
|
||||||
lastRow.down("select").name = "popup_last";
|
|
||||||
|
|
||||||
window.shouldPreserve = true;
|
|
||||||
document.pageform.action = "save";
|
|
||||||
if (CKEDITOR.instances.text) CKEDITOR.instances.text.updateElement();
|
|
||||||
|
|
||||||
triggerAjaxRequest(document.pageform.action, function (http) {
|
|
||||||
if (http.readyState == 4) {
|
|
||||||
if (http.status == 200) {
|
|
||||||
refreshDraftsFolder();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var response = http.responseText.evalJSON(true);
|
|
||||||
showAlertDialog(_("Error while saving the draft:") + " " + response.textStatus);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
null,
|
|
||||||
Form.serialize(document.pageform), // excludes the file input
|
|
||||||
{ "Content-type": "application/x-www-form-urlencoded" });
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* On first focus of textarea, position the caret with respect to user's preferences
|
|
||||||
*/
|
|
||||||
function onTextFocus(event) {
|
|
||||||
if (MailEditor.textFirstFocus) {
|
|
||||||
var content = this.getValue();
|
|
||||||
var replyPlacement = UserDefaults["SOGoMailReplyPlacement"];
|
|
||||||
if (replyPlacement == "above" || !mailIsReply) {
|
|
||||||
// For forwards, place caret at top unconditionally
|
|
||||||
this.setCaretTo(0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var caretPosition = this.getValue().length - MailEditor.signatureLength;
|
|
||||||
caretPosition = adjustOffset(this, caretPosition);
|
|
||||||
if (hasSignature())
|
|
||||||
caretPosition -= 2;
|
|
||||||
this.setCaretTo(caretPosition);
|
|
||||||
}
|
|
||||||
MailEditor.textFirstFocus = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Change behavior of tab key in textarea (plain-text mail)
|
|
||||||
*/
|
|
||||||
function onTextKeyDown(event) {
|
|
||||||
if (event.keyCode == Event.KEY_TAB) {
|
|
||||||
if (event.shiftKey) {
|
|
||||||
// Shift-tab goes back to subject field
|
|
||||||
var subjectField = $$("div#subjectRow input").first();
|
|
||||||
subjectField.focus();
|
|
||||||
subjectField.selectText(0, subjectField.value.length);
|
|
||||||
preventDefault(event);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!(event.shiftKey || event.metaKey || event.ctrlKey)) {
|
|
||||||
// Convert a tab to 4 spaces
|
|
||||||
if (typeof(this.selectionStart) != "undefined") { // Mozilla and Safari
|
|
||||||
var cursor = this.selectionStart;
|
|
||||||
var startText = ((cursor > 0)
|
|
||||||
? this.value.substr(0, cursor)
|
|
||||||
: "");
|
|
||||||
var endText = this.value.substr(cursor);
|
|
||||||
var newText = startText + " " + endText;
|
|
||||||
this.value = newText;
|
|
||||||
cursor += 4;
|
|
||||||
this.setSelectionRange(cursor, cursor);
|
|
||||||
}
|
|
||||||
else if (this.selectionRange) // IE
|
|
||||||
this.selectionRange.text = " ";
|
|
||||||
preventDefault(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onTextIEUpdateCursorPos(event) {
|
|
||||||
this.selectionRange = document.selection.createRange().duplicate();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onHTMLFocus(event) {
|
|
||||||
if (MailEditor.textFirstFocus) {
|
|
||||||
var s = event.editor.getSelection();
|
|
||||||
var selected_ranges = s.getRanges();
|
|
||||||
var children = event.editor.document.getBody().getChildren();
|
|
||||||
var node;
|
|
||||||
var caretAtTop = (UserDefaults["SOGoMailReplyPlacement"] == "above")
|
|
||||||
|| !mailIsReply; // for forwards, place caret at top unconditionally
|
|
||||||
|
|
||||||
if (caretAtTop) {
|
|
||||||
node = children.getItem(0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Search for signature starting from bottom
|
|
||||||
node = children.getItem(children.count() - 1);
|
|
||||||
while (true) {
|
|
||||||
var x = node.getPrevious();
|
|
||||||
if (x == null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (x.getText() == '--') {
|
|
||||||
node = x.getPrevious().getPrevious();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
node = x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s.selectElement(node);
|
|
||||||
|
|
||||||
// Place the caret
|
|
||||||
if (caretAtTop)
|
|
||||||
s.scrollIntoView(); // top
|
|
||||||
selected_ranges = s.getRanges();
|
|
||||||
selected_ranges[0].collapse(true);
|
|
||||||
s.selectRanges(selected_ranges);
|
|
||||||
if (!caretAtTop)
|
|
||||||
s.scrollIntoView(); // bottom
|
|
||||||
|
|
||||||
MailEditor.textFirstFocus = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function initAddresses() {
|
|
||||||
var addressList = $("addressList");
|
|
||||||
addressList.select("input.textField").each(function (input) {
|
|
||||||
if (!input.readAttribute("readonly")) {
|
|
||||||
input.addInterface(SOGoAutoCompletionInterface);
|
|
||||||
input.uidField = "c_name";
|
|
||||||
input.on("focus", addressFieldGotFocus.bind(input));
|
|
||||||
input.on("blur", addressFieldLostFocus.bind(input));
|
|
||||||
input.on("autocompletion:changedlist", expandContactList);
|
|
||||||
input.on("autocompletion:changed", addressFieldChanged.bind(input));
|
|
||||||
//input.onListAdded = expandContactList;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function initAutoSaveTimer() {
|
|
||||||
var autoSave = UserDefaults["SOGoMailAutoSave"];
|
|
||||||
|
|
||||||
if (autoSave) {
|
|
||||||
var interval;
|
|
||||||
|
|
||||||
interval = parseInt(autoSave) * 60;
|
|
||||||
|
|
||||||
autoSaveTimer = window.setInterval(onAutoSaveCallback,
|
|
||||||
interval * 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onAutoSaveCallback(event) {
|
|
||||||
clickedEditorSave();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Overwrite function of MailerUI.js */
|
|
||||||
function configureDragHandle() {
|
|
||||||
var handle = $("hiddenDragHandle");
|
|
||||||
if (handle) {
|
|
||||||
handle.addInterface(SOGoDragHandlesInterface);
|
|
||||||
handle.leftMargin = 135; // minimum width
|
|
||||||
handle.leftBlock = $("leftPanel");
|
|
||||||
handle.rightBlock = $("rightPanel");
|
|
||||||
handle.enableRightSafety();
|
|
||||||
handle.observe("handle:dragged", onWindowResize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function configureAttachments() {
|
|
||||||
var list = $("attachments");
|
|
||||||
|
|
||||||
if (!list) return;
|
|
||||||
|
|
||||||
list.on('click', 'a', function (event, element) {
|
|
||||||
// Don't follow links of attachments not yet uploaded
|
|
||||||
if (!element.up('li').hasClassName('progressDone')) {
|
|
||||||
Event.stop(event);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
list.on('click', 'i.icon-attachment', function (event, element) {
|
|
||||||
// Delete attachment when clicking on small icon
|
|
||||||
var item = element.up('li');
|
|
||||||
if (item.hasClassName('progressDone')) {
|
|
||||||
var filename = item.readAttribute('data-filename');
|
|
||||||
var url = "" + window.location;
|
|
||||||
var parts = url.split("/");
|
|
||||||
parts[parts.length-1] = "deleteAttachment?filename=" + encodeURIComponent(filename);
|
|
||||||
url = parts.join("/");
|
|
||||||
triggerAjaxRequest(url, attachmentDeleteCallback, item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var dropzone = jQuery('#dropZone');
|
|
||||||
jQuery('#fileUpload').fileupload({
|
|
||||||
// With singleFileUploads option enabled, the 'add' and 'done' (or 'fail') callbacks
|
|
||||||
// are called once for each file in the selection for XHR file uploads
|
|
||||||
singleFileUploads: true,
|
|
||||||
pasteZone: null,
|
|
||||||
dataType: 'json',
|
|
||||||
add: function (e, data) {
|
|
||||||
var file = data.files[0];
|
|
||||||
var attachment = createAttachment(file);
|
|
||||||
if (attachment) {
|
|
||||||
file.attachment = attachment;
|
|
||||||
// Update the text field when using HTML mode
|
|
||||||
if (CKEDITOR.instances.text) CKEDITOR.instances.text.updateElement();
|
|
||||||
data.submit();
|
|
||||||
}
|
|
||||||
if (dropzone.is(":visible"))
|
|
||||||
dropzone.fadeOut('fast');
|
|
||||||
},
|
|
||||||
done: function (e, data) {
|
|
||||||
var attachment = data.files[0].attachment;
|
|
||||||
var attrs = data.result[data.result.length-1];
|
|
||||||
attachment.className = 'progressDone';
|
|
||||||
attachment.down('a').setAttribute('href', attrs.url);
|
|
||||||
if (window.opener && window.opener.open && !window.opener.closed)
|
|
||||||
window.opener.refreshFolderByType('draft');
|
|
||||||
},
|
|
||||||
fail: function (e, data) {
|
|
||||||
var attachment = data.files[0].attachment;
|
|
||||||
var filename = data.files[0].name;
|
|
||||||
var textStatus;
|
|
||||||
try {
|
|
||||||
var response = data.xhr().response.evalJSON();
|
|
||||||
textStatus = response.textStatus;
|
|
||||||
} catch (e) {}
|
|
||||||
if (!textStatus)
|
|
||||||
textStatus = _("Can't contact server");
|
|
||||||
showAlertDialog(_("Error while uploading the file \"%{0}\":").formatted(filename) + " " + textStatus);
|
|
||||||
attachment.remove();
|
|
||||||
},
|
|
||||||
dragover: function (e, data) {
|
|
||||||
if (!dropzone.is(":visible"))
|
|
||||||
dropzone.show();
|
|
||||||
},
|
|
||||||
progress: function (e, data) {
|
|
||||||
var progress = parseInt(data.loaded / data.total * 4, 10);
|
|
||||||
var attachment = data.files[0].attachment;
|
|
||||||
attachment.className = 'muted progress' + progress;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
dropzone.on('dragleave', function (e) {
|
|
||||||
dropzone.fadeOut('fast');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function initMailEditor() {
|
|
||||||
var textarea = $("text");
|
|
||||||
|
|
||||||
if (composeMode != "html" && $("text"))
|
|
||||||
textarea.show();
|
|
||||||
|
|
||||||
configureAttachments();
|
|
||||||
|
|
||||||
initAddresses();
|
|
||||||
initAutoSaveTimer();
|
|
||||||
|
|
||||||
var focusField = textarea;
|
|
||||||
if (!mailIsReply) {
|
|
||||||
focusField = $("addr_0");
|
|
||||||
focusField.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
initializePriorityMenu();
|
|
||||||
initializeReturnReceiptMenu();
|
|
||||||
|
|
||||||
configureDragHandle();
|
|
||||||
|
|
||||||
// Set current subject as window title if not set, use '(Untitled)'
|
|
||||||
if (document.pageform.subject.value == "")
|
|
||||||
document.title = '(' + _("Untitled") + ')';
|
|
||||||
else
|
|
||||||
document.title = _(document.pageform.subject.value);
|
|
||||||
|
|
||||||
// Change the window title when typing the subject
|
|
||||||
$$("div#subjectRow input").first().on("keyup", updateWindowTitleFromSubject);
|
|
||||||
|
|
||||||
var composeMode = UserDefaults["SOGoMailComposeMessageType"];
|
|
||||||
if (composeMode == "html") {
|
|
||||||
// HTML mode
|
|
||||||
CKEDITOR.replace('text',
|
|
||||||
{
|
|
||||||
language : localeCode,
|
|
||||||
scayt_sLang : localeCode
|
|
||||||
}
|
|
||||||
);
|
|
||||||
CKEDITOR.on('instanceReady', function(event) {
|
|
||||||
if (focusField == textarea)
|
|
||||||
// CKEditor reports being ready but it's still not focusable;
|
|
||||||
// we wait for a few more milliseconds
|
|
||||||
setTimeout("CKEDITOR.instances.text.focus()", 500);
|
|
||||||
});
|
|
||||||
CKEDITOR.instances.text.on('focus', onHTMLFocus);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Plain text mode
|
|
||||||
var textContent = textarea.getValue();
|
|
||||||
if (hasSignature()) {
|
|
||||||
var sigLimit = textContent.lastIndexOf("--");
|
|
||||||
if (sigLimit > -1)
|
|
||||||
MailEditor.signatureLength = (textContent.length - sigLimit);
|
|
||||||
}
|
|
||||||
if (UserDefaults["SOGoMailReplyPlacement"] != "above") {
|
|
||||||
textarea.scrollTop = textarea.scrollHeight;
|
|
||||||
}
|
|
||||||
textarea.observe("focus", onTextFocus);
|
|
||||||
textarea.observe("keydown", onTextKeyDown);
|
|
||||||
|
|
||||||
if (Prototype.Browser.IE) {
|
|
||||||
// Hack to allow to replace the tab by spaces in IE < 9
|
|
||||||
var ieEvents = [ "click", "select", "keyup" ];
|
|
||||||
for (var i = 0; i < ieEvents.length; i++)
|
|
||||||
textarea.observe(ieEvents[i], onTextIEUpdateCursorPos, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (focusField == textarea)
|
|
||||||
textarea.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
$("contactFolder").observe("change", onContactFolderChange);
|
|
||||||
|
|
||||||
Event.observe(window, "beforeunload", onMailEditorClose);
|
|
||||||
}
|
|
||||||
|
|
||||||
function initializePriorityMenu() {
|
|
||||||
var priority = $("priority").value.toUpperCase();
|
|
||||||
var priorityMenu = $("priorityMenu").childNodesWithTag("ul")[0];
|
|
||||||
var menuEntries = $(priorityMenu).childNodesWithTag("li");
|
|
||||||
var chosenNode;
|
|
||||||
if (priority == "HIGHEST")
|
|
||||||
chosenNode = menuEntries[0];
|
|
||||||
else if (priority == "HIGH")
|
|
||||||
chosenNode = menuEntries[1];
|
|
||||||
else if (priority == "LOW")
|
|
||||||
chosenNode = menuEntries[3];
|
|
||||||
else if (priority == "LOWEST")
|
|
||||||
chosenNode = menuEntries[4];
|
|
||||||
else
|
|
||||||
chosenNode = menuEntries[2];
|
|
||||||
priorityMenu.chosenNode = chosenNode;
|
|
||||||
$(chosenNode).addClassName("_chosen");
|
|
||||||
}
|
|
||||||
|
|
||||||
function initializeReturnReceiptMenu() {
|
|
||||||
var receipt = $("receipt").value.toLowerCase();
|
|
||||||
if (receipt == "true")
|
|
||||||
$("optionsMenu").down('li').addClassName("_chosen");
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMenuCheckReturnReceipt(event) {
|
|
||||||
event.cancelBubble = true;
|
|
||||||
|
|
||||||
this.enabled = !this.enabled;
|
|
||||||
var enabled = this.enabled;
|
|
||||||
if (enabled) {
|
|
||||||
this.addClassName("_chosen");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.removeClassName("_chosen");
|
|
||||||
}
|
|
||||||
var receiptInput = $("receipt");
|
|
||||||
receiptInput.value = (enabled ? "true" : "false") ;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getMenus() {
|
|
||||||
return {
|
|
||||||
"optionsMenu": [ onMenuCheckReturnReceipt,
|
|
||||||
"-",
|
|
||||||
"priorityMenu" ],
|
|
||||||
"priorityMenu": [ onMenuSetPriority,
|
|
||||||
onMenuSetPriority,
|
|
||||||
onMenuSetPriority,
|
|
||||||
onMenuSetPriority,
|
|
||||||
onMenuSetPriority ]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function attachmentDeleteCallback(http) {
|
|
||||||
if (http.readyState == 4) {
|
|
||||||
if (isHttpStatus204(http.status)) {
|
|
||||||
var node = http.callbackData;
|
|
||||||
node.parentNode.removeChild(node);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
log("attachmentDeleteCallback: an error occured: " + http.responseText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adjust offset when the browser uses two characters for line feeds.
|
|
||||||
*/
|
|
||||||
function adjustOffset(element, offset) {
|
|
||||||
var val = element.value, newOffset = offset;
|
|
||||||
if (val.indexOf("\r\n") > -1) {
|
|
||||||
var matches = val.replace(/\r\n/g, "\n").slice(0, offset).match(/\n/g);
|
|
||||||
newOffset -= matches ? matches.length - 1 : 0;
|
|
||||||
}
|
|
||||||
return newOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
function hasSignature() {
|
|
||||||
try {
|
|
||||||
return(UserDefaults["SOGoMailSignature"].length > 0);
|
|
||||||
} catch(e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMenuSetPriority(event) {
|
|
||||||
event.cancelBubble = true;
|
|
||||||
|
|
||||||
var priority = this.getAttribute("priority");
|
|
||||||
if (this.parentNode.chosenNode)
|
|
||||||
this.parentNode.chosenNode.removeClassName("_chosen");
|
|
||||||
this.addClassName("_chosen");
|
|
||||||
this.parentNode.chosenNode = this;
|
|
||||||
|
|
||||||
var priorityInput = $("priority");
|
|
||||||
priorityInput.value = priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onSelectOptions(event) {
|
|
||||||
if (event.button == 0 || (isWebKit() && event.button == 1)) {
|
|
||||||
var node = getTarget(event);
|
|
||||||
if (node.tagName != 'A')
|
|
||||||
node = $(node).up("A");
|
|
||||||
popupToolbarMenu(node, "optionsMenu");
|
|
||||||
Event.stop(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Overwrite definition of MailerUI.js
|
|
||||||
*/
|
|
||||||
function onWindowResize(event) {
|
|
||||||
if (!document.pageform)
|
|
||||||
return;
|
|
||||||
var textarea = document.pageform.text;
|
|
||||||
var rowheight = (Element.getHeight(textarea) / textarea.rows);
|
|
||||||
var headerarea = $("headerArea");
|
|
||||||
var totalwidth = $("rightPanel").getWidth();
|
|
||||||
|
|
||||||
var subjectfield = headerarea.down("div#subjectRow span.headerField");
|
|
||||||
var subjectinput = headerarea.down("div#subjectRow input.textField");
|
|
||||||
|
|
||||||
// Resize subject field
|
|
||||||
subjectinput.setStyle({ width: (totalwidth
|
|
||||||
- $(subjectfield).getWidth()
|
|
||||||
- 17) + 'px' });
|
|
||||||
// Resize from field
|
|
||||||
$("fromSelect").setStyle({ width: (totalwidth
|
|
||||||
- $("fromField").getWidth()
|
|
||||||
- 15) + 'px' });
|
|
||||||
|
|
||||||
// Resize address fields
|
|
||||||
// var addresslist = $('addressList');
|
|
||||||
// addresslist.setStyle({ width: (totalwidth - 10) + 'px' });
|
|
||||||
|
|
||||||
// Resize the textarea (message content)
|
|
||||||
var offsetTop = $('rightPanel').offsetTop + headerarea.getHeight();
|
|
||||||
var composeMode = UserDefaults["SOGoMailComposeMessageType"];
|
|
||||||
if (composeMode == "html") {
|
|
||||||
var editor = $('cke_text');
|
|
||||||
if (editor == null) {
|
|
||||||
onWindowResize.defer();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var height = window.height() - offsetTop;
|
|
||||||
CKEDITOR.instances["text"].resize('100%', height);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
textarea.rows = Math.floor((window.height() - offsetTop) / rowheight);
|
|
||||||
|
|
||||||
// Resize search contacts addressbook selector
|
|
||||||
if ($("contacts").visible())
|
|
||||||
$("contactFolder").setStyle({ width: ($("contactsSearch").getWidth() - 10) + "px" });
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMailEditorClose(event) {
|
|
||||||
var e = event || window.event;
|
|
||||||
|
|
||||||
if (window.shouldPreserve) {
|
|
||||||
window.shouldPreserve = false;
|
|
||||||
if (jQuery('#fileUpload').fileupload('active') > 0) {
|
|
||||||
var msg = _("There is an active file upload. Closing the window will interrupt it.");
|
|
||||||
if (e) {
|
|
||||||
e.returnValue = msg;
|
|
||||||
}
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var url = "" + window.location;
|
|
||||||
var parts = url.split("/");
|
|
||||||
parts[parts.length-1] = "delete";
|
|
||||||
url = parts.join("/");
|
|
||||||
if (window.frameElement && window.frameElement.id)
|
|
||||||
parent.deleteDraft(url);
|
|
||||||
else if (window.opener && window.opener.open && !window.opener.closed)
|
|
||||||
window.opener.deleteDraft(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
Event.stopObserving(window, "beforeunload", onMailEditorClose);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.observe("dom:loaded", initMailEditor);
|
|
|
@ -1,4 +0,0 @@
|
||||||
HTML, BODY
|
|
||||||
{ background-color: #fff;
|
|
||||||
font-size: normal;
|
|
||||||
font-family: sans-serif; }
|
|
|
@ -1,55 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
function onPrintCurrentMessage(event) {
|
|
||||||
window.print();
|
|
||||||
|
|
||||||
preventDefault(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
function initPopupMailer(event) {
|
|
||||||
configureLinksInMessage();
|
|
||||||
resizeMailContent();
|
|
||||||
|
|
||||||
configureLoadImagesButton();
|
|
||||||
configureSignatureFlagImage();
|
|
||||||
|
|
||||||
if (UserDefaults["SOGoMailDisplayRemoteInlineImages"] == 'always')
|
|
||||||
loadRemoteImages();
|
|
||||||
|
|
||||||
window.messageUID = mailboxName + "/" + messageName;
|
|
||||||
|
|
||||||
handleReturnReceipt();
|
|
||||||
|
|
||||||
var td = $("subject");
|
|
||||||
if (td)
|
|
||||||
document.title = td.allTextContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onICalendarButtonClick(event) {
|
|
||||||
var link = $("iCalendarAttachment").value;
|
|
||||||
if (link) {
|
|
||||||
var urlstr = link + "/" + this.action;
|
|
||||||
if (window.opener && window.opener.open && !window.opener.closed && window.messageUID) {
|
|
||||||
var c = window.opener;
|
|
||||||
window.opener.triggerAjaxRequest(urlstr,
|
|
||||||
window.opener.ICalendarButtonCallback,
|
|
||||||
window.messageUID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
log("no link");
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMenuDeleteMessage(event) {
|
|
||||||
if (window.opener && window.opener.open && !window.opener.closed) {
|
|
||||||
var url = ApplicationBaseURL + encodeURI(mailboxName) + "/batchDelete";
|
|
||||||
var path = mailboxName + "/" + messageName;
|
|
||||||
|
|
||||||
window.opener.deleteMessageWithDelay(url, messageName, mailboxName, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
window.close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
document.observe("dom:loaded", initPopupMailer);
|
|
|
@ -1,286 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright (C) 2005 SKYRIX Software AG
|
|
||||||
|
|
||||||
This file is part of OpenGroupware.org.
|
|
||||||
|
|
||||||
OGo is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU Lesser General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2, or (at your option) any
|
|
||||||
later version.
|
|
||||||
|
|
||||||
OGo is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
||||||
License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with OGo; see the file COPYING. If not, write to the
|
|
||||||
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|
||||||
02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Dependencies:
|
|
||||||
* It's required that "currentIndex" is defined in a top level context.
|
|
||||||
*
|
|
||||||
* Exports:
|
|
||||||
* defines hasRecipients() returning a bool for the
|
|
||||||
* surrounding context to check.
|
|
||||||
*/
|
|
||||||
|
|
||||||
var lastIndex = currentIndex;
|
|
||||||
|
|
||||||
function sanitizedCn(cn) {
|
|
||||||
var parts;
|
|
||||||
parts = cn.split(', ');
|
|
||||||
if(parts.length == 1)
|
|
||||||
return cn;
|
|
||||||
return parts[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
function hasAddress(email) {
|
|
||||||
var e = $(email);
|
|
||||||
if(e)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkAddresses() {
|
|
||||||
alert("addressCount: " + this.getAddressCount() + " currentIndex: " + currentIndex + " lastIndex: " + lastIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
function fancyAddRow(text, type) {
|
|
||||||
var addr = $('addr_' + lastIndex);
|
|
||||||
if (addr && addr.value == '') {
|
|
||||||
var sub = $('subjectField');
|
|
||||||
if (sub && sub.value != '') {
|
|
||||||
sub.focus();
|
|
||||||
sub.select();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var addressList = $("addressList").tBodies[0];
|
|
||||||
var lastChild = $("lastRow");
|
|
||||||
|
|
||||||
currentIndex++;
|
|
||||||
var proto = lastChild.previous("tr");
|
|
||||||
var row = proto.cloneNode(true);
|
|
||||||
row.writeAttribute("id", 'row_' + currentIndex);
|
|
||||||
var rowNodes = row.childNodesWithTag("td");
|
|
||||||
var select = $(rowNodes[0]).childNodesWithTag("select")[0];
|
|
||||||
select.name = 'popup_' + currentIndex;
|
|
||||||
select.value = (type? type : proto.down("select").value);
|
|
||||||
var cell = $(rowNodes[1]);
|
|
||||||
var input = cell.childNodesWithTag("input")[0];
|
|
||||||
if (Prototype.Browser.IE) {
|
|
||||||
cell.removeChild(input);
|
|
||||||
input = new Element("input");
|
|
||||||
cell.appendChild(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
input.name = 'addr_' + currentIndex;
|
|
||||||
input.id = 'addr_' + currentIndex;
|
|
||||||
input.value = text;
|
|
||||||
input.stopObserving();
|
|
||||||
input.addInterface(SOGoAutoCompletionInterface);
|
|
||||||
addressList.insertBefore(row, lastChild);
|
|
||||||
input.observe("focus", addressFieldGotFocus.bind(input));
|
|
||||||
input.observe("blur", addressFieldLostFocus.bind(input));
|
|
||||||
input.observe("autocompletion:changedlist", expandContactList);
|
|
||||||
input.on("autocompletion:changed", addressFieldChanged.bind(input));
|
|
||||||
input.focus();
|
|
||||||
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
function expandContactList (e) {
|
|
||||||
var container = $(e).memo;
|
|
||||||
var url = UserFolderURL + "Contacts/" + container + "/"
|
|
||||||
+ this.readAttribute("uid") + "/properties";
|
|
||||||
triggerAjaxRequest (url, expandContactListCallback, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
function expandContactListCallback (http) {
|
|
||||||
if (http.readyState == 4) {
|
|
||||||
var input = http.callbackData;
|
|
||||||
if (http.status == 200) {
|
|
||||||
var data = http.responseText.evalJSON(true);
|
|
||||||
// TODO: Should check for duplicated entries
|
|
||||||
for (var i = data.length - 1; i >= 0; i--)
|
|
||||||
// Remove contacts with no email address
|
|
||||||
if (data[i][2].length == 0) data.splice(i, 1);
|
|
||||||
if (data.length >= 1) {
|
|
||||||
var text = data[0][2];
|
|
||||||
if (data[0][1].length)
|
|
||||||
text = data[0][1] + " <" + data[0][2] + ">";
|
|
||||||
input.value = text;
|
|
||||||
input.writeAttribute("container", null);
|
|
||||||
}
|
|
||||||
if (data.length > 1) {
|
|
||||||
for (var i = 1; i < data.length; i++) {
|
|
||||||
var text = data[i][2];
|
|
||||||
if (data[i][1].length)
|
|
||||||
text = data[i][1] + " <" + data[i][2] + ">";
|
|
||||||
fancyAddRow(text, $(input).up("tr").down("select").value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function addressFieldGotFocus(event) {
|
|
||||||
var idx;
|
|
||||||
|
|
||||||
idx = getIndexFromIdentifier(this.id);
|
|
||||||
if (lastIndex == idx) return;
|
|
||||||
removeLastEditedRowIfEmpty();
|
|
||||||
if (Prototype.Browser.IE && this.value.length == 0)
|
|
||||||
$(this).setCaretTo(0); // IE hack
|
|
||||||
onWindowResize(null);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function addressFieldLostFocus(event) {
|
|
||||||
lastIndex = getIndexFromIdentifier(this.id);
|
|
||||||
addressFieldChanged.bind(this, event)();
|
|
||||||
}
|
|
||||||
|
|
||||||
function addressFieldChanged(event) {
|
|
||||||
// We first split by semi-colon and then by comma only if there's no
|
|
||||||
// email address detected.
|
|
||||||
// Examples:
|
|
||||||
// "dude, buddy dude@domain.com; bro" => "dude, buddy <dude@domain.com>" + "bro"
|
|
||||||
// "dude, buddy, bro <bro@domain.com>" => "dude, buddy, bro <bro@domain.com>"
|
|
||||||
// "dude, buddy, bro" => "dude" + "buddy" + "bro"
|
|
||||||
// "dude@domain.com, <buddy@domain.com>" => "<dude@domain.com>" + "<buddy@domain.com>"
|
|
||||||
var addresses = this.value.split(';');
|
|
||||||
if (addresses.length > 0) {
|
|
||||||
var first = true;
|
|
||||||
for (var i = 0; i < addresses.length; i++) {
|
|
||||||
var words = addresses[i]
|
|
||||||
.replace('\t', ' ')
|
|
||||||
.replace(/,(?! )/, ', ')
|
|
||||||
.split(' ');
|
|
||||||
var phrase = new Array();
|
|
||||||
for (var j = 0; j < words.length; j++) {
|
|
||||||
var word = words[j].strip().replace(/<(.+)>/, "$1").replace(',', '');
|
|
||||||
if (word.length > 0) {
|
|
||||||
// Use the regexp defined in generic.js
|
|
||||||
if (emailRE.test(word)) {
|
|
||||||
phrase.push('<' + word + '>');
|
|
||||||
if (first) {
|
|
||||||
this.value = phrase.join(' ');
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
fancyAddRow(phrase.join(' '), $(this).up("tr").down("select").value);
|
|
||||||
|
|
||||||
phrase = new Array();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
phrase.push(words[j].strip());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (phrase.length > 0) {
|
|
||||||
words = phrase.join(' ').split(',');
|
|
||||||
for (var j = 0; j < words.length; j++) {
|
|
||||||
word = words[j];
|
|
||||||
if (first) {
|
|
||||||
this.value = word;
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
fancyAddRow(word, $(this).up("tr").down("select").value);
|
|
||||||
}
|
|
||||||
|
|
||||||
phrase = new Array();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify if a new row should be created
|
|
||||||
var keyCode = event.memo;
|
|
||||||
if (keyCode == Event.KEY_RETURN) {
|
|
||||||
var input = fancyAddRow("");
|
|
||||||
if (Prototype.Browser.IE)
|
|
||||||
$(input.id).focus();
|
|
||||||
else
|
|
||||||
input.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
onWindowResize(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeLastEditedRowIfEmpty() {
|
|
||||||
var addr, addressList, senderRow;
|
|
||||||
|
|
||||||
addressList = $("addressList").tBodies[0];
|
|
||||||
|
|
||||||
if (lastIndex == 0 && addressList.childNodes.length <= 2) return;
|
|
||||||
addr = $('addr_' + lastIndex);
|
|
||||||
if (!addr) return;
|
|
||||||
if (addr.value.strip() != '') return;
|
|
||||||
senderRow = $("row_" + lastIndex);
|
|
||||||
addressList.removeChild(senderRow);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getIndexFromIdentifier(id) {
|
|
||||||
return id.split('_')[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
function getAddressIDs() {
|
|
||||||
var addressList, rows, i, count, addressIDs;
|
|
||||||
|
|
||||||
addressIDs = new Array();
|
|
||||||
|
|
||||||
addressList = $("addressList").tBodies[0];
|
|
||||||
rows = addressList.childNodes;
|
|
||||||
count = rows.length;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
var row, rowId;
|
|
||||||
|
|
||||||
row = rows[i];
|
|
||||||
rowId = row.id;
|
|
||||||
if (rowId && rowId != 'lastRow') {
|
|
||||||
var idx;
|
|
||||||
|
|
||||||
idx = this.getIndexFromIdentifier(rowId);
|
|
||||||
addressIDs.push(idx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return addressIDs;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getAddressCount() {
|
|
||||||
var addressCount, addressIDs, i, count;
|
|
||||||
|
|
||||||
addressCount = 0;
|
|
||||||
addressIDs = this.getAddressIDs();
|
|
||||||
count = addressIDs.length;
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
var idx, input;
|
|
||||||
|
|
||||||
idx = addressIDs[i];
|
|
||||||
input = $('addr_' + idx);
|
|
||||||
if (input && input.value != '')
|
|
||||||
addressCount++;
|
|
||||||
}
|
|
||||||
return addressCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
function hasRecipients() {
|
|
||||||
var count;
|
|
||||||
|
|
||||||
count = this.getAddressCount();
|
|
||||||
|
|
||||||
return (count > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
function initMailToSelection() {
|
|
||||||
currentIndex = lastIndex = $$("table#addressList tr").length - 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
document.observe("dom:loaded", initMailToSelection);
|
|
|
@ -1,58 +0,0 @@
|
||||||
DIV.delegation
|
|
||||||
{ position: absolute;
|
|
||||||
top: 0px;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
bottom: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
border: 0px;
|
|
||||||
margin: 0px; }
|
|
||||||
|
|
||||||
DIV.delegation LABEL
|
|
||||||
{ white-space: nowrap;
|
|
||||||
width: 100%; }
|
|
||||||
|
|
||||||
#delegateRoles
|
|
||||||
{ position: absolute;
|
|
||||||
top: 5px;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
bottom: 0px; }
|
|
||||||
|
|
||||||
#delegateSelectorButtons
|
|
||||||
{ margin-left: 5px;
|
|
||||||
padding-bottom: 2px; }
|
|
||||||
|
|
||||||
UL#delegateList
|
|
||||||
{ position: absolute;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
top: 40px;
|
|
||||||
bottom: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: auto;
|
|
||||||
border-bottom: 1px solid #fff;
|
|
||||||
border-right: 1px solid #fff;
|
|
||||||
border-top: 1px solid #909090;
|
|
||||||
border-left: 1px solid #909090;
|
|
||||||
background-color: #CCDDEC;
|
|
||||||
list-style-type: none;
|
|
||||||
list-style-image: none; }
|
|
||||||
|
|
||||||
UL#delegateList LI
|
|
||||||
{ clear: both;
|
|
||||||
cursor: pointer;
|
|
||||||
height: 20px;
|
|
||||||
margin-left: 0px;
|
|
||||||
padding-left: 24px;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: 4px center;
|
|
||||||
background-image: url("abcard.png"); }
|
|
||||||
|
|
||||||
DIV#delegateSelectorButtons A.smallToolbarButton
|
|
||||||
{ float: left; }
|
|
||||||
|
|
||||||
SPAN.userFullName
|
|
||||||
{ margin-top: 2px; }
|
|
|
@ -1,111 +0,0 @@
|
||||||
var contactSelectorAction = 'delegation-contacts';
|
|
||||||
|
|
||||||
function addDelegate(delegateName, delegateID) {
|
|
||||||
var result = false;
|
|
||||||
if (!$(delegateID)) {
|
|
||||||
var ul = $("delegateList");
|
|
||||||
var newNode = nodeForDelegate(delegateName, delegateID);
|
|
||||||
ul.appendChild(newNode);
|
|
||||||
|
|
||||||
var url = window.location.href;
|
|
||||||
var elements = url.split("/");
|
|
||||||
elements[elements.length-1] = ("addDelegate?uid="
|
|
||||||
+ delegateID);
|
|
||||||
triggerAjaxRequest(elements.join("/"), addDelegateCallback, newNode);
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function addDelegateCallback(http) {
|
|
||||||
if (http.readyState == 4) {
|
|
||||||
if (!isHttpStatus204(http.status)) {
|
|
||||||
var node = http.callbackData;
|
|
||||||
node.parentNode.removeChild(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setEventsOnDelegateNode(node) {
|
|
||||||
node.observe("mousedown", listRowMouseDownHandler);
|
|
||||||
node.observe("selectstart", listRowMouseDownHandler);
|
|
||||||
node.observe("click", onRowClick);
|
|
||||||
}
|
|
||||||
|
|
||||||
function nodeForDelegate(delegateName, delegateId) {
|
|
||||||
var node = createElement("li");
|
|
||||||
node.id = delegateId;
|
|
||||||
|
|
||||||
var span = createElement("span");
|
|
||||||
span.addClassName("userFullName");
|
|
||||||
span.appendChild(document.createTextNode(" " + delegateName));
|
|
||||||
node.appendChild(span);
|
|
||||||
|
|
||||||
setEventsOnDelegateNode(node);
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onDelegateAdd(event) {
|
|
||||||
openUserFolderSelector(null, "user");
|
|
||||||
|
|
||||||
preventDefault(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeDelegateCallback(http) {
|
|
||||||
var node = http.callbackData;
|
|
||||||
|
|
||||||
if (http.readyState == 4
|
|
||||||
&& isHttpStatus204(http.status))
|
|
||||||
node.parentNode.removeChild(node);
|
|
||||||
else
|
|
||||||
log("error deleting delegate: " + node.getAttribute("id"));
|
|
||||||
}
|
|
||||||
|
|
||||||
function onDelegateRemove(event) {
|
|
||||||
var delegateList = $("delegateList");
|
|
||||||
var nodes = delegateList.getSelectedRows();
|
|
||||||
|
|
||||||
var url = window.location.href;
|
|
||||||
var elements = url.split("/");
|
|
||||||
elements[elements.length-1] = "removeDelegate?uid=";
|
|
||||||
var baseURL = elements.join("/");
|
|
||||||
|
|
||||||
for (var i = 0; i < nodes.length; i++) {
|
|
||||||
var delegateId = nodes[i].id;
|
|
||||||
triggerAjaxRequest(baseURL + delegateId, removeDelegateCallback,
|
|
||||||
nodes[i]);
|
|
||||||
}
|
|
||||||
preventDefault(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
function subscribeToFolder(refreshCallback, refreshCallbackData) {
|
|
||||||
var result = true;
|
|
||||||
if (UserLogin != refreshCallbackData["folder"]) {
|
|
||||||
result = addDelegate(refreshCallbackData["folderName"],
|
|
||||||
refreshCallbackData["folder"]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
refreshCallbackData["window"].alert(_("You cannot subscribe to a folder that you own!"));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onDelegationLoadHandler() {
|
|
||||||
var ul = $("delegateList");
|
|
||||||
var lis = ul.childNodesWithTag("li");
|
|
||||||
for (var i = 0; i < lis.length; i++)
|
|
||||||
setEventsOnDelegateNode(lis[i]);
|
|
||||||
|
|
||||||
var buttonArea = $("delegateSelectorButtons");
|
|
||||||
if (buttonArea) {
|
|
||||||
var buttons = buttonArea.childNodesWithTag("a");
|
|
||||||
$("addDelegate").stopObserving ("click");
|
|
||||||
$("deleteDelegate").stopObserving ("click");
|
|
||||||
$("addDelegate").observe("mousedown", onDelegateAdd);
|
|
||||||
$("deleteDelegate").observe("mousedown", onDelegateRemove);
|
|
||||||
}
|
|
||||||
|
|
||||||
Event.observe(window, "unload", onDelegationCloseHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.observe("dom:loaded", onDelegationLoadHandler);
|
|
|
@ -1,31 +0,0 @@
|
||||||
DIV.title
|
|
||||||
{ color: #000;
|
|
||||||
vertical-align: bottom;
|
|
||||||
padding-top: 8px;
|
|
||||||
padding-left: 1em;
|
|
||||||
padding: 5px;
|
|
||||||
background-color: #fff;
|
|
||||||
border-bottom: 1px solid #555; }
|
|
||||||
|
|
||||||
DIV.title SPAN.value
|
|
||||||
{ margin-left: 2em;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: bold; }
|
|
||||||
|
|
||||||
DIV.title LABEL
|
|
||||||
{ display: block; }
|
|
||||||
|
|
||||||
DIV.calendarUserRights,
|
|
||||||
DIV.basicUserRights
|
|
||||||
{ margin: 1em;}
|
|
||||||
|
|
||||||
DIV.buttons
|
|
||||||
{ text-align: right;
|
|
||||||
margin: 1em; }
|
|
||||||
|
|
||||||
DIV.dialog.none
|
|
||||||
{ position: absolute;
|
|
||||||
top: 0px;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
margin: 75px auto; }
|
|
|
@ -1,51 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
function onUpdateACL(event) {
|
|
||||||
if ($('uid').value == 'anyone') {
|
|
||||||
var inputs = $$('#userRightsForm input[type="checkbox"]');
|
|
||||||
var enabled = false;
|
|
||||||
for (var i = 0; i < inputs.length; i++) {
|
|
||||||
if (inputs[i].checked) {
|
|
||||||
enabled = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (enabled) {
|
|
||||||
showConfirmDialog(_("Warning"), _("Any user with an account on this system will be able to access your mailbox \"%{0}\". Are you certain you trust them all?").formatted($("folderName").allTextContent()),
|
|
||||||
onUpdateACLConfirm, onUpdateACLCancel,
|
|
||||||
"Give Access", "Keep Private");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return onUpdateACLConfirm(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onUpdateACLConfirm(event) {
|
|
||||||
disposeDialog();
|
|
||||||
|
|
||||||
$('userRightsForm').submit();
|
|
||||||
Event.stop(event);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onUpdateACLCancel(event) {
|
|
||||||
var inputs = $$('#userRightsForm input[type="checkbox"]');
|
|
||||||
for (var i = 0; i < inputs.length; i++)
|
|
||||||
if (inputs[i].checked)
|
|
||||||
inputs[i].checked = false;
|
|
||||||
|
|
||||||
disposeDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onCancelACL(event) {
|
|
||||||
window.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
function initACLButtons() {
|
|
||||||
$("updateButton").observe("click", onUpdateACL);
|
|
||||||
$("cancelButton").observe("click", onCancelACL);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.observe("dom:loaded", initACLButtons);
|
|
|
@ -1,7 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
function onPrintCurrentMessage(event) {
|
|
||||||
window.print();
|
|
||||||
|
|
||||||
preventDefault(event);
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
DIV#message, DIV#windowButtons
|
|
||||||
{ margin: 10px; }
|
|
||||||
|
|
||||||
DIV#windowButtons INPUT
|
|
||||||
{ text-align: center; }
|
|
||||||
|
|
||||||
DIV#leftButtons
|
|
||||||
{ float: left;
|
|
||||||
width: 200px;
|
|
||||||
text-align: left; }
|
|
||||||
|
|
||||||
DIV#rightButtons
|
|
||||||
{ text-align: right; }
|
|
||||||
|
|
||||||
A#thisButton
|
|
||||||
{ float: left !important; }
|
|
|
@ -1,48 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
function onCancelButtonClick(event) {
|
|
||||||
window.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onThisButtonClick(event) {
|
|
||||||
if (action == 'edit')
|
|
||||||
window.opener.performEventEdition(calendarFolder, componentName,
|
|
||||||
recurrenceName);
|
|
||||||
else if (action == 'delete')
|
|
||||||
window.opener.performEventDeletion(calendarFolder, componentName,
|
|
||||||
recurrenceName);
|
|
||||||
else if (action == 'adjust')
|
|
||||||
window.opener.performEventAdjustment(calendarFolder, componentName,
|
|
||||||
recurrenceName, queryParameters);
|
|
||||||
else
|
|
||||||
window.alert("Invalid action: " + action);
|
|
||||||
|
|
||||||
window.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onAllButtonClick(event) {
|
|
||||||
if (action == 'edit')
|
|
||||||
window.opener.performEventEdition(calendarFolder, componentName);
|
|
||||||
else if (action == 'delete')
|
|
||||||
window.opener.performEventDeletion(calendarFolder, componentName);
|
|
||||||
else if (action == 'adjust')
|
|
||||||
window.opener.performEventAdjustment(calendarFolder, componentName,
|
|
||||||
null, queryParameters);
|
|
||||||
else
|
|
||||||
window.alert("Invalid action: " + action);
|
|
||||||
|
|
||||||
window.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onOccurenceDialogLoad() {
|
|
||||||
var thisButton = $("thisButton");
|
|
||||||
thisButton.observe("click", onThisButtonClick);
|
|
||||||
|
|
||||||
var allButton = $("allButton");
|
|
||||||
allButton.observe("click", onAllButtonClick);
|
|
||||||
|
|
||||||
var cancelButton = $("cancelButton");
|
|
||||||
cancelButton.observe("click", onCancelButtonClick);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.observe("dom:loaded", onOccurenceDialogLoad);
|
|
|
@ -1,272 +0,0 @@
|
||||||
DIV#preferencesTabs
|
|
||||||
{ position: absolute;
|
|
||||||
top: 54px;
|
|
||||||
left: 5px;
|
|
||||||
right: 5px;
|
|
||||||
bottom: 5px; }
|
|
||||||
|
|
||||||
DIV.bottomToolbar
|
|
||||||
{ position: absolute;
|
|
||||||
height: 20px;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
left: 2em;
|
|
||||||
right: 2em;
|
|
||||||
bottom: 8px; }
|
|
||||||
|
|
||||||
#WhiteListAdd, #WhiteListDelete
|
|
||||||
{
|
|
||||||
border-bottom: 1px solid #9B9B9B;
|
|
||||||
border-right: 1px solid #9B9B9B;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mailAccountsToolbar
|
|
||||||
{ left: 5px;
|
|
||||||
bottom: 9px;
|
|
||||||
width: 130px; }
|
|
||||||
|
|
||||||
TABLE.categoriesList
|
|
||||||
{ width: 100%; }
|
|
||||||
|
|
||||||
#colorTableHeader
|
|
||||||
{ width: 50px; }
|
|
||||||
|
|
||||||
TR.categoryListRow
|
|
||||||
{ background: #ccddec;
|
|
||||||
cursor: pointer; }
|
|
||||||
|
|
||||||
TD.categoryListCell
|
|
||||||
{ -moz-user-select: none; }
|
|
||||||
|
|
||||||
DIV.colorBox
|
|
||||||
{ -webkit-border-radius: 4px;
|
|
||||||
-moz-border-radius: 4px;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: 2px solid #ccddec; }
|
|
||||||
|
|
||||||
DIV.colorBox:hover
|
|
||||||
{ border-color: #eee; }
|
|
||||||
|
|
||||||
DIV.listWrapper
|
|
||||||
{ overflow: auto;
|
|
||||||
position: absolute;
|
|
||||||
padding: 0px;
|
|
||||||
margin-top: 2px;
|
|
||||||
border-left: 1px solid #9b9b9b;
|
|
||||||
border-right: 1px solid #9b9b9b;
|
|
||||||
background: #ccddec;}
|
|
||||||
|
|
||||||
.listWrapper TABLE TD
|
|
||||||
{ height: 22px; }
|
|
||||||
|
|
||||||
#calendarCategoriesListWrapper
|
|
||||||
{ top:1em;
|
|
||||||
bottom: 30px;
|
|
||||||
right: 2em;
|
|
||||||
left: 2em; }
|
|
||||||
|
|
||||||
#appointmentsWhiteListWrapper
|
|
||||||
{ top:4.5em;
|
|
||||||
bottom: 30px;
|
|
||||||
right: 2em;
|
|
||||||
left: 2em; }
|
|
||||||
|
|
||||||
#tableViewWhiteList
|
|
||||||
{ width:100%; }
|
|
||||||
|
|
||||||
DIV#calendarOptionsTabs
|
|
||||||
{ position: absolute;
|
|
||||||
top: 225px;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
bottom: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#contactsCategoriesListWrapper
|
|
||||||
{ overflow: auto;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 30px;
|
|
||||||
right: 2em;
|
|
||||||
top: 20px;
|
|
||||||
left: 2em;
|
|
||||||
padding: 0px;
|
|
||||||
margin-top: 2px;
|
|
||||||
border-left: 1px solid #9b9b9b;
|
|
||||||
background: #ccddec; }
|
|
||||||
|
|
||||||
/* time date control */
|
|
||||||
SPAN.timeDateControl INPUT.textField
|
|
||||||
{ width: 7em;
|
|
||||||
vertical-align: text-bottom; }
|
|
||||||
|
|
||||||
/* vacation, forward */
|
|
||||||
#vacation, #forward
|
|
||||||
{ padding-left: 2.5em; }
|
|
||||||
#vacation LABEL
|
|
||||||
{ margin-left: 0; }
|
|
||||||
#vacation TEXTAREA,
|
|
||||||
#forward TEXTAREA
|
|
||||||
{ width: 100%; }
|
|
||||||
#vacation TEXTAREA#autoReplyText
|
|
||||||
{ height: 100px; }
|
|
||||||
#vacation TEXTAREA#autoReplyEmailAddresses,
|
|
||||||
#forward TEXTAREA
|
|
||||||
{ height: 50px; }
|
|
||||||
#vacation SPAN
|
|
||||||
{ float: right; }
|
|
||||||
#vacation SPAN.timeDateControl,
|
|
||||||
#vacation SPAN.timeDateControl SPAN
|
|
||||||
{ float: none;
|
|
||||||
vertical-align: middle; }
|
|
||||||
#vacation BR,
|
|
||||||
#passwordView BR
|
|
||||||
{ clear: both; }
|
|
||||||
|
|
||||||
/* mail options */
|
|
||||||
DIV#mailOptionsTabs
|
|
||||||
{ position: absolute;
|
|
||||||
top: 225px;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
bottom: 0px; }
|
|
||||||
|
|
||||||
DIV#filtersListWrapper,
|
|
||||||
DIV#mailLabelsListWrapper
|
|
||||||
{ bottom: 22px;
|
|
||||||
right: 0px;
|
|
||||||
top: 0px;
|
|
||||||
left: 0px; }
|
|
||||||
|
|
||||||
#mailOptionsTabs .bottomToolbar
|
|
||||||
{ bottom: 0px;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px; }
|
|
||||||
|
|
||||||
DIV#filtersListWrapper TD,
|
|
||||||
DIV#mailLabelsListWrapper TD,
|
|
||||||
DIV.bottomToolbar
|
|
||||||
{ -khtml-user-select: none;
|
|
||||||
-moz-user-select: none; }
|
|
||||||
|
|
||||||
#filtersList, #labelsList
|
|
||||||
{ width: 100%;
|
|
||||||
cursor: default; }
|
|
||||||
|
|
||||||
TH#activeTableHeader
|
|
||||||
{ width: 50px;
|
|
||||||
text-align: center; }
|
|
||||||
|
|
||||||
TD.activeColumn
|
|
||||||
{ text-align: center; }
|
|
||||||
|
|
||||||
P#passwordFields,
|
|
||||||
P#passwordError
|
|
||||||
{ width: 410px;
|
|
||||||
text-align: right; }
|
|
||||||
|
|
||||||
P.errorMessage#passwordError
|
|
||||||
{ color: #f00; }
|
|
||||||
|
|
||||||
P.infoMessage#passwordError
|
|
||||||
{ color: #00f; }
|
|
||||||
|
|
||||||
/* mail accounts */
|
|
||||||
#mailAccountsListWrapper, #mailAccountEditor
|
|
||||||
{ bottom: 30px;
|
|
||||||
top: 5px;
|
|
||||||
left: 0px;
|
|
||||||
margin: 0px; }
|
|
||||||
|
|
||||||
#mailAccountEditor
|
|
||||||
{ position: absolute;
|
|
||||||
overflow: auto;
|
|
||||||
bottom: 30px;
|
|
||||||
left: 140px;
|
|
||||||
padding: 0px;
|
|
||||||
right: 5px; }
|
|
||||||
|
|
||||||
#mailAccountEditor dl
|
|
||||||
{ margin: 5px; }
|
|
||||||
|
|
||||||
#mailAccountsListWrapper
|
|
||||||
{ overflow-x: hidden;
|
|
||||||
left: 5px;
|
|
||||||
width: 130px;
|
|
||||||
border-top: 1px solid #9b9b9b; }
|
|
||||||
|
|
||||||
#mailAccountsList
|
|
||||||
{ position: absolute;
|
|
||||||
top: 0px;
|
|
||||||
bottom: 0px;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px; }
|
|
||||||
|
|
||||||
#mailAccountsList LI
|
|
||||||
{ cursor: pointer;
|
|
||||||
white-space: nowrap;
|
|
||||||
padding-left: 5px;
|
|
||||||
height: 22px;
|
|
||||||
line-height: 22px; }
|
|
||||||
|
|
||||||
#mailAccountsList LI.readonly
|
|
||||||
{ cursor: default;
|
|
||||||
font-style: italic; }
|
|
||||||
|
|
||||||
#serverName
|
|
||||||
{ width: 100px; }
|
|
||||||
|
|
||||||
#port
|
|
||||||
{ width: 30px; }
|
|
||||||
|
|
||||||
#userName, #password
|
|
||||||
{ width: 180px; }
|
|
||||||
|
|
||||||
#fullName, #email, #replyTo
|
|
||||||
{ width: 180px; }
|
|
||||||
|
|
||||||
#actSignature
|
|
||||||
{ color: #55f;
|
|
||||||
cursor: pointer;
|
|
||||||
text-decoration: underline; }
|
|
||||||
|
|
||||||
#actSignature.disabled
|
|
||||||
{ color: #999;
|
|
||||||
cursor: default;
|
|
||||||
text-decoration: none; }
|
|
||||||
|
|
||||||
#signatureDialog
|
|
||||||
{ position: absolute;
|
|
||||||
left: 10px;
|
|
||||||
width: auto !important;
|
|
||||||
right: 10px;
|
|
||||||
top: 0px; }
|
|
||||||
|
|
||||||
#cke_signature, #cke_signature div
|
|
||||||
{ padding: 0px; }
|
|
||||||
|
|
||||||
#signature
|
|
||||||
{ width: 100%;
|
|
||||||
height: 170px;
|
|
||||||
margin: 0px auto;
|
|
||||||
margin-bottom: 10px; }
|
|
||||||
|
|
||||||
#receiptOptions
|
|
||||||
{ text-align: right; }
|
|
||||||
|
|
||||||
#colorPickerDialog
|
|
||||||
{ width: 146px;
|
|
||||||
height: 191px; }
|
|
||||||
|
|
||||||
#colorPickerDialog.dialog.right > DIV
|
|
||||||
{ padding-left: 10px; }
|
|
||||||
|
|
||||||
.dialog.bottom > DIV:before {
|
|
||||||
top: auto;
|
|
||||||
bottom: 12px;
|
|
||||||
}
|
|
||||||
.dialog.bottom > DIV:after {
|
|
||||||
top: auto;
|
|
||||||
bottom: 13px;
|
|
||||||
}
|
|
|
@ -1,92 +0,0 @@
|
||||||
DIV#windowButtonz
|
|
||||||
{ position: absolute;
|
|
||||||
bottom: 0px;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
height: 2em;
|
|
||||||
margin: 1em;
|
|
||||||
text-align: right; }
|
|
||||||
|
|
||||||
DIV#windowButtons
|
|
||||||
{ position: absolute;
|
|
||||||
bottom: 0px;
|
|
||||||
left: 0px;
|
|
||||||
right: 15px;
|
|
||||||
height: 3em;
|
|
||||||
line-height: 2em;
|
|
||||||
vertical-align: middle;
|
|
||||||
text-align: right; }
|
|
||||||
|
|
||||||
DIV#pageContent
|
|
||||||
{ padding: 1em; }
|
|
||||||
|
|
||||||
TABLE.frame TH
|
|
||||||
{ font-weight: normal;
|
|
||||||
text-align: right;
|
|
||||||
width: 5em; }
|
|
||||||
|
|
||||||
TABLE TD
|
|
||||||
{ text-align: left; }
|
|
||||||
|
|
||||||
TABLE TD.label
|
|
||||||
{ width: 11em; }
|
|
||||||
|
|
||||||
INPUT.textField
|
|
||||||
{ margin: 0px 0.7em;
|
|
||||||
width: 2em; }
|
|
||||||
|
|
||||||
SPAN.datePicker INPUT.textField
|
|
||||||
{ width: 6em; }
|
|
||||||
|
|
||||||
SPAN.datePicker SPAN IMG
|
|
||||||
{ vertical-align: top; }
|
|
||||||
|
|
||||||
/* Days selectors */
|
|
||||||
|
|
||||||
DIV#week,
|
|
||||||
DIV#month
|
|
||||||
{ background-color: #fff;
|
|
||||||
border-top: 1px solid #fff;
|
|
||||||
border-left: 1px solid #fff;
|
|
||||||
border-right: 1px solid #999;
|
|
||||||
border-bottom: 1px solid #999; }
|
|
||||||
|
|
||||||
DIV#week
|
|
||||||
{ width: 210px; /* 7*(28+2)px */ }
|
|
||||||
|
|
||||||
DIV#month
|
|
||||||
{ width: 140px; /* 7*(18+2)px */ }
|
|
||||||
|
|
||||||
SPAN.week
|
|
||||||
{ clear: both;
|
|
||||||
display: block; }
|
|
||||||
|
|
||||||
SPAN.week DIV
|
|
||||||
{ border: 1px solid #fff;
|
|
||||||
cursor: pointer;
|
|
||||||
display: block;
|
|
||||||
float: left; }
|
|
||||||
|
|
||||||
SPAN.week DIV._selected
|
|
||||||
{ background-color: #4b6983;
|
|
||||||
border-color: #4b6983;
|
|
||||||
color: #fff; }
|
|
||||||
|
|
||||||
SPAN.week DIV P
|
|
||||||
{ display: block;
|
|
||||||
margin: 2px 0px;
|
|
||||||
padding: 0px;
|
|
||||||
text-align: center; }
|
|
||||||
|
|
||||||
DIV#week SPAN.week DIV P
|
|
||||||
{ width: 28px; }
|
|
||||||
|
|
||||||
DIV#month SPAN.week DIV P
|
|
||||||
{ width: 18px; }
|
|
||||||
|
|
||||||
SPAN.week DIV:hover
|
|
||||||
{ border: 1px solid #4b6983; }
|
|
||||||
|
|
||||||
A.calendarButton
|
|
||||||
{ right: 240px; }
|
|
||||||
|
|
|
@ -1,404 +0,0 @@
|
||||||
/* -*- Mode: java; tab-width: 2; c-label-minimum-indentation: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
var RecurrenceEditor = {
|
|
||||||
types: new Array("Daily", "Weekly", "Monthly", "Yearly"),
|
|
||||||
currentRepeatType: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
function onRepeatTypeChange(event) {
|
|
||||||
setRepeatType(parseInt(this.value));
|
|
||||||
}
|
|
||||||
|
|
||||||
function setRepeatType(type) {
|
|
||||||
var elements;
|
|
||||||
|
|
||||||
RecurrenceEditor.currentRepeatType = type;
|
|
||||||
|
|
||||||
for (var i = 0; i <= 3; i++) {
|
|
||||||
elements = $$("TABLE TR.recurrence" + RecurrenceEditor.types[i]);
|
|
||||||
if (i != type)
|
|
||||||
elements.each(function(row) {
|
|
||||||
row.hide();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
elements = $$("TABLE TR.recurrence" + RecurrenceEditor.types[type]);
|
|
||||||
elements.each(function(row) {
|
|
||||||
row.show();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSelectedDays(periodType) {
|
|
||||||
var element = $(periodType);
|
|
||||||
var elementsArray = $A(element.getElementsByTagName('DIV'));
|
|
||||||
var days = new Array();
|
|
||||||
var dayPrefix = periodType + "Day";
|
|
||||||
elementsArray.each(function(item) {
|
|
||||||
if (isNodeSelected(item)) {
|
|
||||||
var label = "" + item.getAttribute("id");
|
|
||||||
days.push(label.substr(dayPrefix.length));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return days.join(",");
|
|
||||||
}
|
|
||||||
|
|
||||||
function onDayClick(event) {
|
|
||||||
var element = $(this);
|
|
||||||
if (isNodeSelected(element))
|
|
||||||
this.removeClassName("_selected");
|
|
||||||
else
|
|
||||||
this.addClassName("_selected");
|
|
||||||
}
|
|
||||||
|
|
||||||
function onRangeChange(event) {
|
|
||||||
$('endDate_date').disabled = (this.value != 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onAdjustTime(event) {
|
|
||||||
// must be defined for date picker widget
|
|
||||||
}
|
|
||||||
|
|
||||||
function initializeSelectors() {
|
|
||||||
$$("DIV#week SPAN.week DIV").each(function(element) {
|
|
||||||
element.observe("click", onDayClick, false);
|
|
||||||
});
|
|
||||||
|
|
||||||
$$("DIV#month SPAN.week DIV").each(function(element) {
|
|
||||||
element.observe("click", onDayClick, false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function initializeWindowButtons() {
|
|
||||||
var okButton = $("okButton");
|
|
||||||
var cancelButton = $("cancelButton");
|
|
||||||
|
|
||||||
okButton.observe("click", onEditorOkClick, false);
|
|
||||||
cancelButton.observe("click", onEditorCancelClick, false);
|
|
||||||
|
|
||||||
var repeatType = $("repeatType");
|
|
||||||
setRepeatType(parseInt(repeatType.value));
|
|
||||||
repeatType.observe("change", onRepeatTypeChange, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
function initializeFormValues() {
|
|
||||||
var repeatType = parent$("repeatType").value;
|
|
||||||
|
|
||||||
// Select repeat type
|
|
||||||
$("repeatType").value = repeatType;
|
|
||||||
|
|
||||||
// Default values
|
|
||||||
var startTimeDate = parent$("startTime_date").value.asDate();
|
|
||||||
$('yearlyDayField').value = startTimeDate.getDate();
|
|
||||||
$('yearlyMonth1').value = startTimeDate.getMonth();
|
|
||||||
$("weekDay"+startTimeDate.getDay()).addClassName("_selected");
|
|
||||||
$("monthDay"+startTimeDate.getDate()).addClassName("_selected");
|
|
||||||
|
|
||||||
$('recurrence_form').setRadioValue('dailyRadioButtonName', 0);
|
|
||||||
$('recurrence_form').setRadioValue('monthlyRadioButtonName', 1);
|
|
||||||
$('recurrence_form').setRadioValue('yearlyRadioButtonName', 0);
|
|
||||||
$('endDate_date').disabled = true;
|
|
||||||
$('dailyDaysField').value = "1";
|
|
||||||
$('weeklyWeeksField').value = "1";
|
|
||||||
$('monthlyMonthsField').value = "1";
|
|
||||||
$('yearlyYearsField').value = "1";
|
|
||||||
|
|
||||||
if (repeatType == 0) {
|
|
||||||
// Repeat daily
|
|
||||||
$('recurrence_form').setRadioValue('dailyRadioButtonName', parent$("repeat1").value);
|
|
||||||
$('dailyDaysField').value = parent$("repeat2").value;
|
|
||||||
}
|
|
||||||
else if (repeatType == 1) {
|
|
||||||
// Repeat weekly
|
|
||||||
$('weeklyWeeksField').value = parent$("repeat1").value;
|
|
||||||
// log ("div: " + weekDiv);
|
|
||||||
// log ("days: " + parent$("repeat2").value);
|
|
||||||
for (var i = 0; i < 7; i++) {
|
|
||||||
$("weekDay" + i).removeClassName("_selected");
|
|
||||||
}
|
|
||||||
var days = "" + parent$("repeat2").value;
|
|
||||||
if (days.length > 0) {
|
|
||||||
var daysArray = days.split(",");
|
|
||||||
daysArray.each(function(index) {
|
|
||||||
$("weekDay"+index).addClassName("_selected");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (repeatType == 2) {
|
|
||||||
// Repeat monthly
|
|
||||||
$('monthlyMonthsField').value = parent$("repeat1").value;
|
|
||||||
$('recurrence_form').setRadioValue('monthlyRadioButtonName', parent$("repeat2").value);
|
|
||||||
$('monthlyRepeat').value = parent$("repeat3").value;
|
|
||||||
$('monthlyDay').value = parent$("repeat4").value;
|
|
||||||
var days = "" + parent$("repeat5").value;
|
|
||||||
for (var i = 0; i < 31; i++) {
|
|
||||||
$("monthDay" + (i + 1)).removeClassName("_selected");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (days.length > 0) {
|
|
||||||
var daysArray = days.split(",");
|
|
||||||
daysArray.each(function(index) {
|
|
||||||
$("monthDay" + index).addClassName("_selected");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (repeatType == 3) {
|
|
||||||
// Repeat yearly
|
|
||||||
$('yearlyYearsField').value = parent$("repeat1").value;
|
|
||||||
$('recurrence_form').setRadioValue('yearlyRadioButtonName', parent$("repeat2").value);
|
|
||||||
$('yearlyDayField').value = parent$("repeat3").value;
|
|
||||||
$('yearlyMonth1').value = parent$("repeat4").value;
|
|
||||||
$('yearlyRepeat').value = parent$("repeat5").value;
|
|
||||||
$('yearlyDay').value = parent$("repeat6").value;
|
|
||||||
$('yearlyMonth2').value = parent$("repeat7").value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
repeatType = 0;
|
|
||||||
|
|
||||||
setRepeatType(repeatType);
|
|
||||||
|
|
||||||
var range = parent$("range1").value;
|
|
||||||
$('recurrence_form').setRadioValue('rangeRadioButtonName', range);
|
|
||||||
|
|
||||||
if (range == 1) {
|
|
||||||
$('rangeAppointmentsField').value = parent$("range2").value;
|
|
||||||
}
|
|
||||||
else if (range == 2) {
|
|
||||||
$('endDate_date').value = parent$("range2").value;
|
|
||||||
$('endDate_date').disabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$('rangeAppointmentsField').observe("click", function(event) {
|
|
||||||
// Set the range to a fixed number of appointments if user
|
|
||||||
// clicks in the range field.
|
|
||||||
$('recurrence_form').setRadioValue('rangeRadioButtonName', 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Observe change of range radio buttons to activate the date picker when required
|
|
||||||
Form.getInputs($('recurrence_form'), 'radio', 'rangeRadioButtonName').each(function(input) {
|
|
||||||
input.observe("change", onRangeChange);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Show page
|
|
||||||
$("recurrence_pattern").show();
|
|
||||||
$("range_of_recurrence").show();
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleDailyRecurrence() {
|
|
||||||
var validate = false;
|
|
||||||
|
|
||||||
var radioValue = $('recurrence_form').getRadioValue('dailyRadioButtonName');
|
|
||||||
|
|
||||||
// We check if the dailyDaysField really contains an integer
|
|
||||||
if (radioValue == 0) {
|
|
||||||
var showError = true;
|
|
||||||
|
|
||||||
var v = "" + $('dailyDaysField').value;
|
|
||||||
if (v.length > 0) {
|
|
||||||
v = parseInt(v);
|
|
||||||
// log("v: " + v);
|
|
||||||
if (!isNaN(v) && v > 0) {
|
|
||||||
validate = true;
|
|
||||||
showError = false;
|
|
||||||
parent$("repeat1").value = radioValue;
|
|
||||||
parent$("repeat2").value = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (showError)
|
|
||||||
window.alert(dayFieldInvalid);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
validate = true;
|
|
||||||
parent$("repeat1").value = radioValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return validate;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleWeeklyRecurrence() {
|
|
||||||
var validate = false;
|
|
||||||
|
|
||||||
var showError = true;
|
|
||||||
var fieldValue = "" + $('weeklyWeeksField').value;
|
|
||||||
if (fieldValue.length > 0) {
|
|
||||||
// We check if the weeklyWeeksField really contains an integer
|
|
||||||
var v = parseInt(fieldValue);
|
|
||||||
if (!isNaN(v) && v > 0) {
|
|
||||||
validate = true;
|
|
||||||
showError = false;
|
|
||||||
parent$("repeat1").value = fieldValue;
|
|
||||||
parent$("repeat2").value = getSelectedDays("week");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (showError)
|
|
||||||
window.alert(weekFieldInvalid);
|
|
||||||
|
|
||||||
return validate;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleMonthlyRecurrence() {
|
|
||||||
var validate = false;
|
|
||||||
|
|
||||||
var radioValue = $('recurrence_form').getRadioValue('monthlyRadioButtonName');
|
|
||||||
|
|
||||||
// We check if the monthlyMonthsField really contains an integer
|
|
||||||
var showError = true;
|
|
||||||
|
|
||||||
var fieldValue = "" + $('monthlyMonthsField').value;
|
|
||||||
if (fieldValue.length > 0) {
|
|
||||||
var v = parseInt(fieldValue);
|
|
||||||
if (!isNaN(v) && v > 0) {
|
|
||||||
validate = true;
|
|
||||||
showError = false;
|
|
||||||
parent$("repeat1").value = fieldValue;
|
|
||||||
parent$("repeat2").value = radioValue;
|
|
||||||
parent$("repeat3").value = $('monthlyRepeat').value;
|
|
||||||
parent$("repeat4").value = $('monthlyDay').value;
|
|
||||||
parent$("repeat5").value = getSelectedDays("month");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (showError)
|
|
||||||
window.alert(monthFieldInvalid);
|
|
||||||
|
|
||||||
return validate;
|
|
||||||
}
|
|
||||||
|
|
||||||
function validateYearlyRecurrence() {
|
|
||||||
var errors = [yearFieldInvalid, monthDayFieldInvalid];
|
|
||||||
|
|
||||||
var errorToShow = 0;
|
|
||||||
var fieldValue = "" + $('yearlyYearsField').value;
|
|
||||||
if (fieldValue.length > 0) {
|
|
||||||
// We check if the yearlyYearsField really contains an integer
|
|
||||||
var v = parseInt(fieldValue);
|
|
||||||
if (!isNaN(v) && v > 0) {
|
|
||||||
var radioValue = $('recurrence_form').getRadioValue('yearlyRadioButtonName');
|
|
||||||
if (radioValue == 0) {
|
|
||||||
errorToShow = 1;
|
|
||||||
fieldValue = "" + $('yearlyDayField').value;
|
|
||||||
if (fieldValue.length > 0) {
|
|
||||||
// We check if the yearlyDayField really contains an integer
|
|
||||||
var v = parseInt(fieldValue);
|
|
||||||
if (!isNaN(v) && v > 0) {
|
|
||||||
errorToShow = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
errorToShow = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errorToShow > -1)
|
|
||||||
window.alert(errors[errorToShow]);
|
|
||||||
|
|
||||||
return (errorToShow == -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleYearlyRecurrence() {
|
|
||||||
var validate = false;
|
|
||||||
|
|
||||||
if (validateYearlyRecurrence()) {
|
|
||||||
var radioValue = $('recurrence_form').getRadioValue('yearlyRadioButtonName');
|
|
||||||
var fieldValue = "" + $('yearlyYearsField').value;
|
|
||||||
if (fieldValue.length > 0) {
|
|
||||||
// We check if the yearlyYearsField (interval) really contains an integer
|
|
||||||
var v = parseInt(fieldValue);
|
|
||||||
if (!isNaN(v) && v > 0) {
|
|
||||||
validate = true;
|
|
||||||
showError = false;
|
|
||||||
parent$("repeat1").value = fieldValue;
|
|
||||||
parent$("repeat2").value = radioValue;
|
|
||||||
parent$("repeat3").value = $('yearlyDayField').value;
|
|
||||||
parent$("repeat4").value = $('yearlyMonth1').value;
|
|
||||||
parent$("repeat5").value = $('yearlyRepeat').value;
|
|
||||||
parent$("repeat6").value = $('yearlyDay').value;
|
|
||||||
parent$("repeat7").value = $('yearlyMonth2').value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
validate = false;
|
|
||||||
|
|
||||||
return validate;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleRange() {
|
|
||||||
var validate = false;
|
|
||||||
|
|
||||||
var radioValue = $('recurrence_form').getRadioValue('rangeRadioButtonName');
|
|
||||||
if (radioValue == 0)
|
|
||||||
validate = true;
|
|
||||||
else if (radioValue == 1) {
|
|
||||||
var showError = true;
|
|
||||||
|
|
||||||
var fieldValue = "" + $('rangeAppointmentsField').value;
|
|
||||||
if (fieldValue.length > 0) {
|
|
||||||
// We check if the rangeAppointmentsField really contains an integer
|
|
||||||
var v = parseInt(fieldValue);
|
|
||||||
if (!isNaN(v) && v > 0) {
|
|
||||||
validate = true;
|
|
||||||
showError = false;
|
|
||||||
parent$("range2").value = fieldValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (showError)
|
|
||||||
window.alert(appointmentFieldInvalid);
|
|
||||||
}
|
|
||||||
else if (radioValue == 2) {
|
|
||||||
validate = true;
|
|
||||||
parent$("range2").value = $('endDate_date').value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (validate)
|
|
||||||
parent$("range1").value = radioValue;
|
|
||||||
|
|
||||||
return validate;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onEditorOkClick(event) {
|
|
||||||
preventDefault(event);
|
|
||||||
var repeatType = $("repeatType").value;
|
|
||||||
parent$("repeatType").value = repeatType;
|
|
||||||
|
|
||||||
var validate;
|
|
||||||
if (repeatType == 0)
|
|
||||||
validate = handleDailyRecurrence();
|
|
||||||
else if (repeatType == 1)
|
|
||||||
validate = handleWeeklyRecurrence();
|
|
||||||
else if (repeatType == 2)
|
|
||||||
validate = handleMonthlyRecurrence();
|
|
||||||
else
|
|
||||||
validate = handleYearlyRecurrence();
|
|
||||||
|
|
||||||
if (validate && handleRange())
|
|
||||||
window.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onEditorCancelClick(event) {
|
|
||||||
preventDefault(event);
|
|
||||||
window.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
function escapeAlertMessages () {
|
|
||||||
dayFieldInvalid = dayFieldInvalid.decodeEntities();
|
|
||||||
weekFieldInvalid = weekFieldInvalid.decodeEntities();
|
|
||||||
monthFieldInvalid = monthFieldInvalid.decodeEntities();
|
|
||||||
monthDayFieldInvalid = monthDayFieldInvalid.decodeEntities();
|
|
||||||
yearFieldInvalid = yearFieldInvalid.decodeEntities();
|
|
||||||
appointmentFieldInvalid = appointmentFieldInvalid.decodeEntities();
|
|
||||||
recurrenceUnsupported = recurrenceUnsupported.decodeEntities();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onRecurrenceLoadHandler() {
|
|
||||||
initializeFormValues();
|
|
||||||
initializeSelectors();
|
|
||||||
initializeWindowButtons();
|
|
||||||
jQuery('#endDate_date').closest('.date').datepicker(
|
|
||||||
{ autoclose: true, weekStart: parentvar('firstDayOfWeek') });
|
|
||||||
escapeAlertMessages();
|
|
||||||
}
|
|
||||||
|
|
||||||
document.observe("dom:loaded", onRecurrenceLoadHandler);
|
|
|
@ -1,76 +0,0 @@
|
||||||
DIV#windowButtons
|
|
||||||
{ position: absolute;
|
|
||||||
bottom: 0px;
|
|
||||||
left: 0px;
|
|
||||||
right: 15px;
|
|
||||||
height: 3em;
|
|
||||||
line-height: 2em;
|
|
||||||
vertical-align: middle;
|
|
||||||
text-align: right; }
|
|
||||||
|
|
||||||
DIV#pageContent
|
|
||||||
{ padding: 1em; }
|
|
||||||
|
|
||||||
TABLE TH
|
|
||||||
{ font-weight: normal;
|
|
||||||
text-align: right;
|
|
||||||
width: 5em; }
|
|
||||||
|
|
||||||
TABLE TD
|
|
||||||
{ text-align: left; }
|
|
||||||
|
|
||||||
TABLE TD.label
|
|
||||||
{ width: 11em; }
|
|
||||||
|
|
||||||
INPUT.textField
|
|
||||||
{ margin: 0 0.7em 0 0;
|
|
||||||
width: 2em; }
|
|
||||||
|
|
||||||
SPAN.datePicker INPUT.textField
|
|
||||||
{ width: 6em; }
|
|
||||||
|
|
||||||
/* Days selectors */
|
|
||||||
|
|
||||||
DIV#week,
|
|
||||||
DIV#month
|
|
||||||
{ background-color: #fff;
|
|
||||||
border-top: 1px solid #fff;
|
|
||||||
border-left: 1px solid #fff;
|
|
||||||
border-right: 1px solid #999;
|
|
||||||
border-bottom: 1px solid #999; }
|
|
||||||
|
|
||||||
DIV#week
|
|
||||||
{ width: 210px; /* 7*(28+2)px */ }
|
|
||||||
|
|
||||||
DIV#month
|
|
||||||
{ width: 140px; /* 7*(18+2)px */ }
|
|
||||||
|
|
||||||
SPAN.week
|
|
||||||
{ clear: both;
|
|
||||||
display: block; }
|
|
||||||
|
|
||||||
SPAN.week DIV
|
|
||||||
{ border: 1px solid #fff;
|
|
||||||
cursor: pointer;
|
|
||||||
display: block;
|
|
||||||
float: left; }
|
|
||||||
|
|
||||||
SPAN.week DIV._selected
|
|
||||||
{ background-color: #4b6983;
|
|
||||||
border-color: #4b6983;
|
|
||||||
color: #fff; }
|
|
||||||
|
|
||||||
SPAN.week DIV P
|
|
||||||
{ display: block;
|
|
||||||
margin: 2px 0px;
|
|
||||||
padding: 0px;
|
|
||||||
text-align: center; }
|
|
||||||
|
|
||||||
DIV#week SPAN.week DIV P
|
|
||||||
{ width: 28px; }
|
|
||||||
|
|
||||||
DIV#month SPAN.week DIV P
|
|
||||||
{ width: 18px; }
|
|
||||||
|
|
||||||
SPAN.week DIV:hover
|
|
||||||
{ border: 1px solid #4b6983; }
|
|
|
@ -1,85 +0,0 @@
|
||||||
function initializeWindowButtons() {
|
|
||||||
var okButton = $("okButton");
|
|
||||||
var cancelButton = $("cancelButton");
|
|
||||||
|
|
||||||
okButton.observe("click", onEditorOkClick, false);
|
|
||||||
cancelButton.observe("click", onEditorCancelClick, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
function initializeFormValues() {
|
|
||||||
if (parent$("reminderUnit").value.length > 0) {
|
|
||||||
$("quantityField").value = parent$("reminderQuantity").value;
|
|
||||||
$("unitsList").value = parent$("reminderUnit").value;
|
|
||||||
$("relationsList").value = parent$("reminderRelation").value;
|
|
||||||
$("referencesList").value = parent$("reminderReference").value;
|
|
||||||
}
|
|
||||||
|
|
||||||
var actionList = $("actionList");
|
|
||||||
if (actionList) {
|
|
||||||
actionList.observe("change", onActionListChange);
|
|
||||||
var action = parent$("reminderAction").value;
|
|
||||||
if (!action)
|
|
||||||
action = "display";
|
|
||||||
actionList.value = action;
|
|
||||||
if (action == "email") {
|
|
||||||
$("emailOrganizer").checked = (parent$("reminderEmailOrganizer").value
|
|
||||||
== "true");
|
|
||||||
$("emailAttendees").checked = (parent$("reminderEmailAttendees").value
|
|
||||||
== "true");
|
|
||||||
}
|
|
||||||
updateActionCheckboxes(actionList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onActionListChange() {
|
|
||||||
updateActionCheckboxes(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateActionCheckboxes(list) {
|
|
||||||
var disabled = (list.value != "email");
|
|
||||||
|
|
||||||
$("emailOrganizer").disabled = disabled;
|
|
||||||
$("emailAttendees").disabled = disabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onEditorOkClick(event) {
|
|
||||||
preventDefault(event);
|
|
||||||
if (parseInt($("quantityField").value) > 0) {
|
|
||||||
parent$("reminderQuantity").value = parseInt($("quantityField").value);
|
|
||||||
parent$("reminderUnit").value = $("unitsList").value;
|
|
||||||
parent$("reminderRelation").value = $("relationsList").value;
|
|
||||||
parent$("reminderReference").value = $("referencesList").value;
|
|
||||||
|
|
||||||
var actionList = $("actionList");
|
|
||||||
var action;
|
|
||||||
if (actionList) {
|
|
||||||
action = $("actionList").value;
|
|
||||||
parent$("reminderEmailOrganizer").value = ($("emailOrganizer").checked
|
|
||||||
? "true"
|
|
||||||
: "false");
|
|
||||||
|
|
||||||
parent$("reminderEmailAttendees").value = ($("emailAttendees").checked
|
|
||||||
? "true"
|
|
||||||
: "false");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
action = "display";
|
|
||||||
}
|
|
||||||
parent$("reminderAction").value = action;
|
|
||||||
window.close();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
alert(_("Invalid number."));
|
|
||||||
}
|
|
||||||
|
|
||||||
function onEditorCancelClick(event) {
|
|
||||||
preventDefault(event);
|
|
||||||
window.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onRecurrenceLoadHandler() {
|
|
||||||
initializeFormValues();
|
|
||||||
initializeWindowButtons();
|
|
||||||
}
|
|
||||||
|
|
||||||
document.observe("dom:loaded", onRecurrenceLoadHandler);
|
|
|
@ -1,75 +0,0 @@
|
||||||
DIV.appointmentLabel
|
|
||||||
{ display: block;
|
|
||||||
position: relative;
|
|
||||||
line-height: 1.8em;
|
|
||||||
text-align: right;
|
|
||||||
width: 3em; }
|
|
||||||
|
|
||||||
DIV#eventView
|
|
||||||
{ overflow: hidden;
|
|
||||||
padding: .5em; }
|
|
||||||
|
|
||||||
DIV.appointmentRightLabel
|
|
||||||
{ display: inline;
|
|
||||||
vertical-align: middle; }
|
|
||||||
|
|
||||||
SPAN.checkBoxList#participantsCB
|
|
||||||
{ height: 7em; }
|
|
||||||
|
|
||||||
SPAN.checkBoxList#categoriesCB
|
|
||||||
{ height: 3em; }
|
|
||||||
|
|
||||||
DIV#participants UL.contactList
|
|
||||||
{ height: 4.5em; }
|
|
||||||
|
|
||||||
SPAN.checkBoxList SPAN.content LABEL
|
|
||||||
{ display: inline; }
|
|
||||||
|
|
||||||
A#changeUrlButton
|
|
||||||
{ margin-left: 1em; }
|
|
||||||
|
|
||||||
A#detailsButton
|
|
||||||
{ position: absolute;
|
|
||||||
right: 1em;
|
|
||||||
z-index: 1; }
|
|
||||||
|
|
||||||
SPAN.contactSelectorButtons
|
|
||||||
{ vertical-align: top;
|
|
||||||
line-height: 2em; }
|
|
||||||
|
|
||||||
SPAN#cycleSelectionFirstLevel,
|
|
||||||
SPAN#cycleSelectionSecondLevel
|
|
||||||
{ visibility: hidden;
|
|
||||||
margin-left: 1em; }
|
|
||||||
|
|
||||||
SPAN#cycleSelectionSecondLevel SPAN.timeDateControl
|
|
||||||
{ position: static;
|
|
||||||
margin: 0px; }
|
|
||||||
|
|
||||||
SPAN#categoriesCB INPUT
|
|
||||||
{ border: 2px solid #000;
|
|
||||||
vertical-align: middle;
|
|
||||||
-moz-border-top-colors: #000 #fff;
|
|
||||||
-moz-border-left-colors: #000 #fff;
|
|
||||||
-moz-border-bottom-colors: #000 #fff;
|
|
||||||
-moz-border-right-colors: #000 #fff; }
|
|
||||||
|
|
||||||
SPAN#categoriesCB LABEL
|
|
||||||
{ margin-left: 0px;
|
|
||||||
margin-right: 1em; }
|
|
||||||
|
|
||||||
SPAN#allDay > INPUT
|
|
||||||
{ position: static; }
|
|
||||||
|
|
||||||
SPAN.content > INPUT.textField
|
|
||||||
{ width: 390px;
|
|
||||||
width: 97%; }
|
|
||||||
|
|
||||||
INPUT#startDateCB,
|
|
||||||
INPUT#dueDateCB,
|
|
||||||
INPUT#statusPercent,
|
|
||||||
LABEL#urlArea INPUT
|
|
||||||
{ position: static; }
|
|
||||||
|
|
||||||
INPUT#statusPercent
|
|
||||||
{ width: 2em; }
|
|
|
@ -1,273 +0,0 @@
|
||||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
var contactSelectorAction = 'calendars-contacts';
|
|
||||||
|
|
||||||
function uixEarlierDate(date1, date2) {
|
|
||||||
// can this be done in a sane way?
|
|
||||||
if (date1 && date2) {
|
|
||||||
if (date1.getYear() < date2.getYear()) return date1;
|
|
||||||
if (date1.getYear() > date2.getYear()) return date2;
|
|
||||||
// same year
|
|
||||||
if (date1.getMonth() < date2.getMonth()) return date1;
|
|
||||||
if (date1.getMonth() > date2.getMonth()) return date2;
|
|
||||||
// same month
|
|
||||||
if (date1.getDate() < date2.getDate()) return date1;
|
|
||||||
if (date1.getDate() > date2.getDate()) return date2;
|
|
||||||
}
|
|
||||||
// same day
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function validateDate(which, label) {
|
|
||||||
var result, dateValue;
|
|
||||||
|
|
||||||
dateValue = this._getDate(which);
|
|
||||||
if (dateValue == null) {
|
|
||||||
alert(label);
|
|
||||||
result = false;
|
|
||||||
} else
|
|
||||||
result = dateValue;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function validateTaskEditor() {
|
|
||||||
var e, startdate, enddate, tmpdate;
|
|
||||||
|
|
||||||
e = document.getElementById('summary');
|
|
||||||
if (e.value.length == 0
|
|
||||||
&& !confirm(labels.validate_notitle))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
e = document.getElementById('startTime_date');
|
|
||||||
if (!e.disabled) {
|
|
||||||
startdate = validateDate('start', labels.validate_invalid_startdate);
|
|
||||||
if (!startdate)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
e = document.getElementById('dueTime_date');
|
|
||||||
if (!e.disabled) {
|
|
||||||
enddate = validateDate('due', labels.validate_invalid_enddate);
|
|
||||||
if (!enddate)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (startdate && enddate) {
|
|
||||||
tmpdate = uixEarlierDate(startdate, enddate);
|
|
||||||
if (tmpdate == enddate) {
|
|
||||||
alert(labels.validate_endbeforestart);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (tmpdate == null /* means: same date */) {
|
|
||||||
// TODO: check time
|
|
||||||
|
|
||||||
var startHour, startMinute, endHour, endMinute;
|
|
||||||
var matches;
|
|
||||||
|
|
||||||
matches = document.forms[0]['startTime_time'].value.match(/([0-9]+):([0-9]+)/);
|
|
||||||
if (matches) {
|
|
||||||
startHour = parseInt(matches[1]);
|
|
||||||
startMinute = parseInt(matches[2]);
|
|
||||||
matches = document.forms[0]['dueTime_time'].value.match(/([0-9]+):([0-9]+)/);
|
|
||||||
if (matches) {
|
|
||||||
endHour = parseInt(matches[1]);
|
|
||||||
endMinute = parseInt(matches[2]);
|
|
||||||
|
|
||||||
if (startHour > endHour) {
|
|
||||||
alert(labels.validate_endbeforestart);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (startHour == endHour) {
|
|
||||||
if (startMinute > endMinute) {
|
|
||||||
alert(labels.validate_endbeforestart);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
alert(labels.validate_invalid_enddate);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
alert(labels.validate_invalid_startdate);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onTimeControlCheck(checkBox) {
|
|
||||||
if (checkBox) {
|
|
||||||
var inputs = checkBox.parentNode.getElementsByTagName("input");
|
|
||||||
var selects = checkBox.parentNode.getElementsByTagName("select");
|
|
||||||
for (var i = 0; i < inputs.length; i++)
|
|
||||||
if (inputs[i] != checkBox)
|
|
||||||
inputs[i].disabled = !checkBox.checked;
|
|
||||||
for (var i = 0; i < selects.length; i++)
|
|
||||||
if (selects[i] != checkBox)
|
|
||||||
selects[i].disabled = !checkBox.checked;
|
|
||||||
if (checkBox.id == "startDateCB") {
|
|
||||||
$("repeatList").disabled = !checkBox.checked;
|
|
||||||
$("reminderList").disabled = !checkBox.checked;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveEvent(sender) {
|
|
||||||
if (validateTaskEditor())
|
|
||||||
document.forms['editform'].submit();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function startDayAsShortString() {
|
|
||||||
return dayAsShortDateString($('startTime_date'));
|
|
||||||
}
|
|
||||||
|
|
||||||
function dueDayAsShortString() {
|
|
||||||
return dayAsShortDateString($('dueTime_date'));
|
|
||||||
}
|
|
||||||
|
|
||||||
this._getDate = function(which) {
|
|
||||||
var date = window.timeWidgets[which]['date'].inputAsDate();
|
|
||||||
var time = window.timeWidgets[which]['time'].value.split(":");
|
|
||||||
date.setHours(time[0]);
|
|
||||||
date.setMinutes(time[1]);
|
|
||||||
|
|
||||||
if (isNaN(date.getTime()))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return date;
|
|
||||||
};
|
|
||||||
|
|
||||||
this._getShadowDate = function(which) {
|
|
||||||
var date = window.timeWidgets[which]['date'].getAttribute("shadow-value").asDate();
|
|
||||||
var time = window.timeWidgets[which]['time'].getAttribute("shadow-value").split(":");
|
|
||||||
date.setHours(time[0]);
|
|
||||||
date.setMinutes(time[1]);
|
|
||||||
|
|
||||||
return date;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getStartDate = function() {
|
|
||||||
return this._getDate('start');
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getDueDate = function() {
|
|
||||||
return this._getDate('due');
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getShadowStartDate = function() {
|
|
||||||
return this._getShadowDate('start');
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getShadowDueDate = function() {
|
|
||||||
return this._getShadowDate('due');
|
|
||||||
};
|
|
||||||
|
|
||||||
this._setDate = function(which, newDate) {
|
|
||||||
window.timeWidgets[which]['date'].setInputAsDate(newDate);
|
|
||||||
window.timeWidgets[which]['time'].value = newDate.getDisplayHoursString();
|
|
||||||
|
|
||||||
// Update date picker
|
|
||||||
var dateComponent = jQuery(window.timeWidgets[which]['date']).closest('.date');
|
|
||||||
dateComponent.data('date', window.timeWidgets[which]['date'].value);
|
|
||||||
dateComponent.datepicker('update');
|
|
||||||
};
|
|
||||||
|
|
||||||
this.setStartDate = function(newStartDate) {
|
|
||||||
this._setDate('start', newStartDate);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.setDueDate = function(newDueDate) {
|
|
||||||
this._setDate('due', newDueDate);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.onAdjustTime = function(event) {
|
|
||||||
onAdjustDueTime(event);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.onAdjustDueTime = function(event) {
|
|
||||||
if (!window.timeWidgets['due']['date'].disabled) {
|
|
||||||
var dateDelta = (window.getStartDate().valueOf()
|
|
||||||
- window.getShadowStartDate().valueOf());
|
|
||||||
var newDueDate = new Date(window.getDueDate().valueOf() + dateDelta);
|
|
||||||
window.setDueDate(newDueDate);
|
|
||||||
}
|
|
||||||
window.timeWidgets['start']['date'].updateShadowValue();
|
|
||||||
window.timeWidgets['start']['time'].updateShadowValue();
|
|
||||||
};
|
|
||||||
|
|
||||||
this.initTimeWidgets = function (widgets) {
|
|
||||||
this.timeWidgets = widgets;
|
|
||||||
|
|
||||||
jQuery(widgets['start']['date']).closest('.date').datepicker({autoclose: true, weekStart: firstDayOfWeek})
|
|
||||||
.on('changeDate', onAdjustTime);
|
|
||||||
widgets['start']['time'].on("time:change", onAdjustDueTime);
|
|
||||||
widgets['start']['time'].addInterface(SOGoTimePickerInterface);
|
|
||||||
|
|
||||||
jQuery(widgets['due']['date']).closest('.date').datepicker({autoclose: true, weekStart: firstDayOfWeek});
|
|
||||||
widgets['due']['time'].addInterface(SOGoTimePickerInterface);
|
|
||||||
|
|
||||||
jQuery('#statusTime_date').closest('.date').datepicker({autoclose: true, weekStart: firstDayOfWeek});
|
|
||||||
};
|
|
||||||
|
|
||||||
function onStatusListChange(event) {
|
|
||||||
var value = $("statusList").value;
|
|
||||||
var statusTimeDate = $("statusTime_date");
|
|
||||||
var statusPercent = $("statusPercent");
|
|
||||||
|
|
||||||
if (value == "WONoSelectionString") {
|
|
||||||
statusTimeDate.disabled = true;
|
|
||||||
statusPercent.disabled = true;
|
|
||||||
statusPercent.value = "";
|
|
||||||
}
|
|
||||||
else if (value == "0") {
|
|
||||||
statusTimeDate.disabled = true;
|
|
||||||
statusPercent.disabled = false;
|
|
||||||
}
|
|
||||||
else if (value == "1") {
|
|
||||||
statusTimeDate.disabled = true;
|
|
||||||
statusPercent.disabled = false;
|
|
||||||
}
|
|
||||||
else if (value == "2") {
|
|
||||||
statusTimeDate.disabled = false;
|
|
||||||
statusPercent.disabled = false;
|
|
||||||
statusPercent.value = "100";
|
|
||||||
}
|
|
||||||
else if (value == "3") {
|
|
||||||
statusTimeDate.disabled = true;
|
|
||||||
statusPercent.disabled = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
statusTimeDate.disabled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function initializeStatusLine() {
|
|
||||||
var statusList = $("statusList");
|
|
||||||
if (statusList) {
|
|
||||||
statusList.observe("change", onStatusListChange);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onTaskEditorLoad() {
|
|
||||||
if (readOnly == false) {
|
|
||||||
var widgets = {'start': {'date': $("startTime_date"),
|
|
||||||
'time': $("startTime_time")},
|
|
||||||
'due': {'date': $("dueTime_date"),
|
|
||||||
'time': $("dueTime_time")}};
|
|
||||||
initTimeWidgets(widgets);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enable or disable the reminder list
|
|
||||||
onTimeControlCheck($("startDateCB"));
|
|
||||||
|
|
||||||
initializeStatusLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
document.observe("dom:loaded", onTaskEditorLoad);
|
|
|
@ -1,536 +0,0 @@
|
||||||
/**
|
|
||||||
* XMLHttpRequest.js Copyright (C) 2011 Sergey Ilinsky (http://www.ilinsky.com)
|
|
||||||
*
|
|
||||||
* This work is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2.1 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This work is distributed in the hope that it will be useful,
|
|
||||||
* but without any warranty; without even the implied warranty of
|
|
||||||
* merchantability or fitness for a particular purpose. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function () {
|
|
||||||
|
|
||||||
// Save reference to earlier defined object implementation (if any)
|
|
||||||
var oXMLHttpRequest = window.XMLHttpRequest;
|
|
||||||
|
|
||||||
// Define on browser type
|
|
||||||
var bGecko = !!window.controllers;
|
|
||||||
var bIE = !!window.document.namespaces;
|
|
||||||
var bIE7 = bIE && window.navigator.userAgent.match(/MSIE 7.0/);
|
|
||||||
|
|
||||||
// Enables "XMLHttpRequest()" call next to "new XMLHttpRequest()"
|
|
||||||
function fXMLHttpRequest() {
|
|
||||||
if (!window.XMLHttpRequest || bIE7) {
|
|
||||||
this._object = new window.ActiveXObject("Microsoft.XMLHTTP");
|
|
||||||
} // only use initial XHR object internally if current reference to XHR is our normalized replacement
|
|
||||||
else if (window.XMLHttpRequest.isNormalizedObject) {
|
|
||||||
this._object = new oXMLHttpRequest();
|
|
||||||
} // otherwise use whatever is currently referenced by XMLHttpRequest
|
|
||||||
else {
|
|
||||||
this._object = new window.XMLHttpRequest();
|
|
||||||
}
|
|
||||||
this._listeners = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constructor
|
|
||||||
function cXMLHttpRequest() {
|
|
||||||
return new fXMLHttpRequest;
|
|
||||||
}
|
|
||||||
cXMLHttpRequest.prototype = fXMLHttpRequest.prototype;
|
|
||||||
|
|
||||||
// BUGFIX: Firefox with Firebug installed would break pages if not executed
|
|
||||||
if (bGecko && oXMLHttpRequest.wrapped) {
|
|
||||||
cXMLHttpRequest.wrapped = oXMLHttpRequest.wrapped;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marker to be able to easily identify our object
|
|
||||||
cXMLHttpRequest.isNormalizedObject = true;
|
|
||||||
|
|
||||||
// Constants
|
|
||||||
cXMLHttpRequest.UNSENT = 0;
|
|
||||||
cXMLHttpRequest.OPENED = 1;
|
|
||||||
cXMLHttpRequest.HEADERS_RECEIVED = 2;
|
|
||||||
cXMLHttpRequest.LOADING = 3;
|
|
||||||
cXMLHttpRequest.DONE = 4;
|
|
||||||
|
|
||||||
// Interface level constants
|
|
||||||
cXMLHttpRequest.prototype.UNSENT = cXMLHttpRequest.UNSENT;
|
|
||||||
cXMLHttpRequest.prototype.OPENED = cXMLHttpRequest.OPENED;
|
|
||||||
cXMLHttpRequest.prototype.HEADERS_RECEIVED = cXMLHttpRequest.HEADERS_RECEIVED;
|
|
||||||
cXMLHttpRequest.prototype.LOADING = cXMLHttpRequest.LOADING;
|
|
||||||
cXMLHttpRequest.prototype.DONE = cXMLHttpRequest.DONE;
|
|
||||||
|
|
||||||
// Public Properties
|
|
||||||
cXMLHttpRequest.prototype.readyState = cXMLHttpRequest.UNSENT;
|
|
||||||
cXMLHttpRequest.prototype.responseText = '';
|
|
||||||
cXMLHttpRequest.prototype.responseXML = null;
|
|
||||||
cXMLHttpRequest.prototype.status = 0;
|
|
||||||
cXMLHttpRequest.prototype.statusText = '';
|
|
||||||
|
|
||||||
// Priority proposal
|
|
||||||
cXMLHttpRequest.prototype.priority = "NORMAL";
|
|
||||||
|
|
||||||
// Instance-level Events Handlers
|
|
||||||
cXMLHttpRequest.prototype.onreadystatechange = null;
|
|
||||||
|
|
||||||
// Class-level Events Handlers
|
|
||||||
cXMLHttpRequest.onreadystatechange = null;
|
|
||||||
cXMLHttpRequest.onopen = null;
|
|
||||||
cXMLHttpRequest.onsend = null;
|
|
||||||
cXMLHttpRequest.onabort = null;
|
|
||||||
|
|
||||||
// Public Methods
|
|
||||||
cXMLHttpRequest.prototype.open = function(sMethod, sUrl, bAsync, sUser, sPassword) {
|
|
||||||
// http://www.w3.org/TR/XMLHttpRequest/#the-open-method
|
|
||||||
var sLowerCaseMethod = sMethod.toLowerCase();
|
|
||||||
if (sLowerCaseMethod == "connect" || sLowerCaseMethod == "trace" || sLowerCaseMethod == "track") {
|
|
||||||
// Using a generic error and an int - not too sure all browsers support correctly
|
|
||||||
// http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#securityerror, so, this is safer
|
|
||||||
// XXX should do better than that, but this is OT to XHR.
|
|
||||||
throw new Error(18);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete headers, required when object is reused
|
|
||||||
delete this._headers;
|
|
||||||
|
|
||||||
// When bAsync parameter value is omitted, use true as default
|
|
||||||
if (arguments.length < 3) {
|
|
||||||
bAsync = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save async parameter for fixing Gecko bug with missing readystatechange in synchronous requests
|
|
||||||
this._async = bAsync;
|
|
||||||
|
|
||||||
// Set the onreadystatechange handler
|
|
||||||
var oRequest = this;
|
|
||||||
var nState = this.readyState;
|
|
||||||
var fOnUnload = null;
|
|
||||||
|
|
||||||
// BUGFIX: IE - memory leak on page unload (inter-page leak)
|
|
||||||
if (bIE && bAsync) {
|
|
||||||
fOnUnload = function() {
|
|
||||||
if (nState != cXMLHttpRequest.DONE) {
|
|
||||||
fCleanTransport(oRequest);
|
|
||||||
// Safe to abort here since onreadystatechange handler removed
|
|
||||||
oRequest.abort();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
window.attachEvent("onunload", fOnUnload);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add method sniffer
|
|
||||||
if (cXMLHttpRequest.onopen) {
|
|
||||||
cXMLHttpRequest.onopen.apply(this, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments.length > 4) {
|
|
||||||
this._object.open(sMethod, sUrl, bAsync, sUser, sPassword);
|
|
||||||
} else if (arguments.length > 3) {
|
|
||||||
this._object.open(sMethod, sUrl, bAsync, sUser);
|
|
||||||
} else {
|
|
||||||
this._object.open(sMethod, sUrl, bAsync);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.readyState = cXMLHttpRequest.OPENED;
|
|
||||||
fReadyStateChange(this);
|
|
||||||
|
|
||||||
this._object.onreadystatechange = function() {
|
|
||||||
if (bGecko && !bAsync) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Synchronize state
|
|
||||||
oRequest.readyState = oRequest._object.readyState;
|
|
||||||
fSynchronizeValues(oRequest);
|
|
||||||
|
|
||||||
// BUGFIX: Firefox fires unnecessary DONE when aborting
|
|
||||||
if (oRequest._aborted) {
|
|
||||||
// Reset readyState to UNSENT
|
|
||||||
oRequest.readyState = cXMLHttpRequest.UNSENT;
|
|
||||||
|
|
||||||
// Return now
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (oRequest.readyState == cXMLHttpRequest.DONE) {
|
|
||||||
// Free up queue
|
|
||||||
delete oRequest._data;
|
|
||||||
|
|
||||||
// Uncomment these lines for bAsync
|
|
||||||
/**
|
|
||||||
* if (bAsync) {
|
|
||||||
* fQueue_remove(oRequest);
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
|
|
||||||
fCleanTransport(oRequest);
|
|
||||||
|
|
||||||
// Uncomment this block if you need a fix for IE cache
|
|
||||||
/**
|
|
||||||
* // BUGFIX: IE - cache issue
|
|
||||||
* if (!oRequest._object.getResponseHeader("Date")) {
|
|
||||||
* // Save object to cache
|
|
||||||
* oRequest._cached = oRequest._object;
|
|
||||||
*
|
|
||||||
* // Instantiate a new transport object
|
|
||||||
* cXMLHttpRequest.call(oRequest);
|
|
||||||
*
|
|
||||||
* // Re-send request
|
|
||||||
* if (sUser) {
|
|
||||||
* if (sPassword) {
|
|
||||||
* oRequest._object.open(sMethod, sUrl, bAsync, sUser, sPassword);
|
|
||||||
* } else {
|
|
||||||
* oRequest._object.open(sMethod, sUrl, bAsync);
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* oRequest._object.setRequestHeader("If-Modified-Since", oRequest._cached.getResponseHeader("Last-Modified") || new window.Date(0));
|
|
||||||
* // Copy headers set
|
|
||||||
* if (oRequest._headers) {
|
|
||||||
* for (var sHeader in oRequest._headers) {
|
|
||||||
* // Some frameworks prototype objects with functions
|
|
||||||
* if (typeof oRequest._headers[sHeader] == "string") {
|
|
||||||
* oRequest._object.setRequestHeader(sHeader, oRequest._headers[sHeader]);
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* oRequest._object.onreadystatechange = function() {
|
|
||||||
* // Synchronize state
|
|
||||||
* oRequest.readyState = oRequest._object.readyState;
|
|
||||||
*
|
|
||||||
* if (oRequest._aborted) {
|
|
||||||
* //
|
|
||||||
* oRequest.readyState = cXMLHttpRequest.UNSENT;
|
|
||||||
*
|
|
||||||
* // Return
|
|
||||||
* return;
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* if (oRequest.readyState == cXMLHttpRequest.DONE) {
|
|
||||||
* // Clean Object
|
|
||||||
* fCleanTransport(oRequest);
|
|
||||||
*
|
|
||||||
* // get cached request
|
|
||||||
* if (oRequest.status == 304) {
|
|
||||||
* oRequest._object = oRequest._cached;
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* //
|
|
||||||
* delete oRequest._cached;
|
|
||||||
*
|
|
||||||
* //
|
|
||||||
* fSynchronizeValues(oRequest);
|
|
||||||
*
|
|
||||||
* //
|
|
||||||
* fReadyStateChange(oRequest);
|
|
||||||
*
|
|
||||||
* // BUGFIX: IE - memory leak in interrupted
|
|
||||||
* if (bIE && bAsync) {
|
|
||||||
* window.detachEvent("onunload", fOnUnload);
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* }
|
|
||||||
* };
|
|
||||||
* oRequest._object.send(null);
|
|
||||||
*
|
|
||||||
* // Return now - wait until re-sent request is finished
|
|
||||||
* return;
|
|
||||||
* };
|
|
||||||
*/
|
|
||||||
|
|
||||||
// BUGFIX: IE - memory leak in interrupted
|
|
||||||
if (bIE && bAsync) {
|
|
||||||
window.detachEvent("onunload", fOnUnload);
|
|
||||||
}
|
|
||||||
|
|
||||||
// BUGFIX: Some browsers (Internet Explorer, Gecko) fire OPEN readystate twice
|
|
||||||
if (nState != oRequest.readyState) {
|
|
||||||
fReadyStateChange(oRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
nState = oRequest.readyState;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
cXMLHttpRequest.prototype.send = function(vData) {
|
|
||||||
// Add method sniffer
|
|
||||||
if (cXMLHttpRequest.onsend) {
|
|
||||||
cXMLHttpRequest.onsend.apply(this, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!arguments.length) {
|
|
||||||
vData = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// BUGFIX: Safari - fails sending documents created/modified dynamically, so an explicit serialization required
|
|
||||||
// BUGFIX: IE - rewrites any custom mime-type to "text/xml" in case an XMLNode is sent
|
|
||||||
// BUGFIX: Gecko - fails sending Element (this is up to the implementation either to standard)
|
|
||||||
if (vData && vData.nodeType) {
|
|
||||||
vData = window.XMLSerializer ? new window.XMLSerializer().serializeToString(vData) : vData.xml;
|
|
||||||
if (!this._headers["Content-Type"]) {
|
|
||||||
this._object.setRequestHeader("Content-Type", "application/xml");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this._data = vData;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* // Add to queue
|
|
||||||
* if (this._async) {
|
|
||||||
* fQueue_add(this);
|
|
||||||
* } else { */
|
|
||||||
fXMLHttpRequest_send(this);
|
|
||||||
/**
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
};
|
|
||||||
|
|
||||||
cXMLHttpRequest.prototype.abort = function() {
|
|
||||||
// Add method sniffer
|
|
||||||
if (cXMLHttpRequest.onabort) {
|
|
||||||
cXMLHttpRequest.onabort.apply(this, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
// BUGFIX: Gecko - unnecessary DONE when aborting
|
|
||||||
if (this.readyState > cXMLHttpRequest.UNSENT) {
|
|
||||||
this._aborted = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._object.abort();
|
|
||||||
|
|
||||||
// BUGFIX: IE - memory leak
|
|
||||||
fCleanTransport(this);
|
|
||||||
|
|
||||||
this.readyState = cXMLHttpRequest.UNSENT;
|
|
||||||
|
|
||||||
delete this._data;
|
|
||||||
|
|
||||||
/* if (this._async) {
|
|
||||||
* fQueue_remove(this);
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
};
|
|
||||||
|
|
||||||
cXMLHttpRequest.prototype.getAllResponseHeaders = function() {
|
|
||||||
return this._object.getAllResponseHeaders();
|
|
||||||
};
|
|
||||||
|
|
||||||
cXMLHttpRequest.prototype.getResponseHeader = function(sName) {
|
|
||||||
return this._object.getResponseHeader(sName);
|
|
||||||
};
|
|
||||||
|
|
||||||
cXMLHttpRequest.prototype.setRequestHeader = function(sName, sValue) {
|
|
||||||
// BUGFIX: IE - cache issue
|
|
||||||
if (!this._headers) {
|
|
||||||
this._headers = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
this._headers[sName] = sValue;
|
|
||||||
|
|
||||||
return this._object.setRequestHeader(sName, sValue);
|
|
||||||
};
|
|
||||||
|
|
||||||
// EventTarget interface implementation
|
|
||||||
cXMLHttpRequest.prototype.addEventListener = function(sName, fHandler, bUseCapture) {
|
|
||||||
for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++) {
|
|
||||||
if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add listener
|
|
||||||
this._listeners.push([sName, fHandler, bUseCapture]);
|
|
||||||
};
|
|
||||||
|
|
||||||
cXMLHttpRequest.prototype.removeEventListener = function(sName, fHandler, bUseCapture) {
|
|
||||||
for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++) {
|
|
||||||
if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove listener
|
|
||||||
if (oListener) {
|
|
||||||
this._listeners.splice(nIndex, 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
cXMLHttpRequest.prototype.dispatchEvent = function(oEvent) {
|
|
||||||
var oEventPseudo = {
|
|
||||||
'type': oEvent.type,
|
|
||||||
'target': this,
|
|
||||||
'currentTarget': this,
|
|
||||||
'eventPhase': 2,
|
|
||||||
'bubbles': oEvent.bubbles,
|
|
||||||
'cancelable': oEvent.cancelable,
|
|
||||||
'timeStamp': oEvent.timeStamp,
|
|
||||||
'stopPropagation': function() {}, // There is no flow
|
|
||||||
'preventDefault': function() {}, // There is no default action
|
|
||||||
'initEvent': function() {} // Original event object should be initialized
|
|
||||||
};
|
|
||||||
|
|
||||||
// Execute onreadystatechange
|
|
||||||
if (oEventPseudo.type == "readystatechange" && this.onreadystatechange) {
|
|
||||||
(this.onreadystatechange.handleEvent || this.onreadystatechange).apply(this, [oEventPseudo]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Execute listeners
|
|
||||||
for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++) {
|
|
||||||
if (oListener[0] == oEventPseudo.type && !oListener[2]) {
|
|
||||||
(oListener[1].handleEvent || oListener[1]).apply(this, [oEventPseudo]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
cXMLHttpRequest.prototype.toString = function() {
|
|
||||||
return '[' + "object" + ' ' + "XMLHttpRequest" + ']';
|
|
||||||
};
|
|
||||||
|
|
||||||
cXMLHttpRequest.toString = function() {
|
|
||||||
return '[' + "XMLHttpRequest" + ']';
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* // Queue manager
|
|
||||||
* var oQueuePending = {"CRITICAL":[],"HIGH":[],"NORMAL":[],"LOW":[],"LOWEST":[]},
|
|
||||||
* aQueueRunning = [];
|
|
||||||
* function fQueue_add(oRequest) {
|
|
||||||
* oQueuePending[oRequest.priority in oQueuePending ? oRequest.priority : "NORMAL"].push(oRequest);
|
|
||||||
* //
|
|
||||||
* setTimeout(fQueue_process);
|
|
||||||
* };
|
|
||||||
*
|
|
||||||
* function fQueue_remove(oRequest) {
|
|
||||||
* for (var nIndex = 0, bFound = false; nIndex < aQueueRunning.length; nIndex++)
|
|
||||||
* if (bFound) {
|
|
||||||
* aQueueRunning[nIndex - 1] = aQueueRunning[nIndex];
|
|
||||||
* } else {
|
|
||||||
* if (aQueueRunning[nIndex] == oRequest) {
|
|
||||||
* bFound = true;
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* if (bFound) {
|
|
||||||
* aQueueRunning.length--;
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* //
|
|
||||||
* setTimeout(fQueue_process);
|
|
||||||
* };
|
|
||||||
*
|
|
||||||
* function fQueue_process() {
|
|
||||||
* if (aQueueRunning.length < 6) {
|
|
||||||
* for (var sPriority in oQueuePending) {
|
|
||||||
* if (oQueuePending[sPriority].length) {
|
|
||||||
* var oRequest = oQueuePending[sPriority][0];
|
|
||||||
* oQueuePending[sPriority] = oQueuePending[sPriority].slice(1);
|
|
||||||
* //
|
|
||||||
* aQueueRunning.push(oRequest);
|
|
||||||
* // Send request
|
|
||||||
* fXMLHttpRequest_send(oRequest);
|
|
||||||
* break;
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* };
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Helper function
|
|
||||||
function fXMLHttpRequest_send(oRequest) {
|
|
||||||
oRequest._object.send(oRequest._data);
|
|
||||||
|
|
||||||
// BUGFIX: Gecko - missing readystatechange calls in synchronous requests
|
|
||||||
if (bGecko && !oRequest._async) {
|
|
||||||
oRequest.readyState = cXMLHttpRequest.OPENED;
|
|
||||||
|
|
||||||
// Synchronize state
|
|
||||||
fSynchronizeValues(oRequest);
|
|
||||||
|
|
||||||
// Simulate missing states
|
|
||||||
while (oRequest.readyState < cXMLHttpRequest.DONE) {
|
|
||||||
oRequest.readyState++;
|
|
||||||
fReadyStateChange(oRequest);
|
|
||||||
// Check if we are aborted
|
|
||||||
if (oRequest._aborted) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function fReadyStateChange(oRequest) {
|
|
||||||
// Sniffing code
|
|
||||||
if (cXMLHttpRequest.onreadystatechange){
|
|
||||||
cXMLHttpRequest.onreadystatechange.apply(oRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Fake event
|
|
||||||
oRequest.dispatchEvent({
|
|
||||||
'type': "readystatechange",
|
|
||||||
'bubbles': false,
|
|
||||||
'cancelable': false,
|
|
||||||
'timeStamp': new Date().getTime()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function fGetDocument(oRequest) {
|
|
||||||
var oDocument = oRequest.responseXML;
|
|
||||||
var sResponse = oRequest.responseText;
|
|
||||||
// Try parsing responseText
|
|
||||||
if (bIE && sResponse && oDocument && !oDocument.documentElement && oRequest.getResponseHeader("Content-Type").match(/[^\/]+\/[^\+]+\+xml/)) {
|
|
||||||
oDocument = new window.ActiveXObject("Microsoft.XMLDOM");
|
|
||||||
oDocument.async = false;
|
|
||||||
oDocument.validateOnParse = false;
|
|
||||||
oDocument.loadXML(sResponse);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if there is no error in document
|
|
||||||
if (oDocument){
|
|
||||||
if ((bIE && oDocument.parseError != 0) || !oDocument.documentElement || (oDocument.documentElement && oDocument.documentElement.tagName == "parsererror")) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return oDocument;
|
|
||||||
}
|
|
||||||
|
|
||||||
function fSynchronizeValues(oRequest) {
|
|
||||||
try { oRequest.responseText = oRequest._object.responseText; } catch (e) {}
|
|
||||||
try { oRequest.responseXML = fGetDocument(oRequest._object); } catch (e) {}
|
|
||||||
try { oRequest.status = oRequest._object.status; } catch (e) {}
|
|
||||||
try { oRequest.statusText = oRequest._object.statusText; } catch (e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
function fCleanTransport(oRequest) {
|
|
||||||
// BUGFIX: IE - memory leak (on-page leak)
|
|
||||||
oRequest._object.onreadystatechange = new window.Function;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Internet Explorer 5.0 (missing apply)
|
|
||||||
if (!window.Function.prototype.apply) {
|
|
||||||
window.Function.prototype.apply = function(oRequest, oArguments) {
|
|
||||||
if (!oArguments) {
|
|
||||||
oArguments = [];
|
|
||||||
}
|
|
||||||
oRequest.__func = this;
|
|
||||||
oRequest.__func(oArguments[0], oArguments[1], oArguments[2], oArguments[3], oArguments[4]);
|
|
||||||
delete oRequest.__func;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register new object with window
|
|
||||||
window.XMLHttpRequest = cXMLHttpRequest;
|
|
||||||
|
|
||||||
})();
|
|
Before Width: | Height: | Size: 546 B |
Before Width: | Height: | Size: 489 B |
Before Width: | Height: | Size: 493 B |
Before Width: | Height: | Size: 540 B |
Before Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 953 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 647 B |
Before Width: | Height: | Size: 264 B |
Before Width: | Height: | Size: 283 B |
Before Width: | Height: | Size: 52 B |
Before Width: | Height: | Size: 264 B |
Before Width: | Height: | Size: 263 B |
Before Width: | Height: | Size: 203 B |
Before Width: | Height: | Size: 971 B |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 5.5 KiB |