Example #1
0
        /// <summary>The deep path of this event. (Unclear working draft spec; subject to change).
        /// http://w3c.github.io/webcomponents/spec/shadow/#widl-Event-deepPath-sequence-EventTarget</summary>
        public EventTarget[] deepPath()
        {
            if (eventPhase == NONE)
            {
                // Not been dispatched or isn't currently being dispatched - empty set:
                return(new EventTarget[0]);
            }

            // Create the set:
            EventTarget[] set = new EventTarget[EventTarget.dispatchStackRef.Size];

            // Copy the dispatch stack:
            Array.Copy(EventTarget.dispatchStackRef.Stack, 0, set, 0, set.Length);

            // Ok!
            return(set);
        }
Example #2
0
        /// <summary>Runs an event of the given name.</summary>
        public bool dispatchEvent(Event e)
        {
            e.target = this;

            // First we must go all the way to the bottom of the DOM.
            // As we go, we'll build up a stack of the elements that we went past.

            // We'll store that stack in a DispatchStack object (which are pooled):
            DispatchStack stackNode = PooledStack;

            if (stackNode == null)
            {
                stackNode = new DispatchStack();
            }
            else
            {
                // Pop from the pool:
                PooledStack = stackNode.Next;
            }


            int stackPointer = 0;

            EventTarget[] stack     = stackNode.Stack;
            int           stackSize = stack.Length;

            EventTarget current = eventTargetParentNode;

            while (current != null)
            {
                // Resize required?
                if (stackPointer == stackSize)
                {
                    stackNode.Resize();
                    stack     = stackNode.Stack;
                    stackSize = stack.Length;
                }

                // Push to stack:
                stack[stackPointer++] = current;

                // Up a level:
                current = current.eventTargetParentNode;
            }

            // Stack size (Both are for the Event API):
            stackNode.Size = stackPointer;
            CurrentStack_  = stackNode;

            // Ok we've now got all the elements that we'll be attempting to trigger the event on.
            // Time for the event phases to begin!

            try{
                // Step 1 - Capture phase.
                e.eventPhase = Event.CAPTURING_PHASE;

                for (int i = stackPointer - 1; i >= 0; i--)
                {
                    // The current one:
                    EventTarget currentTarget = stack[i];

                    // Update currentTarget:
                    e.currentTarget = currentTarget;

                    // Run and test if it's been halted:
                    if (currentTarget.HandleLocalEvent(e, false))
                    {
                        // Halt!
                        e.eventPhase = Event.NONE;
                        return(!e._Cancelled);
                    }
                }

                // Step 2 - Target phase (bubble events).
                e.eventPhase    = Event.AT_TARGET;
                e.currentTarget = this;

                // Handle e.g. onclick attributes:
                if (HandleLocalEvent(e, true))
                {
                    // It quit us
                    return(!e._Cancelled);
                }

                // Test if it's been halted:
                if (e.cancelBubble)
                {
                    // Halt!
                    e.eventPhase = Event.NONE;
                    return(!e._Cancelled);
                }

                // Step 3 - Bubble phase.
                e.eventPhase = Event.BUBBLING_PHASE;

                for (int i = 0; i < stackPointer; i++)
                {
                    // The current one:
                    EventTarget currentTarget = stack[i];

                    // Update currentTarget:
                    e.currentTarget = currentTarget;

                    // Run:
                    if (currentTarget.HandleLocalEvent(e, true))
                    {
                        // Halt!
                        e.eventPhase = Event.NONE;
                        return(!e._Cancelled);
                    }
                }
            }catch (Exception ex) {
                // Handler errored.
                Log.Add(ex);
            }

            // Pool the stack:
            stackNode.Next = PooledStack;
            PooledStack    = stackNode;

            // Done!
            e.eventPhase = Event.NONE;

            return(!e._Cancelled);
        }
Example #3
0
 /// <summary>Doubles the size of the dispatch stack.</summary>
 internal void Resize()
 {
     EventTarget[] newStack = new EventTarget[Stack.Length * 2];
     Array.Copy(Stack, 0, newStack, 0, Stack.Length);
     Stack = newStack;
 }