Index: third_party/WebKit/Source/core/events/InputEvent.cpp |
diff --git a/third_party/WebKit/Source/core/events/InputEvent.cpp b/third_party/WebKit/Source/core/events/InputEvent.cpp |
index 337496ae8c03ae9750243fa347e79f0160a22ed1..c485ea8057f2c7e1f1ab98def97e89f7c00d5be5 100644 |
--- a/third_party/WebKit/Source/core/events/InputEvent.cpp |
+++ b/third_party/WebKit/Source/core/events/InputEvent.cpp |
@@ -4,6 +4,7 @@ |
#include "core/events/InputEvent.h" |
+#include "core/dom/Range.h" |
#include "core/events/EventDispatcher.h" |
#include "public/platform/WebEditingCommandType.h" |
@@ -62,10 +63,12 @@ InputEvent::InputEvent(const AtomicString& type, const InputEventInit& initializ |
m_data = initializer.data(); |
if (initializer.hasIsComposing()) |
m_isComposing = initializer.isComposing(); |
+ if (initializer.hasRanges()) |
+ m_ranges = initializer.ranges(); |
} |
/* static */ |
-InputEvent* InputEvent::createBeforeInput(InputType inputType, const String& data, EventCancelable cancelable, EventIsComposing isComposing) |
+InputEvent* InputEvent::createBeforeInput(InputType inputType, const String& data, EventCancelable cancelable, EventIsComposing isComposing, const RangeVector* ranges) |
{ |
InputEventInit inputEventInit; |
@@ -76,6 +79,8 @@ InputEvent* InputEvent::createBeforeInput(InputType inputType, const String& dat |
inputEventInit.setInputType(convertInputTypeToString(inputType)); |
inputEventInit.setData(data); |
inputEventInit.setIsComposing(isComposing == IsComposing); |
+ if (ranges) |
+ inputEventInit.setRanges(*ranges); |
return InputEvent::create(EventTypeNames::beforeinput, inputEventInit); |
} |
@@ -90,9 +95,50 @@ bool InputEvent::isInputEvent() const |
return true; |
} |
+// TODO(chongz): We should get rid of this |EventDispatchMediator| pattern and introduce |
+// simpler interface such as |beforeDispatchEvent()| and |afterDispatchEvent()| virtual methods. |
+EventDispatchMediator* InputEvent::createMediator() |
+{ |
+ return InputEventDispatchMediator::create(this); |
+} |
+ |
DEFINE_TRACE(InputEvent) |
{ |
UIEvent::trace(visitor); |
+ visitor->trace(m_ranges); |
+} |
+ |
+InputEventDispatchMediator* InputEventDispatchMediator::create(InputEvent* inputEvent) |
+{ |
+ return new InputEventDispatchMediator(inputEvent); |
+} |
+ |
+InputEventDispatchMediator::InputEventDispatchMediator(InputEvent* inputEvent) |
+ : EventDispatchMediator(inputEvent) |
+{ |
+} |
+ |
+InputEvent& InputEventDispatchMediator::event() const |
+{ |
+ return toInputEvent(EventDispatchMediator::event()); |
+} |
+ |
+DispatchEventResult InputEventDispatchMediator::dispatchEvent(EventDispatcher& dispatcher) const |
+{ |
+ DispatchEventResult result = dispatcher.dispatch(); |
+ // It's weird to hold and clear live |Range| objects internally, and only expose |StaticRange| |
+ // through |getRanges()|. However there is no better solutions due to the following issues: |
+ // 1. We don't want to expose live |Range| objects for the author to hold as it will slow down |
+ // all DOM operations. So we just expose |StaticRange|. |
+ // 2. Event handlers in chain might modify DOM, which means we have to keep a copy of live |
+ // |Range| internally and return snapshots. |
+ // 3. We don't want authors to hold live |Range| indefinitely by holding |InputEvent|, so we |
+ // clear them after dispatch. |
+ // Authors should explicitly call |getRanges()|->|toRange()| if they want to keep a copy of |Range|. |
+ // See Editing TF meeting notes: |
+ // https://docs.google.com/document/d/1hCj6QX77NYIVY0RWrMHT1Yra6t8_Qu8PopaWLG0AM58/edit?usp=sharing |
+ event().m_ranges.clear(); |
+ return result; |
} |
} // namespace blink |