My only concern is with /tapestry-core/src/main/preprocessed-coffeescript/org/apache/tapestry5/t5-core-dom.coffee
+#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 What happens when not jquery neither prototype is used.Instead it should use the dom api. Shall i post this to the issue itself? On Sun, Mar 19, 2017 at 8:09 PM, Massimo Lusetti <mluse...@gmail.com> wrote: > 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 > >