Javascript

29 Apr 2007

XUL or extjs....

Having just completed one project with extjs, (otherwise known as yui-ext). I thought I would share my thoughts on it.

As a side project, if you liked FlexySvn, my little XUL based Subversion browser, I started playing with a Javascript only version (A single HTML page - no Server / PHP support required):
http://www.akbkhome.com/FlexySvn/templates/test1.html (Firefox only seems to work at present - although I would guess IE fixes should not be to difficult).

This uses XmlHttpRequest's to do roughly the same things that 'svn ls/log/cat' etc. do. - (Done by snooping the packets with Wireshark.). Using Extjs for the interface, and dp.SyntaxHighlighter to do all the syntax highlighting.

This little test does illustrate the key differences between XUL and the Extjs approach.

Ext js advantages/disadvantages
  • In-page popups are faster than desktop popups - leading to a snappier interface. (not seen in my svn browser, but a serious issue for other applications)
  • Interface 'can' work on other browsers, although doing anything complex tends to end up with considerable time taken dealing with IE or Safari bugs.
  • Load times are problematic (even stripped down libraries can be a high load if you are offering just a simple form with validation).
  • Difficult to see how to have a page degrade nicely for non-js browser - eg. mobile devices.
  • extjs bugs tend to be browser specific bugs, and often with things like Safari, which can be exteremly time consuming to fix.
  • Defining CSS styles for OL/UL/BODY etc. in the standard css file makes it a bit of a nightmare to work with existing HTML designs.


XUL development advantages/disadvantages.
  • Single platform make debugging and testing considerably simpler (if it runs in Firefox, it will run everywhere.)
  • Interface as XML has a more natural feel to it -  considerably simpler to spot and fix a  layout issue, rather than decyphering a large number of javascript statements.
  • The approach we used where XUL is served up by PHP, and using frames/pages to react to different sections of the application, make inter-section communication more complex. Compared to a pretty much 'one-page' approach with extjs, which makes managing state considerably simpler.
  • Difficult to mix HTML and XUL, using namespaces is klunky, normally we need to use <HTML:everything in here is HTML!>....</HTML> rather than having to ensure we are using XHTML and the namespace.
  • bugs tend to be either browser related or security related. - modal dialogs comes to mind...
I have to say that Firebug has been a life saver for the projects I've been doing these last few weeks, and has overtaken the webdeveloper extension at the top of the list of essential extensions.

At the end of the day, When we start a new project that needs an administration system, (non-public), Neither of them offer a perfect solution yet. But I think XUL comes out marginally ahead, given the reduced time spend debugging non-mozilla browsers. (Although the modal windows and popup load times is a serious problem)

For a public front end, I think after some consideration, I will still recommend extjs except where support is needed for mobile devices. And Just hope that I dont get too caught out by IE and Safari's bugs.

11 Apr 2007

making XSLT readable - has this been done before?

We where discussing with one of my clients the idea of including dynamic content on their home page, which is currently static HTML, due to extreme load requirements. Normally Php is only reserved for specific parts of the site, and not on the front page.

I had the idea of using XmlHttpRequest, however another member of the team suggested XSLT, and I have to admit, I've never seen that idea before, and the example he showed basically included content from an external file by just adding a simple tag like
<our:include src="mydynamic.html" part="xxx" />
Where the mydynamic.html could use the 404 handler trick that php.net uses. (eg. if the file doesnt exist, it gets generated by the 404 handler, and deleted by a cronjob every 5 minutes etc.)

My only reservation about this is really that XSLT templates are unreadable garbage. Hence if we ever started to get clever with them, they could quickly become unmaintainable.

This however didnt seem to be a problem so much with XSLT but the fact that reading and writing XSLT files is not particulaly simple. Looking at the Basic specification for 1.0, and the example file he had, it seem clear that this file could easily be generated by a simple tool. However I could not find anything after a quick google search that seemed to exist to do this. So I threw together a simple proof of concept.

What if the template looked more like this:
template("/") {
applyTemplates;
}

