From 9319e4d686d5d4b9a45fbea3d8d0236ca41a6133 Mon Sep 17 00:00:00 2001 From: Jumper Chen Date: Wed, 25 Sep 2024 17:58:46 +0800 Subject: [PATCH] ZK-5792: fullfill doesn't create all components in a forEach --- .../org/zkoss/zk/ui/AbstractComponent.java | 11 +++++ .../org/zkoss/zk/ui/impl/UiEngineImpl.java | 6 +++ .../org/zkoss/zk/ui/impl/UiVisualizer.java | 17 ++------ .../org/zkoss/zk/ui/sys/ComponentCtrl.java | 14 ++++-- .../java/org/zkoss/zk/ui/sys/Visualizer.java | 15 ++++++- zkdoc/release-note | 1 + zktest/src/main/webapp/test2/B101-ZK-5792.zul | 43 +++++++++++++++++++ .../src/main/webapp/test2/config.properties | 1 + .../zktest/zats/test2/B101_ZK_5792Test.java | 36 ++++++++++++++++ 9 files changed, 125 insertions(+), 19 deletions(-) create mode 100644 zktest/src/main/webapp/test2/B101-ZK-5792.zul create mode 100644 zktest/src/test/java/org/zkoss/zktest/zats/test2/B101_ZK_5792Test.java diff --git a/zk/src/main/java/org/zkoss/zk/ui/AbstractComponent.java b/zk/src/main/java/org/zkoss/zk/ui/AbstractComponent.java index e2400b1b19e..0268fb262d6 100644 --- a/zk/src/main/java/org/zkoss/zk/ui/AbstractComponent.java +++ b/zk/src/main/java/org/zkoss/zk/ui/AbstractComponent.java @@ -3367,6 +3367,12 @@ public void set(Component o) { //Cloneable// public Object clone() { + // remove first. + Collection callbacks = new ArrayList<>(getCallback(AFTER_CLONED)); + for (Callback callback : new ArrayList(callbacks)) { + removeCallback(AFTER_CLONED, callback); + } + final AbstractComponent clone; try { clone = (AbstractComponent) super.clone(); @@ -3396,6 +3402,11 @@ public Object clone() { if (_auxinf != null) _auxinf.initClone(clone, clone._auxinf); + // invoke after cloned. + for (Callback callback : new ArrayList(callbacks)) { + callback.call(clone); + } + return clone; } diff --git a/zk/src/main/java/org/zkoss/zk/ui/impl/UiEngineImpl.java b/zk/src/main/java/org/zkoss/zk/ui/impl/UiEngineImpl.java index 088290cfdd7..be74c7ae9e9 100644 --- a/zk/src/main/java/org/zkoss/zk/ui/impl/UiEngineImpl.java +++ b/zk/src/main/java/org/zkoss/zk/ui/impl/UiEngineImpl.java @@ -112,6 +112,7 @@ import org.zkoss.zk.ui.sys.UiEngine; import org.zkoss.zk.ui.sys.Visualizer; import org.zkoss.zk.ui.sys.WebAppCtrl; +import org.zkoss.zk.ui.util.Callback; import org.zkoss.zk.ui.util.ComponentCloneListener; import org.zkoss.zk.ui.util.Composer; import org.zkoss.zk.ui.util.ComposerExt; @@ -2443,6 +2444,10 @@ private FulfillListener(String fulfill, ComponentInfo compInfo, Component comp) _compInfo = compInfo; _comp = comp; + // Fix 5792 + ((ComponentCtrl) _comp).addCallback(ComponentCtrl.AFTER_CLONED, + (Callback) data -> willClone((Component) data)); + init(); for (int j = _targets.length; --j >= 0;) @@ -2523,6 +2528,7 @@ public Object willClone(Component comp) { } catch (CloneNotSupportedException e) { throw new InternalError(); } + // TODO: the original implementation assumed the comp is the _comp, but this listener is added to _targets, not _comp. clone._comp = comp; clone.init(); return clone; diff --git a/zk/src/main/java/org/zkoss/zk/ui/impl/UiVisualizer.java b/zk/src/main/java/org/zkoss/zk/ui/impl/UiVisualizer.java index a853bf03ea9..503bdd1d88d 100644 --- a/zk/src/main/java/org/zkoss/zk/ui/impl/UiVisualizer.java +++ b/zk/src/main/java/org/zkoss/zk/ui/impl/UiVisualizer.java @@ -1,9 +1,9 @@ /* UiVisualizer.java Purpose: - + Description: - + History: Tue Jun 14 10:57:48 2005, Created by tomyeh @@ -295,15 +295,6 @@ public void clearSmartUpdate(Component comp) { _smartUpdated.remove(comp); } - /** Sets whether to disable the update of the client widget. - * By default, if a component is attached to a page, modifications that - * change the visual representation will be sent to the client to - * ensure the consistency. - * - * @return whether it has been disabled before this invocation, i.e., - * the previous disable status - * @since 3.6.2 - */ public boolean disableClientUpdate(Component comp, boolean disable) { if (disable) { if (_updDisabled == null) @@ -1119,7 +1110,7 @@ public void setAbortingReason(AbortingReason reason) { } /** Returns the reason to aborting, or null if no aborting at all. - * + * * @see #setAbortingReason */ public AbortingReason getAbortingReason() { @@ -1127,7 +1118,7 @@ public AbortingReason getAbortingReason() { } /** Returns whether it is aborting. - * + * *

The execution is aborting if {@link #getAbortingReason} returns * not null and the returned reason's {@link AbortingReason#isAborting} * is true. diff --git a/zk/src/main/java/org/zkoss/zk/ui/sys/ComponentCtrl.java b/zk/src/main/java/org/zkoss/zk/ui/sys/ComponentCtrl.java index 0f1543de029..0bf7c0b7fb3 100644 --- a/zk/src/main/java/org/zkoss/zk/ui/sys/ComponentCtrl.java +++ b/zk/src/main/java/org/zkoss/zk/ui/sys/ComponentCtrl.java @@ -1,9 +1,9 @@ /* ComponentCtrl.java Purpose: - + Description: - + History: Mon May 30 21:06:56 2005, Created by tomyeh @@ -75,6 +75,12 @@ public interface ComponentCtrl { */ public static String AFTER_PARENT_CHANGED = "afterParentChanged"; + /** + * For after cloned callback, use in {@link #addCallback(String, Callback)} + * @since 10.1.0 + */ + public static String AFTER_CLONED = "afterCloned"; + /** Sets the component definition. * *

The component definition affects how a component behaves. @@ -234,7 +240,7 @@ public interface ComponentCtrl { * and the client must send it back even if no listener is registered. */ public static final int CE_IMPORTANT = 0x0001; - /** Returned by {@link #getClientEvents} to indicate the event is + /** Returned by {@link #getClientEvents} to indicate the event is * no deferrable, i.e., the event has to be sent back immediately. * It is meaningful only used with {@link #CE_IMPORTANT} */ @@ -247,7 +253,7 @@ public interface ComponentCtrl { * can be ignored by the server when the server receives the same AU * requests but not processed yet. * In other words, the server will remove the duplicate AU requests - * if it was queued. + * if it was queued. */ public static final int CE_DUPLICATE_IGNORE = 0x2000; /** Returned by {@link #getClientEvents} to indicate the event diff --git a/zk/src/main/java/org/zkoss/zk/ui/sys/Visualizer.java b/zk/src/main/java/org/zkoss/zk/ui/sys/Visualizer.java index 2c893890715..8939663e5c2 100644 --- a/zk/src/main/java/org/zkoss/zk/ui/sys/Visualizer.java +++ b/zk/src/main/java/org/zkoss/zk/ui/sys/Visualizer.java @@ -1,9 +1,9 @@ /* Visualizer.java Purpose: - + Description: - + History: Fri Jan 20 23:06:03 2006, Created by tomyeh @@ -85,4 +85,15 @@ public interface Visualizer { * @since 10.0.0 */ public void enable(); + + /** Sets whether to disable the update of the client widget. + * By default, if a component is attached to a page, modifications that + * change the visual representation will be sent to the client to + * ensure the consistency. + * + * @return whether it has been disabled before this invocation, i.e., + * the previous disable status + * @since 10.1.0 + */ + public boolean disableClientUpdate(Component comp, boolean disable); } diff --git a/zkdoc/release-note b/zkdoc/release-note index b983fc49809..9929c050e00 100644 --- a/zkdoc/release-note +++ b/zkdoc/release-note @@ -25,6 +25,7 @@ ZK 10.1.0 ZK-5589: a checkmark of a checkbox inside a caption is shifted unexpectedly ZK-5455: Popup causes error if parent is removed during popup opening animation ZK-5551: Shadow Component ForEach adds fullfil listeners everytime the syncModel method is called, doesn't clear them if component is removed + ZK-5792: fullfill doesn't create all components in a forEach * Upgrade Notes + Remove Htmls.encodeJavaScript(), Strings.encodeJavaScript(), Strings.escape() with Strings.ESCAPE_JAVASCRIPT, and replace them with OWASP Java Encoder APIs instead. diff --git a/zktest/src/main/webapp/test2/B101-ZK-5792.zul b/zktest/src/main/webapp/test2/B101-ZK-5792.zul new file mode 100644 index 00000000000..9405c35bc93 --- /dev/null +++ b/zktest/src/main/webapp/test2/B101-ZK-5792.zul @@ -0,0 +1,43 @@ + + + + + + +