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.0 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 |