From VisualWorks®, 7.5 of April 16, 2007 on August 8, 2007 at 2:52:37 pm (Dialog confirm: 'You are filing-in a Parcel source file!\\While this is possible it will not have\the same effect as loading the parcel.\None of the Parcel''s prerequisites will\be loaded and none of its load actions\will be performed.\\Are you sure you want to file-in?' withCRs) ifFalse: [self error: 'Parcel file-in abandoned. Choose terminate or close.'] <class> <name>HBMagicTimeTest</name> <environment>Seaside</environment> <super>Seaside.WAComponent</super> <private>false</private> none <imports></imports> <category>HBStandardScripts</category> <attributes> <package>HBStandardScripts</package> </attributes> </class> <class> <name>HBStandardScripts</name> <environment>Smalltalk</environment> <super>Seaside.WAFileLibrary</super> <private>false</private> none <imports></imports> <category>HBStandardScripts</category> <attributes> <package>HBStandardScripts</package> </attributes> </class> <class> <name>HBMagicDateTest</name> <environment>Seaside</environment> <super>Seaside.WAComponent</super> <private>false</private> none <imports></imports> <category>HBStandardScripts</category> <attributes> <package>HBStandardScripts</package> </attributes> </class> <class> <name>HBMagicStuffDemo</name> <environment>Seaside</environment> <super>Seaside.WAComponent</super> <private>false</private> none date time <imports></imports> <category>HBStandardScripts</category> <attributes> <package>HBStandardScripts</package> </attributes> </class> <methods> Seaside.HBMagicTimeTest <category>rendering</category>
renderContentOn: html "The actual test is inside the script method" html script: 'runMagicTimeTest();'
script ^ ' function magicTimeAssert(input, expectedOutput) { try { if (basicMagicTime(input) != expectedOutput) { document.write("\"" + input + "\" gives \"" + basicMagicTime(input) + "\" instead of \"" + expectedOutput + "\"<br/>"); return false; } } catch (e) { document.write("\"" + input + "\" is identified as invalid instead of \"" + expectedOutput + "\"<br/>" + e +"<br/>"); return false; } return true; } function runMagicTimeTest() { var testData = new Array( "9", "9:00 AM", "11", "11:00 AM", "12", "12:00 PM", "13", "1:00 PM", "923", "9:23 AM", "1223", "12:23 PM", "1323", "1:23 PM", "9a", "9:00 AM", "11a", "11:00 AM", "12a", "12:00 AM", "923a", "9:23 AM", "1223a", "12:23 AM", "9p", "9:00 PM", "11p", "11:00 PM", "12p", "12:00 PM", "923p", "9:23 PM", "1223p", "12:23 PM", "9:23", "9:23 AM", "11:23", "11:23 AM", "12:23", "12:23 PM", "13:23", "1:23 PM", "9:23a", "9:23 AM", "11:23a", "11:23 AM", "12:23a", "12:23 AM", "9:23p", "9:23 PM", "11:23p", "11:23 PM", "12:23p", "12:23 PM" ); var allPass = true; var total = testData.length/2; var fail = 0; for (i=0; i<(testData.length); i=i+2) { if (!magicTimeAssert(testData[i], testData[i+1])) { allPass = false; ++fail; } } document.write("<br/>" + (total-fail) + " passed, " + fail + " failed<br/>"); } '
</methods> <methods> Seaside.HBMagicTimeTest class <category>seaside</category>
canBeRoot ^ true
initialize (self registerAsApplication: 'magic/magictimetests') libraries add: HBStandardScripts.
</methods> <methods> HBStandardScripts <category>javascript</category>
addEventJs "From http://www.scottandrew.com/weblog/articles/cbs-events" ^ ' function addEvent(obj, evType, fn){ if (obj.addEventListener){ obj.addEventListener(evType, fn, false); return true; } else if (obj.attachEvent){ var r = obj.attachEvent("on"+evType, fn); return r; } else { return false; } } '
magicDateParseJs ^ ' /* Adapted from "Magic" date parsing, by Simon Willison (6th October 2003) http://simon.incutio.com/archive/2003/10/06/betterDateInput licensed under Creative Commons http://simon.incutio.com/archive/2002/12/16/creativeCommonsLaunch Original code modified by Yar Hwee Boon [hboon@motionobj.com] */ // Finds the index of the first occurence of item in the array, or -1 if not found Array.prototype.indexOf = function(item) { for (var i = 0; i < this.length; i++) { if (this[i] == item) { return i; } } return -1; }; // Returns an array of items judged "true" by the passed in test function Array.prototype.filter = function(test) { var matches = []; for (var i = 0; i < this.length; i++) { if (test(this[i])) { matches[matches.length] = this[i]; } } return matches; }; var monthNames = "January February March April May June July August September October November December".split(" "); var weekdayNames = "Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "); /* Takes a string, returns the index of the month matching that string, throws an error if 0 or more than 1 matches */ function parseMonth(month) { var matches = monthNames.filter(function(item) { return new RegExp("^" + month, "i").test(item); }); if (matches.length == 0) { throw new Error("Invalid month string"); } if (matches.length > 1) { throw new Error("Ambiguous month"); } return monthNames.indexOf(matches[0]); } // Same as parseMonth but for days of the week function parseWeekday(weekday) { var matches = weekdayNames.filter(function(item) { return new RegExp("^" + weekday, "i").test(item); }); if (matches.length == 0) { throw new Error("Invalid day string"); } if (matches.length > 1) { throw new Error("Ambiguous weekday"); } return weekdayNames.indexOf(matches[0]); } /* Array of objects, each has "re", a regular expression and "handler", a function for creating a date from something that matches the regular expression. Handlers may throw errors if string is unparseable. */ var dateParsePatterns = [ // Empty string or whitespace only { re: /^\s*$/i, handler: function() { return null; } }, // Today { re: /^tod/i, handler: function() { return new Date(); } }, // Tomorrow { re: /^tom/i, handler: function() { var d = new Date(); d.setDate(d.getDate() + 1); return d; } }, // Yesterday { re: /^yes/i, handler: function() { var d = new Date(); d.setDate(d.getDate() - 1); return d; } }, // 4th { re: /^(\d{1,2})(st|nd|rd|th)?$/i, handler: function(bits) { var d = new Date(); d.setDate(parseInt(bits[1], 10)); return d; } }, // 4th Jan { re: /^(\d{1,2})(?:st|nd|rd|th)? (\w+)$/i, handler: function(bits) { var d = newDate(); d.setMonth(parseMonth(bits[2])); d.setDate(parseInt(bits[1], 10)); return d; } }, // 4th Jan 2003 { re: /^(\d{1,2})(?:st|nd|rd|th)? (\w+),? (\d{4})$/i, handler: function(bits) { var d = newDate(); d.setYear(bits[3]); d.setMonth(parseMonth(bits[2])); d.setDate(parseInt(bits[1], 10)); return d; } }, // Jan 4th { re: /^(\w+) (\d{1,2})(?:st|nd|rd|th)?$/i, handler: function(bits) { var d = newDate(); d.setMonth(parseMonth(bits[1])); d.setDate(parseInt(bits[2], 10)); return d; } }, // Jan 4th 2003 { re: /^(\w+) (\d{1,2})(?:st|nd|rd|th)?,? (\d{4})$/i, handler: function(bits) { var d = newDate(); d.setYear(bits[3]); d.setMonth(parseMonth(bits[1])); d.setDate(parseInt(bits[2], 10)); return d; } }, // next Tuesday - this is suspect due to weird meaning of "next" { re: /^next (\w+)$/i, handler: function(bits) { var d = new Date(); var day = d.getDay(); var newDay = parseWeekday(bits[1]); var addDays = newDay - day; if (newDay <= day) { addDays += 7; } d.setDate(d.getDate() + addDays); return d; } }, // last Tuesday { re: /^last (\w+)$/i, handler: function(bits) { throw new Error("Not yet implemented"); } }, // mm/dd/yyyy (American style) { re: /(\d{1,2})\/(\d{1,2})\/(\d{4})/, handler: function(bits) { var d = newDate(); d.setYear(bits[3]); d.setMonth(parseInt(bits[1], 10) - 1); // Because months indexed from 0 d.setDate(parseInt(bits[2], 10)); return d; } }, // yyyy-mm-dd (ISO style) { re: /(\d{4})-(\d{1,2})-(\d{1,2})/, handler: function(bits) { var d = newDate(); d.setYear(parseInt(bits[1])); d.setMonth(parseInt(bits[2], 10) - 1); d.setDate(parseInt(bits[3], 10)); return d; } }, ]; function newDate() { // This naughty trick is from Michel Bany [mbany@cincom.com] var d = new Date(); d.setDate(1); return d; } function parseDateString(s) { for (var i = 0; i < dateParsePatterns.length; i++) { var re = dateParsePatterns[i].re; var handler = dateParsePatterns[i].handler; var bits = re.exec(s); if (bits) { return handler(bits); } } throw new Error("Invalid date string"); } function magicDate(input) { var messagespan = input.id + "Msg"; var monthNames = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"); try { var d = parseDateString(input.value); if (d != null) { input.value = d.getDate() + " " + monthNames[d.getMonth()] + " " + d.getFullYear(); } else { input.value = ""; } } catch (e) { var message = e.message; // Fix for IE6 bug if (message.indexOf("is null or not an object") > -1) { message = "Invalid date string"; } input.value = "<" + message + ">"; } } function magicDateOnFormSubmit(id) { var aTextBox = document.getElementById(id); addEvent(aTextBox.form, "submit", function() { magicDate(aTextBox); }); } '
magicTimeParseJs ^ ' /* Inspired by "Magic" date parsing http://simon.incutio.com/archive/2003/10/06/betterDateInput licensed under Creative Commons http://simon.incutio.com/archive/2002/12/16/creativeCommonsLaunch */ Date.prototype.meridianAbbreviation = function() { if (this.getHours() > 11) { return "PM"; } else { return "AM"; } }; Date.prototype.getHours12 = function() { if (this.getHours() != 0) { return ((this.getHours()- 1) % 12 )+ 1; } else { return 12; } }; function magic24To24Hours(v) { return parseInt(v) % 24; } function magic12AfternoonTo24Hours(v) { return (parseInt(v) % 12) + 12; } /* Array of objects, each has "re", a regular expression and "handler", a function for creating a time from something that matches the regular expression. Handlers may throw errors if string is unparseable. */ var timeParsePatterns = [ // Empty string or whitespace only { re: /^\s*$/i, handler: function() { return null; } }, // Now { re: /^now/i, handler: function() { return new Date(); } }, // hh24 eg. 9, 12, 13 // hh12 AM eg. 9am, 12am (12am is a special case) { re: /^(\d{1,2})\s*(am?)?\s*$/i, handler: function(bits) { var d = new Date(); // Fix for Mozilla & Firefox if (typeof bits[2] == "undefined") { bits[2] = "p" } if (bits[1] == 12 && (bits[2].toLowerCase() == "a" || bits[2].toLowerCase() == "am")) { d.setHours(0); } else { d.setHours(magic24To24Hours(bits[1])); } d.setMinutes(0); return d; } }, // hh24:mi eg. 9:23, 10:23 // hh12 AM eg. 9:23am, 12.34am (12:34am is a special case) { re: /^(\d{1,2}):?(\d{2})\s*(am?)?\s*$/i, handler: function(bits) { var d = new Date(); // Fix for Mozilla & Firefox if (typeof bits[3] == "undefined") { bits[3] = "p" } if (bits[1] == 12 && (bits[3].toLowerCase() == "a" || bits[3].toLowerCase() == "am")) { d.setHours(0); } else { d.setHours(magic24To24Hours(bits[1])); } d.setMinutes(bits[2]); return d; } }, // hh12 PM e.g 9 PM, 12PM, 1PM { re: /^(\d{1,2}):?\s*pm?\s*$/i, handler: function(bits) { var d = new Date(); d.setHours(magic12AfternoonTo24Hours(bits[1])); d.setMinutes(0); return d; } }, // hh12:mi PM eg. 9:23 PM, 10:23 PM, 1:23 PM { re: /^(\d{1,2}):?(\d{2})\s*pm?\s*$/i, handler: function(bits) { var d = new Date(); d.setHours(magic12AfternoonTo24Hours(bits[1])); d.setMinutes(bits[2]); return d; } }, ]; function parseTimeString(s) { for (var i = 0; i < timeParsePatterns.length; i++) { var re = timeParsePatterns[i].re; var handler = timeParsePatterns[i].handler; var bits = re.exec(s); if (bits) { return handler(bits); } } throw new Error("Invalid time string"); } function asTwoCharacterZeroString(v) { var s = "" + v; if (s.length == 1) { return "0" + s; } else { return s; } } function magicTime(input) { try { input.value = basicMagicTime(input.value); } catch (e) { var message = e.message; // Fix for IE6 bug if (message.indexOf("is null or not an object") > -1) { message = "Invalid time string"; } input.value = "<" + message + ">"; } } function basicMagicTime(v) { var d = parseTimeString(v); // document.write(d +"<br/>"); if (d != null) { return d.getHours12() + ":" + asTwoCharacterZeroString(d.getMinutes()) + " " + d.meridianAbbreviation(); } else { return ""; } } function magicTimeOnFormSubmit(id) { var aTextBox = document.getElementById(id); addEvent(aTextBox.form, "submit", function() { magicTime(aTextBox); }); } '
toggleCheckBoxesInSameFormJs ^ ' function toggleCheckBoxesInSameForm(checkbox) { newState = checkbox.checked; form = checkbox.form; for (i=0; i<form.elements.length; i++) { if (form.elements[i].type == "checkbox") { form.elements[i].checked = newState; } } } '
</methods> <methods> HBStandardScripts <category>accessing</category>
selectorsToInclude ^#(addEventJs magicDateParseJs magicTimeParseJs toggleCheckBoxesInSameFormJs)
</methods> <methods> Seaside.HBMagicDateTest <category>rendering</category>
printDate: aDate ^ aDate dayMonthYearDo: [ :d :m :y | d printString , '/' , m printString , '/' , y printString]
renderContentOn: html "The actual test is inside the script method" html script: 'runMagicDateTest();'
script ^ ' function magicDateAssert(input, expectedOutput) { try { if (basicMagicDate(input) != expectedOutput) { document.write("\"" + input + "\" gives \"" + basicMagicDate(input) + "\" instead of \"" + expectedOutput + "\"<br/>"); return false; } } catch (e) { document.write("\"" + input + "\" is identified as invalid instead of \"" + expectedOutput + "\"<br/>" + e +"<br/>"); return false; } return true; } function basicMagicDate(input) { var date = parseDateString(input); var day = date.getDate(); var month = date.getMonth() + 1; // January is zero var year = date.getFullYear(); return (day + "/" + month + "/" + year); } function runMagicDateTest() { var testData = new Array( "today", "' , (self printDate: Date today) ,'" , "tomorrow", "' , (self printDate: (Date today addDays: 1)) ,'" , "yesterday", "' , (self printDate: (Date today subtractDays: 1)) ,'" , "next tuesday", "' , (self printDate: ((Date today addDays: 7) previous: #Tuesday)) ,'" , "last monday", "' , (self printDate: (Date today previous:#Monday)) ,'" , "1st", "' , (self printDate: ((Date today subtractDays: (Date today dayMonthYearDo: [:d :m :y | d])) addDays: 1)) ,'" , "2nd", "' , (self printDate: ((Date today subtractDays: (Date today dayMonthYearDo: [:d :m :y | d])) addDays: 2)) ,'" , "3rd", "' , (self printDate: ((Date today subtractDays: (Date today dayMonthYearDo: [:d :m :y | d])) addDays: 3)) ,'" , "24th", "' , (self printDate: ((Date today subtractDays: (Date today dayMonthYearDo: [:d :m :y | d])) addDays: 24)) ,'" , "24", "' , (self printDate: ((Date today subtractDays: (Date today dayMonthYearDo: [:d :m :y | d])) addDays: 24)) ,'" , "1st Apr", "' , (self printDate: (Date readFrom: ('1 APR ' , Date today year printString) readStream)) ,'" , "22nd Apr", "' , (self printDate: (Date readFrom: ('22 APR ' , Date today year printString) readStream)) ,'" , "23rd Apr", "' , (self printDate: (Date readFrom: ('23 APR ' , Date today year printString) readStream)) ,'" , "25th Apr", "' , (self printDate: (Date readFrom: ('25 APR ' , Date today year printString) readStream)) ,'" , "25 Apr", "' , (self printDate: (Date readFrom: ('25 APR ' , Date today year printString) readStream)) ,'" , "1st Apr 1984", "' , (self printDate: (Date readFrom: '1 APR 1984' readStream)) ,'" , "22nd Apr 1985", "' , (self printDate: (Date readFrom: '22 APR 1985' readStream)) ,'" , "23rd Apr 1986", "' , (self printDate: (Date readFrom: '23 APR 1986' readStream)) ,'" , "25th Apr 1987", "' , (self printDate: (Date readFrom: '25 APR 1987' readStream)) ,'" , "25 Apr 1987", "' , (self printDate: (Date readFrom: '25 APR 1987' readStream)) ,'" , "Apr 1st", "' , (self printDate: (Date readFrom: ('1 APR ' , Date today year printString) readStream)) ,'" , "Apr 22nd", "' , (self printDate: (Date readFrom: ('22 APR ' , Date today year printString) readStream)) ,'" , "Apr 23rd", "' , (self printDate: (Date readFrom: ('23 APR ' , Date today year printString) readStream)) ,'" , "Apr 25th", "' , (self printDate: (Date readFrom: ('25 APR ' , Date today year printString) readStream)) ,'" , "Apr 25", "' , (self printDate: (Date readFrom: ('25 APR ' , Date today year printString) readStream)) ,'" , "Apr 1st 1984", "' , (self printDate: (Date readFrom: '1 APR 1984' readStream)) ,'" , "Apr 22nd 1985", "' , (self printDate: (Date readFrom: '22 APR 1985' readStream)) ,'" , "Apr 23rd 1986", "' , (self printDate: (Date readFrom: '23 APR 1986' readStream)) ,'" , "Apr 25th 1987", "' , (self printDate: (Date readFrom: '25 APR 1987' readStream)) ,'" , "Apr 25 1987", "' , (self printDate: (Date readFrom: '25 APR 1987' readStream)) ,'" , "04/03/1987", "' , (self printDate: (Date readFrom: '3 APR 1987' readStream)) ,'" , "4/3/1987", "' , (self printDate: (Date readFrom: '3 APR 1987' readStream)) ,'" , "1987-04-03", "' , (self printDate: (Date readFrom: '3 APR 1987' readStream)) ,'" , "1987-4-3", "' , (self printDate: (Date readFrom: '3 APR 1987' readStream)) ,'" ); var allPass = true; var total = testData.length/2; var fail = 0; for (i=0; i<(testData.length); i=i+2) { if (!magicDateAssert(testData[i], testData[i+1])) { allPass = false; ++fail; } } document.write("<br/>" + (total-fail) + " passed, " + fail + " failed<br/>"); } '
</methods> <methods> Seaside.HBMagicDateTest class <category>seaside</category>
canBeRoot ^ true
initialize (self registerAsApplication: 'magic/magicdatetests') libraries add: HBStandardScripts.
</methods> <methods> Seaside.HBMagicStuffDemo <category>rendering</category>
renderContentOn: html html heading: 'A better way of entering dates'. html form: [html table: [html tableRow: [html tableData: 'Enter a magic date'. html tableData: [html magicDateInputWithValue: nil callback: [:v | date := v]]. html tableData: date]. html tableRow: [html tableData: 'Enter a magic time'. html tableData: [html magicTimeInputWithValue: nil callback: [:v | time := v]]. html tableData: time]]. (html submitButton) callback: []; text: 'OK']. self renderSuggestionsOn: html. self renderLicensingInfoOn: html
renderDateSuggestionsOn: html (html heading) level: 2; with: 'Try these for the date:'. self renderList: #(#Today #Tod #tomorrow #tom #yesterday '1st' '6th' '6th October' '10th Feb 2004' '12 feb' '1 ja' 'next Friday' 'next fri' 'next m' 'last sun' '2004-04-04' '2004-8-8') on: html
renderLicensingInfoOn: html (html div) id: #license; with: [html text: 'Based on work from Simon Willison and Yar Hwee Boon.'. html break. html text: 'For further information:'. html space. (html anchor) url: 'http://simon.incutio.com/archive/2003/10/06/betterDateInput'; title: 'Simon Willison''s Weblog'; with: 'A better way of entering dates'. html break. (html anchor) url: 'http://simon.incutio.com/archive/2002/12/16/creativeCommonsLaunch'; title: 'Simon Willison''s Weblog'; with: 'Licensing information']
renderList: aCollection on: html html unorderedList: [aCollection do: [:each | html listItem: each]]
renderSuggestionsOn: html (html div) id: #'try-this'; with: [(html table) cellspacing: 50; with: [html tableRow: [html tableData: [self renderDateSuggestionsOn: html]. html tableData: [self renderTimeSuggestionsOn: html]]]]
renderTimeSuggestionsOn: html (html heading) level: 2; with: 'Try these for the time:'. self renderList: #(#now 9 12 923 1223 '9a' '923a' '12a' '9p' '923p' '1123p' '1223p' '9:23' '9:23a' '9:23p' '11:23p' '12:23p') on: html
style ^' div, form { font-family: Verdana; font-size: small; } h2 { font-size: small; } h1 { font-size: 150%; } #license { font-size: x-small; } '
</methods> <methods> Seaside.HBMagicStuffDemo class <category>seaside</category>
initialize (self registerAsApplication: 'magic/magicstuff') libraries add: HBStandardScripts.
</methods> <methods> Seaside.WAHtmlRenderer <category>magic date-time</category>
magicDateInputOn: aSymbol of: anObject | date | date := anObject perform: aSymbol. self magicDateInputWithValue: date callback: (self callbackForSelector: aSymbol of: anObject)
magicDateInputWithValue: aDate callback: aBlock | id | self attributes onblur: 'magicDate(this)'; onfocus: 'this.select()'. id := self ensureId. self textInputWithValue: (aDate isNil ifTrue: [''] ifFalse: [aDate displayString]) callback: [:v | aBlock value: (v isEmptyOrNil ifFalse: [[Date fromString: v] on:Error do: [:ex | nil]])]. self script: 'magicDateOnFormSubmit("' , id , '")'
magicTimeInputOn: aSymbol of: anObject | time | time := anObject perform: aSymbol. self magicTimeInputWithValue: time callback: (self callbackForSelector: aSymbol of: anObject)
magicTimeInputWithValue: aTime callback: aBlock | id | self attributes onblur: 'magicTime(this)'; onfocus: 'this.select()'. id := self ensureId. self textInputWithValue: (aTime isNil ifTrue: [''] ifFalse: [aTime hour12 displayString , ':' , aTime minutes asTwoCharacterString , ' ' , aTime meridianAbbreviation]) callback: [:v | aBlock value: (v isEmptyOrNil ifFalse: [[Time fromString: v] on: Error do: [:ex | nil]])]. self script: 'magicTimeOnFormSubmit("' , id , '")'
</methods> <methods> Seaside.WARenderCanvas <category>magic date-time</category>
callbackForSelector: aSymbol of: anObject ^ MessageSend receiver: anObject selector: (aSymbol copyWith: $:) asSymbol
magicDateInputOn: aSymbol of: anObject | date | date := anObject perform: aSymbol. self magicDateInputWithValue: date callback: (self callbackForSelector: aSymbol of: anObject)
magicDateInputWithValue: aDate callback: aBlock | id | id := self nextId. (self textInput) id: id; value: (aDate isNil ifTrue: [''] ifFalse: [aDate displayString]); onBlur: 'magicDate(this)'; onFocus: 'this.select()'; callback: [:v | aBlock value: (v isEmptyOrNil ifFalse: [[Date fromString: v] on: Error do: [:ex | nil]])]. self script: 'magicDateOnFormSubmit("' , id , '")'
magicTimeInputOn: aSymbol of: anObject | time | time := anObject perform: aSymbol. self magicTimeInputWithValue: time callback: (self callbackForSelector: aSymbol of: anObject)
magicTimeInputWithValue: aTime callback: aBlock | id | id := self nextId. (self textInput) id: id; value: (aTime isNil ifTrue: [''] ifFalse: [aTime hour12 displayString , ':' , aTime minutes asTwoCharacterString , ' ' , aTime meridianAbbreviation]); onBlur: 'magicTime(this)'; onFocus: 'this.select()'; callback: [:v | aBlock value: (v isEmptyOrNil ifFalse: [[Time fromString: v] on: Error do: [:ex | nil]])]. self script: 'magicTimeOnFormSubmit("' , id , '")'
</methods> <initialize> Seaside.HBMagicTimeTest </initialize> <initialize> Seaside.HBMagicDateTest </initialize> <initialize> Seaside.HBMagicStuffDemo </initialize> "Imported Classes:" self error: 'Attempting to file-in parcel imports. Choose terminate or close' <class> <name>WAFileLibrary</name> <environment>Seaside</environment> <super>Seaside.WALibrary</super> <private>false</private> none default <imports></imports> <category>Seaside-Libraries</category> <attributes> <package>Seaside-Libraries</package> </attributes> </class> <class> <name>WARenderCanvas</name> <environment>Seaside</environment> <super>Seaside.WAHtmlCanvas</super> <private>false</private> none context callbacks <imports></imports> <category>Seaside-Canvas</category> <attributes> <package>Seaside-Canvas</package> </attributes> </class> <class> <name>WAHtmlRenderer</name> <environment>Seaside</environment> <super>Seaside.WAAbstractHtmlBuilder</super> <private>false</private> none context callbacks shortcutBuffer <imports></imports> <category>Seaside-Builder</category> <attributes> <package>Seaside-Builder</package> </attributes> </class> <class> <name>WAComponent</name> <environment>Seaside</environment> <super>Seaside.WAPresenter</super> <private>false</private> none decoration <imports></imports> <category>Seaside-Component</category> <attributes> <package>Seaside-Component</package> </attributes> </class>