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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
85 return nullptr; | 85 return nullptr; |
86 } | 86 } |
87 | 87 |
88 RefPtr<SerializedScriptValue> data; | 88 RefPtr<SerializedScriptValue> data; |
89 if (options.hasData()) { | 89 if (options.hasData()) { |
90 data = SerializedScriptValueFactory::instance().create(options.data().is olate(), options.data(), nullptr, exceptionState); | 90 data = SerializedScriptValueFactory::instance().create(options.data().is olate(), options.data(), nullptr, exceptionState); |
91 if (exceptionState.hadException()) | 91 if (exceptionState.hadException()) |
92 return nullptr; | 92 return nullptr; |
93 } | 93 } |
94 | 94 |
95 for (NotificationAction action : options.actions()) { | |
96 if (action.title().isEmpty()) { | |
97 exceptionState.throwTypeError("Notification action titles must not b e empty."); | |
98 return nullptr; | |
99 } | |
100 } | |
101 | |
95 Notification* notification = new Notification(title, context); | 102 Notification* notification = new Notification(title, context); |
96 | 103 |
97 notification->setBody(options.body()); | 104 notification->setBody(options.body()); |
98 notification->setTag(options.tag()); | 105 notification->setTag(options.tag()); |
99 notification->setLang(options.lang()); | 106 notification->setLang(options.lang()); |
100 notification->setDir(options.dir()); | 107 notification->setDir(options.dir()); |
101 notification->setVibrate(NavigatorVibration::sanitizeVibrationPattern(option s.vibrate())); | 108 notification->setVibrate(NavigatorVibration::sanitizeVibrationPattern(option s.vibrate())); |
102 notification->setSilent(options.silent()); | 109 notification->setSilent(options.silent()); |
103 notification->setSerializedData(data.release()); | 110 notification->setSerializedData(data.release()); |
104 if (options.hasIcon()) { | 111 if (options.hasIcon()) { |
105 KURL iconUrl = options.icon().isEmpty() ? KURL() : context->completeURL( options.icon()); | 112 KURL iconUrl = options.icon().isEmpty() ? KURL() : context->completeURL( options.icon()); |
106 if (!iconUrl.isEmpty() && iconUrl.isValid()) | 113 if (!iconUrl.isEmpty() && iconUrl.isValid()) |
107 notification->setIconUrl(iconUrl); | 114 notification->setIconUrl(iconUrl); |
108 } | 115 } |
116 HeapVector<NotificationAction> actions; | |
117 actions.appendRange(options.actions().begin(), options.actions().begin() + s td::min(notificationManager()->maxActions(), options.actions().size())); | |
Peter Beverloo
2015/07/31 15:38:49
nit: you can just write |maxActions()| rather than
johnme
2015/07/31 16:08:52
Done.
| |
118 notification->setActions(actions); | |
109 | 119 |
110 String insecureOriginMessage; | 120 String insecureOriginMessage; |
111 UseCounter::Feature feature = context->isPrivilegedContext(insecureOriginMes sage) | 121 UseCounter::Feature feature = context->isPrivilegedContext(insecureOriginMes sage) |
112 ? UseCounter::NotificationSecureOrigin | 122 ? UseCounter::NotificationSecureOrigin |
113 : UseCounter::NotificationInsecureOrigin; | 123 : UseCounter::NotificationInsecureOrigin; |
114 UseCounter::count(context, feature); | 124 UseCounter::count(context, feature); |
115 | 125 |
116 notification->scheduleShow(); | 126 notification->scheduleShow(); |
117 notification->suspendIfNeeded(); | 127 notification->suspendIfNeeded(); |
118 return notification; | 128 return notification; |
(...skipping 18 matching lines...) Expand all Loading... | |
137 pattern.appendRange(data.vibrate.begin(), data.vibrate.end()); | 147 pattern.appendRange(data.vibrate.begin(), data.vibrate.end()); |
138 notification->setVibrate(pattern); | 148 notification->setVibrate(pattern); |
139 } | 149 } |
140 | 150 |
141 const WebVector<char>& dataBytes = data.data; | 151 const WebVector<char>& dataBytes = data.data; |
142 if (!dataBytes.isEmpty()) { | 152 if (!dataBytes.isEmpty()) { |
143 notification->setSerializedData(SerializedScriptValueFactory::instance() .createFromWireBytes(dataBytes.data(), dataBytes.size())); | 153 notification->setSerializedData(SerializedScriptValueFactory::instance() .createFromWireBytes(dataBytes.data(), dataBytes.size())); |
144 notification->serializedData()->registerMemoryAllocatedWithCurrentScript Context(); | 154 notification->serializedData()->registerMemoryAllocatedWithCurrentScript Context(); |
145 } | 155 } |
146 | 156 |
157 HeapVector<NotificationAction> actions; | |
158 webActionsToActions(data.actions, &actions); | |
159 notification->setActions(actions); | |
160 | |
147 notification->setState(NotificationStateShowing); | 161 notification->setState(NotificationStateShowing); |
148 notification->suspendIfNeeded(); | 162 notification->suspendIfNeeded(); |
149 return notification; | 163 return notification; |
150 } | 164 } |
151 | 165 |
152 Notification::Notification(const String& title, ExecutionContext* context) | 166 Notification::Notification(const String& title, ExecutionContext* context) |
153 : ActiveDOMObject(context) | 167 : ActiveDOMObject(context) |
154 , m_title(title) | 168 , m_title(title) |
155 , m_dir("auto") | 169 , m_dir("auto") |
156 , m_silent(false) | 170 , m_silent(false) |
(...skipping 27 matching lines...) Expand all Loading... | |
184 SecurityOrigin* origin = executionContext()->securityOrigin(); | 198 SecurityOrigin* origin = executionContext()->securityOrigin(); |
185 ASSERT(origin); | 199 ASSERT(origin); |
186 | 200 |
187 // FIXME: Do CSP checks on the associated notification icon. | 201 // FIXME: Do CSP checks on the associated notification icon. |
188 WebNotificationData::Direction dir = m_dir == "rtl" ? WebNotificationData::D irectionRightToLeft : WebNotificationData::DirectionLeftToRight; | 202 WebNotificationData::Direction dir = m_dir == "rtl" ? WebNotificationData::D irectionRightToLeft : WebNotificationData::DirectionLeftToRight; |
189 | 203 |
190 // The lifetime and availability of non-persistent notifications is tied to the page | 204 // The lifetime and availability of non-persistent notifications is tied to the page |
191 // they were created by, and thus the data doesn't have to be known to the e mbedder. | 205 // they were created by, and thus the data doesn't have to be known to the e mbedder. |
192 Vector<char> emptyDataWireBytes; | 206 Vector<char> emptyDataWireBytes; |
193 | 207 |
194 WebNotificationData notificationData(m_title, dir, m_lang, m_body, m_tag, m_ iconUrl, m_vibrate, m_silent, emptyDataWireBytes); | 208 WebVector<WebNotificationAction> webActions; |
209 actionsToWebActions(m_actions, &webActions); | |
210 | |
211 WebNotificationData notificationData(m_title, dir, m_lang, m_body, m_tag, m_ iconUrl, m_vibrate, m_silent, emptyDataWireBytes, webActions); | |
195 notificationManager()->show(WebSecurityOrigin(origin), notificationData, thi s); | 212 notificationManager()->show(WebSecurityOrigin(origin), notificationData, thi s); |
196 | 213 |
197 m_state = NotificationStateShowing; | 214 m_state = NotificationStateShowing; |
198 } | 215 } |
199 | 216 |
200 void Notification::close() | 217 void Notification::close() |
201 { | 218 { |
202 if (m_state != NotificationStateShowing) | 219 if (m_state != NotificationStateShowing) |
203 return; | 220 return; |
204 | 221 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
239 { | 256 { |
240 // The notification will be showing when the user initiated the close, or it will be | 257 // The notification will be showing when the user initiated the close, or it will be |
241 // closing if the developer initiated the close. | 258 // closing if the developer initiated the close. |
242 if (m_state != NotificationStateShowing && m_state != NotificationStateClosi ng) | 259 if (m_state != NotificationStateShowing && m_state != NotificationStateClosi ng) |
243 return; | 260 return; |
244 | 261 |
245 m_state = NotificationStateClosed; | 262 m_state = NotificationStateClosed; |
246 dispatchEvent(Event::create(EventTypeNames::close)); | 263 dispatchEvent(Event::create(EventTypeNames::close)); |
247 } | 264 } |
248 | 265 |
249 NavigatorVibration::VibrationPattern Notification::vibrate(bool& isNull) const | 266 const NavigatorVibration::VibrationPattern& Notification::vibrate(bool& isNull) const |
250 { | 267 { |
251 isNull = m_vibrate.isEmpty(); | 268 isNull = m_vibrate.isEmpty(); |
252 return m_vibrate; | 269 return m_vibrate; |
253 } | 270 } |
254 | 271 |
255 TextDirection Notification::direction() const | 272 TextDirection Notification::direction() const |
256 { | 273 { |
257 // FIXME: Resolve dir()=="auto" against the document. | 274 // FIXME: Resolve dir()=="auto" against the document. |
258 return dir() == "rtl" ? RTL : LTR; | 275 return dir() == "rtl" ? RTL : LTR; |
259 } | 276 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
292 // when Blink supports [Exposed] annotations on class members in IDL definit ions. | 309 // when Blink supports [Exposed] annotations on class members in IDL definit ions. |
293 if (NotificationPermissionClient* permissionClient = NotificationPermissionC lient::from(context)) | 310 if (NotificationPermissionClient* permissionClient = NotificationPermissionC lient::from(context)) |
294 permissionClient->requestPermission(context, callback); | 311 permissionClient->requestPermission(context, callback); |
295 } | 312 } |
296 | 313 |
297 unsigned Notification::maxActions() | 314 unsigned Notification::maxActions() |
298 { | 315 { |
299 return notificationManager()->maxActions(); | 316 return notificationManager()->maxActions(); |
300 } | 317 } |
301 | 318 |
319 void Notification::actionsToWebActions(const HeapVector<NotificationAction>& act ions, WebVector<WebNotificationAction>* webActions) | |
320 { | |
321 size_t count = std::min(notificationManager()->maxActions(), actions.size()) ; | |
Peter Beverloo
2015/07/31 15:38:49
dito
johnme
2015/07/31 16:08:52
Done.
| |
322 WebVector<WebNotificationAction> clearedAndResized(count); | |
323 webActions->swap(clearedAndResized); | |
324 for (size_t i = 0; i < count; ++i) { | |
Peter Beverloo
2015/07/31 15:38:49
nit: no need for {} in one-line if statements
johnme
2015/07/31 16:08:52
Done (but this becomes 2-line in https://coderevie
| |
325 (*webActions)[i].title = actions[i].title(); | |
326 } | |
327 } | |
328 | |
329 void Notification::webActionsToActions(const WebVector<WebNotificationAction>& w ebActions, HeapVector<NotificationAction>* actions) | |
330 { | |
331 actions->clear(); | |
332 actions->grow(webActions.size()); | |
333 for (size_t i = 0; i < webActions.size(); ++i) { | |
334 (*actions)[i].setTitle(webActions[i].title); | |
Peter Beverloo
2015/07/31 15:38:49
dito
johnme
2015/07/31 16:08:52
Done (but this becomes 2-line in https://coderevie
| |
335 } | |
336 } | |
337 | |
302 bool Notification::dispatchEventInternal(PassRefPtrWillBeRawPtr<Event> event) | 338 bool Notification::dispatchEventInternal(PassRefPtrWillBeRawPtr<Event> event) |
303 { | 339 { |
304 ASSERT(executionContext()->isContextThread()); | 340 ASSERT(executionContext()->isContextThread()); |
305 return EventTarget::dispatchEventInternal(event); | 341 return EventTarget::dispatchEventInternal(event); |
306 } | 342 } |
307 | 343 |
308 const AtomicString& Notification::interfaceName() const | 344 const AtomicString& Notification::interfaceName() const |
309 { | 345 { |
310 return EventTargetNames::Notification; | 346 return EventTargetNames::Notification; |
311 } | 347 } |
(...skipping 15 matching lines...) Expand all Loading... | |
327 ScriptValue Notification::data(ScriptState* scriptState) const | 363 ScriptValue Notification::data(ScriptState* scriptState) const |
328 { | 364 { |
329 if (!m_serializedData) | 365 if (!m_serializedData) |
330 return ScriptValue::createNull(scriptState); | 366 return ScriptValue::createNull(scriptState); |
331 | 367 |
332 return ScriptValue(scriptState, m_serializedData->deserialize(scriptState->i solate())); | 368 return ScriptValue(scriptState, m_serializedData->deserialize(scriptState->i solate())); |
333 } | 369 } |
334 | 370 |
335 DEFINE_TRACE(Notification) | 371 DEFINE_TRACE(Notification) |
336 { | 372 { |
373 visitor->trace(m_actions); | |
337 RefCountedGarbageCollectedEventTargetWithInlineData<Notification>::trace(vis itor); | 374 RefCountedGarbageCollectedEventTargetWithInlineData<Notification>::trace(vis itor); |
338 ActiveDOMObject::trace(visitor); | 375 ActiveDOMObject::trace(visitor); |
339 } | 376 } |
340 | 377 |
341 } // namespace blink | 378 } // namespace blink |
OLD | NEW |