new regression tests

This commit is contained in:
karnaze%netscape.com 1999-10-21 22:52:00 +00:00
parent d429f12e92
commit 2c99832a1a
7 changed files with 3496 additions and 0 deletions

View File

@ -0,0 +1,160 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* WINDOWS
*/
window {
background: #FF9; /* pale yellow */
color: black;
}
/* only does anything for calendar */
table { width: 100%; }
box#tabs { padding: 1px; }
/* crash in
#0 0x40b20926 in nsSelectControlFrame::SetProperty ()
#1 0x40ade441 in nsHTMLSelectElement::SetSelectedIndex ()
#2 0x403d30cf in NS_NewScriptHTMLScriptElement ()
#3 0x40446433 in js_SetProperty ()
box#main { overflow: scroll; }
box#main { overflow: auto; }
*/
/* XXX Interesting... */
/* window { overflow: scroll; } */
window[debug] { background: yellow; }
window[debug] box { background: red; }
window[debug] div { background: green; }
/* XXX: Bug: Problems - increases height; should center the table - happens
if any margin is auto */
table {
/* margin: 0 auto; */
}
td, th {
line-height: 1;
padding: 0;
}
/* XXX Doesn't work: */
box#outer { overflow: scroll; }
/*
* BUTTONS AND TABS: Used in schedule and pick windows.
*/
/*
#ApptTable { overflow: scroll; }
*/
button, td[class~="button"], td[class~="tab"] {
text-align: center;
vertical-align: middle;
cursor: pointer;
border: 1px outset #FF9;
padding: 1px;
color: black;
background: #FF9;
}
td[class~="button"]:active, td[class~="tab"]:active {
border-style: inset;
padding: 2px 0px 0px 2px;
background: #fc3;
}
td[class~="tab"][class~="disable"] {
color: #888;
}
td[class~="tab"][class~="disable"]:active {
/* back to default */
background: #FF9;
}
td[id="DateOutput"], td[id="MonthOutput"] {
vertical-align: middle;
text-align: center;
font-weight: bold;
}
/*
* SCHEDULE LIST
*/
/* XXX XUL Bug?? tr[id] without the tbody matches the row in the thead too */
table[class~="data"] tbody[id="ApptTable"] tr {
cursor: pointer;
}
/* Problem with bug 5693
table[class~="data"] tbody#ApptTable tr:hover {
background: #ff0;
text-decoration: underline; /* really a nonstandard use */
}
*/
table[class~="data"] th, table[class~="data"] td {
text-align: left;
vertical-align: baseline;
}
/*
* EVENT ADDER
*/
table#add th {
text-align: right;
font-weight: bold;
}
table#add th:after {
content: ":";
}
/*
* DATE PICKER
*/
/* the numbers in the calendar, including those below */
td[class~="caldate"] {
cursor: pointer;
text-align: center;
border: 1px solid transparent;
}
/* the number in the calendar for the date now being shown (overrides above) */
td[class~="caldate"][class~="nowshowing"] {
background: #f90;
color: black;
}
/* the number in the calendar for today's date (overrides above) */
td[class~="caldate"][class~="today"] {
border: 1px solid black;
/* font-weight: bold; */
}

View File

