Fixes #16424.  CHeck to see if the textbox value is nonempty before removing the placeHolder.
Move widget metadata collection from _applyAttributes() and _onMap() to new _introspect() method, which is hopefully faster since it only scans the prototype properties once.   Also, collect list of all properties with custom getters or setters, and pre-generate custom setter functions for custom setters that are strings or objects (ex: _setFooAttr: "focusNode").   Refs #16693 !strict.
Replace _attrToDom() method with domSetter() method that generates a custom setter function to map a value to a specified DOMNode's attribute, innerHTML, etc.  Use domSetter() when generating this._constructor.props{} hash.

In the future, for performance, probably the existing non-function setters in prototypes (ex: _setLabelAttr: "labelNode") should be changed to use domSetter() directly, so that the setter in the superclass can be reused by the subclasses.   Alternately, implement caching so domSetter() returns a previously created setter when possible.

Refs #16693 !strict.
_WidgetBase support for ES5 setters and getters
trying to get ES5 setters/getters to work in form widgets

When _setBlurValue() is called, this.focused is already false.  But _setBlurValue() effectively temporarily sets this.focused back to true, in order to get the NumberTextBox's value.  Because_getValueAttr() calls parse(), and parse() branches depending on this.focused, expecting a string like "1.2" if focused or "1.200" or "$1.20" (for CurrencyTextBox) if not focused.

This doesn't work well when a widget has ES5 native setter/getters.   Calling lang.mixin({}, this, {focused: true}) will unwantedly calling getters on this, and lang.delegate(this, {focused: true}) will actually modify "this" by calling the custom setter for this.focus.

The other minor related issue I noticed is that watch("value", ...) doesn't work correctly unless intermediateChanges == true.    When intermediateChanges == false, watch("value", func) won't call func until blur, which doesn't match the spec of how watch() works.

So, got rid of the _getValueAttr(), instead always keeping this.value up to date.   We already recompute the value on every keystroke because each keystroke calls _refreshState(), which calls MappedTextBox.validate(), which calls MappedTextBox.toString(), which, by calling get("value"), computes the value.  Plus when intermediateChanges == true, _onInput()  also calls get("value").

Still some issues in DateTextBox:

old code:
  - blank DateTextBox.get("value") --> null (bug?)
  - gibberish DateTextBox.get("value") --> undefined (expected?)
new code:
  - blank DateTextBox.get("value") --> NaN (correct?)
  - gibberish DateTextBox.get("value") --> NaN (bug?)
  - bug: blurring DateTextBox w/gibberish value clears it

Plus a failure in the FilteringSelect test.