Exemplo n.º 1
0
        /// <summary>
        /// Checks if the component has the listener or any of component's ancestors
        /// have listeners for the supplied event type
        /// </summary>
        /// <param name="eventType"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        internal static bool HasBubblingEventListener(string eventType, DisplayListMember target)
        {
            /**
             * 0) Get parent chain
             * */
            List <DisplayListMember> parentChain = ComponentUtil.GetParentChain(target, true);

            parentChain.Add(target); // add myself

            /**
             * 1) Look for at least one subscribed component
             * */
            foreach (DisplayListMember component in parentChain)
            {
                if (component.HasEventListener(eventType))
                {
                    return(true);
                }
            }

            return(false); // no subscribed components
        }
Exemplo n.º 2
0
        /// <summary>
        /// Bubbles event through 3 phases
        /// <see cref="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture"/>
        /// </summary>
        /// <param name="e"></param>
        internal static void BubbleEvent(Event e)
        {
            if (e.Canceled)
            {
                return;
            }

            /**
             * 0) Get parent chain
             * */
            List <DisplayListMember> parentChain = ComponentUtil.GetParentChain((DisplayListMember)e.Target, true); // true for reversing

            /**
             * 1) Capture phase
             * */
            e.Phase = EventPhase.Capture;
            foreach (DisplayListMember d in parentChain)
            {
                // set current target
                e.CurrentTarget = d;

                // execute listeners on current target
                // any of the listeners my cancel the event, that's handled by ExecuteListeners method internally
                d.ExecuteListeners(e);

                // all the listeners (or part of the listeners, in the case of cancelation)
                // on current target have been executed.
                // if event canceled or propagation stopped, go no further
                if (!e.Bubbles || e.Canceled)
                {
                    return;
                }
            }

            /**
             * 2) Target phase
             * */
            e.Phase         = EventPhase.Target;
            e.CurrentTarget = e.Target;
            ((EventDispatcher)e.Target).ExecuteListeners(e); //, EventPhase.Target); // executing target listeners

            // if event canceled or propagation stopped, go no further
            if (!e.Bubbles || e.Canceled)
            {
                return;
            }

            /**
             * 3) Bubbling phase
             * */
            e.Phase = EventPhase.Bubbling;
            parentChain.Reverse(); // reversing the parent chain & starting to bubble

            foreach (DisplayListMember d in parentChain)
            {
                // set current target
                e.CurrentTarget = d;

                // execute listeners on current target
                // any of the listeners my cancel the event, that's handled by ExecuteListeners method internally
                d.ExecuteListeners(e);

                // all the listeners (or part of the listeners, in the case of cancelation)
                // on current target have been executed.
                // if event canceled or propagation stopped, go no further
                if (!e.Bubbles || e.Canceled)
                {
                    return;
                }
            }

            /**
             * Cleanup
             * */
            if (e is IDisposable)
            {
                ((IDisposable)e).Dispose();
            }
        }