Sunday, 15 March 2009

Comments For Script Articles - CSS Style Object, Linked Lists, Browser, Lazy Form Validator, Social Bookmarks

Example Scripts, Comments section

There are a number of scripts that I have posted on this site that are actually on another domain and therefore not part of blogger. Therefore I have added this article so that if anyone wants to post comments related to those scripts they can by adding them to this article.


Scripts List

JavaScript Unpacker. This simple form allows you to reverse engineer a block of JavaScript code that has been obfuscated by being encoded and is usually identified because the first few characters of the function look like this eval(p,a,c,k,e,r) . This method is usually used by hackers to try and hide the types of operation they are trying to carry out so its a wonderful way of being able to work out what the code is doing. Just paste the packed code into the box at the top, hit the "Unpack" button and hey presto you now have some readable code

CSS Style Object. A Javascript object that correctly calculates the computed style for Internet Explorer. Currently the example is using a function dedicated to correctly calculating styles for font-sizes but the core details could be applied to other styles requiring a computed size in pixels.

Querystring Parser: A small Javascript object dedicated to parsing a querystring something I thought would be inbuilt into the language but isn't. This article is on the blog and has its own comment section.

Linked Lists: A Javascript object dedicated to handling linked lists where the list box options in a parent list control the options that appear in a child list. The source of the data within the lists is not important this object controls the event handlers and the flow down of the hierarchy when a parent list has an item change as well as other default display options.

Lazy Form Validator: A Javascript object that can be used either in full production or when you want to quickly add client side form validation to a page with nothing more than including a reference to this script and then setting specific classes on each form element if special validation is required.

Social Bookmark Include: A simple include file and Javascript function that can be used on blogs or other sites to include links to social sites such as Digg, Stumble, Reddit etc. The script will append the appropriate URI and title details which it extracts from the source of the page containing the scripts. No need to customise the script on each page its used.

Browser Object. A little object dedicated to the now dirty art of browser sniffing containing details about css box model, spoofing, flash support, browser details etc. Most frameworks will still contain something similar and there are still cases where the the browser type and version is required knowledge due to feature support that cannot be tested with object testing.

Please specify which script you are commenting about when posting. Thanks.

47 comments:

Danny Edmonds said...

I love this unpacker tool I have been trying to find something simple for ages that worked for the code I wanted to unpack and this does the job nicely. Well done and a good site by the way. Keep it up!

Kimberly Rogers said...

I like the CSS Style object code which gives me a computed style in IE. I just don't understand why they can't do this as standard. I mean they just rewrote their JS and CSS engines for IE 8 so that would have been a good as time as any to do things properly. They must know the computed style when they render the content so why not let JS access it. If even Jquery and Dean Edwards get it wrong when it comes to styles in percentages then there isn't much hope for the rest of us and I see you had to do some parent/child checking and basic math to get it right but then at least it works!
Thanks

Anonymous said...

I like the browser object especially now its got the test for the IE 8 compatibility modes. What a pain they all are!!

EastGuy said...

I've been searching for a solution to the currentStyle vs getComputedStyle dilemma for hours. Finally I found your article on the CSS Style object. It's a very useful finding but I'm having a problem when trying to get the font-size of a text input element in IE8. This is the error reported:

Unexpected call to method or property access at line 378.

It is something to do with an appendChild function call which does not work on all html form elements. It seems to be a common problem with IE. I'm very grateful if you can fix this. I'm also trying to find alternatives to the appendChild function and will post here as soon as it works.
Thank you.

EastGuy said...

I think I've found the solution to the "appendChild not working for input element in IE" issue. This seems to work. What do you think?

//append hidden div to our element OR parent element if required
var cantAppendChild = false;
try {
el.appendChild(div);
}
catch (err) {
cantAppendChild = true;
try {
el.insertBefore(div);
}
catch (err) {
el.parentNode.insertBefore(div);
}
}

//measure size in px by getting offsetHeight
px = div.offsetHeight;

