Skip to content

Instantly share code, notes, and snippets.

@rkatic
Created February 18, 2012 06:55
Show Gist options
  • Save rkatic/1857929 to your computer and use it in GitHub Desktop.
Save rkatic/1857929 to your computer and use it in GitHub Desktop.
var formCheckedRadios = {};
function OldWebKitFakeRadio() {
this._name = "";
this._defaultChecked = false;
this._checked = false;
}
OldWebKitFakeRadio.prototype = {
get name() {
return this._name;
},
set name( value ) {
var name = String( value );
if ( name !== this.name ) {
var checked = this._checked;
this.checked = false;
this._name = name;
this.checked = checked;
}
return value;
},
get defaultChecked() {
return this._defaultChecked;
},
set defaultChecked( value ) {
this._defaultChecked = !!value;
if ( this._checked === undefined ) {
this.checked = this._defaultChecked;
}
return value;
},
get checked() {
return !!this._checked;
},
set checked( value ) {
// Ignore if it seams same...
if ( !value !== !this._checked ) {
this._checked = !!value;
if ( this._name ) {
var key = ":" + this._name;
var curr = formCheckedRadios[ key ];
if ( this._checked ) {
if ( curr && curr != this ) {
curr._checked = false;
}
formCheckedRadios[ key ] = this;
} else if ( curr == this ) {
formCheckedRadios[ key ] = undefined;
}
}
}
return value;
},
cloneNode: function() {
var elem = new OldWebKitFakeRadio();
// Copy HTML "attributes"
elem._name = this._name;
elem._defaultChecked = this._defaultChecked;
if ( this._name && this._checked ) {
// WebKit do not allows multiple checked radios in same group.
// Makes it to apear not checked (momentarily)...
elem._checked = undefined;
// Also unchecks the original one!
this.checked = false;
} else {
elem.checked = this.checked;
}
return elem;
}
}
function FakeRadio( real, fake ) {
real = real || "<input name='foo' type='radio' checked='checked' />";
if ( typeof real === "string" ) {
var div = document.createElement("div");
div.innerHTML = real;
real = div.firstChild;
}
if ( !fake ) {
fake = new OldWebKitFakeRadio();
fake.name = real.name;
fake.defaultChecked = real.defaultChecked;
fake.checked = real.checked;
}
if ( !FakeRadio.debugging ) {
return fake;
}
var o = { fake: fake, real: real };
function check( a, b, msg ) {
if ( a !== b ) {
throw msg + " -> real: " + b + ", fake: " + a;
}
}
["name", "defaultChecked", "checked"].forEach(function( name ) {
o.__defineGetter__(name, function() {
var a = fake[ name ];
var b = real[ name ];
check( a, b, "radio." + name );
return a;
});
o.__defineSetter__(name, function( value ) {
var a = ( fake[ name ] = value );
var b = ( real[ name ] = value );
check( a, b, "( radio." + name + " = " + value + " )" );
return a;
});
});
o.cloneNode = function() {
return FakeRadio( real.cloneNode(false), fake.cloneNode() );
};
return o;
}
FakeRadio.debugging = false; // Turn it 'on' only in old WebKit (like Safari 4).
// Example:
var a = FakeRadio("<input name='radiotest' type='radio' checked='checked' />");
a.checked //-> true
var b = a.cloneNode();
a.checked //-> false
b.checked //-> false
b.defaultChecked = b.defaultChecked // (true)
b.checked //-> true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment