1 /* 2 * Copyright (C) 2007 Esmertec AG. 3 * Copyright (C) 2007 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package com.android.mms.dom.events; 19 20 import java.util.ArrayList; 21 22 import org.w3c.dom.events.Event; 23 import org.w3c.dom.events.EventException; 24 import org.w3c.dom.events.EventListener; 25 import org.w3c.dom.events.EventTarget; 26 27 import android.util.Log; 28 29 public class EventTargetImpl implements EventTarget { 30 private static final String TAG = "EventTargetImpl"; 31 private ArrayList<EventListenerEntry> mListenerEntries; 32 private EventTarget mNodeTarget; 33 34 static class EventListenerEntry 35 { 36 final String mType; 37 final EventListener mListener; 38 final boolean mUseCapture; 39 40 EventListenerEntry(String type, EventListener listener, boolean useCapture) 41 { 42 mType = type; 43 mListener = listener; 44 mUseCapture = useCapture; 45 } 46 } 47 48 public EventTargetImpl(EventTarget target) { 49 mNodeTarget = target; 50 } 51 52 public void addEventListener(String type, EventListener listener, boolean useCapture) { 53 if ((type == null) || type.equals("") || (listener == null)) { 54 return; 55 } 56 57 // Make sure we have only one entry 58 removeEventListener(type, listener, useCapture); 59 60 if (mListenerEntries == null) { 61 mListenerEntries = new ArrayList<EventListenerEntry>(); 62 } 63 mListenerEntries.add(new EventListenerEntry(type, listener, useCapture)); 64 } 65 66 public boolean dispatchEvent(Event evt) throws EventException { 67 // We need to use the internal APIs to modify and access the event status 68 EventImpl eventImpl = (EventImpl)evt; 69 70 if (!eventImpl.isInitialized()) { 71 throw new EventException(EventException.UNSPECIFIED_EVENT_TYPE_ERR, 72 "Event not initialized"); 73 } else if ((eventImpl.getType() == null) || eventImpl.getType().equals("")) { 74 throw new EventException(EventException.UNSPECIFIED_EVENT_TYPE_ERR, 75 "Unspecified even type"); 76 } 77 78 // Initialize event status 79 eventImpl.setTarget(mNodeTarget); 80 81 // TODO: At this point, to support event capturing and bubbling, we should 82 // establish the chain of EventTargets from the top of the tree to this 83 // event's target. 84 85 // TODO: CAPTURING_PHASE skipped 86 87 // Handle AT_TARGET 88 // Invoke handleEvent of non-capturing listeners on this EventTarget. 89 eventImpl.setEventPhase(Event.AT_TARGET); 90 eventImpl.setCurrentTarget(mNodeTarget); 91 if (!eventImpl.isPropogationStopped() && (mListenerEntries != null)) { 92 for (int i = 0; i < mListenerEntries.size(); i++) { 93 EventListenerEntry listenerEntry = mListenerEntries.get(i); 94 if (!listenerEntry.mUseCapture 95 && listenerEntry.mType.equals(eventImpl.getType())) { 96 try { 97 listenerEntry.mListener.handleEvent(eventImpl); 98 } 99 catch (Exception e) { 100 // Any exceptions thrown inside an EventListener will 101 // not stop propagation of the event 102 Log.w(TAG, "Catched EventListener exception", e); 103 } 104 } 105 } 106 } 107 108 if (eventImpl.getBubbles()) { 109 // TODO: BUBBLING_PHASE skipped 110 } 111 112 return eventImpl.isPreventDefault(); 113 } 114 115 public void removeEventListener(String type, EventListener listener, 116 boolean useCapture) { 117 if (null == mListenerEntries) { 118 return; 119 } 120 for (int i = 0; i < mListenerEntries.size(); i ++) { 121 EventListenerEntry listenerEntry = mListenerEntries.get(i); 122 if ((listenerEntry.mUseCapture == useCapture) 123 && (listenerEntry.mListener == listener) 124 && listenerEntry.mType.equals(type)) { 125 mListenerEntries.remove(i); 126 break; 127 } 128 } 129 } 130 131 } 132