 Element::__defineGetter__ 'textContent', getInnerText
 Element::__defineSetter__ 'innerText', setInnerText
 Element::__defineSetter__ 'textContent', setInnerText
+Element::__defineGetter__ 'id', () -> @attributes['id']
+Element::__defineSetter__ 'id', (value) ->
+	o = @ownerDocument?
+	if o
+		if @attributes.id?
+			delete @ownerDocument._private.idMap[@attributes.id]
+	if value in [null, undefined, "undefined"]
+		delete @attributes.id
+	else
+		if o
+			@ownerDocument._private.idMap[value] = @
+		@attributes.id = value
+Element::__defineGetter__ 'className', () -> @attributes['class'] or ""
+Element::__defineSetter__ 'className', (value) ->
+	if value in [null, undefined, "undefined"]
+		delete @attributes.class
+		@_private.classes.length = 0
+	else
+		@attributes['class'] = value
+		# Optimization for getElementsByClassName, cache the split form
+		@_private.classes = value.split(' ')
+
+HTMLInputElement::__defineGetter__ 'value', () -> @attributes.value or ""
+HTMLInputElement::__defineSetter__ 'value', (v) -> @setAttribute('value',v)
+
+HTMLSelectElement::__defineGetter__ 'selectedIndex', () ->
+	if not (@_private.selectedIndex? and @_private.selectedIndex < @childNodes.length)
+		for index in [0...@childNodes.length]
+			if @childNodes[index].hasAttribute 'selected'
+				@_private.selectedIndex = index
+	return @_private.selectedIndex or 0
+HTMLSelectElement::__defineSetter__ 'selectedIndex', (v) ->
+	if v < @childNodes.length
+		for index in [0...@childNodes.length]
+			if index is v
+				@childNodes[index].setAttribute('selected','selected')
+			else
+				@childNodes[index].removeAttribute('selected')
+		@_private.selectedIndex = v
+	return @_private.selectedIndex or 0
+
+HTMLOptionElement::__defineGetter__ 'value', () -> if @hasAttribute('value') then @getAttribute('value') else @innerText
+HTMLOptionElement::__defineSetter__ 'value', (v) -> @setAttribute('value',v)
+
+HTMLSelectElement::__defineGetter__ 'value', () -> @childNodes[@selectedIndex]?.value
+HTMLSelectElement::__defineSetter__ 'value', (v) ->
+	for index in [0...@childNodes.length]
+		child = @childNodes[index]
+		if child.value is v
+			@selectedIndex = index
 
 class Attr extends Node
 	constructor: (name, value) ->

		return ret
	# attributes
	getAttribute: (name) ->
		@attributes[name] ? ""
	getAttributeNode: (name) ->
		n = new Attr(name, @getAttribute(name))
		n.ownerElement = @

		constructor: (a...) ->
			a[0] = "SCRIPT"
			super a...
	select: class HTMLSelectElement extends HTMLInputElement
		constructor: (a...) ->
			a[0] = "SELECT"
			super a...
