Showing posts with label JavaScript. Show all posts
Showing posts with label JavaScript. Show all posts

Tuesday, July 14, 2015

Building a Source Code Generator with AngularJS

If you are looking for generating scaffold for AngularJS, this is not what this blog post about. This blog post is about generate source code with AngularJS.

The principle of creating source code generators is pretty simple (details here): a model, a template, and a driver. Given:
  1. HTML5 can access to local files as the data model
  2. AngularJS has its template language
  3. JavaScript is the driver
The following code in JSFiddle takes a tab delimited (3 columns) file to generate a Oracle script:


The syntax highlighting is done by SHJS.

Since it takes any JavaScript object as the model, other potential input formats are JSON and XML (with aid of some library). This is a lightweight cross-platform source code generator.

Monday, May 04, 2009

E4X Alternative - JSOM

I have been expecting the popularity of E4X for a long time. However, as long as Internet Explorer is the most popular browser, "new" standards will never get popular (Microsoft is suffered from Windows XP legacy, too). Instead of waiting for E4X, some developers use XPath to query the DOM nodes while the other traverse the DOM node by node. However, it would be good if we could access XML content in JavaScript Object Model (JSOM):

xml='<invoice date="01-20-2000" number="123">' +
' <address country="US">' +
' <name>John Smith</name>' +
' <street>123 George St.</street>' +
' <city>Mountain View</city>' +
' <state>CA</state>' +
' <zip>94041</zip>' +
' </address>' +
'</invoice>';
invoice = JSOM(xml);
alert(invoice.$number);
alert(invoice.address.name);

There is a project, IEE4X, in SourceForge for the same purpose but it does not work quite well for a few cases. So, I grabbed the idea and implement the JSOM library myself. The code can be download at Shane's Shelf.

Thursday, September 25, 2008

Developer Friendliness

People usually said that Firefox is more developer friendly than IE or Safari. Currently, there are two embarrassing incidents that flip my perception of Firefox.

1. Text box inside DIV
For some weird reason in Firefox 2, the cursor caret in the text box disappears when the text box is inside a DIV. Web developer has to work with the CSS hack to get the caret back
overflow: hidden; position:fixed;
It is OK if web developer have the total control of the HTML. However, we have web components in .Net and Java Server Face. If such components do not aware of this, user may had a bad experience.

2. Length Required with POST
Content-length is an HTTP header letting the server know how much data it should be expecting in the request. However, Firefox does not send such header to the server with posting with XMLHTTPRequest. Developer need to write it out explicitly
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
xhr.setRequestHeader('Content-length', '0');
XMLHTTPRequest is the key doing AJAX! The HTTP request is usually uncachable when using POST. Why on earth developers need to code it themselves?

I think implementing the standard is important. It relieves the web developers headache. On the other hand, please do not introduce new problem to the developers.

Saturday, September 20, 2008

ShineDraw in JavaScript: Kaleidoscope

This is the JavaScript version of Kaleidoscope in ShineDraw. It uses <canvas> and works with Gecko (Firefox, SeaMonkey), Webkit (Google Chrome, Safari) engines.

Performance:
  • SeaMonkey - Comsumes a lot of CPU power
  • Google Chrome - Renders the Kaleidoscope smoothly.

Sunday, September 14, 2008

ShineDraw in JavaScript: Random Expand Rotator

This is the JavaScript version of Random Expand Rotator in ShineDraw.


Implementation Note:
Image scaling and clipping cannot be done at the same time in JavaScript.

Sunday, August 03, 2008

Taking Google Maps API Offline

Sometimes, we want to utilize the some API for other work. Google Maps API is a very good example. You may want to use it as a photo viewer. Like allowing user to zoom-in and zoom-out, tagging, etc. However, since the API needs to validate the key online, you cannot take it as a standalone application where people can use offline.

Now, Google Maps API is a JavaScript API which we can download the script from the web. It just needs a bit hacking to get the API offline:
1. Highly obfuscated code
2. Dynamic module loading
3. Key verification

The obfuscated code can be ignored since you do not need to understand everything. All you need is finding the key statements that involve loading resources online (like module loading, image loading, etc). You can use a formatter to beautify it a little bit and decode it mentally.

The key verification is the most easiest part. Like all hacking, find the verification function and return a true will be good.

The process can be done within an hour for an experienced programmer.

With a good packager, we can have a really nice image mosaic viewer offline.

Thursday, March 23, 2006

Dissection of Technologies in JavaScript RIA

In the last entry, I have summarized choices we have while writing a JavaScript RIA (or AJAX application). They are under these seven categories:
  1. Communication Model
  2. Communication Style
  3. Push Communication Style
  4. Transportation Protocols
  5. Data Format
  6. UI Rendering
  7. UI Update Style
These categories are actually order in a particular user request:
  1. Is it an asychronous or a synchronous?
  2. Use iFrame or XHR?
  3. Use iFrame or HTTP 1.1 chunked for push data?
  4. Data is transmitted with HTTP, XML-RPC, or SOAP?
  5. Data is returned in what format (plain text, HTML, JSON, Base64, XML)?
  6. The data is the rendered UI or the data values for the client to render the UI?
  7. Use innerHTML or use DOM to maniuplate the UI?
The combination of the technologies can be summarized in the following graph:

To make any design decision, we may highlight the nodes and paths in the graph in top-down manner. For example, in the case of original AJAX defintion, we may hightlight Asychronous, XHR, HTTP/REST, XML, and Client Side Rendering:

The UI update style is undetermined up to this moment. We can make a complete decision before sending the design to programmers. Designers and programmers may have different preference of AJAX approach. With this simple graph, designers can communicate and synchronize with programmers more effectively. The architect can also use the graph to generate the implementation blueprints for programmers to follow so that more maintainable code can be expected.

Wednesday, March 22, 2006

The way to JavaScript RIA is paved with good technologies

As we are working with the Shanghai team, we found that they have different concepts about JavaScript RIA (also known as AJAX). Hong Kong team tends to have a better structure and more graceful way to partition the layers. On the other hand, Shanghai team tends to have less structure but faster development speed.

This leads to the classical design question about the tradeoff between development time and maintenance time.

For this reason, I listed out all possible combinations of different technologies and styles so that we can make the design decision from the beginning of the design stage in the future. The explanations will be added soon. To summarized, they are:
  1. Communication Model
    • Synchronous
    • Asynchronous (AJAX)
  2. Communication Style
    • iFrame
    • XMLHTTPRequest (XHR)
  3. Push Communication Style
    • iFrame
    • HTTP 1.1 chunked
  4. Transportation Protocols
    • HTTP / REST
    • XML-RPC
    • SOAP
  5. Data Format
    • Plain Text
    • HTML
    • XML
    • JSON
    • Base64
  6. UI Rendering
    • Server Side Rendering
    • Client Side Rendering
  7. UI Update Style
    • innerHTML Substitution
    • DOM Manipulation

Tuesday, May 24, 2005

JavaScript Obfuscator

I have recently written an obfuscator for JavaScript in Java. It is available at:
http://www.shaneng.net/

It exploit some feature of JavaScript so that I don't need to understand the content of JavaScript. To start, the obfuscator just "blindly" replace the variables without leading dot (e.g. window.parent has the dot). Then, I managed to remove the comments. Later, it also encode character in the string literals into \uXXXX or \XXX format.

In the current version, I refactor it so that it is more managable. In the future, I would like to handle the source code with E4X syntax.

Tuesday, April 19, 2005

JavaScript: setInterval() problem

Have you been trying to write some class like this:
function y() {
this.x = 0;
this.start = function () {
this.interval = setInterval(this.run, 1000);
};

this.run = function () {
this.x++;
debug(this.x); // or some other things you want to do
};

this.stop = function () {
clearInterval(this.interval);
};
}
You may attempt to refer the x in the run() function. However, in JavaScript, the scope of the function becomes the window after running setInterval() (or setTimeout()).

To solve the problem, the code be written like this:
function y() {
this.x = 0;
var self;

this.start = function () {
self = this;
this.interval = setInterval(run, 1000);
};

function run() {
self.x++;
debug(self.x);
}

this.stop = function () {
clearInterval(this.interval);
self = undefined;
};
}
Since using the self variable will create a cyclic reference, it should be cleaned up properly. Otherwise, the garbage collector of the script interpreter(s) which use(s) reference count will not be able to collect the instance.

Update (2009-03-29)
Thanks to the comment by dedogs, we could actually write the code like this without the cyclic reference:
function y() {
this.x = 0;
this.start = function () {
var self = this;
this.interval = setInterval(function(){ self.run(); }, 1000);
};

this.run = function () {
this.x++;
debug(this.x); // or some other things you want to do
};

this.stop = function () {
clearInterval(this.interval);
};
}

Saturday, April 16, 2005

AJAX: XMLHTTPRequest Event Handling

Most of the XMLHTTPRequest uses the following implementation:
function run1() {
xmlhttp = new XMLHTTPRequest();
xmlhttp.onreadystatechange = processStateChange;
...
}

function processStateChange() {
if (xmlhttp.readyState == 4) ...
}
The problem is, when you have many events to handle, the variable xmlhttp in run1 may have assigned to different instances by different functions (e.g. run2, run3, etc). If you rely on this code, no one can gaurentee that your code will run correctly.

The resolve this problem you can try to write the code in this way:

function run1() {
var xmlhttp = new XMLHTTPRequest();
xmlhttp.onreadystatechange = function() { ... }
}
If you insist to write the handle in a function, here is another style of writing it:
function run1() {
var xmlhttp = new XMLHTTPRequest();
xmlhttp.onreadystatechange = function() {
processStateChange(xmlhttp);
}
...
}

function processStateChange(xmlhttp) { ... }