/** Invoked when an MutationEvent of type 'DOMNodeInserted' is fired. */
  public void handleDOMNodeInsertedEvent(MutationEvent evt) {
    if (evt.getTarget() instanceof Element) {
      Element childElt = (Element) evt.getTarget();

      GVTBuilder builder = ctx.getGVTBuilder();
      GraphicsNode childNode = builder.build(ctx, childElt);
      if (childNode == null) {
        return;
      }

      // There can only be one document element.
      node.add(childNode);
    }
  }
  public void handleEvent(Event evt) {
    super.handleEvent(evt);

    ItsNatHTMLSelectMultImpl comp = getItsNatHTMLSelectMult();
    //        if (comp.isServerUpdatingFromClient())
    //            return;

    String type = evt.getType();
    if (type.equals("DOMCharacterDataModified")) {
      MutationEvent mutEvent = (MutationEvent) evt;
      CharacterData charDataNode = (CharacterData) mutEvent.getTarget();
      HTMLOptionElement option = (HTMLOptionElement) charDataNode.getParentNode();
      int index = option.getIndex();
      String value = charDataNode.getData();
      DefaultListModel dataModel = (DefaultListModel) comp.getListModel();
      if (!value.equals(dataModel.get(index))) dataModel.set(index, value);
    }
  }
  private void mutating(String oldValue, String newValue, short why) {
    if (!reportMutations || parent == null) {
      return;
    }

    // EVENT:  DOMAttrModified, target = parent,
    //	prev/new values provided, also attr name
    MutationEvent event;

    event = (MutationEvent) createEvent("MutationEvents");
    event.initMutationEvent(
        "DOMAttrModified",
        true /* bubbles */,
        false /* nocancel */,
        null,
        oldValue,
        newValue,
        getNodeName(),
        why);
    parent.dispatchEvent(event);
  }
  public void afterRender(Node node, MutationEvent evt) {
    super.afterRender(node, evt);

    String type = evt.getType();
    if (type.equals("DOMNodeInserted")) {
      // Si insertamos un nodo texarea
      // que el usuario creó de la siguiente forma (Java):
      //   Element elem = ...;
      //   Element textarea = document.createElement("textarea");
      //   textarea.setAttribute("value","HOLA \n QUE TAL");
      //   elem.appendChild(textarea);

      // Se inserta el textarea pero el valor visual NO es el dado, sino
      // el contenido del nodo de texto del <textarea> es decir la cadena vacía.
      // Ciertamente al código Java ejecutado en el cliente cmo JavaScript también le pasa lo mismo
      // sin embargo esto no ocurre si fuera un <input> pues el atributo value
      // es la única fuente inicial del valor del control (en textarea el atributo
      // value NO es la fuente inicial del control, es el nodo interno).
      // De igual manera ocurre insertando el textarea via innerHTML
      // con el valor en la propiedad value y sin nodo de texto => manda visualmente el nodo (vacío)
      // de texto.
      // Sin embargo en JavaScript podríamos hacer:
      //   var textarea = document.createElement("textarea");
      //   textarea.value = "HOLA \n QUE TAL";
      //   elem.appendChild(textarea);
      // En este caso el control muestra el valor dado.
      // El problema es que en W3C Java no distinguimos entre propiedad y atributo
      // y sólo se renderiza la propiedad junto al atributo cuando el nodo está ya insertado.

      // Cuando renderizamos via métodos DOM (no innerHTML) usamos
      // normalmente llamadas setAttribute antes de insertar el objeto
      // y la propiedad value no se usa, y cuando es via innerHTML
      // definimos en el markup el atributo pero la propiedad no se toca

      // Por tanto el valor inicial del control lo toma del nodo de texto hijo, no del atributo
      // "value"
      // Si fuera código del usuario no habría problema, él mismo al reinsertar un nodo
      // sería responsable de añadir el texto dentro de <textarea>, pero este no
      // es el caso pues estamos dentro de un componente cuya finalidad es que el usuario
      // no toque el DOM por debajo.

      // Por ello obligamos a que se defina la propiedad "value" incondicionalmente tras la
      // reinserción,
      // lo haremos a través de la definición del atributo "value" que automáticamente ItsNat cambia
      // también la propiedad via JavaScript.
      // Hemos de evitar que la llamada no haga nada al detectar que no ha habido cambio en el valor
      // del atributo
      // por ello llamamos primero con valor "" o similar.

      // Esto NO es necesario en XUL ni en SVG (comprobado en FireFox 3.5, Opera 9.x, Chrome 1.0 y
      // Safari 3.x)
      // pues fuera de X/HTML el nodo de texto del textarea ES IGNORADO, sólo cuenta el
      // atributo/propiedad "value".

      ItsNatHTMLTextAreaUIImpl compUI = getItsNatHTMLTextAreaUIImpl();
      String value = getText(); // Coincide con el valor del atributo "value"
      Element textArea = (Element) node;
      String content = DOMUtilInternal.getTextContent(textArea, false); // Nunca es nulo
      if (content.equals(value)) return; // Nada que hacer
      // Obligamos a que la siguiente sentencia con el valor bueno se ejecute sí o sí
      if (value.equals("")) compUI.setText("-reset-");
      else compUI.setText("");
      compUI.setText(value); // Ahora el valor bueno.
    }
  }