Cool and long awaited feature. On Sun, Mar 19, 2017 at 5:08 PM, <thiag...@apache.org> wrote: > Repository: tapestry-5 > Updated Branches: > refs/heads/master aaa0d550a -> 6b4ca30b8 > > > TAP5-2225 > > Create client-side API to call a component's event handler methods > > Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo > Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/6b4ca30b > Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/6b4ca30b > Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/6b4ca30b > > Branch: refs/heads/master > Commit: 6b4ca30b83bed396006107f5008a3781eee1db86 > Parents: aaa0d55 > Author: Thiago H. de Paula Figueiredo <thi...@arsmachina.com.br> > Authored: Sun Mar 19 13:07:00 2017 -0300 > Committer: Thiago H. de Paula Figueiredo <thi...@arsmachina.com.br> > Committed: Sun Mar 19 13:07:00 2017 -0300 > > ---------------------------------------------------------------------- > .../org/apache/tapestry5/TapestryConstants.java | 11 ++ > .../tapestry5/annotations/PublishEvent.java | 50 ++++++ > .../corelib/mixins/PublishServerSideEvents.java | 151 +++++++++++++++++++ > .../tapestry5/internal/InternalConstants.java | 17 +++ > .../internal/transform/OnEventWorker.java | 54 ++++++- > .../org/apache/tapestry5/t5-core-dom.coffee | 56 +++++++ > .../src/test/app1/PublishEventDemo.tml | 7 + > .../components/PublishEventDemoComponent.java | 32 ++++ > .../components/PublishEventDemoComponent2.java | 32 ++++ > .../tapestry5/integration/app1/pages/Index.java | 21 +-- > .../app1/pages/PublishEventDemo.java | 49 ++++++ > .../META-INF/assets/PublishEventDemo.js | 11 ++ > .../components/PublishEventDemoComponent.tml | 3 + > .../components/PublishEventDemoComponent2.tml | 4 + > 14 files changed, 482 insertions(+), 16 deletions(-) > ---------------------------------------------------------------------- > > > http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6b4ca30b/tapestry-core/src/main/java/org/apache/tapestry5/TapestryConstants.java > ---------------------------------------------------------------------- > diff --git > a/tapestry-core/src/main/java/org/apache/tapestry5/TapestryConstants.java > b/tapestry-core/src/main/java/org/apache/tapestry5/TapestryConstants.java > index ad1495a..cab8c46 100644 > --- a/tapestry-core/src/main/java/org/apache/tapestry5/TapestryConstants.java > +++ b/tapestry-core/src/main/java/org/apache/tapestry5/TapestryConstants.java > @@ -12,6 +12,7 @@ > > package org.apache.tapestry5; > > +import org.apache.tapestry5.annotations.PublishEvent; > import org.apache.tapestry5.internal.structure.PageResetListener; > import org.apache.tapestry5.services.ComponentEventLinkEncoder; > > @@ -68,4 +69,14 @@ public class TapestryConstants > */ > public static final String DISABLE_JAVASCRIPT_MINIMIZATION = > "tapestry.disable-javascript-minimization"; > > + /** > + * Name of the HTML data attribute which contains information about > component events > + * published by using the {@linkplain PublishEvent} annotation > + * in a component event handler method. > + * > + * @see PublishEvent > + * @since 5.4.2 > + */ > + public static final String COMPONENT_EVENTS_ATTRIBUTE_NAME = > "data-component-events"; > + > } > > http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6b4ca30b/tapestry-core/src/main/java/org/apache/tapestry5/annotations/PublishEvent.java > ---------------------------------------------------------------------- > diff --git > a/tapestry-core/src/main/java/org/apache/tapestry5/annotations/PublishEvent.java > > b/tapestry-core/src/main/java/org/apache/tapestry5/annotations/PublishEvent.java > new file mode 100644 > index 0000000..18239d4 > --- /dev/null > +++ > b/tapestry-core/src/main/java/org/apache/tapestry5/annotations/PublishEvent.java > @@ -0,0 +1,50 @@ > +// Licensed under the Apache License, Version 2.0 (the "License"); > +// you may not use this file except in compliance with the License. > +// You may obtain a copy of the License at > +// > +// http://www.apache.org/licenses/LICENSE-2.0 > +// > +// Unless required by applicable law or agreed to in writing, software > +// distributed under the License is distributed on an "AS IS" BASIS, > +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > +// See the License for the specific language governing permissions and > +// limitations under the License. > + > +package org.apache.tapestry5.annotations; > + > +import static java.lang.annotation.RetentionPolicy.RUNTIME; > +import static > org.apache.tapestry5.ioc.annotations.AnnotationUseContext.COMPONENT; > +import static org.apache.tapestry5.ioc.annotations.AnnotationUseContext.PAGE; > + > +import java.lang.annotation.Documented; > +import java.lang.annotation.ElementType; > +import java.lang.annotation.Retention; > +import java.lang.annotation.Target; > + > +import org.apache.tapestry5.ioc.annotations.UseWith; > + > +/** > + * Marks an event handler method to be published as an event to be called in > JavaScript > + * through the <code>t5/core/triggerServerEvent</code> function. > + * > + * The event information is stored in JSON format inside the > + * {@value > org.apache.tapestry5.TapestryConstants#COMPONENT_EVENTS_ATTRIBUTE_NAME} > attribute. > + * > + * When used in a component method, the component must render at least one > element, > + * and that's what get the > + * {@value > org.apache.tapestry5.TapestryConstants#COMPONENT_EVENTS_ATTRIBUTE_NAME} > attribute above. > + * If it doesn't, an exception will be thrown. > + * > + * When used in a page method, the page must render an <body> element, > + * {@value > org.apache.tapestry5.TapestryConstants#COMPONENT_EVENTS_ATTRIBUTE_NAME}. If > it doesn't, > + * an exception will be thrown. > + * > + * @since 5.4.2 > + */ > +@Target(ElementType.METHOD) > +@Retention(RUNTIME) > +@Documented > +@UseWith({ COMPONENT, PAGE }) > +public @interface PublishEvent > +{ > +} > > http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6b4ca30b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/mixins/PublishServerSideEvents.java > ---------------------------------------------------------------------- > diff --git > a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/mixins/PublishServerSideEvents.java > > b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/mixins/PublishServerSideEvents.java > new file mode 100644 > index 0000000..3d73746 > --- /dev/null > +++ > b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/mixins/PublishServerSideEvents.java > @@ -0,0 +1,151 @@ > +// Licensed under the Apache License, Version 2.0 (the "License"); > +// you may not use this file except in compliance with the License. > +// You may obtain a copy of the License at > +// > +// http://www.apache.org/licenses/LICENSE-2.0 > +// > +// Unless required by applicable law or agreed to in writing, software > +// distributed under the License is distributed on an "AS IS" BASIS, > +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > +// See the License for the specific language governing permissions and > +// limitations under the License. > + > +package org.apache.tapestry5.corelib.mixins; > + > +import org.apache.tapestry5.ComponentResources; > +import org.apache.tapestry5.MarkupWriter; > +import org.apache.tapestry5.MarkupWriterListener; > +import org.apache.tapestry5.TapestryConstants; > +import org.apache.tapestry5.annotations.PublishEvent; > +import org.apache.tapestry5.dom.Element; > +import org.apache.tapestry5.internal.InternalConstants; > +import org.apache.tapestry5.ioc.annotations.Inject; > +import org.apache.tapestry5.json.JSONArray; > +import org.apache.tapestry5.json.JSONObject; > +import org.apache.tapestry5.model.ComponentModel; > + > +/** > + * Tapestry internal mixin used to implement the {@link PublishEvent} event > logic. Don't use directly. > + */ > +public class PublishServerSideEvents > +{ > + > + private static final String PUBLISH_COMPONENT_EVENTS_URL_PROPERTY = > InternalConstants.PUBLISH_COMPONENT_EVENTS_URL_PROPERTY; > + private static final String COMPONENT_EVENTS_ATTRIBUTE_NAME = > TapestryConstants.COMPONENT_EVENTS_ATTRIBUTE_NAME; > + > + @Inject > + private ComponentResources resources; > + > + void beginRender(final MarkupWriter writer) { > + > + final Element element = writer.getElement(); > + > + // When the component is actually a page, nothing was rendered yet. > + // The listener we add here will add the events attribute to the > <body> element > + // later > + if (element == null) { > + writer.addListener(new BodyElementListener(writer)); > + } > + else { > + writer.addListener(new DelayedListener(writer)); > + } > + > + } > + > + private void addEventsAttribute(final Element element) > + { > + > + if (element == null) > + { > + throw new IllegalStateException("@PublishEvent used inside a > page which didn't generate a <body> element"); > + } > + > + final ComponentResources containerResources = > resources.getContainerResources(); > + final ComponentModel componentModel = > containerResources.getComponentModel(); > + final String metaValue = > componentModel.getMeta(InternalConstants.PUBLISH_COMPONENT_EVENTS_META); > + final JSONArray componentEvents = new JSONArray(metaValue); > + final JSONObject events = new JSONObject(); > + final String existingValue = > element.getAttribute(COMPONENT_EVENTS_ATTRIBUTE_NAME); > + > + if (existingValue != null) > + { > + final JSONObject existing = new JSONObject(existingValue); > + for (String key : existing.keys()) { > + events.put(key, existing.get(key)); > + } > + } > + > + for (int i = 0; i < componentEvents.length(); i++) > + { > + final String eventName = componentEvents.getString(i); > + JSONObject event = new JSONObject(); > + event.put(PUBLISH_COMPONENT_EVENTS_URL_PROPERTY, > containerResources.createEventLink(eventName).toString()); > + events.put(eventName, event); > + } > + > + > element.forceAttributes(TapestryConstants.COMPONENT_EVENTS_ATTRIBUTE_NAME, > events.toString()); > + } > + > + final private class DelayedListener implements MarkupWriterListener { > + > + private MarkupWriter writer; > + > + private Element element; > + > + public DelayedListener(MarkupWriter writer) > + { > + super(); > + this.writer = writer; > + } > + > + @Override > + public void elementDidStart(Element element) > + { > + // Store first element generated by rendering the component > + if (this.element == null) > + { > + this.element = element; > + } > + } > + > + @Override > + public void elementDidEnd(Element element) > + { > + if (this.element == null) > + { > + throw new IllegalStateException("@PublishEvent used inside a > component which didn't generate any HTML elements"); > + } > + addEventsAttribute(this.element); > + writer.removeListener(this); > + } > + > + } > + > + final private class BodyElementListener implements MarkupWriterListener { > + > + private MarkupWriter writer; > + > + public BodyElementListener(MarkupWriter writer) > + { > + super(); > + this.writer = writer; > + } > + > + @Override > + public void elementDidStart(Element element) > + { > + if (element.getName().equals("body")) > + { > + addEventsAttribute(element); > + writer.removeListener(this); > + } > + } > + > + @Override > + public void elementDidEnd(Element element) > + { > + } > + > + } > + > +} > > http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6b4ca30b/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalConstants.java > ---------------------------------------------------------------------- > diff --git > a/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalConstants.java > > b/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalConstants.java > index 32b80a6..8370ae0 100644 > --- > a/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalConstants.java > +++ > b/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalConstants.java > @@ -13,8 +13,10 @@ > package org.apache.tapestry5.internal; > > import org.apache.tapestry5.ContentType; > +import org.apache.tapestry5.annotations.PublishEvent; > import org.apache.tapestry5.dom.MarkupModel; > import org.apache.tapestry5.ioc.util.TimeInterval; > +import org.apache.tapestry5.model.ComponentModel; > import org.apache.tapestry5.services.javascript.JavaScriptStack; > > public final class InternalConstants > @@ -213,4 +215,19 @@ public final class InternalConstants > * @since 5.4 > */ > public static final ContentType JAVASCRIPT_CONTENT_TYPE = new > ContentType("text/javascript"); > + > + /** > + * Name of the {@linkplain ComponentModel} metadata key whiche stores > the {@linkplain PublishEvent} > + * data. > + * @since 5.4.2 > + */ > + public static final String PUBLISH_COMPONENT_EVENTS_META = > "meta.publish-component-events"; > + > + /** > + * Name of the JSONObject key name which holds the name of the event to > be published. > + * > + * @since 5.4.2 > + */ > + public static final String PUBLISH_COMPONENT_EVENTS_URL_PROPERTY = "url"; > + > } > > http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6b4ca30b/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java > ---------------------------------------------------------------------- > diff --git > a/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java > > b/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java > index fb4502b..fdb2dc9 100644 > --- > a/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java > +++ > b/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java > @@ -12,15 +12,23 @@ > > package org.apache.tapestry5.internal.transform; > > +import java.lang.reflect.Array; > +import java.util.Arrays; > +import java.util.List; > +import java.util.Map; > + > import org.apache.tapestry5.ComponentResources; > import org.apache.tapestry5.EventContext; > import org.apache.tapestry5.ValueEncoder; > import org.apache.tapestry5.annotations.OnEvent; > +import org.apache.tapestry5.annotations.PublishEvent; > import org.apache.tapestry5.annotations.RequestParameter; > +import org.apache.tapestry5.corelib.mixins.PublishServerSideEvents; > import org.apache.tapestry5.func.F; > import org.apache.tapestry5.func.Flow; > import org.apache.tapestry5.func.Mapper; > import org.apache.tapestry5.func.Predicate; > +import org.apache.tapestry5.internal.InternalConstants; > import org.apache.tapestry5.internal.services.ComponentClassCache; > import org.apache.tapestry5.ioc.OperationTracker; > import org.apache.tapestry5.ioc.internal.util.CollectionFactory; > @@ -28,8 +36,19 @@ import > org.apache.tapestry5.ioc.internal.util.InternalUtils; > import org.apache.tapestry5.ioc.internal.util.TapestryException; > import org.apache.tapestry5.ioc.util.ExceptionUtils; > import org.apache.tapestry5.ioc.util.UnknownValueException; > +import org.apache.tapestry5.json.JSONArray; > import org.apache.tapestry5.model.MutableComponentModel; > -import org.apache.tapestry5.plastic.*; > +import org.apache.tapestry5.plastic.Condition; > +import org.apache.tapestry5.plastic.InstructionBuilder; > +import org.apache.tapestry5.plastic.InstructionBuilderCallback; > +import org.apache.tapestry5.plastic.LocalVariable; > +import org.apache.tapestry5.plastic.LocalVariableCallback; > +import org.apache.tapestry5.plastic.MethodAdvice; > +import org.apache.tapestry5.plastic.MethodDescription; > +import org.apache.tapestry5.plastic.MethodInvocation; > +import org.apache.tapestry5.plastic.PlasticClass; > +import org.apache.tapestry5.plastic.PlasticField; > +import org.apache.tapestry5.plastic.PlasticMethod; > import org.apache.tapestry5.runtime.ComponentEvent; > import org.apache.tapestry5.runtime.Event; > import org.apache.tapestry5.runtime.PageLifecycleListener; > @@ -39,11 +58,6 @@ import org.apache.tapestry5.services.ValueEncoderSource; > import > org.apache.tapestry5.services.transform.ComponentClassTransformWorker2; > import org.apache.tapestry5.services.transform.TransformationSupport; > > -import java.lang.reflect.Array; > -import java.util.Arrays; > -import java.util.List; > -import java.util.Map; > - > /** > * Provides implementations of the > * {@link > org.apache.tapestry5.runtime.Component#dispatchComponentEvent(org.apache.tapestry5.runtime.ComponentEvent)} > @@ -151,6 +165,8 @@ public class OnEventWorker implements > ComponentClassTransformWorker2 > int minContextValues = 0; > > boolean handleActivationEventContext = false; > + > + final PublishEvent publishEvent; > > EventHandlerMethod(PlasticMethod method) > { > @@ -165,6 +181,8 @@ public class OnEventWorker implements > ComponentClassTransformWorker2 > > eventType = extractEventType(methodName, onEvent); > componentId = extractComponentId(methodName, onEvent); > + > + publishEvent = method.getAnnotation(PublishEvent.class); > } > > void buildMatchAndInvocation(InstructionBuilder builder, final > LocalVariable resultVariable) > @@ -343,9 +361,31 @@ public class OnEventWorker implements > ComponentClassTransformWorker2 > implementDispatchMethod(plasticClass, isRoot, model, > eventHandlerMethods); > > addComponentIdValidationLogicOnPageLoad(plasticClass, > eventHandlerMethods); > + > + addPublishEventInfo(eventHandlerMethods, model); > + } > + > + private void addPublishEventInfo(Flow<EventHandlerMethod> > eventHandlerMethods, > + MutableComponentModel model) > + { > + JSONArray publishEvents = new JSONArray(); > + for (EventHandlerMethod eventHandlerMethod : eventHandlerMethods) > + { > + if (eventHandlerMethod.publishEvent != null) > + { > + > publishEvents.put(eventHandlerMethod.eventType.toLowerCase()); > + } > + } > + > + // If we do have events to publish, we apply the mixin and pass > + // event information to it. > + if (publishEvents.length() > 0) { > + model.addMixinClassName(PublishServerSideEvents.class.getName(), > "after:*"); > + model.setMeta(InternalConstants.PUBLISH_COMPONENT_EVENTS_META, > publishEvents.toString()); > + } > } > > - private void addComponentIdValidationLogicOnPageLoad(PlasticClass > plasticClass, Flow<EventHandlerMethod> eventHandlerMethods) > + private void addComponentIdValidationLogicOnPageLoad(PlasticClass > plasticClass, Flow<EventHandlerMethod> eventHandlerMethods) > { > ComponentIdValidator[] validators = > extractComponentIdValidators(eventHandlerMethods); > > > http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6b4ca30b/tapestry-core/src/main/preprocessed-coffeescript/org/apache/tapestry5/t5-core-dom.coffee > ---------------------------------------------------------------------- > diff --git > a/tapestry-core/src/main/preprocessed-coffeescript/org/apache/tapestry5/t5-core-dom.coffee > > b/tapestry-core/src/main/preprocessed-coffeescript/org/apache/tapestry5/t5-core-dom.coffee > index 9d419bc..9b975d4 100644 > --- > a/tapestry-core/src/main/preprocessed-coffeescript/org/apache/tapestry5/t5-core-dom.coffee > +++ > b/tapestry-core/src/main/preprocessed-coffeescript/org/apache/tapestry5/t5-core-dom.coffee > @@ -906,6 +906,60 @@ define ["underscore", "./utils", "./events", "jquery"], > events = utils.split events > #endif > onevent elements, events, match, handler > + > + # Returns the URL of a component event based on its name and an optional > element > + # or null if the event information is not found. When the element isn't > passed > + # or it's null, the event data is taken from the <body> element. > + # > + # * eventName - (string) name of the component event > + # * element - (object) HTML DOM element to be used as the begining of > the event data search. Optional. > + getEventUrl = (eventName, element) -> > + > + if not (eventName?) > + throw 'dom.getEventUrl: the eventName parameter cannot be null' > + > + if not _.isString eventName > + throw 'dom.getEventUrl: the eventName parameter should be a string' > + > + eventName = eventName.toLowerCase() > + > + if element is null > + element = document.getElementsByTagName('body')[0] > + > + # Look for event data in itself first, then in the preceding siblings > + # if not found > + url = null > + > + while not url? and element.previousElementSibling? > + data = getDataAttributeAsObject(element, 'component-events') > + url = data?[eventName]?.url > + element = element.previousElementSibling > + > + if not url? > + > + # Look at parent elements recursively > + while not url? and element.parentElement? > + data = getDataAttributeAsObject(element, 'component-events') > + url = data?[eventName]?.url > + element = element.parentElement; > + > + return url; > + > + # Returns the value of a given data attribute as an object. > + # The "data-" prefix is added automatically. > + # element - (object) HTML dom element > + # attribute - (string) name of the data attribute without the "data-" > prefix. > + getDataAttributeAsObject = (element, attribute) -> > + > +#if jquery > + value = $(element).data(attribute) > +#elseif prototype > + value = JSON.parse($(element).readAttribute('data-' + attribute)) > + if value isnt null > + value = JSON.parse(value) > + else > + value = {} > +#endif > > # onDocument() is used to add an event handler to the document object; > this is used > # for global (or default) handlers. > @@ -919,5 +973,7 @@ define ["underscore", "./utils", "./events", "jquery"], > body: wrapElement document.body > > scanner: scanner > + > + getEventUrl : getEventUrl > > return exports > > http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6b4ca30b/tapestry-core/src/test/app1/PublishEventDemo.tml > ---------------------------------------------------------------------- > diff --git a/tapestry-core/src/test/app1/PublishEventDemo.tml > b/tapestry-core/src/test/app1/PublishEventDemo.tml > new file mode 100644 > index 0000000..43c2bd7 > --- /dev/null > +++ b/tapestry-core/src/test/app1/PublishEventDemo.tml > @@ -0,0 +1,7 @@ > +<t:border xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd" > + xmlns:p="tapestry:parameter"> > + <div id="page"> > + <t:PublishEventDemoComponent/> > + <t:PublishEventDemoComponent2/> > + </div> > +</t:border> > \ No newline at end of file > > http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6b4ca30b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/PublishEventDemoComponent.java > ---------------------------------------------------------------------- > diff --git > a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/PublishEventDemoComponent.java > > b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/PublishEventDemoComponent.java > new file mode 100644 > index 0000000..b8054f9 > --- /dev/null > +++ > b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/PublishEventDemoComponent.java > @@ -0,0 +1,32 @@ > +// Licensed under the Apache License, Version 2.0 (the "License"); > +// you may not use this file except in compliance with the License. > +// You may obtain a copy of the License at > +// > +// http://www.apache.org/licenses/LICENSE-2.0 > +// > +// Unless required by applicable law or agreed to in writing, software > +// distributed under the License is distributed on an "AS IS" BASIS, > +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > +// See the License for the specific language governing permissions and > +// limitations under the License. > +package org.apache.tapestry5.integration.app1.components; > + > +import org.apache.tapestry5.annotations.OnEvent; > +import org.apache.tapestry5.annotations.PublishEvent; > +import org.apache.tapestry5.json.JSONObject; > + > +public class PublishEventDemoComponent > +{ > + @OnEvent("answer") > + @PublishEvent > + JSONObject answer() { > + return new JSONObject("origin", "component"); > + } > + > + @PublishEvent > + JSONObject onAction() > + { > + return new JSONObject("origin", "component"); > + } > + > +} > > http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6b4ca30b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/PublishEventDemoComponent2.java > ---------------------------------------------------------------------- > diff --git > a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/PublishEventDemoComponent2.java > > b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/PublishEventDemoComponent2.java > new file mode 100644 > index 0000000..7771557 > --- /dev/null > +++ > b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/PublishEventDemoComponent2.java > @@ -0,0 +1,32 @@ > +// Licensed under the Apache License, Version 2.0 (the "License"); > +// you may not use this file except in compliance with the License. > +// You may obtain a copy of the License at > +// > +// http://www.apache.org/licenses/LICENSE-2.0 > +// > +// Unless required by applicable law or agreed to in writing, software > +// distributed under the License is distributed on an "AS IS" BASIS, > +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > +// See the License for the specific language governing permissions and > +// limitations under the License. > +package org.apache.tapestry5.integration.app1.components; > + > +import org.apache.tapestry5.annotations.OnEvent; > +import org.apache.tapestry5.annotations.PublishEvent; > +import org.apache.tapestry5.json.JSONObject; > + > +public class PublishEventDemoComponent2 > +{ > + @PublishEvent > + JSONObject onAction() > + { > + return new JSONObject("origin", "component"); > + } > + > + @OnEvent("answer") > + @PublishEvent > + JSONObject answer() { > + return new JSONObject("origin", "component"); > + } > + > +} > > http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6b4ca30b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java > ---------------------------------------------------------------------- > diff --git > a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java > > b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java > index d7d76d6..e78a874 100644 > --- > a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java > +++ > b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java > @@ -57,32 +57,35 @@ public class Index > > private static final List<Item> ITEMS = CollectionFactory > .newList( > - new Item("ZoneFormDemo", "Zone Form Decoration", "Fields > inside an Ajax-updatd Form are still decorated properly."), > + > + new Item("PublishEventDemo", "@PublishEvent Demo", > "Publishing server-side events to client-side code (JavaScript)"), > + > +// new Item("ZoneFormDemo", "Zone Form Decoration", > "Fields inside an Ajax-updatd Form are still decorated properly."), > > - new Item("AjaxValidationDemo", "Ajax Validation", > "Demonstrated proper integration of server-side validation and client-side > field decoration."), > +// new Item("AjaxValidationDemo", "Ajax Validation", > "Demonstrated proper integration of server-side validation and client-side > field decoration."), > > new Item("OverrideEventHandlerDemo", "Event Handler > Override Demo", "Event Handler methods overridden by sub-classes invoke > base-class correctly."), > > - new Item("LogoSubclass", "Base class Assets in > sub-classes", "Assets are resolved for the parent class if that's where the > annotations are."), > +// new Item("LogoSubclass", "Base class Assets in > sub-classes", "Assets are resolved for the parent class if that's where the > annotations are."), > > new Item("MissingRequiredARP", "Missing Query Parameter > for @ActivationRequestParameter", "Activating a page with a required > @ActivationRequestParameter, but no matching query parameter, is an error."), > > - new Item("DateFieldValidationDemo", "DateField > Validation Demo", > - "Use of DateField component when client > validation is disabled."), > +// new Item("DateFieldValidationDemo", "DateField > Validation Demo", > +// "Use of DateField component when client > validation is disabled."), > > new Item("MixinParameters54", "Strict Mixin Parameters", > "In the 5.4 DTD, Parameter Mixins must be qualified with the mixin id."), > > - new Item("AsyncDemo", "Async Links and Forms Demo", > "Async (XHR) Updates without a containing Zone."), > +// new Item("AsyncDemo", "Async Links and Forms Demo", > "Async (XHR) Updates without a containing Zone."), > > new Item("FormCancelActionDemo", "Form Cancel Action > Demo", "FormSupport.addCancel() support"), > > new Item("AjaxRadioDemo", "Ajax Radio Demo", "Radio > components inside an Ajax form"), > > - new Item("TimeIntervalDemo", "TimeInterval Demo", > "Interval component, based on Moment.js"), > +// new Item("TimeIntervalDemo", "TimeInterval Demo", > "Interval component, based on Moment.js"), > > - new Item("LocalDateDemo", "LocalDate Demo", "LocalDate > component, based on Moment.js"), > +// new Item("LocalDateDemo", "LocalDate Demo", "LocalDate > component, based on Moment.js"), > > - new Item("EmptyIfDemo", "Empty If Demo", "Ensure an > empty If can still render."), > +// new Item("EmptyIfDemo", "Empty If Demo", "Ensure an > empty If can still render."), > > new Item("MissingAssetDemo", "Missing Asset Demo", > "Error when injecting an asset that does not exist."), > > > http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6b4ca30b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/PublishEventDemo.java > ---------------------------------------------------------------------- > diff --git > a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/PublishEventDemo.java > > b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/PublishEventDemo.java > new file mode 100644 > index 0000000..1876de5 > --- /dev/null > +++ > b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/PublishEventDemo.java > @@ -0,0 +1,49 @@ > +// Copyright 2016 The Apache Software Foundation > +// > +// Licensed under the Apache License, Version 2.0 (the "License"); > +// you may not use this file except in compliance with the License. > +// You may obtain a copy of the License at > +// > +// http://www.apache.org/licenses/LICENSE-2.0 > +// > +// Unless required by applicable law or agreed to in writing, software > +// distributed under the License is distributed on an "AS IS" BASIS, > +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > +// See the License for the specific language governing permissions and > +// limitations under the License. > + > +// Licensed under the Apache License, Version 2.0 (the "License"); > +// you may not use this file except in compliance with the License. > +// You may obtain a copy of the License at > +// > +// http://www.apache.org/licenses/LICENSE-2.0 > +// > +// Unless required by applicable law or agreed to in writing, software > +// distributed under the License is distributed on an "AS IS" BASIS, > +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > +// See the License for the specific language governing permissions and > +// limitations under the License. > +package org.apache.tapestry5.integration.app1.pages; > + > +import org.apache.tapestry5.annotations.Import; > +import org.apache.tapestry5.annotations.OnEvent; > +import org.apache.tapestry5.annotations.PublishEvent; > +import org.apache.tapestry5.json.JSONObject; > + > +@Import(stack = "core", library = "PublishEventDemo.js") > +public class PublishEventDemo > +{ > + > + @PublishEvent > + JSONObject onAction() > + { > + return new JSONObject("origin", "page"); > + } > + > + @OnEvent("answer") > + @PublishEvent > + JSONObject answer() { > + return new JSONObject("origin", "page"); > + } > + > +} > > http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6b4ca30b/tapestry-core/src/test/resources/META-INF/assets/PublishEventDemo.js > ---------------------------------------------------------------------- > diff --git > a/tapestry-core/src/test/resources/META-INF/assets/PublishEventDemo.js > b/tapestry-core/src/test/resources/META-INF/assets/PublishEventDemo.js > new file mode 100644 > index 0000000..20c0406 > --- /dev/null > +++ b/tapestry-core/src/test/resources/META-INF/assets/PublishEventDemo.js > @@ -0,0 +1,11 @@ > +require(["t5/core/dom", "t5/core/ajax", "jquery"], function (dom, ajax, $) { > + > + $(document).ready(function() { > + console.log('dom.getEventURL() : ' + dom.getEventUrl('answer', > document.getElementById("page"))); > + console.log('dom.getEventURL() 1 : ' + dom.getEventUrl('answer', > document.getElementById("componentParagraph"))); > + console.log('dom.getEventURL() 2 : ' + dom.getEventUrl('answer', > document.getElementById("componentParagraph2"))); > + console.log('dom.getEventURL() 3 : ' + dom.getEventUrl('answer', > document.getElementById("componentParagraph3"))); > + }); > + > +}); > + > > http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6b4ca30b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/PublishEventDemoComponent.tml > ---------------------------------------------------------------------- > diff --git > a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/PublishEventDemoComponent.tml > > b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/PublishEventDemoComponent.tml > new file mode 100644 > index 0000000..2d2b5f1 > --- /dev/null > +++ > b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/PublishEventDemoComponent.tml > @@ -0,0 +1,3 @@ > +<div id="component" > xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"> > + <p id="componentParagraph">I'm a component</p> > +</div> > > http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/6b4ca30b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/PublishEventDemoComponent2.tml > ---------------------------------------------------------------------- > diff --git > a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/PublishEventDemoComponent2.tml > > b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/PublishEventDemoComponent2.tml > new file mode 100644 > index 0000000..b10d020 > --- /dev/null > +++ > b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/PublishEventDemoComponent2.tml > @@ -0,0 +1,4 @@ > +<t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"> > + <p id="componentParagraph2">I'm another component</p> > + <p id="componentParagraph3">I'm another component</p> > +</t:container> >
-- Massimo Lusetti --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tapestry.apache.org For additional commands, e-mail: dev-h...@tapestry.apache.org