giovedì, novembre 09, 2006

latest version of getXDOC don't work in IE 4 because in IE 4
try catch are not supported, but IE4 also know the CC
so we need a check for this..
and how can we make try catch invisible to IE4?
using a 'simple' eval
IE4 still don't work well, but is the better I can do ^_^;;

Also notice that the correct object for a XHR is
Msxml2.XMLHTTP, not DOMDocument!

getXDOC modified version:


function getXDOC(){
if(typeof(window.XMLHttpRequest)!='undefined')
return new XMLHttpRequest();

/*@cc_on

if(!(@_jscript_version<4)){
return eval('(function(){try{return new ActiveXObject("Msxml2.XMLHTTP.6.0");}catch(e__x){return new ActiveXObject("Msxml2.XMLHTTP.3.0");}}())');
}
@*/
return new ActiveXObject('Msxml2.XMLHTTP.3.0');

}



Sorry Andrea, I use conditional compilation again -.-

giovedì, novembre 02, 2006

Final method to obtain a dom Document ?

after the reading of this post on IE Blog talking about using the right version of msxml I come of a possible solution to get the XMLHttpRequest:

function getXDOC(){
//W3C native Object
if (window.XMLHttpRequest)return new XMLHttpRequest();

//IE 4.0 fallback [try..catch]
var progIDs=[];
progIDs[0]='Msxml2.XMLHTTP.3.0';
var i = 0;
/*@cc_on
progIDs = [ 'Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.3.0']; //6.0 is better of 3.0
for (; i < progIDs.length; i++) {
try{
@*/
if (window.ActiveXObject){
var xmlDOM = new ActiveXObject(progIDs[i]);
xmlDOM.setProperty("SelectionLanguage", "XPath");//because 3.0 default is XSLPattern
return xmlDOM;
}
/*@cc_on
}
catch (ex) {
}
}
@*/
return null;
}


Enjoy ;)

Ps. stay tuned for a corrected version..
Update:
http://mykenta.blogspot.com/2006/11/latest-version-of-getxdoc-dont-work-in.html

martedì, ottobre 10, 2006

Observer Subscriber in Base

I was playing with Dean Edwards Base and I would to implement
the Observer Subscriver pattern.
I wrote this Observer implementation:


//Clone method
Base.prototype.clone=function(){return new Base(this);}

//Define the Observer class
var Observer= Base.extend({
subscribe:function (obj,evt){
//if(!this["on"+evt])this["on"+evt]=[];
if(typeof(this["on"+evt]) === "undefined")this["on"+evt]=[];
this["on"+evt].push(obj);
},
raise:function (evt){
var list=this["on"+evt];

if(list){
var max=list.length;
for(var i=0;i<max;i++)
//if(list[i].update)list[i].update();
if(typeof(list[i].update)!=="undefined")list[i].update();
}
}
});
//Define the subscriber class
var Subscriber = Base.extend({update:function(){alert("update() must be implemented");}});


and this little test

/*Simple example of implementation*/

//Istantantiate a Observer
var observer= new Observer();

//Define a Event
observer.evt=function(){
//do stuff
this.raise("evt");
}

//Istantiate a Subscriber
var subscriber1=new Subscriber();
//Clone a Subscriber
var subscriber2=subscriber1.clone();

//define a custom update function
subscriber2.update=function(){
alert("here update() was implemented");
}

//subscribe our 2 object
observer.subscribe(subscriber1,"evt");
observer.subscribe(subscriber2,"evt");

//Raise the event
observer.evt();


Base is Great, it was so simple!




Update!
As I said in the comment this wasn't a correct implementation.

A correct(I hope) is the follow implementation:

//Clone method
Base.prototype.clone=function(){return new Base(this);}

