- The textbox (XML) element is a wrapper around the input (HTML) element:
- createElement("textbox") creates not a ready-to-use object, but a "blank", that lucks many necessary functions. All properties/functions from XBL bindings get added to it only at adding this element to DOM tree (only at this stage its __proto__ is being changed from XULElementPrototype to XBL prototype).
Before adding to DOM tree:After adding to DOM tree:And XULElementPrototype becomes a grandparent: - Also only at adding to DOM tree the textbox's constructor() is being executed.
This constructor is quite remarkable. (Note manipulations with inputField.value - inputField is an underlying HTML input element): - It looks like the problem stems from the fact that XBL bindings can only add new properties/methods, but not replace (overwrite) existed ones. So when we are assigning something to textbox.value before adding this element to DOM tree, we thus preventing to add a value property from the XBL binding (with its getter and setter).
- The textbox (XML) element is a wrapper around the input (HTML) element:
- On the other hand, cloneNode() returns a real clone of the source element - with all its currently existing properties.
So if we are cloning an element that already is (or was) attached to DOM tree, we receive a fully functional element (or a tree of elements).
And if we are cloning a textbox that never was attached to DOM tree, we receive a non-functional element without its XBL bindings. Only when setAttribute("value", ...) is used instead of direct assignment to .value.
If both operations are used, then textbox will be broken as well.
For example, with:the input field will appear on screen with "initial value", and you will be able to change this text, but textBox.value will contain "trash" all the time.
The possible fix of the textbox constructor is quite simple and very similar to what is implemented in it already - just look if a .value property is present in the object being processed, and if yes then transfer its content to the inputField.value and remove the existent field:



