Closed Bug 285272 Opened 19 years ago Closed 19 years ago

neither onPropertyChange nor watch works

Categories

(Core :: DOM: Events, defect)

x86
All
defect
Not set
normal

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: danswer, Unassigned)

Details

Attachments

(1 file)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) Gecko/20050225 Firefox/1.0.1
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) Gecko/20050225 Firefox/1.0.1

Bug https://bugzilla.mozilla.org/show_bug.cgi?id=280683 does not go far enough:

I would like to have an onPropertyChange in Firefox (ie.  if a (user specified)
specific named property of a (user specified) given DOM element changes it
triggers this event)  This corresponds to what Danny Goodman described as
watch/unwatch in his javascript Bible.  If you put this in, I hope it will be
less buggy than Microsoft's version.

Note that this is not asking for something that isn't inherently there (for
example, we can put in a one second timer and keep checking the property of
interest, but this is hugely wasteful).  The point being that there are no
security issues here, since we're only interested in being notified efficiently
of changes to objects that we own anyway.

The scenarios that I'm thinking of for my own use are when the user enters text
into a text element or textarea element and the page should respond immediately.
 Or perhaps the user has changed something on hir browser which results in a
layout change that the page should respond to (for example, on Opera, (it used
to be, anyway) that you could not detect when a user scaled the font even though
the page would get redrawn.

For example, on a current project, I allow the user to enter a width or height
where the ratio is fixed.  As the user makes the entry of one of the other, I'd
like to display in real time the corresponding value of the other.  With onKeyUp
and onMouseUp, I can catch the manual typing, but there are several ways to
paste, including mouse or keyboard activation of the menu (Edit/Paste), ctrl+V,
and the right context menu.  If onPaste is implemented, that would solve this
particular problem, but that is really a band-aidy inelegant way.  The real
issue is to know and react to a change in the value of the text element, and not
to try to account for all events leading to that change.

To be specific, I would like domElement.onPropertyChange("namedAttribute") =
funcToRun;

where domElement could also be a style object.
If namedAttribute is missing, any change would fire funcToRun.

funcToRun takes 3 arguments (well, at least the first one)
function funcToRun (nameOfPropertyThatChanged, beforeValueIfTextOrNumber,
afterValueIfTextOrNumber) {
    // this === object whose property/attribute changed
    ...
}

My motto:  if I own it, I want to (be able to) know about changes to it.

Csaba Gabor from New York

Reproducible: Always

Steps to Reproduce:
> Note that this is not asking for something that isn't inherently there 

it is there, in the form of mutation events.
and note that changing the value of a textarea does not change any attributes.
Chris, this is fantastic.  Firstly, thanks for your comments.  It took me
several hours to track down what you meant and then how to to use it since the
documentation that I found on the web was sparse indeed.  However, this is great
stuff.  Once all the bugs are out.

Note to self and any uninitiates wandering into this: MutationEvent is just a
fancy way of saying 'change event'.  To my mind they must have run out of words,
because mutation implies randomness and there doesn't seem to be any of that
inherent here.

OK, I have found four bugs in my simple example (testing on Win XP Pro, SP2), so
here we go:
First, do a copy of some string (Say: Bob)
Now bring up:

<html><head><title>MutationEvent test</title></head>
<BODY onLoad="init()">
<SCRIPT type='text/javascript'>
function init() {
    document.forms[0].inp.addEventListener("DOMCharacterDataModified",
        function(e){document.getElementById('label1').innerHTML = e.prevValue+"
=&gt; "+e.newValue;}, false);
}
</SCRIPT>
<FORM>
<INPUT type='text' name='inp' value='Mom'>
<br>DOMCharacterDataModified:&nbsp;&nbsp;
<LABEL id=label1>initial CharacterData label</LABEL>
</FORM> 
</BODY>
</html>


Bug 1)
TAB (do not use the mouse) to the input element (Mom will be selected).  Now
press ctrl+v.  Notice that Bob has replaced Mom, ==> but our expected event did
not fire as expected (I expected to see Mom => Bob).  <==
If we continue on by typing 'b' then we will see Bob => Bobb which is as expected.

Bug 2)
Start fresh.  This time select the text (Mom) in the input element with the
mouse.  Now select Edit/Paste from the menu.  Bob has replace Mom, ==>  but I
only see 'Mom => ' in yellow whereas I expect to see 'Mom => Bob'  <==
If we now type a 'b' things revert back to OK.  I think the important part of
the action here is to have selected everything in the input element.  Things are
working OK if not all (including none) of the text is selected.

Bug 3)
Start fresh.  Select the text (Mom) with the mouse.  Now press the delete key. 
Mom is gone and in yellow we see 'Mom => ' as expected.  Now press the letter
'a'.  ==> I expect to see the yellow change to ' => a' but it has not changed at
all <==.  If we now type a b, things revert back to normal.  I think the
important part of this bug is the element starting out empty.

