Subject: Re: Spice
From: Dave Raggett (dsr@w3.org)
Received: 03.03.98 18:33:55
Perhaps its worth summarising the changes we are exploring in our implementation work: a) to add support for constructs for representing style rules using the same syntax as W3C's CSS 'style''{' [';' ]* '}' To avoid complicating lexical analysis, we propose to disallow the use of hyphens in property names, and to make a small change from the CSS selector syntax to simplify whitespace handling. There is also some syntax for mode dependent style rules, such as when you want to process headings twice, once for the body of the document, and once for a table of contents, applying different style rules in each case. b) to allow undeclared identifiers to be used for symbols. For instance: bold You can make assignments such as: block.style.fontWeight = bold; and test symbols in conditions, as in: if (block.style.fontWeight == bold) .... The idea is that any undeclared identifier is considered as a kind of symbol. You can test symbols for equality but if you try to do arithmetic with them you get an undeclared variable error. In languages such as C you are reduced to having to declare symbols as numbers, e.g. #define bold 531 #define italic 532 ... When the compiler comes across undeclared identifiers they are inserted into the symbol table and marked as uninitialized. c) a syntax for explicitly declaring prototypes As an example: prototype foo extends bar; defines a new prototype object called foo which has as its prototype the object called bar. Following this statement, you can now use "foo" with the new operator to create objects that have "foo" as their prototype. You can also use the prototype construct to set named methods for the prototype, e.g. prototype Warning extends Block { function layout(element) { this.style.borderStyle = solid; this.append(new Text("Warning!")); ProcessChildren(element, this) } } This avoids the tedium of having to declare methods with global names when they are only going to be used with a particular object. In the function layout "this" refers to the object created with the new operator, not to the object's prototype (Warning). The previous example is roughly equivalent to: function Warning() { this.name = "Warning"; this.flow = null; this.children = new Array; } function Warning_layout(element) { this.style.borderStyle = solid; this.append(new Text("Warning!")); ProcessChildren(element, this); } new Warning; // make sure prototype is created Warning.prototype.append = block.prototype.append; Warning.prototype.layout = Warning_layout; We are also interested in being able to declare event handlers in a simplified syntax, e.g. prototype Link extends Inline { href = "http://www.w3.org/"; when onmousedown { document.load(this.href); } } We would like to define an import statement to take advantage of definitions in other modules, perhaps in other languages, for instance: import document, block, inline from "http://www.w3.org/Style/std.lib"; The implements statement is used to specify implementations for particular libraries, e.g. "css.spice" implements "http://www.w3.org/Style/std.lib" on "Spice"; "css.jar" implements "http://www.w3.org/Style/std.lib" on "Java"; "css.cab" implements "http://www.w3.org/Style/std.lib" on "ActiveX/win32"; Here "css.jar" and "css.cab" are relative URLs, defined as relative to the URL for the current script module. You can also use absolute URLs. The on keyword precedes a string naming the platform that this implementation applies to. In the absence of a matching implements statement, the import statement expects to get the implementation from the URL specified by the from keyword. If that too is missing, you can simply list the URLs for the files you want to import, for instance: import "housestyle.css"; // imports a CSS style sheet import "koolbits.spice"; // imports a Spice style sheet -- Dave Raggett http://www.w3.org/People/Raggett phone: +44 122 578 2984 (or 2521) +44 385 320 444 (gsm mobile) World Wide Web Consortium (on assignment from HP Labs)