//clean up
if (cantAppendChild) {
//just specify false since div has no children anyway
div.removeNode(false);
}
else {
el.removeChild(div);
}

R Reid said...

Sorry I didn't get back to you I've been off work ill with the pork flu so my head is a bit fuzzy. I'm glad you found a solution and looking at your code I can see how

el.insertBefore(div);

will work in the same manner as appendChild as the parent object of the newly inserted div will be the element (el) which we have set the size to 1em and therefore measuring the divs height will give a computed style of px equivalent to 1em.

However this line

el.parentNode.insertBefore(div);

won't give the correct results as the new DIVs parent will be the elements parent not the element which is what we are aiming for. If the element and its parent both have the same style properties then you may see what looks like the correct result value but it won't work in all cases.

I know its the 3rd option in the try/catch so shouldn't really fire anyway. Apart from that looks good.

EastGuy said...

Sad to say this but it is the 3rd option that gets fired successfully. Therefore my solution is wrong.

I just realized that calling insertBefore without making use of its second parameter is no different than appendChild because when I changed it to

el.parentNode.appendChild(div);

it works too. The bottom line is IE simply isn't allowing me to put any elements inside input. I can use the 'value' property but it will just be rendered as plain text.

R Reid said...

Well the reason I said

el.insertBefore(div);

would work in IE is because IE does allow only one parameter to be submitted and when doing so you basically get the same action as doing

el.appendChild(div)

However I hadn't tested this with inputs which I can imagine would behave differently from other DOM nodes due to them being FORM elements.

I have just quickly knocked up a test page where you can see this in action at

http://www.strictly-software.com/testInsertBefore.htm

I have outputted all the debug into a div so you can easily see the results in case you don't have a console available.

Running the button "run before" will try to insert 4 paragraphs into the DOM with the following methods:

(where np = new paragraph element)
1: div.appendChild(np);
2: div.insertBefore(np);
3: div.parentNode.insertBefore(np);
4: div.parentNode.insertBefore(np,div);

As you can see in IE/Chrome/Safari all 4 methods work without erroring however in Firefox methods 2 & 3 don't work as FF requires both params to be passed when using insertBefore.

Also you can see in IE that the insertBefore acts just like appendChild and the new paragraphs are inserted above each other.

More importantly thinking about my CSS test they both report the same parent object.

The second button "Run input test" will try to append a child element to the text input with the following try/catch

try{ el.appendChild(div);
}catch(e){
try{ el.insertBefore(div);
}catch(e){
try{
el.parentNode.insertBefore(div);
}catch(e){

}
}
}

As you can see in IE although the last method works in attaching the DIV to the DOM (which is the 3rd method you said works) the parent node is not the INPUT but rather the main DIV.

As my CSS object when calculating sizes in EMs and % requires the test DIV to be attached to the element its trying to measure then this won't work.

Also notice in Firefox although the appendChild works in appending the DIV to the input its not visible/viewable even though the style values are set so it should be. (view it in IE to see the blue block)

I don't know what the answer is for IE yet but I am thinking about it.

joe said...

I am trying to build a linked list. I've followed your Linked List Object tutorial but I don't know how to write the server side script part to handle the AJAX request. I'm using PHP. Any clues??

R Reid said...

Well you will need a PHP page that will accept a request (querystring/post) with details of the filter.

If you don't want to edit my JS source then you need to make sure that this server side page is expecting the values to be supplied by a parameter with the name cat e.g in my example I am filtering by location so I pass the selected values of list A to my AJAX page like so

?cat=UK

or multiples like

?cat=UK,Scotland,France

So your page needs to take the value of the parameter "cat" and use it to filter your database, XML file or whatever it is you are querying.

e.g

SELECT Location FROM LOCATIONS WHERE Location IN('UK','Scotland','France');

Then I return the recordset of values back to the calling page with an Echo (you can modify my JS code to use JSON but I am using a simple pipe delimited format)

