Reinitializing OBJECT and EMBED - data and type changes

In regards to:
<http://www.whatwg.org/specs/web-apps/current-work/multipage/section-embedded0.html#the-object>

"Whenever the data attribute changes, or, if the data attribute is not
present, whenever the type attribute changes, the user agent must run
the following steps to determine what the object element represents:"

I think the paragraph needs to go into a lot more detail on what
causes an Object element to be reinitialized.

For example:

The paragraph isn't clear what happens when both type and data are
present. Does changing type only work if data isn't present. Does
changing data only work if type isn't present?

"attribute changes" I assume applies to both the DOM attribute and the
content attribute. But, does it also apply if I change the value via
obj.attributes["type"].value or obj.attributes["type"].textContent for
example?  I think it does, but not 100% sure.

Does "attribute changes" apply when the attribute isn't present and you add it?

Does "attribute changes" apply when you remove the attribute?

Does "attribute changes" really mean "change", as in, the value has to
be assigned a *different* value than the current?

There are plenty of ways to add, remove and modify the type and data
or src attributes.

.type, .attributes["type"].value, .attributes["type"].nodeValue,
.attributes["type"].textContent, setAttribute, setAttributeNS,
setAttributeNode, setAttributeNodeNS, removeAttribute,
removeAttributeNS, removeAttributeNode, removeAttributeNodeNS etc.

Which ways should cause the object to reinitialize?

I assume the paragraph means: "If data or type is added or removed (in
any way) or modified (in any way, even to the same exact value), the
user agent must run the following steps to determine what the object
element represents:", but I'm not sure.

In other words, if I had something like:

var obj = document.getElementsByTagName("object")[0];
obj.addEventListener("DOMAttrModified", function(e) {
    if (e.attrName.match(/type|data/i)) {
        reinitialize object;
    }
}, false);

var emb = document.getElementsByTagName("embed")[0];
emb.addEventListener("DOMAttrModified", function(e) {
    if (e.attrName.match(/type|src/i)) {
        reinitialize embed;
    }
}, false);

, would that describe the intent?

If not, I suggest that it does work like that. It would greatly
simplify what causes the object or embed to reinitialize and would
provide lots of flexibility for the author.

Also:

Opera and Firefox currently support reinitializing an object when you
change the type. However, it only works in certain cases.  Switching
an object to a Java applet from the Windows media plugin is an example
of one situation that doesn't work.

I've found that if you do something like
obj.parentNode.replaceChild(obj.cloneNode(true), obj), things work
great in FF, Opera and Safari.  Perhaps the spec needs to go into more
detail on how the new resource should be loaded.

The specifics should probably be left up to the implementor, but
perhaps saying that reinitializing should give the same result as
you'd get from doing the replaceChild deal above (with maybe making
sure variable references are updated and making sure eventlisteners on
the object remain).

As an example of a failed reuse of an object:

<head>
<script>
HTMLObjectElement.prototype.addParam = function(name, value) {
    var p = this.ownerDocument.createElement("param");
    p.setAttribute("name", name);
    p.setAttribute("value", value);
    this.appendChild(p);
};
window.addEventListener("DOMContentLoaded", function() {
    var obj = document.body.getElementsByTagName("object");
    obj[0].width = "40";
    obj[0].height = "40";
    obj[0].textContent = "You need Java!";
    obj[0].addParam("code", "JavaAppletTest");
    obj[0].setAttribute("type", "application/x-java-applet");
    //obj[0].parentNode.replaceChild(obj[0].cloneNode(true), obj[0]);
    obj[0].style.width = "200px";
}, false);
</script>
</head>
<body>
<object type="application/x-mplayer2" width="300" height="300">
    <param name="ShowStatusBar" value="1">
    You need WMP!
</object>
</body>

(Uncomment the one line and it works as expected.)

I understand you want to leave plugin issues out of the spec, but it
would be bad if changing type and data only worked right when dealing
with native stuff and there was no guide on what to do exactly.

Thanks.

-- 
Michael

Received on Wednesday, 23 April 2008 16:24:47 UTC