var Observer = Base.extend({
update:function(evt){
alert("update() must be defined");
}
});
var Subject = Base.extend({
observers:[],
constructor:function(){this.observers=new Array();},
registerObserver:function(obj){
this.observers.push(obj);
return obj;
},
unregisterObserver:function(obj){
if(this.observers.length>0)
var tmp=this.observers.pop();
if (tmp!==obj){
var max=this.observers.length;
for(var i=0;i<max;i++)
if(this.observers[i]===obj){this.observers[i]=tmp;break;}
}
return this;
},
notifyObserver:function(evt){
var max=this.observers.length;
for(var i=0;i<max;i++)
this.observers[i].update(evt);
}
});

And so the Test:

/*Example:*/
var subject = new Subject();
subject.x=0;
subject.add=function(){
this.x++;
this.notifyObserver();
}
var observer1 = new Observer();
var observer2 =observer1.clone();
observer1.update=function(){alert("now x is "+subject.x);}
observer2.update=function(){alert("something happened on subject")}

subject.registerObserver(observer1);
subject.registerObserver(observer2);
subject.add();
subject.unregisterObserver(observer2);
subject.add();

venerdì, ottobre 06, 2006

typeof and Typeof

Dean Edwards point me out that typeof doesn’t always work so I come to a solution to this issue.

function isFunction(x){
return
typeof(x)==="function" &&
(typeof(x.toSource)==="undefined" || x.toSource().charAt(0)!="/")

}

basically it control if is a function (typeof(x)==="function")
and if is a gecko browser (typeof(x.toSource)==="undefined")
it control if is a RegExp(x.toSource().charAt(0)!="/").

So I wrote my simple Typeof function

function Typeof(what){
switch(what){
case Object:return "Object";
case Function:return "Function";
case Array:return "Array";
case String:return "String";
case Boolean:return "Boolean";
case Number:return "Number";
case RegExp:return "RegExp";
case Date:return "Date";
case Error:return "Error";
case Math:return "object";
case null:return "null";
}
if(typeof(what)==="function" && (typeof(what.toSource)!=="undefined" && what.toSource().charAt(0)=="/"))return "object"; //regex for moz
return typeof(what);
}


Enjoy ;)

venerdì, agosto 25, 2006

kentaromiura fastest device (duff's device optimized)


function kentaromiuraFastestDevice(iterations) {

var testVal=iterations;
if(parseInt(iterations/8)){
var n=iterations%8;
do{
--testVal; //do stuff
--testVal; //do stuff
--testVal; //do stuff
--testVal; //do stuff
--testVal; //do stuff
--testVal; //do stuff
--testVal; //do stuff
--testVal; //do stuff
}while(testVal!=n);
}
while(testVal--){
//do stuff
}
}

giovedì, luglio 20, 2006

standardise IE setAttribute (Part 2)

I go back to this subject because I've done some improvements to
the custom comment script that should Standardise IE 5.x setAttribute,
I create no other Object that could collide, look:


document.createElement = function(cE,interface){
//this is for DOM node not dinamically created
onload=function(){
var list=document.all;
var max=list.length;

while(--max)
{
list[max].getAttribute=interface.getAttribute;
list[max].setAttribute=interface.setAttribute;

}
//HTML node
list[0].getAttribute=interface.getAttribute;
list[0].setAttribute=interface.setAttribute;
}


return function (tagName) {
var element = cE(tagName);
element.getAttribute=interface.getAttribute;
element.setAttribute=interface.setAttribute;

return element;
}
}(document.createElement,{

getAttribute:function (attribute) {

switch(attribute){
case "class": attribute = "className";break;
case "for": attribute = "htmlFor";break;
case "style": return this.style.cssText;break;
case "type":return(this.id)?((document.getElementById)?document.getElementById(this.id):document.all[this.id]).type:this.type;break;
case "accesskey":return this.accessKey;break;
case "maxlength":return this.maxLength;break;
}
return this[attribute];
}

,setAttribute:function (attribute, value) {

switch(attribute){
case "name":return document.createElement(this.outerHTML.replace(/name=[a-zA-Z]+/," ").replace(">"," name="+value+">"));
case "class": attribute = "className";break;
case "for": attribute = "htmlFor";break;
case "type":
var me=this.parentNode;

if(!/id=/.test(this.outerHTML))
this.id=this.uniqueID;
if(me){
this.outerHTML=this.outerHTML.replace(/type=[a-zA-Z]+/," ").replace(">"," type="+value+">");




var t=me.childNodes;
var max=t.length;
for(var i=0;i<max;i++)
if(t[i].id==this.id){
t[i].getAttribute=this.getAttribute;
t[i].setAttribute=this.setAttribute;
}
}else this.type=value;

return;break;
case "accesskey":this.accessKey=value;return;break;
case "style": this.style.cssText =value;return;break;
case "maxlength":this.maxLength=value;return;break;
}

if(attribute.indexOf("on")==0){


this[attribute] = function(){eval(value)};

}
else
this[attribute] = value;
}
});


to use it just insert this line of code:

<!--[if lt IE 7]><script language="javascript" type="text/javascript" src="IEDOM.js"></script><![endif]-->

where IEDOM.js is the name of the script ..
Enjoy!


P.s. Look at http://www.devpro.it/JSL/ for a Great Library (
I would make a post for who don't want to Prototypize Object but won't use this great library!!
)