Then my JS object uses that data to populate List B (list A's child)

I am not a PHP expert so you will need to look on the web for examples of correct syntax etc for this server side page depending on what you want to do.

My example expects the data that is echoed out by the server side page to be in the format of ID|value with newlines separating each row so for 3 rows it would be

1|UK
2|Scotland
3|France

My code then splits this data and populates the child list.

So your server side page just needs to return the data in that format.

Hope this helps

Joe Smalley said...

Thanks for that, yes it did help. What wasn't quite clear in the script description was that the server side script needs to accept POST data and return values by means of 'echo'. Your comment cleared this up.

I now have a working linked list group containing two linked lists. However like your example I need three linked lists. Since all that is passed to the server side script is the POST var 'cat' I can't see how to distinguish between requests from my lists 1 and 2? I need this so I can run a different SQL query depending on which list has just been clicked. Surely the name of the Select needs to be passed somehow?

R Reid said...

Yes you could change the code that calls the serverside ajax page to pass in extra info in the qry value e.g cat=23,23,32&name=lstRegion or whatever you need.

The reason I don't need to pass any extra info is because the data for the linked lists (locations) is all coming from one table. The table is an adjacency hierarchy which stores the categoryID and its ParentID. Categories from the top list have no parentID (0). Those in the middle and subsequent lists will have pointers to their parent category.

E.G

CategoryID, ParentID, Category
1, 0, UK
2, 1, England
3, 1, Scotland
4, 2, London
5, 2, Birmingham
6, 3, Glasgow

Therefore when my example code passes in a CSV list of category IDS the serverside page only needs one SQL statement to handle all 3 lists as it just does a lookup from this table to get any child records that contain these category IDs in their ParentID column.

Passing in IDs from the top list will return records for the 2nd list as they will have matching parent ID values e.g passing in
cat=1

will return England,Scotland as these records have UK/1 as their parent.

Passing in selected items from the 2nd list will return records for the 3rd list as they will have matching parent IDs.

I don't know what your data schema is or how you are storing your data but this how I achieve a 3 or more tiered linked list with only one set of IDs being passed and one SQL statement.

Hope this helps.

trackfinder said...

You rock Dude! Awesome tool, best thing it keeps the formatting!

Way better than using eval = alert;

Best tool I've seen so far!

Martin

Snatch said...

Really a great tool!
Thanks for sharing it with us!

Ranjith said...

how can i implement your encoder.js in my application

R Reid said...

I am not sure what you are asking me. The code is all within a self contained javascript object so you can just copy the file into your applicaton and reference it with a SCRIPT tag.

The article http://www.strictly-software.com/htmlencode explains how to call all the functions and propeties along with details of what each one does.

Plus the page itself has an example of both the encode and decode working so you can just look at the source on that page to see how it works.

nalor said...

thanks for your encoder.js! just a small error I've found so far: ø encodes correctly to & oslash; - but & oslash; decodes to Ø what is usually & Oslash;

this comes because & #216 is also assigned to & oslash; and not & Oslash; as it should be.

Maybe you'd like to correct in your script also.

Best regards, Roland

R Reid said...

Hi Roland

I have fixed that and the script has been updated.

Thanks for letting me know

Rob

Anonymous said...

Hi,

Thanks for the cool script!
It is really very useful.

I found a similar problem already mentioned in the last post with...

è vs. È

and

&#230 ; vs. &#232 ;

Mike

autor desconocido #2 said...

.. THANK YOU for the encoder.js

man I looked so hard for something like this. seriously. thank you.

-jose

Rob Y said...

Thank you *very* much for this - quite useful.

Ferdinand said...

good job. thanks a bunch. =]

Anonymous said...

Thanks for the encoder.js. Worked first time and save a whole bunch of pain. Good work!

zoltan.dulac said...

The encoder.js tool is great ... but i don't see it referenced in this page! It rocks! Thanks for publishing it.

Mohammad Mustafa Ahmedzai said...

hi R Reid!

Dude I loved the code and the only problem I am facing is adding the decoder to my blog. I have tried using your form but nothing seems to work. Can you kindly provide me the code just for the decoder and the form code which will give it visual appearance.. I hope I was clear..

