浏览代码

Support for pointer events (#13549)

Added support for pointer events using the “extensible event mechanism” in GWT 2.6

Change-Id: Idac62114fe26536e62609edc944ff9dfef886e1c
tags/7.2.0.beta1
Matti Tahvonen 10 年前
父节点
当前提交
a2f2e40438

+ 34
- 1
client/src/com/vaadin/Vaadin.gwt.xml 查看文件

@@ -1,4 +1,3 @@

<module>
<!-- This GWT module inherits all Vaadin client side functionality modules.
This is the module you want to inherit in your client side project to be
@@ -64,4 +63,38 @@
<!-- Remove IE6/IE7 permutation as they are not supported -->
<set-property name="user.agent" value="ie8,ie9,ie10,gecko1_8,safari,opera" />

<!-- Pointer event support -->
<define-property name="modernie" values="none,yes" />
<property-provider name="modernie"><![CDATA[
{
var ua = $wnd.navigator.userAgent;
if (ua.indexOf('IE') == -1 && ua.indexOf('Trident') != -1) { return 'yes'; }
return 'none';
}
]]></property-provider>

<set-property name="modernie" value="none">
<none>
<when-property-is name="user.agent" value="gecko1_8" />
</none>
</set-property>

<!-- Fall through to this rule when the browser doesn't support pointer
event -->
<replace-with class="com.vaadin.client.event.PointerEventSupportImpl">
<when-type-is class="com.vaadin.client.event.PointerEventSupportImpl" />
</replace-with>

<replace-with
class="com.vaadin.client.event.PointerEventSupportImplModernIE">
<when-type-is class="com.vaadin.client.event.PointerEventSupportImpl" />
<none>
<when-property-is value="none" name="modernie" />
</none>
</replace-with>

<replace-with class="com.vaadin.client.event.PointerEventSupportImplIE10">
<when-type-is class="com.vaadin.client.event.PointerEventSupportImpl" />
<when-property-is value="ie10" name="user.agent" />
</replace-with>
</module>

+ 4
- 0
client/src/com/vaadin/client/ApplicationConfiguration.java 查看文件

@@ -43,6 +43,7 @@ import com.vaadin.client.debug.internal.ProfilerSection;
import com.vaadin.client.debug.internal.Section;
import com.vaadin.client.debug.internal.TestBenchSection;
import com.vaadin.client.debug.internal.VDebugWindow;
import com.vaadin.client.event.PointerEventSupport;
import com.vaadin.client.metadata.BundleLoadCallback;
import com.vaadin.client.metadata.ConnectorBundleLoader;
import com.vaadin.client.metadata.NoDataException;
@@ -610,6 +611,9 @@ public class ApplicationConfiguration implements EntryPoint {
enableIEPromptFix();
}

// Register pointer events (must be done before any events are used)
PointerEventSupport.init();

// Prepare the debugging window
if (isDebugMode()) {
/*

+ 62
- 0
client/src/com/vaadin/client/event/PointerCancelEvent.java 查看文件

@@ -0,0 +1,62 @@
/*
* Copyright 2000-2013 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.client.event;

import com.google.gwt.event.dom.client.DomEvent;

/**
* Represents a native PointerCancelEvent.
*
* @since 7.2
*/
public class PointerCancelEvent extends PointerEvent<PointerCancelHandler> {

/**
* Event type for PointerCancelEvent. Represents the meta-data associated
* with this event.
*/
private static final Type<PointerCancelHandler> TYPE = new Type<PointerCancelHandler>(
EventType.PointerCancel.getNativeEventName(),
new PointerCancelEvent());

/**
* Gets the event type associated with pointer cancel events.
*
* @return the handler type
*/
public static Type<PointerCancelHandler> getType() {
return TYPE;
}

/**
* Protected constructor, use
* {@link DomEvent#fireNativeEvent(com.google.gwt.dom.client.NativeEvent, com.google.gwt.event.shared.HasHandlers)}
* to fire pointer up events.
*/
protected PointerCancelEvent() {
}

@Override
public final Type<PointerCancelHandler> getAssociatedType() {
return TYPE;
}

@Override
protected void dispatch(PointerCancelHandler handler) {
handler.onPointerCancel(this);
}

}

+ 34
- 0
client/src/com/vaadin/client/event/PointerCancelHandler.java 查看文件

@@ -0,0 +1,34 @@
/*
* Copyright 2000-2013 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.client.event;

import com.google.gwt.event.shared.EventHandler;

/**
* Handler interface for {@link PointerCancelEvent} events.
*
* @since 7.2
*/
public interface PointerCancelHandler extends EventHandler {

/**
* Called when PointerCancelEvent is fired.
*
* @param event
* the {@link PointerCancelEvent} that was fired
*/
void onPointerCancel(PointerCancelEvent event);
}

+ 61
- 0
client/src/com/vaadin/client/event/PointerDownEvent.java 查看文件

@@ -0,0 +1,61 @@
/*
* Copyright 2000-2013 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.client.event;

import com.google.gwt.event.dom.client.DomEvent;

/**
* Represents a native PointerDownEvent.
*
* @since 7.2
*/
public class PointerDownEvent extends PointerEvent<PointerDownHandler> {

/**
* Event type for PointerDownEvent. Represents the meta-data associated with
* this event.
*/
private static final Type<PointerDownHandler> TYPE = new Type<PointerDownHandler>(
EventType.PointerDown.getNativeEventName(), new PointerDownEvent());

/**
* Gets the event type associated with PointerDownEvent events.
*
* @return the handler type
*/
public static Type<PointerDownHandler> getType() {
return TYPE;
}

/**
* Protected constructor, use
* {@link DomEvent#fireNativeEvent(com.google.gwt.dom.client.NativeEvent, com.google.gwt.event.shared.HasHandlers)}
* to fire pointer down events.
*/
protected PointerDownEvent() {
}

@Override
public final Type<PointerDownHandler> getAssociatedType() {
return TYPE;
}

@Override
protected void dispatch(PointerDownHandler handler) {
handler.onPointerDown(this);
}

}

+ 34
- 0
client/src/com/vaadin/client/event/PointerDownHandler.java 查看文件

@@ -0,0 +1,34 @@
/*
* Copyright 2000-2013 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.client.event;

import com.google.gwt.event.shared.EventHandler;

/**
* Handler interface for {@link PointerDownEvent} events.
*
* @since 7.2
*/
public interface PointerDownHandler extends EventHandler {

/**
* Called when PointerDownEvent is fired.
*
* @param event
* the {@link PointerDownEvent} that was fired
*/
void onPointerDown(PointerDownEvent event);
}

+ 173
- 0
client/src/com/vaadin/client/event/PointerEvent.java 查看文件

@@ -0,0 +1,173 @@
/*
* Copyright 2000-2013 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.client.event;

import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.MouseEvent;
import com.google.gwt.event.shared.EventHandler;

/**
* Abstract class representing Pointer events.
*
* @param <H>
* handler type
*
* @since 7.2
*/
public abstract class PointerEvent<H extends EventHandler> extends
MouseEvent<H> {

enum EventType {
PointerDown, PointerMove, PointerOut, PointerOver, PointerUp, PointerCancel;

String getNativeEventName() {
return PointerEventSupport.getNativeEventName(this);
}
}

public static final String TYPE_UNKNOWN = "";
public static final String TYPE_TOUCH = "touch";
public static final String TYPE_PEN = "pen";
public static final String TYPE_MOUSE = "mouse";

/**
* Gets a unique identifier for the pointer that caused this event. The
* identifiers of previously active but retired pointers may be recycled.
*
* @return unique pointer id
*/
public final int getPointerId() {
return getPointerId(getNativeEvent());
}

/**
* Gets the width of the contact geometry of the pointer in CSS pixels.
*
* @return width in CSS pixels
*/
public final int getWidth() {
return getWidth(getNativeEvent());
}

/**
* Gets the height of the contact geometry of the pointer in CSS pixels.
*
* @return height in CSS pixels.
*/
public final int getHeight() {
return getHeight(getNativeEvent());
}

/**
* Gets the pressure of the pointer input as a value in the range of [0, 1]
* where 0 and 1 represent the minimum and maximum, respectively.
*
* @return input pressure as a value between 0 and 1
*/
public final double getPressure() {
return getPressure(getNativeEvent());
}

/**
* Gets the angle between the Y-Z plane and the plane containing both the
* transducer and the Y axis. A positive tilt is to the right.
*
* @return the tilt along the X axis as degrees in the range of [-90, 90],
* or 0 if the device does not support tilt
*/
public final double getTiltX() {
return getTiltX(getNativeEvent());
}

/**
* Gets the angle between the X-Z plane and the plane containing both the
* transducer and the X axis. A positive tilt is towards the user.
*
* @return the tilt along the Y axis as degrees in the range of [-90, 90],
* or 0 if the device does not support tilt
*/
public final double getTiltY() {
return getTiltY(getNativeEvent());
}

/**
* Gets the type of the pointer device that caused this event.
*
* @see PointerEvent#TYPE_UNKNOWN
* @see PointerEvent#TYPE_TOUCH
* @see PointerEvent#TYPE_PEN
* @see PointerEvent#TYPE_MOUSE
*
* @return a String indicating the type of the pointer device
*/
public final String getPointerType() {
return getPointerType(getNativeEvent());
}

/**
* Indicates whether the pointer is the primary pointer of this type.
*
* @return true if the pointer is the primary pointer, otherwise false
*/
public final boolean isPrimary() {
return isPrimary(getNativeEvent());
}

private static native final int getPointerId(NativeEvent e)
/*-{
return e.pointerId;
}-*/;

private static native final int getWidth(NativeEvent e)
/*-{
return e.width;
}-*/;

private static native final int getHeight(NativeEvent e)
/*-{
return e.height;
}-*/;

private static native final double getPressure(NativeEvent e)
/*-{
return e.pressure;
}-*/;

private static native final double getTiltX(NativeEvent e)
/*-{
return e.tiltX;
}-*/;

private static native final double getTiltY(NativeEvent e)
/*-{
return e.tiltY;
}-*/;

private static native final String getPointerType(NativeEvent e)
/*-{
var pointerType = e.pointerType;
if (typeof pointerType === "number") {
pointerType = [ , , "touch", "pen", "mouse" ][pointerType];
}
return pointerType || "";
}-*/;

private static native final boolean isPrimary(NativeEvent e)
/*-{
return e.isPrimary;
}-*/;

}

+ 55
- 0
client/src/com/vaadin/client/event/PointerEventSupport.java 查看文件

@@ -0,0 +1,55 @@
/*
* Copyright 2000-2013 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.client.event;

import com.google.gwt.core.client.GWT;
import com.vaadin.client.event.PointerEvent.EventType;

/**
* Main class for pointer event support. Contains functionality for determining
* if pointer events are available or not.
*
* @since 7.2
* @author Vaadin Ltd
*/
public class PointerEventSupport {

private static final PointerEventSupportImpl impl = GWT
.create(PointerEventSupportImpl.class);

private PointerEventSupport() {
}

public static void init() {
impl.init();
}

/**
* @return true if pointer events are supported by the browser, false
* otherwise
*/
public static boolean isSupported() {
return impl.isSupported();
}

/**
* @param eventType
* @return the native event name of the given event
*/
public static String getNativeEventName(EventType eventType) {
return impl.getNativeEventName(eventType);
}
}

+ 51
- 0
client/src/com/vaadin/client/event/PointerEventSupportImpl.java 查看文件

@@ -0,0 +1,51 @@
/*
* Copyright 2000-2013 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.client.event;

import com.vaadin.client.event.PointerEvent.EventType;

/**
* Main pointer event support implementation class. Made for browser without
* pointer event support.
*
* @since 7.2
* @author Vaadin Ltd
*/
public class PointerEventSupportImpl {

/**
* @return true if the pointer events are supported, false otherwise
*/
protected boolean isSupported() {
return false;
}

/**
* @param events
* @return the native event name of the given event
*/
public String getNativeEventName(EventType eventName) {
return eventName.toString().toLowerCase();
}

/**
* Initializes event support
*/
protected void init() {

}

}

+ 34
- 0
client/src/com/vaadin/client/event/PointerEventSupportImplIE10.java 查看文件

@@ -0,0 +1,34 @@
/*
* Copyright 2000-2013 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.client.event;

import com.vaadin.client.event.PointerEvent.EventType;

/**
* Pointer event support class for IE 10 ("ms" prefixed pointer events)
*
* @since 7.2
* @author Vaadin Ltd
*/
public class PointerEventSupportImplIE10 extends
PointerEventSupportImplModernIE {

@Override
public String getNativeEventName(EventType eventName) {
return "MS" + eventName;
}

}

+ 72
- 0
client/src/com/vaadin/client/event/PointerEventSupportImplModernIE.java 查看文件

@@ -0,0 +1,72 @@
/*
* Copyright 2000-2013 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.client.event;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.user.client.impl.DOMImplStandard;
import com.vaadin.client.event.PointerEvent.EventType;

/**
* Pointer event support class for IE 11+ (unprefixed pointer events)
*
* @since 7.2
* @author Vaadin Ltd
*/

public class PointerEventSupportImplModernIE extends PointerEventSupportImpl {

protected static boolean inited = false;

@Override
protected boolean isSupported() {
return true;
}

@Override
protected void init() {
if (!inited) {
JavaScriptObject eventDispatcherMapExtensions = JavaScriptObject
.createObject();
JavaScriptObject captureEventDispatcherMapExtensions = JavaScriptObject
.createObject();
for (EventType e : EventType.values()) {
addEventDispatcher(e.getNativeEventName(),
eventDispatcherMapExtensions);
getPointerEventCaptureDispatchers(e.getNativeEventName(),
captureEventDispatcherMapExtensions);
}
DOMImplStandard
.addBitlessEventDispatchers(eventDispatcherMapExtensions);
DOMImplStandard
.addCaptureEventDispatchers(captureEventDispatcherMapExtensions);

inited = true;
}
}

private static native void addEventDispatcher(String eventName,
JavaScriptObject jso)
/*-{
jso[eventName] = @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent(*);
}-*/;

private static native void getPointerEventCaptureDispatchers(
String eventName, JavaScriptObject jso)
/*-{
jso[eventName] = @com.google.gwt.user.client.impl.DOMImplStandard::dispatchCapturedMouseEvent(*);
}-*/;

}

+ 61
- 0
client/src/com/vaadin/client/event/PointerMoveEvent.java 查看文件

@@ -0,0 +1,61 @@
/*
* Copyright 2000-2013 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.client.event;

import com.google.gwt.event.dom.client.DomEvent;

/**
* Represents a native PointerMoveEvent event.
*
* @since 7.2
*/
public class PointerMoveEvent extends PointerEvent<PointerMoveHandler> {

/**
* Event type for PointerMoveEvent. Represents the meta-data associated with
* this event.
*/
private static final Type<PointerMoveHandler> TYPE = new Type<PointerMoveHandler>(
EventType.PointerMove.getNativeEventName(), new PointerMoveEvent());

/**
* Gets the event type associated with PointerMoveEvent.
*
* @return the handler type
*/
public static Type<PointerMoveHandler> getType() {
return TYPE;
}

/**
* Protected constructor, use
* {@link DomEvent#fireNativeEvent(com.google.gwt.dom.client.NativeEvent, com.google.gwt.event.shared.HasHandlers)}
* to fire pointer down events.
*/
protected PointerMoveEvent() {
}

@Override
public final Type<PointerMoveHandler> getAssociatedType() {
return TYPE;
}

@Override
protected void dispatch(PointerMoveHandler handler) {
handler.onPointerMove(this);
}

}

+ 34
- 0
client/src/com/vaadin/client/event/PointerMoveHandler.java 查看文件

@@ -0,0 +1,34 @@
/*
* Copyright 2000-2013 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.client.event;

import com.google.gwt.event.shared.EventHandler;

/**
* Handler interface for {@link PointerMoveEvent} events.
*
* @since 7.2
*/
public interface PointerMoveHandler extends EventHandler {

/**
* Called when PointerMoveEvent is fired.
*
* @param event
* the {@link PointerMoveEvent} that was fired
*/
void onPointerMove(PointerMoveEvent event);
}

+ 61
- 0
client/src/com/vaadin/client/event/PointerUpEvent.java 查看文件

@@ -0,0 +1,61 @@
/*
* Copyright 2000-2013 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.client.event;

import com.google.gwt.event.dom.client.DomEvent;

/**
* Represents a native PointerUpEvent.
*
* @since 7.2
*/
public class PointerUpEvent extends PointerEvent<PointerUpHandler> {

/**
* Event type for PointerUpEvent. Represents the meta-data associated with
* this event.
*/
private static final Type<PointerUpHandler> TYPE = new Type<PointerUpHandler>(
EventType.PointerUp.getNativeEventName(), new PointerUpEvent());

/**
* Gets the event type associated with PointerUpEvent.
*
* @return the handler type
*/
public static Type<PointerUpHandler> getType() {
return TYPE;
}

/**
* Protected constructor, use
* {@link DomEvent#fireNativeEvent(com.google.gwt.dom.client.NativeEvent, com.google.gwt.event.shared.HasHandlers)}
* to fire pointer down events.
*/
protected PointerUpEvent() {
}

@Override
public final Type<PointerUpHandler> getAssociatedType() {
return TYPE;
}

@Override
protected void dispatch(PointerUpHandler handler) {
handler.onPointerUp(this);
}

}

+ 34
- 0
client/src/com/vaadin/client/event/PointerUpHandler.java 查看文件

@@ -0,0 +1,34 @@
/*
* Copyright 2000-2013 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.client.event;

import com.google.gwt.event.shared.EventHandler;

/**
* Handler interface for {@link PointerUpEvent} events.
*
* @since 7.2
*/
public interface PointerUpHandler extends EventHandler {

/**
* Called when PointerUpEvent is fired.
*
* @param event
* the {@link PointerUpEvent} that was fired
*/
void onPointerUp(PointerUpEvent event);
}

正在加载...
取消
保存