Update:
there are two known issues with this library:
first, if you use innerHTML instead of createElement you don't have the standard setAttribute,
so the solution is getting the node you are adding and extending the methods to each node it has

the second issue is the setAttribute("name") not updating dom. You was forced to return the correct node with setAttribute, so

var t=document.getElementById("x");
var n=t.setAttribute("name","usrname");
if(n)t=n;

now t is correct ;)

martedì, luglio 11, 2006

Another Pearl in the Javascript World

He Done It!


After my IE setAttribute solution (get here the complete solution along with my framework)


Andrea Giammarchi wrote a solution for the replace method, now you can use replace with a function as parameter, and is Standard ECMA compatible!


Try it or Get It!


It works on IE 5.x+, FF, NN,Opera, Safari, Konqueror ,


currently I haven't the complete compatibility list because is in a test state.


Now Javascript world is more standard!!! ;)


Example:


ECMA define that the function get the follow parameters


a)the Match of Regex passed as 1st argument


b)the N submatch (also known as parenthetical matches) with 0<N<99


c)position of the match in the original string


d)the original string


so "a12b34".replace(/[0-9][0-9]/g,function(a,b,c){return (Number(a)+1);}) must return "a13b35" in all the browser ;)

giovedì, maggio 11, 2006

addEvent

//Cannot be detached

function addEvent(obj,type,fn){
/*@cc_on obj.attachEvent('on'+type,function(){fn.apply(obj)});if(0){ @*/
obj.addEventListener( type, fn, false );
/*@cc_on } @*/
}

venerdì, maggio 05, 2006

getElementByClass

this code is now obsolete, take a look at this one to a better one, thanks.


document.getElementsByClassName = function(searchClass,node,tag)
{

if(node == null)node=document;
var ce = new Array();
if(tag==null || tag=='*')tag='*';
var els = new Array();
if (tag=='*' &&amp; document.evaluate){
var xpr=document.evaluate("//*",document, null, 0, null);
var t=true;
while (t=xpr.iterateNext()){
if(els.push)
els.push(t);
else
els[els.length]=t;
};
}
else
els = node.getElementsByTagName(tag);
var elsLen = els.length;
var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
var i;var j;
for (i = 0, j = 0; i < elsLen; i++) {
if ( pattern.test(els[i].className) )
if (ce.push)
ce.push(els[i]);
else
ce[j++] = els[i];
}

return ce;

}

venerdì, aprile 21, 2006

standardizzare setAttribute on IE

setAttribute lavora in maniera strana su IE,
fà quello che deve fare, ovvero cambiare dei valori di alcune proprietà,
ma essendo che vengono modificate le proprietà di un oggetto JScript,
alcune parole come class, for hanno un nome diverso..

