Fix bugs with spurious dirtyFlagChange events

Fix two bugs with spurious dirtyFlagChange events:

* Document ctor always fires it, even though isDirty stays false whole time.  This causes a huge pile of spurious notifications on startup, for example (due to JSCodeHints newing up a ton of Documents).
* Calling refreshText() (e.g. syncing external changes) always fires a pair of isDirty->true,->false (causing longstanding bug #502)

This also adds unit tests for various cases around Document dirty/undo state.