ICEfaces
  1. ICEfaces
  2. ICE-6341

Excessive DOM update for select components

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Major Major
    • Resolution: Won't Fix
    • Affects Version/s: 2.0-Beta2
    • Fix Version/s: 3.2
    • Component/s: Framework
    • Labels:
      None
    • Environment:
      ICEfaces, h:selectManyMenu
    • Assignee Priority:
      P3

      Description


      Mojarra select component renderers buffer the output then write the body of the select (containing the options) as a single string:


              <option value="bean.selection.cars.car1.value">bean.selection.cars.car1.value</option>
      <option value="bean.selection.cars.car2.value">bean.selection.cars.car2.value</option>
      <option value="bean.selection.cars.car3.value">bean.selection.cars.car3.value</option>
      <option value="bean.selection.cars.car4.value">bean.selection.cars.car4.value</option>
      <option value="bean.selection.cars.car5.value">bean.selection.cars.car5.value</option>

      This causes problems during applyBrowserChanges() as the "oldDOM" values cannot be modified by the submitted values. This results in the oldDOM not being updated to contain the browser submitted values, typically causing a larger DOM diff than necessary. In other cases, it may result in an inability to clear browser values.

        Activity

        Hide
        Ted Goddard added a comment -

        Hacked up DOMPartialViewContext that implements regex-based processing for the option children:

        +++ src/main/java/org/icefaces/impl/context/DOMPartialViewContext.java (working copy)
        @@ -53,6 +53,8 @@
        import java.util.Iterator;
        import java.util.List;
        import java.util.Map;
        +import java.util.regex.Matcher;
        +import java.util.regex.Pattern;
        import java.util.logging.Level;
        import java.util.logging.Logger;

        @@ -60,6 +62,8 @@
        private static final String JAVAX_FACES_VIEW_HEAD = "javax.faces.ViewHead";
        private static final String JAVAX_FACES_VIEW_BODY = "javax.faces.ViewBody";
        private static final Logger log = Logger.getLogger(DOMPartialViewContext.class.getName());
        + private static String OPTION_PATTERN = "option value=\"([^\"])\"\\s(selected=\"[^\"]\")";
        + private Pattern optionPattern;

        private PartialViewContext wrapped;
        protected FacesContext facesContext;
        @@ -69,6 +73,7 @@
        public DOMPartialViewContext(PartialViewContext partialViewContext, FacesContext facesContext)

        { this.wrapped = partialViewContext; this.facesContext = facesContext; + optionPattern = Pattern.compile(OPTION_PATTERN, Pattern.DOTALL); }

        @Override
        @@ -139,7 +144,12 @@
        facesContext.setResponseWriter(writer);

        Document oldDOM = writer.getOldDocument();
        +//System.out.println("---before applyBrowserChanges---");
        +//System.out.println(DOMUtils.nodeToString(oldDOM));
        applyBrowserChanges(ec.getRequestParameterValuesMap(), oldDOM);
        +//System.out.println("---after applyBrowserChanges---");
        +//System.out.println(DOMUtils.nodeToString(oldDOM));
        +//System.out.println("-------------");

        UIViewRoot viewRoot = facesContext.getViewRoot();
        Node[] diffs = new Node[0];
        @@ -158,6 +168,11 @@

        if (oldDOM != null && newDOM != null)

        { diffs = domDiff(oldDOM, newDOM); +//System.out.println("----oldDOM----"); +//System.out.println(DOMUtils.nodeToString(oldDOM)); +//System.out.println("----newDOM----"); +//System.out.println(DOMUtils.nodeToString(newDOM)); +//System.out.println("-------------"); }

        } else {
        writer.startSubtreeRendering();
        @@ -396,18 +411,76 @@
        for (int i = 0; i < selectElementsLength; i++) {
        Element selectElement = (Element) selectElements.item;
        String id = selectElement.getAttribute("id");
        +System.out.println("looking at select " + id);
        if (!"".equals(id) && parameters.containsKey(id)) {
        List values = Arrays.asList((String[]) parameters.get(id));

        +// NodeList optionElements =
        +// selectElement.getElementsByTagName("option");
        NodeList optionElements =

        • selectElement.getElementsByTagName("option");
          + selectElement.getChildNodes();
          int optionElementsLength = optionElements.getLength();
          +System.out.println("select has options " + optionElementsLength);
          + if (1 == optionElementsLength) {
          + Node singleNode = optionElements.item(0);
          + if (singleNode instanceof org.w3c.dom.Text) {
          + String selectText = singleNode.getNodeValue();
          +System.out.println("text in the select \n" + selectText);
          + String output = selectText;
          +
          +
          + Matcher optionMatcher = optionPattern.matcher(selectText);
          + while (optionMatcher.find())
          Unknown macro: {+ String optionValue = optionMatcher.group(1);+ String selected = optionMatcher.group(2);+ if ((null != selected) && !values.contains(optionValue)) { +System.out.println("clearing " + optionValue); + output = output.replace("value=\"" + optionValue + "\"" + " selected=\"true\"", "value=\"" + optionValue + "\""); + } + if ((null == selected) && values.contains(optionValue)) { +System.out.println("setting " + optionValue); + output = output.replace("value=\"" + optionValue + "\"", "value=\"" + optionValue + "\"" + " selected=\"true\""); + } + }

          +System.out.println(output);
          +
          +
          + singleNode.setNodeValue(output);
          +
          +
          + }
          + }
          for (int j = 0; j < optionElementsLength; j++)

          Unknown macro: {+ if (!(optionElements.item(j) instanceof Element)) { + continue; + } Element optionElement = (Element) optionElements.item(j);+System.out.println(" looking at " + optionElement.getAttribute("value")); if (values.contains(optionElement.getAttribute("value"))) { optionElement.setAttribute("selected", "selected"); +System.out.println("set selected true on " + optionElement); } else { optionElement.removeAttribute("selected"); +System.out.println("removed select element " + optionElement); } }

          }

        Show
        Ted Goddard added a comment - Hacked up DOMPartialViewContext that implements regex-based processing for the option children: +++ src/main/java/org/icefaces/impl/context/DOMPartialViewContext.java (working copy) @@ -53,6 +53,8 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.logging.Level; import java.util.logging.Logger; @@ -60,6 +62,8 @@ private static final String JAVAX_FACES_VIEW_HEAD = "javax.faces.ViewHead"; private static final String JAVAX_FACES_VIEW_BODY = "javax.faces.ViewBody"; private static final Logger log = Logger.getLogger(DOMPartialViewContext.class.getName()); + private static String OPTION_PATTERN = "option value=\"( [^\"] )\"\\s (selected=\" [^\"] \") "; + private Pattern optionPattern; private PartialViewContext wrapped; protected FacesContext facesContext; @@ -69,6 +73,7 @@ public DOMPartialViewContext(PartialViewContext partialViewContext, FacesContext facesContext) { this.wrapped = partialViewContext; this.facesContext = facesContext; + optionPattern = Pattern.compile(OPTION_PATTERN, Pattern.DOTALL); } @Override @@ -139,7 +144,12 @@ facesContext.setResponseWriter(writer); Document oldDOM = writer.getOldDocument(); +//System.out.println("--- before applyBrowserChanges ---"); +//System.out.println(DOMUtils.nodeToString(oldDOM)); applyBrowserChanges(ec.getRequestParameterValuesMap(), oldDOM); +//System.out.println("--- after applyBrowserChanges ---"); +//System.out.println(DOMUtils.nodeToString(oldDOM)); +//System.out.println("-------------"); UIViewRoot viewRoot = facesContext.getViewRoot(); Node[] diffs = new Node [0] ; @@ -158,6 +168,11 @@ if (oldDOM != null && newDOM != null) { diffs = domDiff(oldDOM, newDOM); +//System.out.println("----oldDOM----"); +//System.out.println(DOMUtils.nodeToString(oldDOM)); +//System.out.println("----newDOM----"); +//System.out.println(DOMUtils.nodeToString(newDOM)); +//System.out.println("-------------"); } } else { writer.startSubtreeRendering(); @@ -396,18 +411,76 @@ for (int i = 0; i < selectElementsLength; i++) { Element selectElement = (Element) selectElements.item ; String id = selectElement.getAttribute("id"); +System.out.println("looking at select " + id); if (!"".equals(id) && parameters.containsKey(id)) { List values = Arrays.asList((String[]) parameters.get(id)); +// NodeList optionElements = +// selectElement.getElementsByTagName("option"); NodeList optionElements = selectElement.getElementsByTagName("option"); + selectElement.getChildNodes(); int optionElementsLength = optionElements.getLength(); +System.out.println("select has options " + optionElementsLength); + if (1 == optionElementsLength) { + Node singleNode = optionElements.item(0); + if (singleNode instanceof org.w3c.dom.Text) { + String selectText = singleNode.getNodeValue(); +System.out.println("text in the select \n" + selectText); + String output = selectText; + + + Matcher optionMatcher = optionPattern.matcher(selectText); + while (optionMatcher.find()) Unknown macro: {+ String optionValue = optionMatcher.group(1);+ String selected = optionMatcher.group(2);+ if ((null != selected) && !values.contains(optionValue)) { +System.out.println("clearing " + optionValue); + output = output.replace("value=\"" + optionValue + "\"" + " selected=\"true\"", "value=\"" + optionValue + "\""); + } + if ((null == selected) && values.contains(optionValue)) { +System.out.println("setting " + optionValue); + output = output.replace("value=\"" + optionValue + "\"", "value=\"" + optionValue + "\"" + " selected=\"true\""); + } + } +System.out.println(output); + + + singleNode.setNodeValue(output); + + + } + } for (int j = 0; j < optionElementsLength; j++) Unknown macro: {+ if (!(optionElements.item(j) instanceof Element)) { + continue; + } Element optionElement = (Element) optionElements.item(j);+System.out.println(" looking at " + optionElement.getAttribute("value")); if (values.contains(optionElement.getAttribute("value"))) { optionElement.setAttribute("selected", "selected"); +System.out.println("set selected true on " + optionElement); } else { optionElement.removeAttribute("selected"); +System.out.println("removed select element " + optionElement); } } }
        Hide
        Ted Goddard added a comment -

        Better solution is an ICEfaces select component that does not behave in this way.

        Show
        Ted Goddard added a comment - Better solution is an ICEfaces select component that does not behave in this way.
        Hide
        Ken Fyten added a comment - - edited

        Marking this as Won't Fix as the future solution lies with new ace:selection type component(s).

        Show
        Ken Fyten added a comment - - edited Marking this as Won't Fix as the future solution lies with new ace:selection type component(s).

          People

          • Assignee:
            Ted Goddard
            Reporter:
            Ted Goddard
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: