OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 18 matching lines...) Expand all Loading... |
29 */ | 29 */ |
30 | 30 |
31 #include "config.h" | 31 #include "config.h" |
32 #include "modules/notifications/Notification.h" | 32 #include "modules/notifications/Notification.h" |
33 | 33 |
34 #include "bindings/core/v8/ExceptionState.h" | 34 #include "bindings/core/v8/ExceptionState.h" |
35 #include "bindings/core/v8/ScriptState.h" | 35 #include "bindings/core/v8/ScriptState.h" |
36 #include "bindings/core/v8/ScriptValue.h" | 36 #include "bindings/core/v8/ScriptValue.h" |
37 #include "bindings/core/v8/ScriptWrappable.h" | 37 #include "bindings/core/v8/ScriptWrappable.h" |
38 #include "bindings/core/v8/SerializedScriptValueFactory.h" | 38 #include "bindings/core/v8/SerializedScriptValueFactory.h" |
| 39 #include "bindings/modules/v8/UnionTypesModules.h" |
39 #include "core/dom/Document.h" | 40 #include "core/dom/Document.h" |
40 #include "core/dom/ExecutionContext.h" | 41 #include "core/dom/ExecutionContext.h" |
41 #include "core/dom/ExecutionContextTask.h" | 42 #include "core/dom/ExecutionContextTask.h" |
42 #include "core/dom/ScopedWindowFocusAllowedIndicator.h" | 43 #include "core/dom/ScopedWindowFocusAllowedIndicator.h" |
43 #include "core/events/Event.h" | 44 #include "core/events/Event.h" |
44 #include "core/frame/UseCounter.h" | 45 #include "core/frame/UseCounter.h" |
45 #include "modules/notifications/NotificationOptions.h" | 46 #include "modules/notifications/NotificationOptions.h" |
46 #include "modules/notifications/NotificationPermissionClient.h" | 47 #include "modules/notifications/NotificationPermissionClient.h" |
47 #include "platform/RuntimeEnabledFeatures.h" | 48 #include "platform/RuntimeEnabledFeatures.h" |
48 #include "platform/UserGestureIndicator.h" | 49 #include "platform/UserGestureIndicator.h" |
(...skipping 21 matching lines...) Expand all Loading... |
70 exceptionState.throwTypeError("Illegal constructor. Use ServiceWorkerReg
istration.showNotification() instead."); | 71 exceptionState.throwTypeError("Illegal constructor. Use ServiceWorkerReg
istration.showNotification() instead."); |
71 return nullptr; | 72 return nullptr; |
72 } | 73 } |
73 | 74 |
74 // The Web Notification constructor may not be used in Service Worker contex
ts. | 75 // The Web Notification constructor may not be used in Service Worker contex
ts. |
75 if (context->isServiceWorkerGlobalScope()) { | 76 if (context->isServiceWorkerGlobalScope()) { |
76 exceptionState.throwTypeError("Illegal constructor."); | 77 exceptionState.throwTypeError("Illegal constructor."); |
77 return nullptr; | 78 return nullptr; |
78 } | 79 } |
79 | 80 |
| 81 // If options's silent is true, and options's vibrate is present, throw a Ty
peError exception. |
| 82 if (options.hasVibrate() && options.silent()) { |
| 83 exceptionState.throwTypeError("Slient notification must not specify vibr
ation patterns"); |
| 84 return nullptr; |
| 85 } |
| 86 |
80 RefPtr<SerializedScriptValue> data; | 87 RefPtr<SerializedScriptValue> data; |
81 if (options.hasData()) { | 88 if (options.hasData()) { |
82 data = SerializedScriptValueFactory::instance().create(options.data(), n
ullptr, exceptionState, options.data().isolate()); | 89 data = SerializedScriptValueFactory::instance().create(options.data(), n
ullptr, exceptionState, options.data().isolate()); |
83 if (exceptionState.hadException()) | 90 if (exceptionState.hadException()) |
84 return nullptr; | 91 return nullptr; |
85 } | 92 } |
86 | 93 |
87 Notification* notification = new Notification(title, context); | 94 Notification* notification = new Notification(title, context); |
88 | 95 |
89 notification->setBody(options.body()); | 96 notification->setBody(options.body()); |
90 notification->setTag(options.tag()); | 97 notification->setTag(options.tag()); |
91 notification->setLang(options.lang()); | 98 notification->setLang(options.lang()); |
92 notification->setDir(options.dir()); | 99 notification->setDir(options.dir()); |
| 100 notification->setVibrate(sanitizeVibrationPattern(options.vibrate())); |
93 notification->setSilent(options.silent()); | 101 notification->setSilent(options.silent()); |
94 notification->setSerializedData(data.release()); | 102 notification->setSerializedData(data.release()); |
95 if (options.hasIcon()) { | 103 if (options.hasIcon()) { |
96 KURL iconUrl = options.icon().isEmpty() ? KURL() : context->completeURL(
options.icon()); | 104 KURL iconUrl = options.icon().isEmpty() ? KURL() : context->completeURL(
options.icon()); |
97 if (!iconUrl.isEmpty() && iconUrl.isValid()) | 105 if (!iconUrl.isEmpty() && iconUrl.isValid()) |
98 notification->setIconUrl(iconUrl); | 106 notification->setIconUrl(iconUrl); |
99 } | 107 } |
100 | 108 |
101 String insecureOriginMessage; | 109 String insecureOriginMessage; |
102 UseCounter::Feature feature = context->securityOrigin()->canAccessFeatureReq
uiringSecureOrigin(insecureOriginMessage) | 110 UseCounter::Feature feature = context->securityOrigin()->canAccessFeatureReq
uiringSecureOrigin(insecureOriginMessage) |
(...skipping 12 matching lines...) Expand all Loading... |
115 notification->setPersistentId(persistentId); | 123 notification->setPersistentId(persistentId); |
116 notification->setDir(data.direction == WebNotificationData::DirectionLeftToR
ight ? "ltr" : "rtl"); | 124 notification->setDir(data.direction == WebNotificationData::DirectionLeftToR
ight ? "ltr" : "rtl"); |
117 notification->setLang(data.lang); | 125 notification->setLang(data.lang); |
118 notification->setBody(data.body); | 126 notification->setBody(data.body); |
119 notification->setTag(data.tag); | 127 notification->setTag(data.tag); |
120 notification->setSilent(data.silent); | 128 notification->setSilent(data.silent); |
121 | 129 |
122 if (!data.icon.isEmpty()) | 130 if (!data.icon.isEmpty()) |
123 notification->setIconUrl(data.icon); | 131 notification->setIconUrl(data.icon); |
124 | 132 |
| 133 if (!data.vibrate.isEmpty()) { |
| 134 Vector<unsigned> pattern; |
| 135 pattern.appendRange(data.vibrate.begin(), data.vibrate.end()); |
| 136 notification->setVibrate(pattern); |
| 137 } |
| 138 |
125 const WebVector<char>& dataBytes = data.data; | 139 const WebVector<char>& dataBytes = data.data; |
126 if (!dataBytes.isEmpty()) { | 140 if (!dataBytes.isEmpty()) { |
127 notification->setSerializedData(SerializedScriptValueFactory::instance()
.createFromWireBytes(dataBytes.data(), dataBytes.size())); | 141 notification->setSerializedData(SerializedScriptValueFactory::instance()
.createFromWireBytes(dataBytes.data(), dataBytes.size())); |
128 notification->serializedData()->registerMemoryAllocatedWithCurrentScript
Context(); | 142 notification->serializedData()->registerMemoryAllocatedWithCurrentScript
Context(); |
129 } | 143 } |
130 | 144 |
131 notification->setState(NotificationStateShowing); | 145 notification->setState(NotificationStateShowing); |
132 notification->suspendIfNeeded(); | 146 notification->suspendIfNeeded(); |
133 return notification; | 147 return notification; |
134 } | 148 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 SecurityOrigin* origin = executionContext()->securityOrigin(); | 181 SecurityOrigin* origin = executionContext()->securityOrigin(); |
168 ASSERT(origin); | 182 ASSERT(origin); |
169 | 183 |
170 // FIXME: Do CSP checks on the associated notification icon. | 184 // FIXME: Do CSP checks on the associated notification icon. |
171 WebNotificationData::Direction dir = m_dir == "rtl" ? WebNotificationData::D
irectionRightToLeft : WebNotificationData::DirectionLeftToRight; | 185 WebNotificationData::Direction dir = m_dir == "rtl" ? WebNotificationData::D
irectionRightToLeft : WebNotificationData::DirectionLeftToRight; |
172 | 186 |
173 // The lifetime and availability of non-persistent notifications is tied to
the page | 187 // The lifetime and availability of non-persistent notifications is tied to
the page |
174 // they were created by, and thus the data doesn't have to be known to the e
mbedder. | 188 // they were created by, and thus the data doesn't have to be known to the e
mbedder. |
175 Vector<char> emptyDataWireBytes; | 189 Vector<char> emptyDataWireBytes; |
176 | 190 |
177 WebNotificationData notificationData(m_title, dir, m_lang, m_body, m_tag, m_
iconUrl, m_silent, emptyDataWireBytes); | 191 WebNotificationData notificationData(m_title, dir, m_lang, m_body, m_tag, m_
iconUrl, m_vibrate, m_silent, emptyDataWireBytes); |
178 notificationManager()->show(WebSerializedOrigin(*origin), notificationData,
this); | 192 notificationManager()->show(WebSerializedOrigin(*origin), notificationData,
this); |
179 | 193 |
180 m_state = NotificationStateShowing; | 194 m_state = NotificationStateShowing; |
181 } | 195 } |
182 | 196 |
183 void Notification::close() | 197 void Notification::close() |
184 { | 198 { |
185 if (m_state != NotificationStateShowing) | 199 if (m_state != NotificationStateShowing) |
186 return; | 200 return; |
187 | 201 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 { | 236 { |
223 // The notification will be showing when the user initiated the close, or it
will be | 237 // The notification will be showing when the user initiated the close, or it
will be |
224 // closing if the developer initiated the close. | 238 // closing if the developer initiated the close. |
225 if (m_state != NotificationStateShowing && m_state != NotificationStateClosi
ng) | 239 if (m_state != NotificationStateShowing && m_state != NotificationStateClosi
ng) |
226 return; | 240 return; |
227 | 241 |
228 m_state = NotificationStateClosed; | 242 m_state = NotificationStateClosed; |
229 dispatchEvent(Event::create(EventTypeNames::close)); | 243 dispatchEvent(Event::create(EventTypeNames::close)); |
230 } | 244 } |
231 | 245 |
| 246 Vector<unsigned> Notification::vibrate(bool& isNull) const |
| 247 { |
| 248 isNull = m_vibrate.isEmpty(); |
| 249 return m_vibrate; |
| 250 } |
| 251 |
232 TextDirection Notification::direction() const | 252 TextDirection Notification::direction() const |
233 { | 253 { |
234 // FIXME: Resolve dir()=="auto" against the document. | 254 // FIXME: Resolve dir()=="auto" against the document. |
235 return dir() == "rtl" ? RTL : LTR; | 255 return dir() == "rtl" ? RTL : LTR; |
236 } | 256 } |
237 | 257 |
238 String Notification::permissionString(WebNotificationPermission permission) | 258 String Notification::permissionString(WebNotificationPermission permission) |
239 { | 259 { |
240 switch (permission) { | 260 switch (permission) { |
241 case WebNotificationPermissionAllowed: | 261 case WebNotificationPermissionAllowed: |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 } | 317 } |
298 | 318 |
299 ScriptValue Notification::data(ScriptState* scriptState) const | 319 ScriptValue Notification::data(ScriptState* scriptState) const |
300 { | 320 { |
301 if (!m_serializedData) | 321 if (!m_serializedData) |
302 return ScriptValue::createNull(scriptState); | 322 return ScriptValue::createNull(scriptState); |
303 | 323 |
304 return ScriptValue(scriptState, m_serializedData->deserialize(scriptState->i
solate())); | 324 return ScriptValue(scriptState, m_serializedData->deserialize(scriptState->i
solate())); |
305 } | 325 } |
306 | 326 |
| 327 Vector<unsigned> Notification::sanitizeVibrationPattern(const UnsignedLongOrUnsi
gnedLongSequence& vibrate) |
| 328 { |
| 329 Vector<unsigned> vibratePattern; |
| 330 |
| 331 if (vibrate.isUnsignedLong()) |
| 332 vibratePattern.append(vibrate.getAsUnsignedLong()); |
| 333 else if (vibrate.isUnsignedLongSequence()) |
| 334 vibratePattern = vibrate.getAsUnsignedLongSequence(); |
| 335 |
| 336 return vibratePattern; |
| 337 } |
| 338 |
307 DEFINE_TRACE(Notification) | 339 DEFINE_TRACE(Notification) |
308 { | 340 { |
309 RefCountedGarbageCollectedEventTargetWithInlineData<Notification>::trace(vis
itor); | 341 RefCountedGarbageCollectedEventTargetWithInlineData<Notification>::trace(vis
itor); |
310 ActiveDOMObject::trace(visitor); | 342 ActiveDOMObject::trace(visitor); |
311 } | 343 } |
312 | 344 |
313 } // namespace blink | 345 } // namespace blink |
OLD | NEW |