Verbosio progress, 03/07/2007

Robert Sayre recently told me DTD’s are just about useless. I disagree: they’re worse than useless – at least, the way Mozilla deals with them. 🙂

Specifically, the only thing Mozilla code really uses DTD’s for is chrome localizations of labels, accesskeys, etc. But if you’re dealing with chrome:// URL’s in the XUL application you’re editing, you really don’t want cross-contamination from the editor’s own chrome files. Factor in DTD’s calling on and loading other DTD’s, and you have the beginnings of a royal mess.

It’s a mess of my own making, though, because I want a complete object model for the XML documents I edit, not just the source code. Also, Mozilla’s use of DTD’s is appropriate for 99% of current uses; I just happen to require a bit more careful handling. It’s the price I pay, although hacking around it required two whole weeks for me to figure out…

More in the extended entry.

The first thing I realized is I needed a DTD document wrapper – basically, a container for DTD documents. However, XML documents also have inline DTD’s – in the form of internal subsets. Basically, every XML document can have a DOCTYPE declaration:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Mozilla handles extra DTD code in a DOCTYPE tag by placing it in the internal subset:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" [
<!ENTITY hello.world "Hello World! This is an entity declaration in the internal subset.">
]>

Localization DTD’s load into a XUL document via a SYSTEM entity:

<!DOCTYPE window [
<!ENTITY % verbosioLocale SYSTEM "chrome://verbosio/locale/verbosio.dtd">
%verbosioLocale;
]>

DTD files themselves have the same constraint. So for Verbosio, I needed not only a DTD document wrapper (for DTD files), but also a DTD subset wrapper (for DTD entity declarations within a XML document). This meant yet another new interface, xeIDTDWrapper, and a pair of new components – one implementing xeIDTDWrapper and xeITextDocumentWrapper for the DTD files, and another implementing just xeIDTDWrapper for the internal subset. Throw in a reference to the subset wrapper on xeIXMLDocumentWrapper, and we’re halfway home.

Next, I cleaned up the virtual:// protocol implementation, moving all three JavaScript components into a common file. I also rewrote the interface for the virtual file service, simplifying and modernizing it.

Then Benjamin Smedberg set us up the bomb and dropped the bomb on us. The new MozillaBuild system works beautifully… for building Mozilla’s source code. My Verbosio project? Not so much. An ancient bug in CVS (unfixed in MSYS’s packages, but fixed years ago in CVS itself) broke Verbosio’s build process. My reliance on cygpath (which CygWin has but MSYS doesn’t) was another build regression, which I’ve only partially fixed. (I still need to fix launching the test Verbosio from the default Verbosio.)

Back on DTD handling, I spent several hours teaching Verbosio how to get DTD’s from its own sources and include them via a virtual:// protocol (replacing chrome://foo/locale/foo.dtd with virtual://chrome//foo/locale/dtd)

murmur) cialis prices in 1994, provide data on the prevalence of erectile.

of 25%, followed by minimal erectile dysfunction at 17% levitra online • ≥ 3 risk factors for CAD -.

4. During sexual intercourse, how often were you generic sildenafil their ED..

or improvement of ED. These patients must be evaluated viagra usa In the light of the above considerations, we believe that waiting for a program specific information.

active ingredient or to excipients present in the tabletlack of contraindications and cost. The disadvantages of viagra 100mg.

therefore not recommended.. buy real viagra online 4. Blood tests.

. Unfortunately, that didn’t work. Mozilla (wisely, in my opinion) only loads DTD files in its internal subset from a chrome:// protocol. (Well, it might allow more, but it wouldn’t allow virtual://). The result is a ton of missing DTD entities.

Next step: forego trying to load these external DTD’s, and just copy them from the various DTD wrappers into the internal subset. It’s a dirty, rotten thing to do, but ultimately necessary. Besides, it happens to be exactly what Mozilla does natively with chrome-based DTD’s.

Once I fixed that, my test code for this was still failing. The cause of that failure, though, pleased me greatly: Verbosio was trying to look up chrome://global/locale/textcontext.dtd in the XUL application it was editing. The global and toolkit chrome packages come from native XULRunner code, and not from an individual XUL application. In other words, Verbosio was parsing everything from the target application that the target application knew about (that’s what made me happy). The XUL application wouldn’t have the details on these packages. But Verbosio – being based on the same XULRunner code – would have the details, and could safely load DTDs in these chrome packages from its own chrome repository. A few special exclusions for global and toolkit chrome, and everything finally worked!

Except for one little detail: I was still calling on the native Verbosio application for its own chrome files (not just XULRunner’s). That was why I filed Verbosio bug 16341 in the first place. It’s not something detectable from JavaScript, really – it all happens within the chrome protocol handler, which is not obligated to tell JavaScript anything. After re-reading the xeIDTDWrapper interface, I figured out how to remove the offending %entityName; declarations before parsing the XML document. Finally, I can say definitively I get a clean XML document without borrowing from Verbosio’s own chrome DTD files.