R Reid said...

The JS script for the decoder is downloadable from the links on the page.

Mohammad Mustafa Ahmedzai said...

oh thanks for replying but I actually want the form code. I tried copying your form code but not working. Can you please send me the html code of the form.

R Reid said...

I have made the functions available for free and they are pretty easy to use for your own code and my decoder / encoder form is just an example of putting them to use.

If you would like to contract my services as a web developer then you can do so but I am not going to be rewriting other peoples sites for free especially those that are aimed at copying my own ideas!

X said...

As a comment on the clientside htmlencoding and decoding. I think it's a great idea and it was exactly what i needed. But while testing it on the Iñtërnâtiônàlizætiøn⌠ string, i found that when I decode it, the code went capitalized on me

R Reid said...

Hi X

Try using the "Numeric" option instead of the "Entity" option.

You shouldn't have any problems with that method of HTML encoding and decoding

Thanks

Anonymous said...

Hello,

Thanks for the script.

However, some text character code are inverted:
ex: é = É instead of é
$Eacute = é instead of É

Anonymous said...

Hello again, (I just posted regarding an error with accentuated characters conversion)

I have applied a correction on the encoder.js file and the problem is solved.

Is there a way I can send it back to you so you can publish it on your site? (up to you of course...)

Thanks regards.

R Reid said...

Yes just email me the amended source code.

You will find links in the footer.

sociorobotics said...

Fantastic tool many thanks. We have been given the source code for a defunct product with the most important files being compressed. So big thanks from me.

Mark Wright said...

Thank you for JS unpacker. Saved me good :)

Anonymous said...

Grazie per il 'encode' e 'decode' dei caratteri speciali javascript!
Alex

Anonymous said...

Hi R.Reid!

Very much thanks for your free Encoder.js Your object script is a master piece which is really missing! Clever simple and very useful.
It helped me much to resolve the encoding/decoding problem to store and get back some html content put into CDATA section in an xml document.

Thank you spending your time helping others, too.

karl-heinz christ said...

Hello Reid.

Thank you very much for the Encoder.
I was searching around for 2 hoers to solve a problem with qTip ajax and your script solved my problem.

Have a good time. I which you the best. saluti da Genova Italy

Karl

karl-heinz christ said...

Hello Reid.

Thank you very much for the Encoder.
I was searching around for 2 hoers to solve a problem with qTip2 ajax data and your script solved my problem.

Have a good time. I which you the best. saluti da Genova Italy

Karl

Rob Reid said...

Well that's great! I shall be expecting a large donation from you for saving all that time in the coming days then???

Anonymous said...

Thank you for the Encoder.js, it was really useful

Silviu said...

how can I unpack a file with multiple eval inside?

Rob Reid said...

Try the unpacker page now. I have just wrapped a loop round the unpack process so it loops 5 times until it stops finding evals at the start or comes to 5 tries. I have tried it by using deans packer tool > http://dean.edwards.name/packer/ and then packing the function, then packing the encoded function, then packing it again (so 3 times packed). If I try unpacking it on the pages now it will go back to the original function. It depends on the code you are using but have a try.

Anonymous said...

Cool, I really like the way that tool now unpacks multiple packed pieces of code.

Cheers!

Anonymous said...

I'm looking for a robotstxt parser what can work linke GoogleBot, unfortunately yours solution has same problem like others, can not poperly check this:
User-agent: *
Disallow: /
User-agent: Googlebot
Allow: /

Rob Reid said...

Hi

That's because there is no such thing as allow.

GoogleBot may have tried introducing it but it is pointless and most other BOTS and SERPS don't support it. Plus logically it doesn't make sense.

Unless you disallow a BOT they are allowed. Otherwise you would be putting ALLOW statements for every BOT in the world for a page you want to allow access to. Easier specify DISALLOW to just prevent the BOTS you DON'T want to access a page.

So all you need are the disallow commands.

Google are not always right!

Thanks

Rob

Carl Edwards said...

Good info provided .Thanks for sharing..

Web Design London