The library uses what some would call "multi-paradigm" programming, which basically means that we aren't entirely OO or entirely non-OO.
Many of the files, such as burst/Alg.js are just collections of "static" functions. The so-called classes in those cases such as burst.Alg would be treated as namespaces in C++ since they exist only to group symbols, and cannot be instantiate. We refer to these as "scoping" classes in the Class List .Other areas are object-oriented, such as the widget classes.
There is also support for functional programming in burst.Functional , and you could consider rolling your own paradigm with burst.MOP .For more about how we implement some of these paradigms, see Emulating Programming Constructs in ECMAScript 262-3 .
A release contains a snapshot of the source tree, as well as a "build" directory which was made by a maintainer.
To use the library, at run time you only need the "build/burst/" and "build/burststatic" directories, as discussed in "URL Mapping" below.
The rest of the release is only of interest for documentation, or for maintainers.
The structure of what is under source control is:
Makefile index.html # home for public web site. has some links pointing into build/ burst/ # the library source directory. may be tested in place by make target "testsrc". Alg.js # core source files ... webui/ widgets/ SortTable.js # widget files ... burststatic/ # static content used by source scripts images/ # image files used by widgets ... html/ # html files used by widgets or Log.js BurstLog.html ... docsrc/ # source files for documentation demos/ # widget demos (runs in place, depends on build/) tools/ # tools (runs in place) tests/ # various kinds of tests testscripts/ # unit tests for the library test_URI.js ... webui/ widgets/ test_SortTable.js testdata/ # data files used by test scripts iframe_text_data.txt ... testbrowser/ # html files with browser tests (not library tests)
No make target ever alters anything in a directory under source control. A "make all" will populate a top-level directory "build" with this structure:
build/ doc/ # generated or copied from source docsrc/ intro.html ... tooldoc/ # doc generated from source tools/ jsunit_wrap.html testhtml/ # generated html files for running tests, made from tests/ apidoc/ # generated by doxygen html/ doxysrc/ # the intermediary Java or C++ when doing 2-stage doxygen burst/ # copied from source burst/, plus the generated burstlib.js burstlib.js # if we supported partial sub-core library file loading, they'd be copied here too webui/ widgets/ ... burststatic/ # copied from source burststatic/ images/ ... html/ ...
Various versioned release tarballs are kept in the "releases/" directory.
A programmer who wants to run library demos, run browser tests, and so on, should expose the entire tree (the parent of "build").
To use the library, a web page might be:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>My Web Page</title> <script language="JavaScript" type="text/javascript"> var bu_AppConfig = {'burst.logging.Log.maxLevel' : 'DEBUG'}; </script> <script src="wherever/burst/burstlib.js" language="JavaScript" type="text/javascript"></script> ... </head> <body> ... </body> </html>
To cut down on repetition across web pages, you may want to consolidate your configuration into a script:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>My Web Page</title> <script src="myarea/burstWrapper.js" language="JavaScript" type="text/javascript"></script> <script src="wherever/burst/burstlib.js" language="JavaScript" type="text/javascript"></script> ... </head> <body> ... </body> </html>
where burstWrapper.js is a file that you write that might contain something like:
var bu_AppConfig = {'burst.logging.Log.maxLevel' : 'DEBUG'};
You could even reduce it further by putting:
document.write('<script src="wherever/burst/burstlib.js" language="JavaScript" type="text/javascript"></' + 'script>');
in your wrapper and taking out of the web page.
Note that setting or changing bu_AppConfig after the library is loaded has no effect.
In a browser environment, the library will also look for class property settings in the query string (if any) of the document's url. This can be turned off by setting
var bu_AppConfig = {'burst.Config.urlConfigDisabled': 'true'}
If enabled, settings in the url take precedence over any in bu_AppConfig, which in turn take precedence over the builtin defaults.
As of this writing, some modules that define class properties are: The entire library may be disabled (despite being loaded) by setting'burst.Config.allDisabled': 'true'
in bu_AppConfig.
If this is done, there is currently no way to re-enable it.
This is intended as a mechanism for testing "fallback html" in widgets, without disabling
all javascript.
"JavaScript1.2"
, which was an aberration released by Netscape
starting with Netscape 4.0, prior to edition 3 standardization.
It has many subtle but important differences, including interpretation of "==", Array.toString(),
and condition tests of Object primitives.
Even now, declaring language="JavaScript1.2" will cause a Mozilla family browser to
use that different language. You should instead use language="JavaScript", or language="JavaScript1.3".IE5.5 and IE6.0 will not execute script elements with language="JavaScript1.5" if the element has no type attribute, despite their ability to do so. They will execute any script with type="text/javascript" or type="text/ecmascript", regardless of the language attribute. IE5.x and IE6.x will not run type="application/javascript". No IANA assignments have been made yet for javascript or ecmascript, so the type attribute is still premature, even though it is now required for DTD validation.
In the end, our current recommendation is to use:
<code>script language="JavaScript" type="text/ecmascript"</code>
We do generally try to behave correctly regardless of quirks mode.
If you want to add an onload handler via script, we suggest that you use:
burst.web.WindowEvent.addWindowOnload
not so much because of conflicts (because by the time you'd have access to the function
we'd have already used it), but because it deals with the vagaries of window.addEventListener,
window.attachEvent, window.onload, or document.body.onload being available.
An example inline constructor in an HTML page might be:
... <table border="1" id="t1" buType="SortTable" sortOnLoad="true"> <thead><tr><th sortComparator='integer:10'>Numbers</th><th>Strings</th></tr></thead> <tbody> <tr><td>17</td><td>b</td></tr> <tr><td>3</td><td>a</td></tr> <tr><td>11</td><td>c</td></tr> </tbody> </table> ...
Note that the default namespace for widget classes is "burst.webui.widgets". It is possible to specify some other namespace in a buType value [TBD].
There are several alternatives for how to get the library to find and process your inline constructors:
burst.webui.WidgetManager.findWidgets='true'
prior to
library loading.
(See burst.webui.WidgetManager documentation .)
Setting this attribute will cause the library to iterate through the entire page, looking for elements
with the buType attribute.
burst.webui.WidgetManager.findAndProcessConstructorNodes()
after the library has loaded and after document onload.
burst.webui.WidgetManager.initWidgetIds='id1,id2, ...'
prior to library loading.
This is a comma-separated String (or, if specified in ECMAScript, possibly an Array)
of id values. This is more efficient that the iteration caused by findWidgets,
because document.getElementById can be used.
burst.webui.WidgetManager.getAndProcessConstructorNodes(ids)
after the library has loaded and after document onload.
new burst.webui.widgets.SortTable(document.getElementById('t1'), true);Note that in this case, the buType attribute is not required.
The approaches which do not iterate over the page are clearly preferable. Note that if you are dynamically generating html, you can use a server-side variable to accumulate the ids of inline constructors, and at the bottom of the page add a script element like:
<script language="JavaScript">burst.webui.WidgetManager.getAndProcessConstructorNodes('id1 id2 id3')</script>
where the argument to the function is server-side generated.
For now however, it is best if you explicitly put a script element in the head of the page, such as:
<script src="wherever/burst/burstlib.js" language="JavaScript" type="text/javascript"></script> <script src="wherever/burst/webui/widgets/SortTable.js" language="JavaScript" type="text/javascript"></script>
Of course, as discussed above, these might be combined into your own application specific script file, so that each page loads only one file.
At least for those widgets that construct a new DOM sub-tree to entirely replace the inline constructor, it generally does not matter what the element type (tag name) is for the top-level element or (often) the tag names of its children. This is deliberate, so that the inline constructors can support "fallback html". That is, if the library is disabled (and/or no javascript is available), the page will still provide some interaction.
If the widget constructor is executed, unless otherwise documented, all of the element tag names, and all the attributes in the HTML namespace in the inline constructor are ignored.
Widgets that merely add behavior but do not replace the inline constructor will naturally preserve any styling that exists.
As for widgets that replace their inline constructor, an exception to the general rule of not copying HTML attributes is that any class attribute in the top-level element of an inline constructor is copied over. (Any style attribute is not copied over, so if you do want styling that is specific to fallback HTML, that is the way to do it.) Note that depending on how the style sheet is defined, and whether the widget implementation happens to use the same top-level element type as the inline constructor, this class may or may not have the intended effect.Each widget that replaces its constructor will define a set of CSS class names that can be used to style the generated HTML that implements the widget. The convention for the names of these classes are:'BU' + WidgetName + '-' + role + '-' tagnameAn example would be "BUComboBox-choice-option". (The reason for specifying the tagname as part of the CSS class name is that allowed CSS properties are dependent on the HTML element type, and so unfortunately it is necessary to expose that much of the implementation choices within the widget.)
As can be seen from the above discussion, at least for those widgets that replace their inline constructor (versus just adding behavior to it), the page's DOM structure prior to execution of the inline constructors may differ substantially from what it is afterwards.
The "fallback html" may be replaced with entirely different HTML. For example, the fallback HTML for a menu may use an HTML "select", but a replacing widget implementation may use something else.
Note also that the parent-to-child widget hierarchy is relatively unrelated to the containment hierarchy within the DOM. In particular, the widget containment hierarchy may skip levels present in the inline constructor.
Some caveats apply:
<div buType="Button"/>This is presumably because it concludes that the element has no use. The library won't be able to find it in the DOM.
<select buType="Menu"><div buType="Item"></div></select>So far, this behavior appears to be specific to child containment; the invalid attributes seem not to be an issue.
In order to debug problems, there are various approaches:
In any browser, enable javascript error popups and/or the javascript console. In Mozilla, turn on strict JavaScript warnings. In Mozilla, use the JavaScript Debugger to trace all errors. Enable debug logging within the library itself.
Some general comments on debugging in browsers are in http://www.quirksmode.org/js/intro.html
Some quick instructions::
IE: "Tools => Internet Options => Advanced => Disable script debugging" Also, download the "Script Debugger" from http://msdn.microsoft.com/downloads/list/webdev.asp Mozilla/Netscape: "Tools => JavaScript Console" or "Tools => JavaScript Debugger". You may want to also set strict warnings via url "about:config". (Or, in some builds, go to Edit, Preferences, Debug, and check the box for "Show strict JavaScript warnings".) Opera: check 'Open JavaScript console on error' in File => Preferences => Multimedia Konqeror: nothing supported. Safari: See developer.apple.com/internet/safari/safari_faq.html To enable the Safari debug menu: "defaults write com.apple.Safari IncludeDebugMenu 1" View the log using Applications/Utilities/Console Ice: java -jar ICEsculptor_5.4.0_Trial/lib/icesculptor_trial.jar -Dice.debug.debug=true ice.ri.swing.Main java -jar ICEsculptorOCS_5.4.0_Trial/lib/icebrowser_ocs_trial.jar -Dice.debug.debug=true ice.ri.swing.Main
You may also want to disable the cache in your browser while testing.
We suggest using the profiling abilities in the Mozilla JavaScript Debugger (Venkman).
Also see Jprof http://lxr.mozilla.org/mozilla/source/tools/jprof/README.html
Some of the functions in the library do throw exceptions. These are generally documented if the exception condition is out of the control of the programmer or the library (for example, the availability of some remote resource).
Exceptions may also be thrown if a library function is called with bad arguments; these exceptions are not documented. They are always of type BurstError or a subclass of it.