@ -0,0 +1,929 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
// FOR TESTING XXX
function StartCodeTime ( ) {
CodeTimeInitial = new Date();
}
function EndCodeTime ( str ) {
var CodeTimeFinal = new Date();
var diff = CodeTimeFinal.getTime() - CodeTimeInitial.getTime();
dump("Timing " + str + " took " + diff + " milliseconds.\n");
}
// ************************************************************
// Initialize stuff
// ************************************************************
haveRead = false;
currentTime = new Date(); // a new Date object with the current time
monthShowing = new Date();
nowShowing = new Date();
month_names_internal = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
// the namespace of the RDF literals
rdf_ns="http://when.com/1999/07/03-appts-rdf#";
// find the location of the appointments data - relative URLs don't work (now, anyway)
// the filename within the directory of the XUL document
var RDFRelFileName = 'bug12012.rdf';
dump("Getting window.location.href...\n");
// to get the directory, start with the filename of the XUL document
var baseURL = window.location.href;
dump("...done.\n");
// XXX Needs three slashes because of file:// URL parsing bug (see Bug 9236)
//if ((baseURL.indexOf("file:/") != -1) && (baseURL.indexOf("file:///") == -1)) {
//baseURL = "file:///" + baseURL.substring(6);
//}
if (baseURL.indexOf("file:") == 0) {
baseURL = baseURL.substring(5);
while (baseURL.charAt(0) == '/') {
baseURL = baseURL.substring(1);
}
baseURL = "file:///" + baseURL;
}
// and take off whatever is after the last "/"
baseURL = baseURL.substring(0, baseURL.lastIndexOf("/") + 1);
// combine these to get the filename for the RDF
RDFFileName = baseURL + RDFRelFileName;
appts_resourcename = RDFFileName + "#WhenComAppointmentsRoot";
// the rdf service
RDFService = Components.classes['component://netscape/rdf/rdf-service'].getService();
RDFService = RDFService.QueryInterface(Components.interfaces.nsIRDFService);
// ************************************************************
// Event handler for Edit code
// ************************************************************
function ascendToTR (node) {
var rv = node;
while ( rv.nodeName.toLowerCase() != "tr" ) {
rv = rv.parentNode;
}
return rv;
}
function handleRClick ( event ) {
// XXX event.type and event.currentNode and event.button are broken
var currentNode = ascendToTR(event.target);
EditApptById(currentNode.getAttribute("id"));
}
// ************************************************************
// Functions for event handlers (e.g., onclick)
// ************************************************************
function gotoURL( url ) {
window.content.location = url;
}
function getAddDiv() {
return document.documentElement.firstChild.nextSibling.nextSibling.firstChild.firstChild;
}
function getScheduleDiv() {
return document.documentElement.firstChild.nextSibling.nextSibling.firstChild.firstChild.nextSibling;
}
function getPickDiv() {
return document.documentElement.firstChild.nextSibling.nextSibling.firstChild.firstChild.nextSibling.nextSibling;
}
function buttonDisabled ( number ) {
// 0 for AddEvent
// 1 for Schedule
// 2 for Go To Date
var tabTR = document.getElementById("tabsTR");
tabTR.childNodes.item(0).className = "tab";
tabTR.childNodes.item(1).className = "tab";
tabTR.childNodes.item(2).className = "tab";
tabTR.childNodes.item(number).className = "tab disable";
// XXX BUG These two lines cause failure to display
// setting is on an XULElement
//tabTR.parentNode.parentNode.style.border="medium solid black";
//tabTR.parentNode.parentNode.style.border="none";
// XXX BUG These two lines cover up most of a shifting bug...
// Setting is on a table
tabTR.parentNode.style.border="medium solid black";
tabTR.parentNode.style.border="none";
}
function divActive( number ) {
// 0 for AddEvent
// 1 for Schedule
// 2 for Go To Date
buttonDisabled(number)
// for speed:
var AddDiv = getAddDiv();
var ScheduleDiv = getScheduleDiv();
var PickDiv = getPickDiv()
if ( number == 0 ) {
ScheduleDiv.style.display = "none";
PickDiv.style.display = "none";
AddDiv.style.display = "block";
} else if ( number == 1 ) {
AddDiv.style.display = "none";
PickDiv.style.display = "none";
ScheduleDiv.style.display = "block";
ShowSchedule();
} else if ( number == 2 ) {
AddDiv.style.display = "none";
ScheduleDiv.style.display = "none";
PickDiv.style.display = "block";
ShowPick();
}
}
function editButtonsActive( number ) {
// 0 for addbuttons
// 1 for editbuttons
var adddiv = getAddDiv();
var addbdiv = GetElementWithIdIn("addbuttons", adddiv);
var edbdiv = GetElementWithIdIn("editbuttons", adddiv);
if (number == 0) {
edbdiv.style.display = "none";
addbdiv.style.display = "block";
} else if (number == 1) {
addbdiv.style.display = "none";
edbdiv.style.display = "block";
}
}
function nextDay() {
nowShowing.setDate(nowShowing.getDate() + 1);
ShowSchedule();
}
function nextWeek() {
nowShowing.setDate(nowShowing.getDate() + 7);
ShowSchedule();
}
function prevDay() {
nowShowing.setDate(nowShowing.getDate() - 1);
ShowSchedule();
}
function prevWeek() {
nowShowing.setDate(nowShowing.getDate() - 7);
ShowSchedule();
}
function today() {
nowShowing = new Date();
ShowSchedule();
}
/* Date Picker */
function nextMonth() {
monthShowing.setMonth(monthShowing.getMonth() + 1);
ShowPick();
}
function prevMonth() {
monthShowing.setMonth(monthShowing.getMonth() - 1);
ShowPick();
}
function nextYear() {
monthShowing.setFullYear(monthShowing.getFullYear() + 1);
ShowPick();
}
function prevYear() {
monthShowing.setFullYear(monthShowing.getFullYear() - 1);
ShowPick();
}
function thisMonth() {
monthShowing = new Date();
ShowPick();
}
function pickDate( year, month, date ) {
// the month is 1..12
nowShowing = new Date(year, month - 1, date);
divActive(1); // calls ShowSchedule
}
// ************************************************************
// Utility functions
// ************************************************************
// XXX Should this be needed?
function GetElementWithIdIn ( id, ancestor ) {
// recursive search for an element with a given id
if ( ancestor.getAttribute("id") == id ) {
return ancestor;
} else { // else shows logic, not really needed because of return
for (var i = 0; i < ancestor.childNodes.length ; i++ ) {
// This isn't an official way to use named constants, but
// Mozilla supports it
if ( ancestor.childNodes.item(i).nodeType == Node.ELEMENT_NODE ) {
var rv = GetElementWithIdIn(id, ancestor.childNodes.item(i));
if (rv != null) {
return rv; // exits the function here, since we found the target
}
}
}
return null;
}
}
// ************************************************************
// The Appointment type
// ************************************************************
function ApptToString () {
return "[" + String(this.date) + "," + this.title + "]";
}
Appointment.prototype.toString = ApptToString;
function Appointment ( date, title, desc, dur, id ) { // used as a constructor
this.date = date; // date
this.title = title; // title
this.desc = desc; // description
this.dur = dur; // duration (minutes)
this.id = id; // id (in the RDF and in the table row)
// A useful debugging function:
// XXX If error in string, get silent error:
//this.toString = new Function('return "[" + String(this.date) + "," + this.title + "]"');
}
function compareAppt ( x , y ) { // for passing to Array::sort
// should return negative if x<y, 0 if x=y, and positive if x>y
// Date::getTime returns milliseconds since Jan 1, 1970, so
return x.date.getTime() - y.date.getTime();
}
// ************************************************************
// Code used for showing the schedule
// ************************************************************
function getOutputTBody() {
// get the TBody element for output
// XXX a hack, since getElementById doesn't work with mixed XUL/HTML, it
// seems.
//return document.documentElement.childNodes.item(2).childNodes.item(1);
// hack within a hack, to get around bug 8044
// for thead:
return getScheduleDiv().firstChild.nextSibling.firstChild.nextSibling;
// for no thead:
// return getScheduleDiv().firstChild.nextSibling.firstChild;
}
function getOutputForDate() {
// 2, 1, 3
return getScheduleDiv().firstChild.firstChild.firstChild.nextSibling.nextSibling;
}
function timeString( date ) {
var minutes = date.getMinutes();
if (minutes < 10 ) {
minutes = "0" + minutes;
}
var hours = date.getHours();
if (hours < 12) {
var suffix = "A";
} else {
var suffix = "P";
}
if (hours == 0) {
hours = 12;
} else if (hours > 12) {
hours -= 12;
}
return hours + ":" + minutes + suffix;
}
function dateString( date ) {
// month is 0..11
// ISO-8601 version:
// return date.getFullYear() + "-" + ( date.getMonth() + 1) + "-" + date.getDate();
return month_names_internal[date.getMonth()] + // both 0-based
" " + date.getDate() + ", " + date.getFullYear();
}
function getAttr(rdf_datasource,service,attr_name) {
var attr = rdf_datasource.GetTarget(service,
RDFService.GetResource(rdf_ns + attr_name),
true);
if (attr)
attr = attr.QueryInterface(
Components.interfaces.nsIRDFLiteral);
if (attr)
attr = attr.Value;
return attr;
}
function ReadAndSort () {
if ( ! haveRead ) {
// enumerate all of the flash datasources.
var enumerator = appts_container.GetElements();
// put all the appointments into an array
allAppts = new Array();
try {
while (enumerator.HasMoreElements()) {
var service = enumerator.GetNext().QueryInterface(
Components.interfaces.nsIRDFResource);
// get the title text
var title = getAttr(rdf_datasource, service, 'title');
// get the description text
var descrip = getAttr(rdf_datasource, service, 'notes');
// get the date, and see if it's for us
var year = getAttr(rdf_datasource, service, 'year');
var month = getAttr(rdf_datasource, service, 'month');
var date = getAttr(rdf_datasource, service, 'date');
var hour = getAttr(rdf_datasource, service, 'hour');
var minute = getAttr(rdf_datasource, service, 'minute');
// get the full resource URL:
var theid = service.Value;
// and use only the fragment identifier:
theid = theid.substring(theid.lastIndexOf("#") + 1);
var duration = getAttr(rdf_datasource, service, 'duration');
// month is 0..11
var apptDate = new Date(year, month - 1, date, hour, minute);
allAppts[allAppts.length] = new Appointment( apptDate, title, descrip, duration, theid );
}
} catch (ex) {
window.alert("Caught exception [[" + ex + "]]\n");
}
haveRead = true;
}
var todaysAppts = new Array();
for ( var i = 0 ; i < allAppts.length ; i++ ) {
var appt = allAppts[i];
if ( (appt.date.getFullYear() == nowShowing.getFullYear())
&& (appt.date.getMonth() == nowShowing.getMonth())
&& (appt.date.getDate() == nowShowing.getDate()) ) {
todaysAppts[todaysAppts.length] = appt;
}
}
// sort todaysAppts using the JavaScript builtin Array::sort(), by
// providing a sort function
todaysAppts.sort( compareAppt );
return todaysAppts;
}
function ShowSchedule() {
// Get the nodes where we will output
var outTB = getOutputTBody();
var outDate = getOutputForDate();
// Remove all its existing children, since we'll rewrite them
while (outTB.hasChildNodes() ) {
outTB.removeChild(outTB.firstChild);
}
while (outDate.hasChildNodes() ) {
outDate.removeChild(outDate.firstChild);
}
// Write the date at the top
outDate.appendChild(document.createTextNode(dateString(nowShowing)));
// and write the appointments to the table...
// XXX Hack: get around insertRow() bug.
var newrow = outTB.insertRow(outTB.rows.length);
// Get the appointments for today, already sorted, from some kind of input
// this is an Array of Appointment
var todaysAppts = ReadAndSort();
for ( var i = 0 ; i < todaysAppts.length ; i++ ) {
var appt = todaysAppts[i];
// add the appointment to the list:
var newrow = outTB.insertRow(outTB.rows.length);
// set up event handling
newrow.setAttribute("id", appt.id);
// XXX extra param shouldn't be needed
newrow.addEventListener("click", handleRClick, false, false);
// XXX Hack: get around insertCell() bug by switching order.
var titlecell = newrow.insertCell(1);
var timecell = newrow.insertCell(0);
timecell.appendChild(document.createTextNode(timeString(appt.date)));
titlecell.appendChild(document.createTextNode(appt.title));
}
}
// ************************************************************
// Code used for the Goto date function
// ************************************************************
// monthShowing holds Year and Month for current Calendar
function monthString( date ) {
// ISO-8601 format
// return date.getFullYear() + "-" + ( date.getMonth() + 1);
return month_names_internal[date.getMonth()] + // both 0-based
" " + date.getFullYear();
}
function ShowPick() {
var pickDiv = getPickDiv(); // for speed
// StartCodeTime();
var outCal = GetElementWithIdIn("calendar", pickDiv);
var outDate = GetElementWithIdIn("MonthOutput", pickDiv);
// EndCodeTime("two runs of GetElementWithIdIn");
// StartCodeTime();
// Remove all existing children, since we'll rewrite them
while (outCal.hasChildNodes() ) {
outCal.removeChild(outCal.firstChild);
}
while (outDate.hasChildNodes() ) {
outDate.removeChild(outDate.firstChild);
}
// EndCodeTime("removing existing children");
// StartCodeTime();
// Write the month at the top
outDate.appendChild(document.createTextNode(monthString(monthShowing)));
// EndCodeTime("initial stuff");
// and write the calendar to the table...
// StartCodeTime();
// XXX Hack: get around insertRow() bug.
var myrow = outCal.insertRow(0);
// EndCodeTime("initial stuff");
// make room before the first day, which starts on a strange day of the week
// note that getDay(), 0=Sunday and 6=Saturday
// StartCodeTime();
var curDay = new Date(monthShowing); // get the month we want to show
curDay.setDate(1); // start with the first day of the month
// EndCodeTime("setting curDay");
// StartCodeTime();
myrow = outCal.insertRow(outCal.rows.length);
var junkcell = myrow.insertCell(0); // XXX Bug in insertCell
for (var i = 0 ; i < curDay.getDay() ; i++ ) {
myrow.insertCell(myrow.cells.length);
}
// EndCodeTime("writing extra cells");
// StartCodeTime();
var mycell;
var targMonth = monthShowing.getMonth(); // for speed - saves 30ms
// for speed:
var testNowShowing = (
( monthShowing.getFullYear() == nowShowing.getFullYear()) &&
( monthShowing.getMonth() == nowShowing.getMonth()) );
var testCurrentTime = (
( monthShowing.getFullYear() == currentTime.getFullYear()) &&
( monthShowing.getMonth() == currentTime.getMonth()) );
while ( curDay.getMonth() == targMonth ) {
if ( ( curDay.getDay() == 0) && (curDay.getDate() != 1) ) {
// if it's Sunday, and not the 1st of the month
// then add a new row
myrow = outCal.insertRow(outCal.rows.length);
junkcell = myrow.insertCell(0); // XXX Bug in insertCell
}
mycell = myrow.insertCell( myrow.cells.length );
// put the number of the current date in the cell
mycell.appendChild( document.createTextNode( curDay.getDate() ) );
// and set the onClick handler
mycell.setAttribute("onclick", "pickDate(" + curDay.getFullYear()
+ "," + (curDay.getMonth() + 1)
+ "," + curDay.getDate()
+ ")");
// and set the class
var classNm = "caldate";
if ( testNowShowing && ( curDay.getDate() == nowShowing.getDate())) {
classNm += " nowshowing";
}
if ( testCurrentTime && ( curDay.getDate() == currentTime.getDate())) {
classNm += " today";
}
mycell.setAttribute("class", classNm);
// and loop...
curDay.setDate(curDay.getDate() + 1);
}
// EndCodeTime("writing the days");
}
// ************************************************************
// Code used for Adding to the data
// ************************************************************
function makeAssert ( source, data, name ) {
var target = RDFService.GetLiteral(data);
var arc = RDFService.GetResource(rdf_ns + name);
rdf_datasource.Assert(source, arc, target, true);
}
function SendBackToSource( appt ) {
// make a resource for the new appointment
// These four all write, but only first appt works
// var sourceNode = RDFService.GetResource("http://www.w3.org/1999/02/22-rdf-syntax-ns#Description");
// var sourceNode = RDFService.GetResource("");
// var sourceNode = RDFService.GetResource("aoeuidhtns");
// var sourceNode = RDFService.GetResource("http://when.com/aoeuidhtns#");
// milliseconds since 1970-01-01 00:00 should be a good enough
// unique identifier (creation time of appt)
var sourceNode
= RDFService.GetResource(RDFFileName +"#" + appt.id);
// create literals and assert a relationship to the new appointment
// for each piece of data
makeAssert( sourceNode, appt.date.getFullYear(), 'year');
makeAssert( sourceNode, appt.date.getMonth() + 1, 'month'); // month is 0..1 in the date structure
makeAssert( sourceNode, appt.date.getDate(), 'date');
makeAssert( sourceNode, appt.date.getHours(), 'hour');
makeAssert( sourceNode, appt.date.getMinutes(), 'minute');
makeAssert( sourceNode, appt.title, 'title');
makeAssert( sourceNode, appt.desc, 'notes');
makeAssert( sourceNode, appt.dur, 'duration');
// connect the new appointment to the datasource
appts_container.AppendElement( sourceNode );
// write the datasource back to disk
try {
rdf_remote_datasource.Flush(); // must be a RemoteDataSource, after 1999-06-23
} catch (ex) {
window.alert("Caught exception [[" + ex + "]] in Flush().\n");
}
}
function Add( appt ) {
// Add it to our internal data -- note that we don't show it!
allAppts[allAppts.length] = appt;
// and add it to the external data
SendBackToSource( appt );
}
function ResetAddFormTo( year, month, date, hrs, min, durhrs, durmin, title, notes) {
var addDiv = getAddDiv(); // for speed
var yearselect = GetElementWithIdIn("addyear", addDiv );
var monthselect = GetElementWithIdIn("addmonth", addDiv );
var dayselect = GetElementWithIdIn("addday", addDiv );
var hourselect = GetElementWithIdIn("addtimehrs", addDiv );
var minselect = GetElementWithIdIn("addtimemin", addDiv );
var durhourselect = GetElementWithIdIn("adddurhrs", addDiv );
var durminselect = GetElementWithIdIn("adddurmin", addDiv );
var titleInput = GetElementWithIdIn("addtitle", addDiv );
var notesInput = GetElementWithIdIn("addnotes", addDiv );
if (yearselect != null) { // "if (yearselect)" works too
// Subtract the value of the first year in the list to set
// selectedIndex. JavaScript converts the string value to a number.
yearselect.selectedIndex =
year - yearselect.options.item(0).value;
} else {
window.alert("Hit a null.");
}
if (monthselect != null) {
// selectedIndex 0 based, so subtract one
monthselect.selectedIndex = month - 1;
} else {
window.alert("Hit a null.");
}
if (dayselect != null) {
// selectedIndex 0 based, so subtract one
dayselect.selectedIndex = date - 1;
} else {
window.alert("Hit a null.");
}
if (hourselect != null) {
// both 0 based
hourselect.selectedIndex = hrs ;
} else {
window.alert("Hit a null.");
}
if (minselect != null) {
minselect.selectedIndex = Math.round(min / 5);
} else {
window.alert("Hit a null.");
}
if (durhourselect != null) {
durhourselect.selectedIndex = durhrs;
} else {
window.alert("Hit a null.");
}
if (durminselect != null) {
durminselect.selectedIndex = Math.round(durmin / 5);
} else {
window.alert("Hit a null.");
}
if (titleInput != null) {
if ( title == null) {
title = "";
}
titleInput.value = title;
} else {
window.alert("Hit a null.");
}
if (notesInput != null) {
if ( notes == null) {
notes = "";
}
notesInput.value = notes;
} else {
window.alert("Hit a null.");
}
}
function ResetAddForm() {
editButtonsActive(0);
ResetAddFormTo( nowShowing.getFullYear(),
nowShowing.getMonth() + 1,
nowShowing.getDate(),
nowShowing.getHours() + 1, // upcoming hour
0, // minutes
0, // duration hours
0, // duration minutes
"", // title
""); // notes
}
function SubmitAddForm() {
var addDiv = getAddDiv(); // for speed
var title = GetElementWithIdIn("addtitle", addDiv );
var years = GetElementWithIdIn("addyear", addDiv );
var months = GetElementWithIdIn("addmonth", addDiv );
var days = GetElementWithIdIn("addday", addDiv );
var timehrs = GetElementWithIdIn("addtimehrs", addDiv );
var timemin = GetElementWithIdIn("addtimemin", addDiv );
var durhrs = GetElementWithIdIn("adddurhrs", addDiv );
var durmin = GetElementWithIdIn("adddurmin", addDiv );
var notes = GetElementWithIdIn("addnotes", addDiv );
if ( ( title == null ) ||
( years == null ) ||
( months == null ) ||
( days == null ) ||
( timehrs == null ) ||
( timemin == null ) ||
( durhrs == null ) ||
( durmin == null ) ||
( notes == null ) ) {
window.alert("Something is null. Addition failed.\n");
} else {
// months go 0..11
var apptid = "appt" + (new Date().getTime());
Add( new Appointment( new Date ( years.value, months.value - 1,
days.value, timehrs.value,
timemin.value ),
title.value,
notes.value,
(durhrs.value * 60) + (durmin.value * 1),
apptid));
// ResetAddForm();
divActive(1);
}
}
// ************************************************************
// Edit code, which uses add form
// ************************************************************
function getApptById( id ) {
for (var i = 0 ; i < allAppts.length ; i++ ) {
if ( allAppts[i].id == id ) {
return allAppts[i];
}
}
return null;
}
function removeApptById ( id ) {
for (var i = 0 ; i < allAppts.length ; i++ ) {
if ( allAppts[i].id == id ) {
// Remove from list
allAppts[i] = allAppts[allAppts.length - 1];
allAppts[allAppts.length - 1] = null;
allAppts.length -= 1;
return;
}
}
}
function EditApptById( theid ) {
idEditing = theid; // global variable
var apptEditing = getApptById( idEditing );
if ( apptEditing == null) {
window.alert("Null appointment. Something's wrong.\n");
return;
}
divActive(0); // XXX This should come later, but...
editButtonsActive(1);
ResetAddFormTo( apptEditing.date.getFullYear(),
apptEditing.date.getMonth() + 1,
apptEditing.date.getDate(),
apptEditing.date.getHours(),
apptEditing.date.getMinutes(),
Math.floor(apptEditing.dur / 60),
apptEditing.dur % 60,
apptEditing.title,
apptEditing.desc );
}
function getAttrLiteral(rdf_datasource,service,attr_name) {
var attr = rdf_datasource.GetTarget(service,
RDFService.GetResource(rdf_ns + attr_name),
true);
if (attr)
attr = attr.QueryInterface(
Components.interfaces.nsIRDFLiteral);
return attr;
}
function makeUnAssert ( rdf_datasource, resource, name ) {
var target = getAttrLiteral(rdf_datasource, resource, name);
var data = getAttr(rdf_datasource, resource, name); // function above
var arc = RDFService.GetResource(rdf_ns + name);
rdf_datasource.Unassert(resource, arc, target);
}
function DeleteEditing() {
// delete from our list:
removeApptById(idEditing);
// delete from the data source
var sourceNode = RDFService.GetResource(RDFFileName +"#" + idEditing);
appts_container.RemoveElement( sourceNode, true );
// Need to unassert all of sourceNode's relationships
makeUnAssert(rdf_datasource, sourceNode, 'year');
makeUnAssert(rdf_datasource, sourceNode, 'month');
makeUnAssert(rdf_datasource, sourceNode, 'date');
makeUnAssert(rdf_datasource, sourceNode, 'hour');
makeUnAssert(rdf_datasource, sourceNode, 'minute');
makeUnAssert(rdf_datasource, sourceNode, 'title');
makeUnAssert(rdf_datasource, sourceNode, 'notes');
makeUnAssert(rdf_datasource, sourceNode, 'duration');
try {
rdf_remote_datasource.Flush(); // must be a RemoteDataSource, after 1999-06-23
} catch (ex) {
window.alert("Caught exception [[" + ex + "]] in Flush().\n");
}
}
function EditFormSubmit() {
DeleteEditing();
SubmitAddForm();
divActive(1);
}
function EditFormDelete() {
DeleteEditing();
divActive(1);
}
function EditFormCancel() {
divActive(1);
}
// ************************************************************
// Startup Code
// ************************************************************
function Init()
{
// Initialize the Sidebar
// Install all the datasources named in the Flash Registry into
// the tree control. Datasources are listed as members of the
// NC:FlashDataSources sequence, and are loaded in the order that
// they appear in that sequence.
try {
// First try to construct a new one and load it
// synchronously. nsIRDFService::GetDataSource() loads RDF/XML
// asynchronously by default.
rdf_datasource = Components.classes['component://netscape/rdf/datasource?name=xml-datasource'].createInstance();
rdf_datasource = rdf_datasource.QueryInterface(Components.interfaces.nsIRDFDataSource);
rdf_remote_datasource = rdf_datasource.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
rdf_remote_datasource.Init(RDFFileName); // this will throw if it's already been opened and registered.
dump("Reading datasource synchronously.\n");
// read it in synchronously.
rdf_remote_datasource.Refresh(true);
}
catch (ex) {
// if we get here, then the RDF/XML has been opened and read
// once. We just need to grab the datasource.
dump("Datasource already read. Grabbing.\n");
rdf_datasource = RDFService.GetDataSource(RDFFileName);
}
// Create a 'container' wrapper around the appts_resourcename
// resource so we can use some utility routines that make access a
// bit easier.
// NOT var, so it's global
appts_container = Components.classes['component://netscape/rdf/container'].createInstance();
appts_container = appts_container.QueryInterface(Components.interfaces.nsIRDFContainer);
appts_resource = RDFService.GetResource(appts_resourcename);
appts_container.Init(rdf_datasource, appts_resource);
}
function Boot() {
if (document.getElementById("ApptsWindow")) {
dump("Calling init:\n");
Init();
// XXX Bug 9136 - this doesn't work when form is hidden.
// ResetAddForm();
// ShowSchedule();
dump("Calling divActive(1):\n");
divActive(1);
dump("Done initializing.\n");
// and let events take things from there...
} else {
setTimeout("Boot()", 0);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,475 @@
<?xml version="1.0"?> <!-- -*- Mode: SGML; indent-tabs-mode: nil; -*- -->
<!--
The contents of this file are subject to the Netscape Public License
Version 1.0 (the "NPL"); you may not use this file except in
compliance with the NPL. You may obtain a copy of the NPL at
http://www.mozilla.org/NPL/
Software distributed under the NPL is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
for the specific language governing rights and limitations under the
NPL.
The Initial Developer of this code under the NPL is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998 Netscape Communications Corporation. All Rights
Reserved.
-->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="bug12012.css" type="text/css"?>
<!DOCTYPE window
[
<!ENTITY text_to_be_replaced "Loading. Please wait.">
<!-- set up selectors for the date in the adder. Using entities makes
it much easier to change the format of the date. Right now, it is
"Month Day, Year" -->
<!ENTITY add.day.selector.year "
<html:select id='addyear'>
<html:option value='1998'>1998</html:option>
<html:option value='1999'>1999</html:option>
<html:option value='2000'>2000</html:option>
<html:option value='2001'>2001</html:option>
<html:option value='2002'>2002</html:option>
<html:option value='2003'>2003</html:option>
<html:option value='2004'>2004</html:option>
<html:option value='2005'>2005</html:option>
<html:option value='2006'>2006</html:option>
<html:option value='2007'>2007</html:option>
<html:option value='2008'>2008</html:option>
<html:option value='2009'>2009</html:option>
</html:select>
">
<!ENTITY add.month.1 "Jan">
<!ENTITY add.month.2 "Feb">
<!ENTITY add.month.3 "Mar">
<!ENTITY add.month.4 "Apr">
<!ENTITY add.month.5 "May">
<!ENTITY add.month.6 "Jun">
<!ENTITY add.month.7 "Jul">
<!ENTITY add.month.8 "Aug">
<!ENTITY add.month.9 "Sep">
<!ENTITY add.month.10 "Oct">
<!ENTITY add.month.11 "Nov">
<!ENTITY add.month.12 "Dec">
<!ENTITY add.day.selector.month "
<html:select id='addmonth'>
<html:option value='1'>&add.month.1;</html:option>
<html:option value='2'>&add.month.2;</html:option>
<html:option value='3'>&add.month.3;</html:option>
<html:option value='4'>&add.month.4;</html:option>
<html:option value='5'>&add.month.5;</html:option>
<html:option value='6'>&add.month.6;</html:option>
<html:option value='7'>&add.month.7;</html:option>
<html:option value='8'>&add.month.8;</html:option>
<html:option value='9'>&add.month.9;</html:option>
<html:option value='10'>&add.month.10;</html:option>
<html:option value='11'>&add.month.11;</html:option>
<html:option value='12'>&add.month.12;</html:option>
</html:select>
">
<!ENTITY add.day.selector.day "
<html:select id='addday'>
<html:option value='1'>1</html:option>
<html:option value='2'>2</html:option>
<html:option value='3'>3</html:option>
<html:option value='4'>4</html:option>
<html:option value='5'>5</html:option>
<html:option value='6'>6</html:option>
<html:option value='7'>7</html:option>
<html:option value='8'>8</html:option>
<html:option value='9'>9</html:option>
<html:option value='10'>10</html:option>
<html:option value='11'>11</html:option>
<html:option value='12'>12</html:option>
<html:option value='13'>13</html:option>
<html:option value='14'>14</html:option>
<html:option value='15'>15</html:option>
<html:option value='16'>16</html:option>
<html:option value='17'>17</html:option>
<html:option value='18'>18</html:option>
<html:option value='19'>19</html:option>
<html:option value='20'>20</html:option>
<html:option value='21'>21</html:option>
<html:option value='22'>22</html:option>
<html:option value='23'>23</html:option>
<html:option value='24'>24</html:option>
<html:option value='25'>25</html:option>
<html:option value='26'>26</html:option>
<html:option value='27'>27</html:option>
<html:option value='28'>28</html:option>
<html:option value='29'>29</html:option>
<html:option value='30'>30</html:option>
<html:option value='31'>31</html:option>
</html:select>
">
<!--
This controls the date format and is used in the document below
We escape the ampersands here so that the entities are not expanded
here, but in the text. This ought to save memory, I would think...
-->
<!ENTITY add.day.selectors
"&#38;add.day.selector.month; &#38;add.day.selector.day;, &#38;add.day.selector.year;">
<!ENTITY add.time.selector.hours "
<html:select id='addtimehrs'>
<html:option value='0'>12 AM</html:option>
<html:option value='1'>1 AM</html:option>
<html:option value='2'>2 AM</html:option>
<html:option value='3'>3 AM</html:option>
<html:option value='4'>4 AM</html:option>
<html:option value='5'>5 AM</html:option>
<html:option value='6'>6 AM</html:option>
<html:option value='7'>7 AM</html:option>
<html:option value='8'>8 AM</html:option>
<html:option value='9'>9 AM</html:option>
<html:option value='10'>10 AM</html:option>
<html:option value='11'>11 AM</html:option>
<html:option value='12'>12 PM</html:option>
<html:option value='13'>1 PM</html:option>
<html:option value='14'>2 PM</html:option>
<html:option value='15'>3 PM</html:option>
<html:option value='16'>4 PM</html:option>
<html:option value='17'>5 PM</html:option>
<html:option value='18'>6 PM</html:option>
<html:option value='19'>7 PM</html:option>
<html:option value='20'>8 PM</html:option>
<html:option value='21'>9 PM</html:option>
<html:option value='22'>10 PM</html:option>
<html:option value='23'>11 PM</html:option>
</html:select>
">
<!ENTITY add.time.selector.minutes "
<html:select id='addtimemin'>
<html:option value='00'>:00</html:option>
<html:option value='05'>:05</html:option>
<html:option value='10'>:10</html:option>
<html:option value='15'>:15</html:option>
<html:option value='20'>:20</html:option>
<html:option value='25'>:25</html:option>
<html:option value='30'>:30</html:option>
<html:option value='35'>:35</html:option>
<html:option value='40'>:40</html:option>
<html:option value='45'>:45</html:option>
<html:option value='50'>:50</html:option>
<html:option value='55'>:55</html:option>
</html:select>
">
<!ENTITY add.time.selectors
"&#38;add.time.selector.hours; &#38;add.time.selector.minutes;">
<!ENTITY add.duration.selector.hours "
<html:select id='adddurhrs'>
<html:option value='0'>0</html:option>
<html:option value='1'>1</html:option>
<html:option value='2'>2</html:option>
<html:option value='3'>3</html:option>
<html:option value='4'>4</html:option>
<html:option value='5'>5</html:option>
<html:option value='6'>6</html:option>
<html:option value='7'>7</html:option>
<html:option value='8'>8</html:option>
<html:option value='9'>9</html:option>
<html:option value='10'>10</html:option>
<html:option value='11'>11</html:option>
<html:option value='12'>12</html:option>
</html:select>
">
<!ENTITY add.duration.selector.minutes "
<html:select id='adddurmin'>
<html:option value='00'>:00</html:option>
<html:option value='05'>:05</html:option>
<html:option value='10'>:10</html:option>
<html:option value='15'>:15</html:option>
<html:option value='20'>:20</html:option>
<html:option value='25'>:25</html:option>
<html:option value='30'>:30</html:option>
<html:option value='35'>:35</html:option>
<html:option value='40'>:40</html:option>
<html:option value='45'>:45</html:option>
<html:option value='50'>:50</html:option>
<html:option value='55'>:55</html:option>
</html:select>
">
<!ENTITY add.duration.selectors
"&#38;add.duration.selector.hours; &#38;add.duration.selector.minutes;">
<!ENTITY schedule.header.button.weekbefore.label "&lt;&lt;">
<!ENTITY schedule.header.button.daybefore.label "&lt;">
<!ENTITY schedule.header.button.daylater.label "&gt;">
<!ENTITY schedule.header.button.weeklater.label "&gt;&gt;">
<!ENTITY schedule.header.button.today.label "Now">
<!ENTITY schedule.header.button.weekbefore.title "One week earlier">
<!ENTITY schedule.header.button.daybefore.title "One day earlier">
<!ENTITY schedule.header.button.daylater.title "One day later">
<!ENTITY schedule.header.button.weeklater.title "One week later">
<!ENTITY schedule.header.button.today.title "Today">
<!ENTITY pick.header.button.yearbefore.label "&lt;&lt;">
<!ENTITY pick.header.button.monthbefore.label "&lt;">
<!ENTITY pick.header.button.monthlater.label "&gt;">
<!ENTITY pick.header.button.yearlater.label "&gt;&gt;">
<!ENTITY pick.header.button.thismonth.label "Now">
<!ENTITY pick.header.button.yearbefore.title "One year earlier">
<!ENTITY pick.header.button.monthbefore.title "One month earlier">
<!ENTITY pick.header.button.monthlater.title "One month later">
<!ENTITY pick.header.button.yearlater.title "One year later">
<!ENTITY pick.header.button.thismonth.title "This Month">
<!ENTITY pick.calendar.header.day.1 "S">
<!ENTITY pick.calendar.header.day.2 "M">
<!ENTITY pick.calendar.header.day.3 "T">
<!ENTITY pick.calendar.header.day.4 "W">
<!ENTITY pick.calendar.header.day.5 "T">
<!ENTITY pick.calendar.header.day.6 "F">
<!ENTITY pick.calendar.header.day.7 "S">
<!ENTITY footer.tab.add.label "Add">
<!ENTITY footer.tab.sched.label "List">
<!ENTITY footer.tab.goto.label "Date">
<!ENTITY footer.button.whencom.label "Calendar">
<!ENTITY footer.button.whencom.url "http://when.com/">
]>
<window
xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="Boot()"
id="ApptsWindow"
align="horizontal">
<html:script src="bug12012.js" />
<spring flex="1"/>
<box align="vertical"> <!-- fill all horizontal space -->
<box flex="1" id="main"> <!-- fill all vertical space -->
<html:div class="add" style="display: none">
<html:table id="add">
<html:col class="addtitle" />
<html:col class="addbody" />
<html:tbody>
<html:tr>
<html:th>
Title
</html:th>
<html:td>
<html:input type="text" id="addtitle" />
</html:td>
</html:tr>
<html:tr>
<html:th>
Day
</html:th>
<html:td>
&add.day.selectors;
</html:td>
</html:tr>
<html:tr>
<html:th>
Time
</html:th>
<html:td>
&add.time.selectors;
</html:td>
</html:tr>
<html:tr>
<html:th>
Length
</html:th>
<html:td>
&add.duration.selectors;
</html:td>
</html:tr>
<html:tr>
<html:th>
Notes
</html:th>
<html:td>
<html:input type="text" id="addnotes" />
</html:td>
</html:tr>
</html:tbody>
</html:table>
<html:div id="addbuttons">
<html:input type="button" value="Add" onclick="SubmitAddForm()" />
<html:input type="button" value="Clear" onclick="ResetAddForm()" />
</html:div>
<html:div id="editbuttons" style="display: none;">
<html:input type="button" value="Change" onclick="EditFormSubmit()" />
<html:input type="button" value="Delete" onclick="EditFormDelete()" />
<html:input type="button" value="Cancel" onclick="EditFormCancel()" />
</html:div>
</html:div>
<html:div class="schedule">
<html:table>
<html:tr>
<html:td class="button" onclick="prevWeek()" title="&schedule.header.button.weekbefore.title;">
&schedule.header.button.weekbefore.label;
</html:td>
<html:td class="button" onclick="prevDay()" title="&schedule.header.button.daybefore.title;">
&schedule.header.button.daybefore.label;
</html:td>
<html:td id="DateOutput">
</html:td>
<html:td class="button" onclick="nextDay()" title="&schedule.header.button.daylater.title;">
&schedule.header.button.daylater.label;
</html:td>
<html:td class="button" onclick="nextWeek()" title="&schedule.header.button.weeklater.title;">
&schedule.header.button.weeklater.label;
</html:td>
<html:td class="button" onclick="today()" title="&schedule.header.button.today.title;">
&schedule.header.button.today.label;
</html:td>
</html:tr>
</html:table>
<html:table width="100%" class="data">
<!-- XXX Bug: if we take out this thead while border-collapse on
the parent is collapse XXX WHICH IT SHOULD BE BY DEFAULT (?)
((and/and not) make the corresponding
removal of a .nextSibling to the JS), we crash, even without
the script element entirely -->
<html:thead>
<html:tr>
<html:th>
Time
</html:th>
<html:th>
Title
</html:th>
</html:tr>
</html:thead>
<html:tbody id="ApptTable">
<html:tr>
<html:td colspan="2">
&text_to_be_replaced;
</html:td>
</html:tr>
</html:tbody>
</html:table>
</html:div>
<html:div class="pick" style="display: none">
<html:table>
<html:tr>
<html:td class="button" onclick="prevYear()" title="&pick.header.button.yearbefore.title;">
&pick.header.button.yearbefore.label;
</html:td>
<html:td class="button" onclick="prevMonth()" title="&pick.header.button.monthbefore.title;">
&pick.header.button.monthbefore.label;
</html:td>
<html:td id="MonthOutput">
</html:td>
<html:td class="button" onclick="nextMonth()" title="&pick.header.button.monthlater.title;">
&pick.header.button.monthlater.label;
</html:td>
<html:td class="button" onclick="nextYear()" title="&pick.header.button.yearlater.title;">
&pick.header.button.yearlater.label;
</html:td>
<html:td class="button" onclick="thisMonth()" title="&pick.header.button.thismonth.title;">
&pick.header.button.thismonth.label;
</html:td>
</html:tr>
</html:table>
<html:table>
<html:thead>
<html:tr>
<html:th>
&pick.calendar.header.day.1;
</html:th>
<html:th>
&pick.calendar.header.day.2;
</html:th>
<html:th>
&pick.calendar.header.day.3;
</html:th>
<html:th>
&pick.calendar.header.day.4;
</html:th>
<html:th>
&pick.calendar.header.day.5;
</html:th>
<html:th>
&pick.calendar.header.day.6;
</html:th>
<html:th>
&pick.calendar.header.day.7;
</html:th>
</html:tr>
</html:thead>
<html:tbody id="calendar">
<html:tr>
<html:td colspan="7">
&text_to_be_replaced;
</html:td>
</html:tr>
</html:tbody>
</html:table>
</html:div>
</box>
<box id="tabs" align="horizontal">
<spring flex="1"/>
<html:table>
<html:tr id="tabsTR">
<html:td class="tab" onclick="if (this.className != 'tab disable') { divActive(0); ResetAddForm() }"> <!-- XXX need to reset due to bug 9136 -->
&footer.tab.add.label;
</html:td>
<html:td class="tab" onclick="if (this.className != 'tab disable') { divActive(1) }">
&footer.tab.sched.label;
</html:td>
<html:td class="tab" onclick="if (this.className != 'tab disable') { divActive(2) }">
&footer.tab.goto.label;
</html:td>
<html:td>
<html:a href="#" onclick="gotoURL('&footer.button.whencom.url;');return false;">&footer.button.whencom.label;</html:a>
</html:td>
</html:tr>
</html:table>
<spring flex="1"/>
</box> <!-- id="tabs" -->
</box>
<spring flex="1"/>
</window>

View File

@ -0,0 +1,9 @@
<table border=5>
<tr>
<td width=50%>almaalmaalmaalmaalma</td><td>x</td>
</table>
<BR>
<table border=5>
<tr>
<td>almaalmaalmaalmaalma</td><td width=50%>x</td>
</table>

View File

@ -105,6 +105,7 @@ file:///s:/mozilla/layout/html/tests/table/bugs/bug4803.html
REMfile:///s:/mozilla/layout/html/tests/table/bugs/bug5188.html
REMfile:///s:/mozilla/layout/html/tests/table/bugs/bug5797.html
file:///s:/mozilla/layout/html/tests/table/bugs/bug5798.html
file:///s:/mozilla/layout/html/tests/table/bugs/bug5799.html
REMfile:///s:/mozilla/layout/html/tests/table/bugs/bug5835.html
file:///s:/mozilla/layout/html/tests/table/bugs/bug5838.html
REMfile:///s:/mozilla/layout/html/tests/table/bugs/bug625.html

View File

@ -2,4 +2,5 @@ file:///s:/mozilla/layout/html/tests/table/bugs/bug5835.html
file:///s:/mozilla/layout/html/tests/table/bugs/bug625.html
file:///s:/mozilla/layout/html/tests/table/bugs/bug6933.html
file:///s:/mozilla/layout/html/tests/table/bugs/bug709.html
file:///s:/mozilla/layout/html/tests/table/bugs/bug12012.html
file:///s:/mozilla/layout/html/tests/table/bugs/bug15933.html