This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 105179
Collapse All | Expand All

(-)visualweb/insync/src/org/netbeans/modules/visualweb/insync/faces/FacesPageUnit.java (-2 / +6 lines)
Lines 1607-1612 Link Here
1607
1607
1608
// <copied from designer/FacesSupport>
1608
// <copied from designer/FacesSupport>
1609
    public static DocumentFragment renderHtml(FacesModel model, MarkupDesignBean bean) {
1609
    public static DocumentFragment renderHtml(FacesModel model, MarkupDesignBean bean) {
1610
        return renderHtml(model, bean, true);
1611
    }
1612
    
1613
    public static DocumentFragment renderHtml(FacesModel model, MarkupDesignBean bean, boolean markRendered) {
1610
    	ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
1614
    	ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
1611
    	try {
1615
    	try {
1612
            FacesModelSet facesModelSet = model.getFacesModelSet();
1616
            FacesModelSet facesModelSet = model.getFacesModelSet();
Lines 1659-1668 Link Here
1659
//        // TODO: Rather than check for the box persistence side-effect flag, should I
1663
//        // TODO: Rather than check for the box persistence side-effect flag, should I
1660
//        // be smarter here and only mark rendered nodes if the target is the DomSynchronizer's
1664
//        // be smarter here and only mark rendered nodes if the target is the DomSynchronizer's
1661
//        // DOM?
1665
//        // DOM?
1662
//        if (markRendered) {
1666
        if (markRendered) {
1663
//            markRenderedNodes(null, df);
1667
//            markRenderedNodes(null, df);
1664
                MarkupService.markRenderedNodes(df);
1668
                MarkupService.markRenderedNodes(df);
1665
//        }
1669
        }
1666
    
1670
    
1667
            return df;
1671
            return df;
1668
    	} finally {    		
1672
    	} finally {    		
(-)visualweb/designer/jsf/src/org/netbeans/modules/visualweb/designer/jsf/DomSynchronizer.java (-27 / +298 lines)
Lines 42-49 Link Here
42
import com.sun.rave.designtime.Position;
42
import com.sun.rave.designtime.Position;
43
import com.sun.rave.designtime.event.DesignContextListener;
43
import com.sun.rave.designtime.event.DesignContextListener;
44
import com.sun.rave.designtime.markup.MarkupDesignBean;
44
import com.sun.rave.designtime.markup.MarkupDesignBean;
45
import java.util.ArrayList;
46
import java.util.HashMap;
47
import java.util.List;
48
import java.util.Map;
45
import org.netbeans.modules.visualweb.designer.html.HtmlTag;
49
import org.netbeans.modules.visualweb.designer.html.HtmlTag;
46
import org.openide.ErrorManager;
50
import org.openide.ErrorManager;
51
import org.w3c.dom.Attr;
52
import org.w3c.dom.NamedNodeMap;
47
53
48
/**
54
/**
49
 * XXX Moved from designer.
55
 * XXX Moved from designer.
Lines 689-708 Link Here
689
//            Node previouslyRendered = ((RaveElement)bean.getElement()).getRendered();
695
//            Node previouslyRendered = ((RaveElement)bean.getElement()).getRendered();
690
            Node previouslyRendered = MarkupService.getRenderedElementForElement(bean.getElement());
696
            Node previouslyRendered = MarkupService.getRenderedElementForElement(bean.getElement());
691
697
692
            if (!processDelete(bean)) {
698
//            if (!processDelete(bean)) {
693
                processRefresh();
699
//                processRefresh();
694
//                webform.getPane().getPaneUI().modelChanged();
700
////                webform.getPane().getPaneUI().modelChanged();
695
                jsfForm.modelChanged();
701
//                jsfForm.modelChanged();
696
702
//
697
                return;
703
//                return;
698
            }
704
//            }
699
705
//
700
            // Insert new version of component
706
//            // Insert new version of component
701
            if (!processInsert(bean)) {
707
//            if (!processInsert(bean)) {
708
//                processRefresh();
709
////                webform.getPane().getPaneUI().modelChanged();
710
//                jsfForm.modelChanged();
711
//
712
//                return;
713
//            }
714
            if (!processUpdate(bean)) {
702
                processRefresh();
715
                processRefresh();
703
//                webform.getPane().getPaneUI().modelChanged();
704
                jsfForm.modelChanged();
716
                jsfForm.modelChanged();
705
706
                return;
717
                return;
707
            }
718
            }
708
719
Lines 712-732 Link Here
712
            Node rendered = MarkupService.getRenderedElementForElement(bean.getElement());
723
            Node rendered = MarkupService.getRenderedElementForElement(bean.getElement());
713
724
714
            if (rendered != null) {
725
            if (rendered != null) {
715
                if (rendered != previouslyRendered) {
726
//                if (rendered != previouslyRendered) {
716
                    Node parent = rendered.getParentNode();
727
//                    Node parent = rendered.getParentNode();
717
//                    PageBox pageBox = webform.getPane().getPaneUI().getPageBox();
728
////                    PageBox pageBox = webform.getPane().getPaneUI().getPageBox();
718
//                    pageBox.changed(rendered, parent, false);
729
////                    pageBox.changed(rendered, parent, false);
719
                    jsfForm.nodeChanged(rendered, parent, false);
730
//                    jsfForm.nodeChanged(rendered, parent, false);
720
                } else {
731
//                } else {
721
                    // We've re-rendered but the bean-reference doesn't point
732
//                    // We've re-rendered but the bean-reference doesn't point
722
                    // to a new node.  This means that the component must have
733
//                    // to a new node.  This means that the component must have
723
                    // supplied bogus component references when rendering.
734
//                    // supplied bogus component references when rendering.
724
                    // Note: With wrong element referenced we're not well off anyway -
735
//                    // Note: With wrong element referenced we're not well off anyway -
725
                    // the component won't be selectable!
736
//                    // the component won't be selectable!
726
//                    PageBox pageBox = webform.getPane().getPaneUI().getPageBox();
737
////                    PageBox pageBox = webform.getPane().getPaneUI().getPageBox();
727
//                    webform.getPane().getPaneUI().modelChanged();
738
////                    webform.getPane().getPaneUI().modelChanged();
728
                    jsfForm.modelChanged();
739
//                    // XXX Now it means, that the node was updated, see the tryUpdateOriginalNode.
729
                }
740
//                    jsfForm.modelChanged();
741
//                }
742
                // Now the original node could be reused (see the tryUpdateOriginalNode).
743
                Node parent = rendered.getParentNode();
744
                jsfForm.nodeChanged(rendered, parent, false);
730
            } else if (previouslyRendered != null) {
745
            } else if (previouslyRendered != null) {
731
                // It was just deleted - for example when you change a component by
746
                // It was just deleted - for example when you change a component by
732
                // switching off its "rendered" property
747
                // switching off its "rendered" property
Lines 793-798 Link Here
793
                    InSyncServiceProvider.get().getHtmlStream(html));
808
                    InSyncServiceProvider.get().getHtmlStream(html));
794
            }
809
            }
795
        }
810
        }
811
    }
812
    
813
    private boolean processUpdate(MarkupDesignBean bean) {
814
        // Deleting
815
//        if (!processDelete(bean)) {
816
//            return false;
817
//        }
818
        
819
        Element element = bean.getElement();
820
        Node rendered = MarkupService.getRenderedElementForElement(element);
821
        if (rendered == null) {
822
            return false;
823
        }
824
825
        Node parent = rendered.getParentNode();
826
        // Find leftmost node
827
        Node curr = rendered.getPreviousSibling();
828
        while (curr != null) {
829
            if (curr.getNodeType() == Node.ELEMENT_NODE) {
830
                Element xel = (Element)curr;
831
                if (MarkupUnit.getMarkupDesignBeanForElement(xel) == bean) {
832
                    rendered = curr;
833
                } else {
834
                    break;
835
                }
836
            }
837
            curr = curr.getPreviousSibling();
838
        }
839
840
        deleteParent = parent;
841
842
        List<Node> originalNodes = new ArrayList<Node>();
843
        Node before = null;
844
        // TODO - I ought to assert here that the parent is in the
845
        // HTML DOM I'm attached to
846
        // Remove all the rendered nodes
847
        while (rendered != null) {
848
//            Node before = rendered.getNextSibling();
849
            before = rendered.getNextSibling();
850
//            parent.removeChild(rendered);
851
            originalNodes.add(rendered);
852
            if (before == null) {
853
                break;
854
            }
855
            // See if I need to delete additional siblings. This is slightly
856
            // tricky because I can't just look at the next sibling. Components
857
            // may separate tags with text nodes that are associated with the
858
            // parent rather than the component being rendered; for example,
859
            // a component renderer may do this:
860
            //    writer.startElement(foo, component);
861
            //    writer.endElement(foo);
862
            //    writer.write("\n");
863
            //    writer.startElement(bar, component);
864
            //    ....
865
            // Note that we want to delete both foo and bar even though there's
866
            // a text node in between which is not associated with the component
867
            // since it's not within a startElement for "component", it's within
868
            // the element for the parent these children (foo and bar) are being
869
            // added to.
870
            // So, my strategy is to peek ahead and see if the next element
871
            // found is associated with the same DesignBean, and if so, delete
872
            // everything up to it.
873
            if (!moreElements(before, bean)) {
874
                break;
875
            }
876
            rendered = before;
877
        }
878
        
879
        // Inserting
880
//        if (!processInsert(bean)) {
881
//            return false;
882
//        }
883
884
        // XXX TODO There is not needed webform here.
885
        // Render the new element
886
        // TODO - this should not necessarily have to involve FacesBeans!
887
        // XXX Do not mark the new nodes as rendered for this case yet.
888
        DocumentFragment df = jsfForm.renderMarkupDesignBean(bean, false);
889
890
        // This seems to be not the correct place.
891
//        // XXX FIXME Is this correct here?
892
//        jsfForm.updateErrorsInComponent();
893
894
        if (DEBUG) {
895
            System.out.println("Got fragment from insert render html: " +
896
                InSyncServiceProvider.get().getHtmlStream(df));
897
        }
898
899
        List<Node> newNodes = new ArrayList<Node>();
900
        
901
        if (df != null) {
902
            // Insert nodes into the rendered dom
903
            NodeList nl = df.getChildNodes();
904
            int num = nl.getLength();
905
906
            if (num == 0) {
907
                // Rendered to nothing. This happens if you switch the Rendered attribute
908
                // to off for example - this comes in as a change request rather than
909
                // as a delete request - but we need to go and update the source element's
910
                // rendered reference since it would now be obsolete in the future
911
                // and we shouldn't attempt to use it
912
//                ((RaveElement)bean.getElement()).setRendered(null);
913
                // XXX FIXME Modifying the data structure!
914
                MarkupService.setRenderedElementForElement(bean.getElement(), null);
915
                return true;
916
            }
917
918
            // Can't remove from a NodeList while iterating over it - causes
919
            // surprises like null siblings. So we need to copy first.
920
            int n = nl.getLength();
921
            Node[] nodes = new Node[n];
922
923
            for (int i = 0; i < n; i++) {
924
                nodes[i] = nl.item(i);
925
            }
926
927
            for (int i = 0; i < n; i++) {
928
                Node nn = nodes[i];
929
                if (DEBUG) {
930
                    if (nn != null) {
931
                        System.out.println("next node is: " + InSyncServiceProvider.get().getHtmlStream(nn));
932
                        System.out.println("Fragment is now: " + InSyncServiceProvider.get().getHtmlStream(df));
933
                    }
934
                }
935
936
                if (nn != null) {
937
                    assert !isJspNode(nn);
938
//                    parent.insertBefore(nn, before);
939
                    newNodes.add(nn);
940
                }
941
            }
942
        } else {
943
            ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL,
944
                    new NullPointerException("Null DocumentFragment for JsfForm, jsfForm=" + jsfForm)); // NOI18N
945
            return false;
946
        }
947
948
        if (originalNodes.size() == 1 && newNodes.size() == 1) {
949
            Node originalNode = originalNodes.get(0);
950
            Node newNode = newNodes.get(0);
951
            if (tryUpdateOriginalNode(originalNode, newNode)) {
952
                // XXX The original nodes are updated, do not mark the new as rendered, they are not used.
953
                return true;
954
            } else {
955
                parent.replaceChild(newNode, originalNode);
956
            }
957
        } else {
958
            for (Node toRemove : originalNodes) {
959
                parent.removeChild(toRemove);
960
            }
961
            for (Node toAdd : newNodes) {
962
                parent.insertBefore(toAdd, before);
963
            }
964
        }
965
        
966
        // XXX Mark the newly used nodes as rendered.
967
        MarkupService.markRenderedNodes(df);
968
        
969
        return true;
970
    }
971
    
972
    private static boolean tryUpdateOriginalNode(Node originalNode, Node newNode) {
973
        if (originalNode.getNodeType() != newNode.getNodeType()) {
974
            return false;
975
        }
976
        
977
        if (originalNode.isEqualNode(newNode)) {
978
            return true;
979
        }
980
        
981
        // Update children
982
        NodeList originalNodeChildren = originalNode.getChildNodes();
983
        NodeList newNodeChildren = newNode.getChildNodes();
984
        if (originalNodeChildren == null) {
985
            if (newNodeChildren != null) {
986
                return false;
987
            }
988
        } else {
989
            if (newNodeChildren == null) {
990
                return false;
991
            }
992
            int originalNodeChildrenSize = originalNodeChildren.getLength();
993
            int newNodeChildrenSize = newNodeChildren.getLength();
994
            if (originalNodeChildrenSize != newNodeChildrenSize) {
995
                return false;
996
            }
997
            
998
            for (int i = 0; i < originalNodeChildrenSize; i++) {
999
                boolean childOK = tryUpdateOriginalNode(originalNodeChildren.item(i), newNodeChildren.item(i));
1000
                if (!childOK) {
1001
                    return false;
1002
                }
1003
            }
1004
        }
1005
        
1006
        // Update value.
1007
        String originalValue = originalNode.getNodeValue();
1008
        String newValue = newNode.getNodeValue();
1009
        if ((originalValue == null && newValue != null)
1010
        || (originalValue != null && !originalValue.equals(newValue))) {
1011
            originalNode.setNodeValue(newValue);
1012
        }
1013
        
1014
        // Update attributes.
1015
        if (originalNode instanceof Element && newNode instanceof Element) {
1016
            Element originalElement = (Element)originalNode;
1017
            Element newElement = (Element)newNode;
1018
            
1019
            Map<String, Attr> originalMap = getAttributesMap(originalElement);
1020
            Map<String, Attr> newMap = getAttributesMap(newElement);
1021
            
1022
            // Remove redundant attributes.
1023
            for (String name : originalMap.keySet()) {
1024
                if (newMap.containsKey(name)) {
1025
                    continue;
1026
                }
1027
                originalElement.removeAttribute(name);
1028
            }
1029
            // Add/update the remaining attributes.
1030
            for (String name : newMap.keySet()) {
1031
                Attr newAttribute = newMap.get(name);
1032
                Attr originalAttribute = originalMap.get(name);
1033
                
1034
                if (originalAttribute == null) {
1035
                    originalElement.setAttributeNode((Attr)newAttribute.cloneNode(false));
1036
                } else {
1037
                    String oldAttributeValue = originalAttribute.getValue();
1038
                    String newAttributeValue = newAttribute.getValue();
1039
                    if (newAttributeValue == null) {
1040
                        if (oldAttributeValue != null) {
1041
                            originalElement.removeAttribute(name);
1042
                        }
1043
                    } else {
1044
                        if (!newAttributeValue.equals(oldAttributeValue)) {
1045
                            originalElement.setAttributeNode((Attr)newAttribute.cloneNode(false));
1046
                        }
1047
                    }
1048
                }
1049
            }
1050
        }
1051
        
1052
        return true;
1053
    }
1054
    
1055
    private static Map<String, Attr> getAttributesMap(Element element) {
1056
        NamedNodeMap attributes = element.getAttributes();
1057
        Map<String, Attr> attributesMap = new HashMap<String, Attr>();
1058
        int size = attributes == null ? 0 : attributes.getLength();
1059
        for (int i = 0; i < size; i++) {
1060
            Node attr = attributes.item(i);
1061
            if (attr instanceof Attr) {
1062
                Attr attribute = (Attr)attr;
1063
                attributesMap.put(attribute.getName(), attribute);
1064
            }
1065
        }
1066
        return attributesMap;
796
    }
1067
    }
797
1068
798
    /**
1069
    /**
(-)visualweb/designer/jsf/src/org/netbeans/modules/visualweb/designer/jsf/JsfForm.java (-2 / +5 lines)
Lines 2707-2715 Link Here
2707
        }
2707
        }
2708
    } // End of DesignProjectListener.
2708
    } // End of DesignProjectListener.
2709
2709
2710
    
2711
    DocumentFragment renderMarkupDesignBean(MarkupDesignBean markupDesignBean) {
2710
    DocumentFragment renderMarkupDesignBean(MarkupDesignBean markupDesignBean) {
2712
        return FacesPageUnit.renderHtml(getFacesModel(), markupDesignBean);
2711
        return renderMarkupDesignBean(markupDesignBean, true);
2712
    }
2713
    
2714
    DocumentFragment renderMarkupDesignBean(MarkupDesignBean markupDesignBean, boolean markRendered) {
2715
        return FacesPageUnit.renderHtml(getFacesModel(), markupDesignBean, markRendered);
2713
    }
2716
    }
2714
    
2717
    
2715
    LiveUnit getLiveUnit() {
2718
    LiveUnit getLiveUnit() {

Return to bug 105179