<html>
<head>
<script>
function ok(b,m) {
    return external.ok(b, m);
}

function test_removeAttribute(e) {
    ok(e.removeAttribute('nonexisting') === false, "removeAttribute('nonexisting') didn't return false");

    e.title = "title";
    ok(e.removeAttribute('title') === true, "removeAttribute('title') didn't return true");
    ok(e.title === "", "e.title = " + e.title);
    ok(("title" in e) === true, "title is not in e");

    e["myattr"] = "test";
    ok(e.removeAttribute('myattr') === true, "removeAttribute('myattr') didn't return true");
    ok(e["myattr"] === undefined, "e['myattr'] = " + e['myattr']);
    ok(("myattr" in e) === false, "myattr is in e");

}

function test_select_index() {
    var s = document.getElementById("sel");

    ok("0" in s, "'0' is not in s");
    ok(s[0].text === "opt1", "s[0].text = " + s[0].text);
    ok("1" in s, "'1 is not in s");
    ok(s[1].text === "opt2", "s[1].text = " + s[1].text);
    ok("2" in s, "'2' is in s");
    ok(s[2] === null, "s[2] = " + s[2]);
}

function test_createDocumentFragment() {
    var fragment = document.createDocumentFragment();

    ok(typeof(fragment) === "object", "typeof(fragmend) = " + typeof(fragment));
    ok(fragment.nodeType === 11, "fragment.nodeType = " + fragment.nodeType);
    ok(fragment.nodeName === "#document-fragment", "fragment.nodeName = " + fragment.nodeName);

    var cloned = fragment.cloneNode(true);
    ok(cloned.nodeType === 11, "cloned.nodeType = " + cloned.nodeType);
    ok(cloned.nodeName === "#document-fragment", "cloned.nodeName = " + cloned.nodeName);
}

function test_document_name_as_index() {
    document.body.innerHTML = '<form name="formname"></form>';
    var e = document.getElementById("formname");
    ok(!!e, "e is null");

    ok(document.formname === e, "document.formname != getElementById('formname')");
    ok("formname" in document, "formname' is not in document");

    document.body.removeChild(e);

    ok(document.formname === undefined, "document.formname is not undefined");
    ok(!("formname" in document), "formname' is in document");

    document.body.innerHTML = '<form id="formid"></form>';
    var e = document.getElementById("formid");
    ok(!!e, "e is null");
    ok(!("formid" in document), "formid is in document");

    document.body.innerHTML = '<form name="formname"></form>';
    ok("formname" in window, "formname' is not in window");
    ok(typeof(window.formname) === "object", "typeof(window.formname) = " + typeof(window.formname));
    window.formname = 1;
    ok(window.formname === 1, "window.formname = " + window.formname);
    formname = 2;
    ok(window.formname === 2, "window.formname = " + window.formname);
}

function test_remove_style_attribute() {
    var s = document.body.style, b;

    s.somevar = "test";
    b = s.removeAttribute("somevar", 1);
    ok(b, "removeAttribute returned " + b + " expected true");
    b = s.removeAttribute("somevar", 1);
    ok(b === false, "removeAttribute returned " + b + " expected false");
}

function test_clone_node() {
    var elem, cloned;

    elem = document.getElementById("divid");
    elem.style.filter = "alpha(opacity=50)";
    ok(elem.style.filter === "alpha(opacity=50)", "elem.style.filter = " + elem.style.filter);

    cloned = elem.cloneNode(true);
    ok(cloned.style.filter === "alpha(opacity=50)", "cloned.style.filter = " + cloned.style.filter);
}

function test_getter_call() {
    document.body.innerHTML = '<div id="divid"></div>';

    var e = document.getElementById("divid");

    e.myfunc = function(x) { this.myfinc_called = x; };
    e.myfunc("test");
    ok(e.myfinc_called === "test", "e.myfinc_called = " + e.myfinc_called);

    e.onmousedown = function(x) { this.onmousedown_called = x; };
    e.onmousedown("test");
    ok(e.onmousedown_called === "test", "e.onmousedown_called = " + e.onmousedown_called);
}

var globalVar = false;

function runTest() {
    obj = new Object();
    ok(obj === window.obj, "obj !== window.obj");

    ok(typeof(divid) === "object", "typeof(divid) = " + typeof(divid));

    test_removeAttribute(document.getElementById("divid"));
    test_removeAttribute(document.body);
    test_select_index();
    test_clone_node();
    test_createDocumentFragment();
    test_document_name_as_index();
    test_remove_style_attribute();
    test_getter_call();

    var r = window.execScript("globalVar = true;");
    ok(r === undefined, "execScript returned " + r);
    ok(globalVar === true, "globalVar = " + globalVar);

    external.reportSuccess();
}
</script>
<body onload="runTest();">
<div id="divid"></div>
<select id="sel">
<option>opt1</option>
<option>opt2</option>
</select>
</body>
</html>
