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.