Monotone-Parent: 8aa07a8f048c7e50cdc15d7dd7aa1b00d822b02f

Monotone-Revision: 7db6fbb0b2c9e675b2ca5efecf2fbe3abb0ea5f9

Monotone-Author: flachapelle@inverse.ca
Monotone-Date: 2007-10-02T15:29:16
Monotone-Branch: ca.inverse.sogo
maint-2.0.2
Francis Lachapelle 2007-10-02 15:29:16 +00:00
parent 43af980501
commit 3e46e3a10c
9 changed files with 121 additions and 73 deletions

1
NEWS
View File

@ -11,6 +11,7 @@
- added checkmarks in live search options popup menus; - added checkmarks in live search options popup menus;
- added browser detection with recommanded alternatives; - added browser detection with recommanded alternatives;
- support for resizable columns in tables; - support for resizable columns in tables;
- improved support for multiple selection in tables and lists;
- improved IE7 and Safari support: attendees selector, email file attachments; - improved IE7 and Safari support: attendees selector, email file attachments;
- countless bugfixes; - countless bugfixes;

View File

@ -274,6 +274,7 @@
([[cc userAgentType] isEqualToString: @"IE"] && [cc majorVersion] >= 7) || ([[cc userAgentType] isEqualToString: @"IE"] && [cc majorVersion] >= 7) ||
([[cc userAgentType] isEqualToString: @"Mozilla"] && [cc majorVersion] >= 5) || ([[cc userAgentType] isEqualToString: @"Mozilla"] && [cc majorVersion] >= 5) ||
([[cc userAgentType] isEqualToString: @"Safari"] && [cc majorVersion] >= 4) ([[cc userAgentType] isEqualToString: @"Safari"] && [cc majorVersion] >= 4)
// ([[cc userAgentType] isEqualToString: @"Konqueror"])
); );
} }

View File

@ -94,12 +94,15 @@
<var:component className="UIxCalFilterPanel" /> <var:component className="UIxCalFilterPanel" />
<div id="eventsListView"> <div id="eventsListView">
<table id="eventsList"> <table id="eventsList">
<tr> <thead>
<td class="headerCell headerTitle sortableTableHeader"><var:string label:value="Title"/></td> <tr>
<td class="headerCell headerDateTime sortableTableHeader"><var:string label:value="Start"/></td> <td class="headerCell headerTitle sortableTableHeader"><var:string label:value="Title"/></td>
<td class="headerCell headerDateTime sortableTableHeader"><var:string label:value="End"/></td> <td class="headerCell headerDateTime sortableTableHeader"><var:string label:value="Start"/></td>
<td class="headerCell headerLocation sortableTableHeader"><var:string label:value="Location"/></td> <td class="headerCell headerDateTime sortableTableHeader"><var:string label:value="End"/></td>
</tr> <td class="headerCell headerLocation sortableTableHeader"><var:string label:value="Location"/></td>
</tr>
</thead>
<tbody></tbody>
</table> </table>
</div> </div>
<div id="rightDragHandle" class="dragHandle"><!-- space --></div> <div id="rightDragHandle" class="dragHandle"><!-- space --></div>

View File

@ -27,7 +27,7 @@
label:title="Remove the selected Calendar" label:title="Remove the selected Calendar"
/></span></a> /></span></a>
</span> </span>
<ul id="calendarList" multiselect="yes"> <ul id="calendarList">
<var:foreach list="calendars" item="currentCalendar" <var:foreach list="calendars" item="currentCalendar"
><li class="denied" var:id="currentCalendar.id" ><li class="denied" var:id="currentCalendar.id"
var:owner="currentCalendar.owner"> var:owner="currentCalendar.owner">

View File