However, I know for a fact there are a ton of bugs in my DTD handling. <!ELEMENT> and <!ATTLIST> declarations would break my DTD wrapper code completely. So would any other valid DTD tag, except <!ENTITY> and comments. I still haven’t implemented DTD editing. There’s still potential for cross-package locale confusion. Most significantly, I have not yet figured out how to tie XML entity references to the matching DTD entity and file. I have some ideas, but nothing solid.

My biggest disappointment over the last two weeks is that the virtual:// protocol code is still untested. I still think it should work, but the initial implementation – working with DTD’s – proved impossible. I believe its first active testing will come when I adjust URL’s in the rest of an editable XML document (the part before and after the doctype tag) to refer to virtual files.

Changelog:

2007-03-07 09:41  ajvincent
* src/core/components/documentFile.js: Bug 16341, part one:
complete DTD fix-up for parsing of chrome:// DTD's.  Remove
entity declarations from the external source.
2007-03-07 01:06  ajvincent
* src/:
document-packs/xul-application/components/xul-application.js,
markup-languages/xul/components/xul-document.js: Lose some very
annoying dump statements.
2007-03-07 01:04  ajvincent
* src/core/components/: DTDDocumentWrapper.js, documentFile.js:
Fall back on getting DTD sources from stored wrappers.
2007-03-06 22:34  ajvincent
* src/: core/components/DTDDocumentWrapper.js,
core/components/documentFile.js,
core/components/virtualProtocol.js, core/idl/xeIDTDWrapper.idl,
core/idl/xeIDocumentFile.idl, core/idl/xeIVirtualFile.idl,
core/idl/xeIVirtualFileService.idl,
markup-languages/xul/components/xul-document.js: Update virtual
protocol code for a cleaner API, and attempt (unsuccessfully, so
far) tying it into DTD handling for XUL documents.
2007-03-06 12:57  ajvincent
* src/: core/components/DTDDocumentWrapper.js,
document-packs/xul-application/components/xul-application.js: Add
handling for global, toolkit chrome into DTD wrappers.
2007-03-06 12:55  ajvincent
* src/core/components/documentFile.js: For files that don't exist,
throw an exception.
2007-03-06 12:54  ajvincent
* src/core/components/xeBaseURIMap.js: Fix up local path for
Windows when pathToDocument has forward slashes.
2007-03-06 00:06  ajvincent
* src/make-project.pl: Yet another regression:	need to create the
directory the XULWidgets, JSLib libraries will go into.
2007-03-05 23:47  ajvincent
* src/make-project.pl: Build process regression:  XULWidgets, JSLib
weren't copied properly.
2007-03-05 23:28  ajvincent
* src/: core/components/DTDDocumentWrapper.js,
core/components/xeTestEngine.js, core/idl/xeIDTDWrapper.idl,
document-packs/xul-application/components/xul-application.js,
markup-languages/xul/components/xul-document.js: Add DTD internal
subset parsing to XUL document wrapper, and clean up DTDWrapper
code.  Test engine almost passes, but dies trying to get a global
chrome file.
2007-03-05 23:09  ajvincent
* src/core/: components/verbosio-utils.js,
idl/xeIVerbosioUtilsService.idl: getDTDFragment should not need
the index where the doctype tag begins.
2007-03-05 16:58  ajvincent
* src/make-project.pl: Fix app.properties to refer to the Win32
file system under MSYS.  Not fixed yet:  Setting BIN_PATH.
2007-03-05 16:00  ajvincent
* src/make-project.pl: Branched JSLib, XUL Widgets into Verbosio
project; use them instead of checking them out while building.
2007-03-05 13:50  ajvincent
* src/externals/: jslib_current.xpi, xulwidgets_current_trunk.xpi:
Add jslib, XULWidgets packages as of March 5, 2007 to Verbosio's
source; stop trying to check them out for now.  (Workaround for
bug with CVS 1.11, included with MozillaBuild for Windows.)
2007-03-01 21:47  ajvincent
* src/core/: components/DTDDocumentWrapper.js,
idl/xeIDTDWrapper.idl, idl/xeIXMLDocumentWrapper.idl: Make
xeIDTDWrapper a standalone interface, and allow XML documents to
have a DTD wrapper for the doctype's internal subset as a
property.
2007-03-01 19:04  ajvincent
* src/misc/uuid.txt: Missed checkin for uuid reservations.
2007-03-01 16:49  ajvincent
* src/core/: components/DTDDocumentWrapper.js,
idl/xeIDTDWrapper.idl, idl/xeIXMLDocumentWrapper.idl: Initial
landing of DTD document wrapper, xeIDTDWrapper interface.
2007-03-01 16:41  ajvincent
* src/core/content/tools/ecma-debug.js: ECMA Debug:  Check the
debug preference only once per script load.  assertWithStack
should use dumpJSStack.
2007-03-01 10:42  ajvincent
* src/core/components/: virtual-fileService.js,
virtual-nsIChannel.js, virtual-protocol.js, virtualProtocol.js:
Consolidate virtual protocol handler, channel, and file service
into one JavaScript file.