template("*") {
copy {
applyTemplates("@*|node()");
}
}

template("processing-instruction()") {
copy {
applyTemplates("@*|node()|text");
}
}

// make h1 green

template("html:h1")
{
copy {
attribute("style") <colour:green>
applyTemplates("@*|node()");
}
}

template("our:include")
{
variable("part", "@part");
applyTemplates("document(@src)//*[@id=$part]");
}


Writing a simple parser generator in D, enabled the generation of the xslt file from this file.

Compile parser generator:
dmd xsltgen.d -of/tmp/xsltgen -od/tmp

Convert the above file to xslt:
/tmp/xsltgen inctest.xslts

And magically you have a generated file, and a maintainable version.. - Makes me wonder though, has someone done this already?

the source: xsltgen.d
output from the above example: inctest.xslt

25 Mar 2007

Javascript Tookits Part Two

<style type="text/css"> <!-- #toc, .toc, .mw-warning { border: 1px solid #aaa; background-color: #f9f9f9; padding: 5px; font-size: 95%; } #toc h2, .toc h2 { display: inline; border: none; padding: 0; font-size: 100%; font-weight: bold; } #toc #toctitle, .toc #toctitle, #toc .toctitle, .toc .toctitle { text-align: center; } #toc ul, .toc ul { list-style-type: none; list-style-image: none; margin-left: 0; padding-left: 0; text-align: left; } #toc ul ul, .toc ul ul { margin: 0 0 0 2em; } #toc .toctoggle, .toc .toctoggle { font-size: 94%; }@media print, projection, embossed { body { padding-top:1in; padding-bottom:1in; padding-left:1in; padding-right:1in; } } body { font-family:'Times New Roman'; color:#000000; widows:2; font-style:normal; text-indent:0in; font-variant:normal; font-size:12pt; text-decoration:none; font-weight:normal; text-align:left; } table { } td { border-collapse:collapse; text-align:left; vertical-align:top; } p, h1, h2, h3, li { color:#000000; font-family:'Times New Roman'; font-size:12pt; text-align:left; vertical-align:normal; } --> </style> <div> <p>My last post about Javascript toolkits garnered a few comments, which seems to be rare for most of my blog posts... (I must be getting too old..or the spam protection works to well). There where quite a few suggestions for alternatives to dojo, along with a not too complimentary comment about dojo's development status. </p> <p /> <p>As luck had it, I started a new project Last week, a contact manager for one of my clients, and rather than carry on with dojo, that had begun to annoy me a little, with little bugs (for example , the Accordion was broken), or just weird stuff, like getting forms on dialogs to look just right. I thought that it would be a good opportunity to review some of the other toolkit's mentioned on the post.</p> <p /> <p>The extended Entry contains reviews of jQuery and yui-ext (and see which is now the prefered library)</p> </div> </DIV> <DIV class="" xbuilderid="roo-gen50" xtype="Roo.bootstrap.Element"> <A href="/index.php/View/133/Javascript_Tookits_Part_Two.html" xbuilderid="roo-gen51" xtype="Roo.bootstrap.Link">View Extended Entry</A> </DIV> <DIV class="" xbuilderid="roo-gen52" xtype="Roo.bootstrap.Element">Posted by in <A href="/index.php/BlogCategory/272/Javascript.html">Javascript</A> | <A href="/index.php/View/133/Javascript Tookits Part Two.html#comments">Add / View Comments()</A> </DIV> </DIV><DIV class=" well" xbuilderid="roo-gen45" xtype="Roo.bootstrap.Container"> <H3 xbuilderid="roo-gen46" xtype="Roo.bootstrap.Header">08 Mar 2007</H3> <H2 xbuilderid="roo-gen47" xtype="Roo.bootstrap.Header"> <A href="/index.php/View/132/Javascript_Toolkits.html" xbuilderid="roo-gen48" xtype="Roo.bootstrap.Link">Javascript Toolkits</A> </H2> <DIV class="" xbuilderid="roo-gen49" xtype="Roo.bootstrap.Element"> <p>Like alot of people, I'm really impressed with google's applications. They have created web applications that behave alot like desktop ones. Core to this is the javascript tricks that hold it together.<br /><br />In the past few years I've been building applications using XUL, that provides a similar set of functionality, and is pretty fast to develop with. However we have run into a few issues<br /></p><ul><li>Its not cross browser, which is ok for intranet style applications, obviously is a little problematic for public internet ones.</li><li>After many projects we began to see that dialog, modal prompts where better for user input, as the prevent the user modifying the application state while entering data, along with making it less likely to forget to press the submit button. Recent builds of Firefox have disabled the modal feature of popup window, and along with the noticeable speed penalty on most modern operating systems for opening new windows, these issues begins to dig into the benefits of this approach.</li><li>WYSIWG editors are still not easy and simple to use...<br /></li></ul><p><br />Since one of my pet projects, an online accounting package needed a bit of sprucing up, and testing my home grown JavaScript code on IE is such a nightmare, I started looking at JavaScript toolkits.<br /><br />The biggy from countless blog posts recently has been YUI, Yahoo's interface toolkit. I spent quite a while looking at this, the website for it is very complete, along with a comprehensive set of widgets. There was alot too like about it, however as I dug deeper, I began to dislike some of the things i saw.<br /><br /></p><ul><li>silly things like all the JavaScript code libraries appeared to use a weird, double lined coding standard.<span style="font-style: italic;">yes I know it's silly, but it makes a difference when you read code to see something that odd.</span></li><li>(from what i remember ), alot of those set*, get* methods.</li><li>almost all the demos appeared to create the widgets in JavaScript and using js associative arrays to configure the widgets , rather than using extra attributes on existing html tags, and doing some kind auto conversion.</li><li>the constructors did some strange namespace hack.</li></ul><p>In general, it looked like using the widgets was very un-javascripty.<br /><br />So after some consideration, I started looking for alternatives. The first I came across was prototype which looked more like someone rewriting JavaScript than a toolkit, then i came across <a href="http://www.dojotoolkit.org/">dojo</a>, <br />which looked alot more promising. The website has focused on the demos, which is pretty good. There is documentation (i'll talk about that more later)</p><p>Best of all it works alot more like the widget based JavaScript code i've written. it focuses on converting existing dull html widgets into super js enabled ones at the flip of a switch.<br /><br /></p><h3>Concept</h3><p>Conceptially, as show on the demo's, takes the HTML page, and when the library is loaded, it hooks into the onload method of the page, and looks for all the widgets with the attribute dojotype="Select" or similar, and has a javascript class to handle each "dojotype". <br /></p><p>The dojo widget class takes a look at the attributes, and sets the javascript object properties to match those HTML attributes (hence behaving like the configuration for the widget). Then it builds the new widget based on those attributes, and merges it in with a template file (which is in dojo/src/widgets/templates/*) or uses a text attribute of the javascript object for the template. It then adds all the behaviour and just makes stuff happen.</p>This means getting upto speed with the widget set is fast, and you only slow down when you want to alter the default behaviours, at which point looking through the code seems to be the best idea.<br /><br />Unfortunatly, I found the documentation for dojo, a little thick and rather pointless, it comes of as more of a overview, and the real information is so far down in the chapters that it doesnt help much.. Rather than a nice reference of all the attributes that each widget type uses. (although the API reference is quite handy)<br /><br /><h3>Features</h3><p>Dojo has all the basic features that you would expect from a javascript widget toolkit, dialogs, windows, autocompletion, clever select widgets and more. It also has quite a library of backend tools for formating dates, doing xmlhttprequests. and more. What is nice about this, is that these libraries are not forced on you, rather they are used by the widget libraries, and you dont really need to know about them, or learn them. And offer a gradual learning path. So when you are ready you can start diving in and seeing if they are usefull in other parts of your code.</p>The architecture looks to be extendable as well, so you theoretically could build on the existing widget types and create your own bastard children, suiting your needs better. The syntax for the widget's is realitively straight forward, although they do use a slightly strange javascript syntax, but I doubt there is a better way to do what dojo acheives.<br /><p>Most of the really usefull stuff is in src/widgets/*<br /></p><h3>Flaws</h3><p>Well, nothings ever perfect, and looking at the huge number of bugs in the dojo bugtracker, I suspect they developers are having difficulting keeping up with it's popularity. <br /><br />There are a few design decisions that where annoying (although this has to be taken against the fact that the majority where excellent). The key ones being:</p><ul><li>CSS interaction, Widget's can load their own CSS from the template directory, This makes modifying the CSS for widget's rather difficult. (unless you treat the template directory as your own working space - or override it somehow). The more I worked with it, the more I thought it would be better to provide a generic CSS file that contains all the CSS needed for the widgets (or a file that @imports all the individual ones) , and force you to load it manually. - hence allowing you to replace the CSS quickly and simply. As often the dojo styling can conflict with any generic CSS that you may have already for your application.<br /><br />In addition, there are quite a few style="..." tags in the HTML templates used by the widgets, these should really have been moved into the CSS files, allowing more flexibility. <br /></li></ul><ul><li>Creating your own widgets. based on the dojo ones, It looks like a theroetically simple task, but an example in the demo's would probably help out alot (eg. a single file with an extended dojo widget example) - not a sexy demo, but would be really handy..</li></ul><ul><li>Documentation of attributes. as I mentioned before, the two set's of documentation - API and Manual miss out on the esential part of dojo, the use of HTML attributes to change settings. This could probably be generated or displayed in the API manual but is missing.</li></ul><ul><li> Missing widgets, or features lacking. There are many little things missing from dojo, that seem obvious, yet are not there (yet), </li></ul><ul style="margin-left: 40px;"><li>Dialogs that are more complete, the basic dialog is very baren, having no OK/Cancel built in, and no styling that makes it look particularly sexy.</li><li>No Basic Dialog set's like prompts, warnings etc. that just display messages or get simple user feedback</li><li>Interaction of the button widget with things like wizards and dialogs - you would expect these to be used by default on the standard wizard, but the default is a rather poor looking button</li><li>The great love of blue - the standard button widget uses rather a inelegant blue colour, a faded grey would probably be more neutral for generic applications.<br /></li></ul><br />So far though I've been pretty impressed with dojo, so I would recommend it as a good solution for a adding a stylish interferace to rather dull get/post web sites.<br /><br /> </DIV> <DIV class="" xbuilderid="roo-gen50" xtype="Roo.bootstrap.Element"> <A href="/index.php/View/132/Javascript_Toolkits.html" xbuilderid="roo-gen51" xtype="Roo.bootstrap.Link">View Extended Entry</A> </DIV> <DIV class="" xbuilderid="roo-gen52" xtype="Roo.bootstrap.Element">Posted by in <A href="/index.php/BlogCategory/272/Javascript.html">Javascript</A> | <A href="/index.php/View/132/Javascript Toolkits.html#comments">Add / View Comments()</A> </DIV> </DIV> <DIV class=" col-md-8 maincontent" xbuilderid="roo-gen54" xtype="Roo.bootstrap.Container"> <DIV class="text-center text-center" xbuilderid="roo-gen55" xtype="Roo.bootstrap.Element"> <A href="/index.php/BlogCategory/272/Javascript.html?page=3" xbuilderid="roo-gen56" xtype="Roo.bootstrap.Link">« prev page</A> <SPAN class="" xbuilderid="roo-gen57" xtype="Roo.bootstrap.Element">   (Page 4 of 4, totalling 34 entries)   </SPAN> </DIV> </DIV> </DIV> </DIV> </DIV> </SECTION> <DIV xbuilderid="roo-comp-1003" xtype="Roo.bootstrap.Element"> <SECTION class=" social" xbuilderid="roo-comp-1005" xtype="Roo.bootstrap.Container"> <H3 xbuilderid="roo-comp-1007" xtype="Roo.bootstrap.Header"> Follow us on <A href="http://www.roojs.com/index.php/BlogRSS/0/All%20Categories.xml"> <IMG src="/Roojscom/templates/images/rss_32.png" width="32" height="32"></IMG> </A> <A href="http://www.linkedin.com/in/roojs"> <IMG src="/Roojscom/templates/images/linkedin_32.png" width="32" height="32"></IMG> </A> <A href="http://twitter.com/roojs"> <IMG src="/Roojscom/templates/images/twitter_32.png" width="32" height="32"></IMG> </A> </H3> <DIV class="row clearfix" xbuilderid="roo-comp-1009" xtype="Roo.bootstrap.Row"> <DIV class="column col-md-6" xbuilderid="roo-comp-1011" xtype="Roo.bootstrap.Column"> <DIV class=" alert alert-warning" xbuilderid="roo-comp-1013" xtype="Roo.bootstrap.Container"> <H2 xbuilderid="roo-comp-1015" class="head-set" xtype="Roo.bootstrap.Header">OUR BLOG</H2> <DIV xbuilderid="roo-comp-1017" xtype="Roo.bootstrap.Element"> <A href="/index.php/View/304/Some thoughts on the language server and its usefulness in the roobuilder " xbuilderid="roo-comp-1019" xtype="Roo.bootstrap.Link">Some thoughts on the language server and its usefulness in the roobuilder </A> </DIV><DIV xbuilderid="roo-comp-1017" xtype="Roo.bootstrap.Element"> <A href="/index.php/View/303/Roo Builder for Gtk4 moving forward" xbuilderid="roo-comp-1019" xtype="Roo.bootstrap.Link">Roo Builder for Gtk4 moving forward</A> </DIV><DIV xbuilderid="roo-comp-1017" xtype="Roo.bootstrap.Element"> <A href="/index.php/View/297/Clustered Web Applications - Mysql and File replication" xbuilderid="roo-comp-1019" xtype="Roo.bootstrap.Link">Clustered Web Applications - Mysql and File replication</A> </DIV><DIV xbuilderid="roo-comp-1017" xtype="Roo.bootstrap.Element"> <A href="/index.php/View/293/GitLive - Branching - Merging" xbuilderid="roo-comp-1019" xtype="Roo.bootstrap.Link">GitLive - Branching - Merging</A> </DIV><DIV xbuilderid="roo-comp-1017" xtype="Roo.bootstrap.Element"> <A href="/index.php/View/292/PDO_DataObject Released" xbuilderid="roo-comp-1019" xtype="Roo.bootstrap.Link">PDO_DataObject Released</A> </DIV><DIV xbuilderid="roo-comp-1017" xtype="Roo.bootstrap.Element"> <A href="/index.php/View/291/PDO_DataObject is under way" xbuilderid="roo-comp-1019" xtype="Roo.bootstrap.Link">PDO_DataObject is under way</A> </DIV><DIV xbuilderid="roo-comp-1017" xtype="Roo.bootstrap.Element"> <A href="/index.php/View/288/Mass email Marketing and anti-spam - some of the how-to.." xbuilderid="roo-comp-1019" xtype="Roo.bootstrap.Link">Mass email Marketing and anti-spam - some of the how-to..</A> </DIV><DIV xbuilderid="roo-comp-1017" xtype="Roo.bootstrap.Element"> <A href="/index.php/View/287/Hydra - Recruitment done right" xbuilderid="roo-comp-1019" xtype="Roo.bootstrap.Link">Hydra - Recruitment done right</A> </DIV> </DIV> </DIV> <DIV class="column col-md-6" xbuilderid="roo-comp-1021" xtype="Roo.bootstrap.Column"> <DIV class=" alert alert-warning" xbuilderid="roo-comp-1023" xtype="Roo.bootstrap.Container"> <DIV xbuilderid="roo-comp-1025" xtype="Roo.bootstrap.Element"> <A class="twitter-timeline" data-dnt="true" href="https://twitter.com/roojs" data-widget-id="478410483276328960"> </A> </DIV> </DIV> </DIV> </DIV> </SECTION> <A name="contact" xbuilderid="roo-comp-1027" style="position:relative; top:-30px" xtype="Roo.bootstrap.Link"></A> <FOOTER class=" top-space" xbuilderid="roo-comp-1029" xtype="Roo.bootstrap.Container"> <DIV class="container" xbuilderid="roo-comp-1031" xtype="Roo.bootstrap.Container"> <DIV class="container" xbuilderid="roo-comp-1033" xtype="Roo.bootstrap.Container"> <DIV class="row clearfix" xbuilderid="roo-comp-1035" xtype="Roo.bootstrap.Row"> <DIV class="column col-md-3 widget" xbuilderid="roo-comp-1037" xtype="Roo.bootstrap.Column"> <H3 xbuilderid="roo-comp-1039" class="widget-title" xtype="Roo.bootstrap.Header">Contact</H3> <DIV xbuilderid="roo-comp-1041" class="widget-body" xtype="Roo.bootstrap.Element"> <P xbuilderid="roo-comp-1043" xtype="Roo.bootstrap.Element"> <BR /> Email: <A href="mailto:sales@roojs.com">sales@roojs.com</A> <BR /> Tel: <A href="Tel:+85237092951">+852 3709 2951</A> <BR /> Room 2710, Trend Center <BR /> 29-31 Cheung Lee Street, <BR /> Chai Wan <BR /> Hong Kong <BR /> </P> </DIV> </DIV> <DIV class="column col-md-offset-4 col-md-4 widget" xbuilderid="roo-comp-1045" xtype="Roo.bootstrap.Column"> <DIV xbuilderid="roo-comp-1047" class="widget-body" xtype="Roo.bootstrap.Element"> <P xbuilderid="roo-comp-1049" xtype="Roo.bootstrap.Element">Copyright 2023 - Roo J Solutions Limited</P> <P xbuilderid="roo-comp-1051" xtype="Roo.bootstrap.Element">Powered by the Roo Javascript Library and our Roo bootstrap toolkit</P> </DIV> </DIV> </DIV> </DIV> </DIV> </FOOTER> </DIV> </body> <script type="text/javascript" src="/roojs1/roojs-core-debug.js?ts=1234"></script> <script type="text/javascript" src="/roojs1/roojs-bootstrap-debug.js?ts=1234"></script> <script type='text/javascript'> var baseURL="\/index.php"; var rootURL=""; var authenticated=null; var error_data=null; var page_args=null; </script> <script type="text/javascript" src="/Roojscom/Roojscom.js"></script> <script type="text/javascript" src="/Roojscom/Header.js"></script> <script type="text/javascript" src="/Roojscom/Footer.js"></script> <script type="text/javascript" src="/Roojscom/ContactDialog.js"></script> <script type="text/javascript" src="/Roojscom/ViewArticles.js"></script> <script type="text/javascript"> Roojscom.init(); </script> </script> <script type="application/ld+json"> { "@context": "http://schema.org", "@type": "Organization", "name" : "Roo J Solutions Ltd.", "url": "http://www.roojs.com", "sameAs" : [ "https://www.facebook.com/roojs", "https://www.linkedin.com/company/roo-j-solutions-ltd-", "https://twitter.com/roojs" ] } </script> <script type="application/ld+json"> { "@context": "http://schema.org", "@type": "LocalBusiness", "name" : "Roo J Solutions Ltd.", "url": "http://www.roojs.com", "logo": "https://www.roojs.com/Roojscom/templates/images/roojsolutions-tr-100.png", "description": "Hong Kong's Premier SME Software Development Service", "telephone": "+852 3709 2951 ", "address": { "@type": "PostalAddress", "addressLocality": "Hong Kong", "addressRegion": "HK", "streetAddress": "Room 2710, Trend Center, 29-31 Cheung Lee Street" }, "openingHours": [ "Mo-Fr 09:00-17:00" ] } </script> </html>