@ -381,7 +381,8 @@ function openMailbox(mailbox, reload, idx) {
var url = ApplicationBaseURL + mailbox + "/view?noframe=1"; var url = ApplicationBaseURL + mailbox + "/view?noframe=1";
var messageContent = $("messageContent"); var messageContent = $("messageContent");
messageContent.update(); messageContent.update();
lastClickedRow = null; // from generic.js
var currentMessage; var currentMessage;
if (!idx) { if (!idx) {
currentMessage = currentMessages[mailbox]; currentMessage = currentMessages[mailbox];
@ -637,7 +638,7 @@ function storeCachedMessage(cachedMessage) {
cachedMessages[oldest] = cachedMessage; cachedMessages[oldest] = cachedMessage;
} }
function onMessageSelectionChange() { log("onMessageSelectionChange"); function onMessageSelectionChange() {
var rows = this.getSelectedRowsId(); var rows = this.getSelectedRowsId();
if (rows.length == 1) { if (rows.length == 1) {
@ -987,6 +988,7 @@ function configureMessageListBodyEvents(table) {
rows = table.tBodies[0].rows; rows = table.tBodies[0].rows;
for (var i = 0; i < rows.length; i++) { for (var i = 0; i < rows.length; i++) {
Event.observe(rows[i], "mousedown", onRowClick); Event.observe(rows[i], "mousedown", onRowClick);
Event.observe(rows[i], "selectstart", listRowMouseDownHandler);
Event.observe(rows[i], "contextmenu", onMessageContextMenu.bindAsEventListener(rows[i])); Event.observe(rows[i], "contextmenu", onMessageContextMenu.bindAsEventListener(rows[i]));
rows[i].dndTypes = function() { return new Array("mailRow"); }; rows[i].dndTypes = function() { return new Array("mailRow"); };

View File

@ -61,6 +61,7 @@ UL#tasksList, UL#calendarList
border-top: 2px solid #222; border-top: 2px solid #222;
border-left: 2px solid #222; border-left: 2px solid #222;
background-color: #fff; background-color: #fff;
-khtml-user-select: none;
-moz-border-top-colors: #9c9a94 #000 transparent; -moz-border-top-colors: #9c9a94 #000 transparent;
-moz-border-left-colors: #9c9a94 #000 transparent; -moz-border-left-colors: #9c9a94 #000 transparent;
list-style-type: none; list-style-type: none;

View File

@ -311,6 +311,7 @@ function eventsListCallback(http) {
var params = parseQueryParameters(http.callbackData); var params = parseQueryParameters(http.callbackData);
sortKey = params["sort"]; sortKey = params["sort"];
sortOrder = params["desc"]; sortOrder = params["desc"];
lastClickedRow = null; // from generic.js
var data = http.responseText.evalJSON(true); var data = http.responseText.evalJSON(true);
for (var i = 0; i < data.length; i++) { for (var i = 0; i < data.length; i++) {
@ -370,7 +371,7 @@ function tasksListCallback(http) {
//log(i + " = " + data[i][3]); //log(i + " = " + data[i][3]);
var listItem = document.createElement("li"); var listItem = document.createElement("li");
list.appendChild(listItem); list.appendChild(listItem);
Event.observe(listItem, "mousedown", listRowMouseDownHandler); // causes problem with Safari Event.observe(listItem, "mousedown", listRowMouseDownHandler);
Event.observe(listItem, "click", onRowClick); Event.observe(listItem, "click", onRowClick);
Event.observe(listItem, "dblclick", editDoubleClickedEvent.bindAsEventListener(listItem)); Event.observe(listItem, "dblclick", editDoubleClickedEvent.bindAsEventListener(listItem));
listItem.setAttribute("id", data[i][0]); listItem.setAttribute("id", data[i][0]);
@ -896,8 +897,8 @@ function _loadEventHref(href) {
= triggerAjaxRequest(url, eventsListCallback, href); = triggerAjaxRequest(url, eventsListCallback, href);
var table = $("eventsList").tBodies[0]; var table = $("eventsList").tBodies[0];
while (table.rows.length > 1) while (table.rows.length > 0)
table.removeChild(table.rows[1]); table.removeChild(table.rows[0]);
return false; return false;
} }
@ -1131,17 +1132,15 @@ function updateTaskStatus(event) {
var taskId = this.parentNode.getAttribute("id"); var taskId = this.parentNode.getAttribute("id");
var newStatus = (this.checked ? 1 : 0); var newStatus = (this.checked ? 1 : 0);
var http = createHTTPClient(); var http = createHTTPClient();
if (isSafari()) if (isSafari() && !isSafari3()) {
newStatus = (newStatus ? 0 : 1); newStatus = (newStatus ? 0 : 1);
//log("update task status: " + taskId + " to " + this.checked); }
event.cancelBubble = true;
url = (ApplicationBaseURL + "/" + this.parentNode.calendar url = (ApplicationBaseURL + "/" + this.parentNode.calendar
+ "/" + taskId + "/changeStatus?status=" + newStatus); + "/" + taskId + "/changeStatus?status=" + newStatus);
if (http) { if (http) {
// log ("url: " + url);
// TODO: add parameter to signal that we are only interested in OK // TODO: add parameter to signal that we are only interested in OK
http.open("POST", url, false /* not async */); http.open("POST", url, false /* not async */);
http.url = url; http.url = url;
@ -1156,6 +1155,12 @@ function updateTaskStatus(event) {
function updateCalendarStatus(event) { function updateCalendarStatus(event) {
var list = new Array(); var list = new Array();
var newStatus = (this.checked ? 1 : 0);
if (isSafari() && !isSafari3()) {
newStatus = (newStatus ? 0 : 1);
this.checked = newStatus;
}
var nodes = $("calendarList").childNodesWithTag("li"); var nodes = $("calendarList").childNodesWithTag("li");
for (var i = 0; i < nodes.length; i++) { for (var i = 0; i < nodes.length; i++) {
@ -1181,7 +1186,7 @@ function updateCalendarStatus(event) {
if (event) { if (event) {
var folderID = this.parentNode.getAttribute("id"); var folderID = this.parentNode.getAttribute("id");
var urlstr = URLForFolderID(folderID); var urlstr = URLForFolderID(folderID);
if (this.checked) if (newStatus)
urlstr += "/activateFolder"; urlstr += "/activateFolder";
else else
urlstr += "/deactivateFolder"; urlstr += "/deactivateFolder";
@ -1201,18 +1206,18 @@ function updateCalendarStatus(event) {
function calendarStatusCallback(http) { function calendarStatusCallback(http) {
if (http.readyState == 4) { if (http.readyState == 4) {
if (isHttpStatus204(http.status)) { if (isHttpStatus204(http.status)) {
refreshEvents(); refreshEvents();
refreshTasks(); refreshTasks();
changeCalendarDisplay(); changeCalendarDisplay();
} }
else { else {
var folder = $(http.callbackData); var folder = $(http.callbackData);
var input = folder.childNodesWithTag("input")[0]; var input = folder.childNodesWithTag("input")[0];
input.checked = (!input.checked); input.checked = (!input.checked);
} }
} }
else else
log("calendarStatusCallback Ajax error"); log("calendarStatusCallback Ajax error");
} }
function calendarEntryCallback(http) { function calendarEntryCallback(http) {
@ -1342,12 +1347,15 @@ function initCalendarSelector() {
updateCalendarStatus(); updateCalendarStatus();
selector.changeNotification = updateCalendarsList; selector.changeNotification = updateCalendarsList;
var list = $("calendarList").childNodesWithTag("li"); var list = $("calendarList");
for (var i = 0; i < list.length; i++) { list.multiselect = true;
var input = list[i].childNodesWithTag("input")[0]; var items = list.childNodesWithTag("li");
Event.observe(input, "click", updateCalendarStatus.bindAsEventListener(input)); // not registered in IE? for (var i = 0; i < items.length; i++) {
//Event.observe(list[i], "mousedown", listRowMouseDownHandler, true); // problem with Safari var input = items[i].childNodesWithTag("input")[0];
Event.observe(list[i], "click", onRowClick); Event.observe(input, "click", updateCalendarStatus.bindAsEventListener(input));
Event.observe(items[i], "mousedown", listRowMouseDownHandler);
Event.observe(items[i], "selectstart", listRowMouseDownHandler);
Event.observe(items[i], "click", onRowClick);
} }
var links = $("calendarSelectorButtons").childNodesWithTag("a"); var links = $("calendarSelectorButtons").childNodesWithTag("a");
@ -1414,30 +1422,31 @@ function appendCalendar(folderName, folder) {
var li = document.createElement("li"); var li = document.createElement("li");
calendarList.appendChild(li); calendarList.appendChild(li);
li.setAttribute("id", folder);
var checkBox = document.createElement("input"); var checkBox = document.createElement("input");
checkBox.setAttribute("type", "checkbox"); checkBox.setAttribute("type", "checkbox");
li.appendChild(checkBox); li.appendChild(checkBox);
li.appendChild(document.createTextNode(" ")); li.appendChild(document.createTextNode(" "));
$(checkBox).addClassName("checkBox");
var colorBox = document.createElement("div"); var colorBox = document.createElement("div");
li.appendChild(colorBox); li.appendChild(colorBox);
li.appendChild(document.createTextNode(" " + folderName)); li.appendChild(document.createTextNode(" " + folderName)); log (folderName);
colorBox.appendChild(document.createTextNode("OO")); colorBox.appendChild(document.createTextNode("OO"));
li.setAttribute("id", folder);
Event.observe(li, "mousedown", listRowMouseDownHandler);
Event.observe(li, "click", onRowClick);
$(checkBox).addClassName("checkBox");
Event.observe(checkBox, "click",
updateCalendarStatus.bindAsEventListener(checkBox));
$(colorBox).addClassName("colorBox"); $(colorBox).addClassName("colorBox");
if (color) if (color)
$(colorBox).setStyle({color: color, $(colorBox).setStyle({color: color,
backgroundColor: color}); backgroundColor: color});
// Register events (doesn't work with Safari)
Event.observe(li, "mousedown", listRowMouseDownHandler);
Event.observe(li, "selectstart", listRowMouseDownHandler);
Event.observe(li, "click", onRowClick);
Event.observe(checkBox, "click",
updateCalendarStatus.bindAsEventListener(checkBox));
var url = URLForFolderID(folder) + "/canAccessContent"; var url = URLForFolderID(folder) + "/canAccessContent";
triggerAjaxRequest(url, calendarEntryCallback, folder); triggerAjaxRequest(url, calendarEntryCallback, folder);
@ -1460,7 +1469,7 @@ function appendCalendar(folderName, folder) {
} }
function onFolderSubscribeCB(folderData) { function onFolderSubscribeCB(folderData) {
var folder = $(folderData["folder"]); var folder = $(folderData["folder"]);
if (!folder) if (!folder)
appendCalendar(folderData["folderName"], folderData["folder"]); appendCalendar(folderData["folderName"], folderData["folder"]);
} }

View File

@ -22,7 +22,7 @@ function addLineToTree(tree, parent, line) {
|| nodes.length > 1) { || nodes.length > 1) {
var parentNode = nodes[0]; var parentNode = nodes[0];
var userInfos = parentNode.split(":"); var userInfos = parentNode.split(":");
var email = userInfos[1] + " &lt;" + userInfos[2] + ">"; var email = userInfos[1] + " &lt;" + userInfos[2] + "&gt;";
tree.add(parent, 0, email, 0, '#', userInfos[0], 'person', tree.add(parent, 0, email, 0, '#', userInfos[0], 'person',
'', '', '', '',
ResourcesURL + '/abcard.gif', ResourcesURL + '/abcard.gif',
@ -35,7 +35,11 @@ function addLineToTree(tree, parent, line) {
else else
icon += 'calendar-folder-16x16.png'; icon += 'calendar-folder-16x16.png';
var folderId = userInfos[0] + ":" + folderInfos[1]; var folderId = userInfos[0] + ":" + folderInfos[1];
tree.add(parent + i, parent, folderInfos[0], 0, '#', folderId, var name = folderInfos[0]; // name has the format "Folername (Firstname Lastname <email>)"
var pos = name.indexOf(' (')
if (pos !== -1)
name = name.substring(0, pos); // strip the part with fullname and email
tree.add(parent + i, parent, name, 0, '#', folderId,
folderInfos[2] + '-folder', '', '', icon, icon); folderInfos[2] + '-folder', '', '', icon, icon);
} }
offset = nodes.length - 1; offset = nodes.length - 1;

View File

@ -32,6 +32,8 @@ var menus = new Array();
var search = {}; var search = {};
var sorting = {}; var sorting = {};
var lastClickedRow = null;
var weekStartIsMonday = true; var weekStartIsMonday = true;
// logArea = null; // logArea = null;
@ -343,6 +345,10 @@ function checkAjaxRequestsState() {
} }
} }
function isSafari3() {
return (navigator.appVersion.indexOf("Version") > -1);
}
function isSafari() { function isSafari() {
//var agt = navigator.userAgent.toLowerCase(); //var agt = navigator.userAgent.toLowerCase();
//var is_safari = ((agt.indexOf('safari')!=-1)&&(agt.indexOf('mac')!=-1))?true:false; //var is_safari = ((agt.indexOf('safari')!=-1)&&(agt.indexOf('mac')!=-1))?true:false;
@ -483,7 +489,7 @@ function isNodeSelected(node) {
function acceptMultiSelect(node) { function acceptMultiSelect(node) {
var response = false; var response = false;
var attribute = node.getAttribute('multiselect'); var attribute = node.getAttribute('multiselect');
if (attribute) { if (attribute && attribute.length > 0) {
log("node '" + node.getAttribute("id") log("node '" + node.getAttribute("id")
+ "' is still using old-stylemultiselect!"); + "' is still using old-stylemultiselect!");
response = (attribute.toLowerCase() == 'yes'); response = (attribute.toLowerCase() == 'yes');
@ -496,42 +502,63 @@ function acceptMultiSelect(node) {
function onRowClick(event) { function onRowClick(event) {
var node = getTarget(event); var node = getTarget(event);
var rowIndex = null;
if (node.tagName == 'TD') if (node.tagName == 'TD') {
node = node.parentNode; node = node.parentNode; // select TR
var startSelection = $(node.parentNode).getSelectedNodes(); rowIndex = node.rowIndex - $(node).up('table').down('thead').getElementsByTagName('tr').length;
if (event.shiftKey == 1 }
else if (node.tagName == 'LI') {
// Find index of clicked row
var list = node.parentNode;
var items = list.childNodesWithTag("li");
for (var i = 0; i < items.length; i++) {
if (items[i] == node) {
rowIndex = i;
break;
}
}
}
var initialSelection = $(node.parentNode).getSelectedNodes();
if ((event.shiftKey == 1 || event.ctrlKey == 1)
&& lastClickedRow
&& (acceptMultiSelect(node.parentNode) && (acceptMultiSelect(node.parentNode)
|| acceptMultiSelect(node.parentNode.parentNode))) { || acceptMultiSelect(node.parentNode.parentNode))) {
if (isNodeSelected(node) == true) { if (event.shiftKey)
$(node.parentNode).selectRange(lastClickedRow, rowIndex);
else if (isNodeSelected(node) == true) {
$(node).deselect(); $(node).deselect();
} else { } else {
$(node).select(); $(node).select();
} }
// At this point, should empty content of 3-pane view
} else { } else {
// Single line selection
$(node.parentNode).deselectAll(); $(node.parentNode).deselectAll();
$(node).select(); $(node).select();
}
if (initialSelection != $(node.parentNode).getSelectedNodes()) {
if (startSelection != $(node.parentNode).getSelectedNodes()) { // Selection has changed; fire mousedown event
// Selection has changed; fire mousedown event var parentNode = node.parentNode;
var parentNode = node.parentNode; if (parentNode.tagName == 'TBODY')
if (parentNode.tagName == 'TBODY') parentNode = parentNode.parentNode;
parentNode = parentNode.parentNode; if (document.createEvent) {
if (document.createEvent) { var onSelectionChangeEvent;
var onSelectionChangeEvent; if (isSafari())
if (isSafari()) onSelectionChangeEvent = document.createEvent("UIEvents");
onSelectionChangeEvent = document.createEvent("UIEvents"); else
else onSelectionChangeEvent = document.createEvent("Events");
onSelectionChangeEvent = document.createEvent("Events"); onSelectionChangeEvent.initEvent("mousedown", true, true);
onSelectionChangeEvent.initEvent("mousedown", true, true); parentNode.dispatchEvent(onSelectionChangeEvent);
parentNode.dispatchEvent(onSelectionChangeEvent); }
} else if (document.createEventObject) {
else if (document.createEventObject) { parentNode.fireEvent("onmousedown");
parentNode.fireEvent("onmousedown"); }
} }
} }
lastClickedRow = rowIndex;
return true; return true;
} }