Bug 4)
Start fresh.  Put the cursor at the end of the text in the input element (or you
could tab to the input element and press 'end').  Now press ctrl+v to paste.  In
the yellow we now see 'Mom => MomBob' as expected.  Now press ctrl+a to select
all the text.  Now press the delete key.  ==> I expect to see the yellow change
to 'MomBob => ' but it has not changed at all.  Typing an 'a' at this point
produces no change in the yellow text (I'd expect to see ' => a') <== Typing a b
now produces 'a => ab'

Anamoly 5)
Start fresh.  Put the cursor at the end of Mom.  Type 'a', type 's'.  So far so
good, we see 'Moma => Momas'.  Now press ctrl+z (Edit/Undo).  In the input box
we wind up with Mom.  ==> In yellow we see 'Moma => Mom' whereas I expected to
see 'Momas => Mom' <==
At least this one I understand.  There are two undo events in succession, the
first strips off the s, the next the a.  Only I would argue that the user
(developer) has no interest in how those undo's are internally being done.  He's
only interested in the starting and ending state of his control as the result of
a single action.  Nevertheless, I wouldn't consider it tragic to keep this
behaviour as is (though I'd prefer it to be transparent to me).  But I thought I
should bring it up.



Finally, a side comment.
Neither DOMSubtreeModified nor DOMAttrModified event listeners fired when I
inluded them above.  This is in keeping with Chris' comment above and Boris'
comment about property vs. attribute of value at
http://groups-beta.google.com/group/netscape.public.mozilla.dom/browse_frm/thread/8b35def67b6c0151/

Also, I must be missing something becuase I get false when I do:
alert(document.implementation.hasFeature("MutationEvents", "2.0"));


Csaba Gabor from Vienna
Phooey.  This is what the test page should be:

<html><head><title>MutationEvent test</title></head>
<BODY onLoad="init()">
<SCRIPT type='text/javascript'>
function init() {
    document.forms[0].inp.addEventListener("DOMCharacterDataModified",
	function(e){document.getElementById('label1').innerHTML=
	    e.prevValue+" =&gt; "+e.newValue;}, false);}
</SCRIPT>
<FORM>
<INPUT type='text' name='inp' value='Mom'>
<br>DOMCharacterDataModified:&nbsp;&nbsp;
<LABEL id=label1 style="background-color:yellow">initial label</LABEL>
</FORM> 
</BODY>
</html>
The last test case posted by Csaba works fine for me with Firefox 1.03. I
recommend changing the status of this bug to "WORKSFORME".
I've just tested this out and can confirm that it is indeed bugged. Especially
in a textarea, the produced values are completely upside-down, with multiple
triggers for the same operation (e.g. cutting or pasting across lines).

Additionally, pasting text onto an empty line in a textbox (e.g.:
[text
<== empty line
text]) does not trigger DOMCharacterDataModified as it should.

-Kalle.
Anyone care to confirm this bug, one way or the other?

/be
So what is the use case and scope?  Doing this in general for everything (base URIs, all tree-state-dependent properties, computed style, etc) really won't fly performance-wise...
This attachment is for testing as described in Comment 3
(In reply to comment #8)
> So what is the use case and scope?  Doing this in general for everything (base
> URIs, all tree-state-dependent properties, computed style, etc) really won't
> fly performance-wise...

May I suggest that we take Comment 3 as the statement of this bug report?  In other words, this is a bug report about the DOMCharacterDataModified mutation event as it applies to text and textarea (and the use case for this has been made in Comment 1), and not something more general.

On my FF, the same problems reported in Comment 3 are still there, and I have created an attachment to make it simple to test.  The attachment has some minor modifications from the code listed in Comment 4 - namely, that the entire history of the DOMCharacterDataModified event is shown.

Csaba
This bug is all over the place. It starts out as being an RFE to get watch or onpropertychange working, but then morphs into a bug about mutationevents. On top of this a lot of the claimed mutationevent bugs are in fact invalid[*]. Would anyone mind if we just closed this bug so that new, easier to follow, bugs can be filed.

[*] When the text inside a <textarea> or <input type="text"> is changed the DOM is not mutated. No textnodes are ever added or removed or have their data changed, and thus no mutation events should be sent out. The only thing that changes is the .value property.
What sicking said.  The fact that any mutation events fire while editing a textarea is a bug in our anonymous content and event retargeting code.  There should be no such events at all during typing and copy/paste operations.
I don't mind if this is closed so a new, cleaner report can be filed.  But in the interest of getting it right, what should I file it under - should I essentially refile the original report?  To be specific, my immediate interest in all this is to have a way to detect when the text of a textbox or textarea changes.  This is both reasonable and useful for web apps.  From http://www.w3.org/TR/DOM-Level-3-Events/events.html#event-textInput it seems I could wait around until the textInput event appears, but I'm betting that will be an awfully long time.

Also, I'm somewhat confused about Sicking vs. Zbarsky's comment about DOMCharacterDataModified.  If I understand it correctly, Sicking says that it should not fire at all due to changing the character data of a text element, whereas Zbarsky says it shouldn't fire upon the text being modified - presumably only after focus is lost(?).  Which is more correct, and if it is the latter, what is the utility in waiting, as with onchange?
Sicking and I are saying the same thing.  Typing in a textarea or pasting into it should not fire mutation events.  Period.

Note that there is already an oninput event (which may or may not fire on pastes; if it does not, there are existing bugs on that).
If all you're interested in is the user modifying the text then the oninput attribute should be enough for you. No need to file any bugs on that.

Boris and I am saying the same thing about mutation events. The user modifying the text inside an <textarea> and <input type=text> should not cause any mutation events to fire at any time. The fact that some mutation events do fire is a bug. Feel free to file a bug on this unless one is already filed.

I'm closing this bug as works-for-me since the oninput event is available.
Status: UNCONFIRMED → RESOLVED
Closed: 19 years ago
Resolution: --- → WORKSFORME
Oh, and for checkboxes, radiobuttons, and selects you can use onchange
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: