172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/*
272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2007 Esmertec AG.
372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *
572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * you may not use this file except in compliance with the License.
772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * You may obtain a copy of the License at
872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *
972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
1072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *
1172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * See the License for the specific language governing permissions and
1572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * limitations under the License.
1672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */
1772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
1872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpackage com.android.mms.dom.events;
1972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
2072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.ArrayList;
2172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
2272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.events.Event;
2372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.events.EventException;
2472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.events.EventListener;
2572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.w3c.dom.events.EventTarget;
2672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
2772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Log;
2872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
2972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class EventTargetImpl implements EventTarget {
3072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final String TAG = "EventTargetImpl";
3172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private ArrayList<EventListenerEntry> mListenerEntries;
3272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private EventTarget mNodeTarget;
3372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
3472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    static class EventListenerEntry
3572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    {
3672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        final String mType;
3772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        final EventListener mListener;
3872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        final boolean mUseCapture;
3972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
4072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        EventListenerEntry(String type, EventListener listener, boolean useCapture)
4172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        {
4272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mType = type;
4372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mListener = listener;
4472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mUseCapture = useCapture;
4572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
4672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
4772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
4872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public EventTargetImpl(EventTarget target) {
4972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mNodeTarget = target;
5072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
5172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
5272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void addEventListener(String type, EventListener listener, boolean useCapture) {
5372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if ((type == null) || type.equals("") || (listener == null)) {
5472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return;
5572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
5672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
5772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Make sure we have only one entry
5872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        removeEventListener(type, listener, useCapture);
5972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
6072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (mListenerEntries == null) {
6172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mListenerEntries = new ArrayList<EventListenerEntry>();
6272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
6372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mListenerEntries.add(new EventListenerEntry(type, listener, useCapture));
6472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
6572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
6672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean dispatchEvent(Event evt) throws EventException {
6772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // We need to use the internal APIs to modify and access the event status
6872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        EventImpl eventImpl = (EventImpl)evt;
6972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
7072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (!eventImpl.isInitialized()) {
7172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            throw new EventException(EventException.UNSPECIFIED_EVENT_TYPE_ERR,
7272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    "Event not initialized");
7372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else if ((eventImpl.getType() == null) || eventImpl.getType().equals("")) {
7472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            throw new EventException(EventException.UNSPECIFIED_EVENT_TYPE_ERR,
7572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    "Unspecified even type");
7672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
7772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
7872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Initialize event status
7972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        eventImpl.setTarget(mNodeTarget);
8072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
8172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // TODO: At this point, to support event capturing and bubbling, we should
8272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // establish the chain of EventTargets from the top of the tree to this
8372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // event's target.
8472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
8572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // TODO: CAPTURING_PHASE skipped
8672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
8772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Handle AT_TARGET
8872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Invoke handleEvent of non-capturing listeners on this EventTarget.
8972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        eventImpl.setEventPhase(Event.AT_TARGET);
9072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        eventImpl.setCurrentTarget(mNodeTarget);
9172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (!eventImpl.isPropogationStopped() && (mListenerEntries != null)) {
9272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            for (int i = 0; i < mListenerEntries.size(); i++) {
9372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                EventListenerEntry listenerEntry = mListenerEntries.get(i);
9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (!listenerEntry.mUseCapture
9572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        && listenerEntry.mType.equals(eventImpl.getType())) {
9672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    try {
9772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        listenerEntry.mListener.handleEvent(eventImpl);
9872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
9972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    catch (Exception e) {
10072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        // Any exceptions thrown inside an EventListener will
10172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        // not stop propagation of the event
10272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        Log.w(TAG, "Catched EventListener exception", e);
10372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
10472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
10572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
10672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
10772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
10872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (eventImpl.getBubbles()) {
10972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // TODO: BUBBLING_PHASE skipped
11072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
11172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
11272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return eventImpl.isPreventDefault();
11372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
11472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
11572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void removeEventListener(String type, EventListener listener,
11672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            boolean useCapture) {
11772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (null == mListenerEntries) {
11872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return;
11972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
12072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (int i = 0; i < mListenerEntries.size(); i ++) {
12172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            EventListenerEntry listenerEntry = mListenerEntries.get(i);
12272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if ((listenerEntry.mUseCapture == useCapture)
12372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    && (listenerEntry.mListener == listener)
12472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    && listenerEntry.mType.equals(type)) {
12572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                mListenerEntries.remove(i);
12672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
12772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
12872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
12972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
13072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
13172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project}
132