dopo aver letto l'articolo su delete.me.uk
ho deciso di utilizzare il metodo ben spiegato per risolvere
i problemi su class,for e style e l'associazione di eventi on...

ho usato un commento condizionale, includendo il codice sotto riportato si ottiene un setAttribute piu' standard.

/*@cc_on
Element = function () {};

Element.prototype.getAttribute = function (attribute) {
if (attribute == "class") attribute = "className";
if (attribute == "for") attribute = "htmlFor";
if (attribute == "style") return this.style.cssText;
else return this[attribute];
}

Element.prototype.setAttribute = function (attribute, value) {
if (attribute == "class") attribute = "className";
if (attribute == "for") attribute = "htmlFor";
if (attribute == "style") this.style.cssText =value;
else
if(value.indexOf("on")!=0)
this[attribute] = function(){eval(value)};
else
this[attribute] = value;
}
var __IEcreateElement = document.createElement;

document.createElement = function (tagName) {

var element = __IEcreateElement(tagName);

element.getAttribute=interface.getAttribute;
element.setAttribute=interface.setAttribute;

return element;
}
var interface = new Element;
onload=function(){
var list=document.all;
var max=list.length;

while(--max)
{
list[max].getAttribute=interface.getAttribute;
list[max].setAttribute=interface.setAttribute;

}
}
@*/
naturalmente per aggiungere un evento nell'onload dovrete poi usare una funzione del genere:

function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof oldonload != 'function') {
window.onload = func;
}
else {
window.onload = function() {
oldonload();
func();
}
}
}

venerdì, aprile 14, 2006

InnerDom

WHY INNERDOM

Some months ago I found that innerHTML is not a standard way to manipulate HTML. Actually it is a proprietary implementation followed by many browser, althought it's very close to a de-facto standard and a lot faster that DOM actions.
So I learnt what could replace innerHTML as the combinations of createElement, insertBefore or the better replaceChild, setAttribute; so I wrote the code this way...

However I felt the need to write HTML directly into a node in a single step.
So I thought and I wrote a function ResToDom that appends an object in eval-notation
down to a node. Recently I felt it wasn't enough.
What I really needed was a function that used that EVAL-Notation object and replace a node (as innerHTML does). I rewrite the whole resToDom into innerDom (i used two different names as the functions are different).

Innerdom takes an object in EVAL notation and tries to convert it into HTML.
this object has 2 special properties:

TAG "the name of the tag to create"
INNER "what tag contains"

If innerDom finds an array it concatenates the nodes into a single node, so if used to write:

document.getElementById("node").innerHTML="aaa <b>some bold text<b/>";

now you can write it as:

innerDom("node",[{TAG:'a',name:'aa'},' ',{TAG:'b',INNER:'some bold text'}]);

Isn't that sw33t?

why EvaL-Notation?

because JSON it nowadays very frequently used joint with AJAx.


Here the Code

lunedì, aprile 03, 2006

Kentaromiura CrazyCorner 0.1 alpha(Gatsu)

I've recentelly find Krazy Corner (www.mswebpeople.com/krazy.html)
and i like some things but there was other things that i don't like,
example if i' ve already a site i don't want to rewrite it all from scratch adding a lot of
extra HTML tag, so i write myself a function that write that code for me ;)

i used span instead of b tag because that seems me better,
the source is HERE :
http://freeforumzone.leonardo.it/viewmessaggi.aspx?f=19716&idd=174

there isn't a live test page avaible yet nor a zip file,sorry but just
put test.html , crazycorner.css and crazycorner.js
in the same directory and enjoy ;)


I don't use innerHTML in this library ,so i should have high compatibility..
I test successful in
Netscape 7.2,
Ie 6.0sp2,
FF1.5, (it should work on 1.0 too because NN have the same gecko)
opera 8.51

..
I'm waiting for a lot of comments!

EDIT:
as Alessandro Fulciniti told me the original idea of Krazy Corners is of Stu Nicholls.(http://www.cssplay.co.uk/boxes/krazy.html)
as soon as possible i release a live-test page