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 notification->m_actions.appendRange(options.actions().begin(), options.actio ns().begin() + std::min(+maxActions, options.actions().size())); | |
109 | 117 |
110 String insecureOriginMessage; | 118 String insecureOriginMessage; |
111 UseCounter::Feature feature = context->isPrivilegedContext(insecureOriginMes sage) | 119 UseCounter::Feature feature = context->isPrivilegedContext(insecureOriginMes sage) |
112 ? UseCounter::NotificationSecureOrigin | 120 ? UseCounter::NotificationSecureOrigin |
113 : UseCounter::NotificationInsecureOrigin; | 121 : UseCounter::NotificationInsecureOrigin; |
114 UseCounter::count(context, feature); | 122 UseCounter::count(context, feature); |
115 | 123 |
116 notification->scheduleShow(); | 124 notification->scheduleShow(); |
117 notification->suspendIfNeeded(); | 125 notification->suspendIfNeeded(); |
118 return notification; | 126 return notification; |
119 } | 127 } |
120 | 128 |
121 Notification* Notification::create(ExecutionContext* context, int64_t persistent Id, const WebNotificationData& data) | 129 Notification* Notification::create(ExecutionContext* context, int64_t persistent Id, const WebNotificationData& data) |
122 { | 130 { |
123 Notification* notification = new Notification(data.title, context); | 131 Notification* notification = new Notification(data.title, context); |
124 | 132 |
125 notification->setPersistentId(persistentId); | 133 notification->setPersistentId(persistentId); |
126 notification->setDir(data.direction == WebNotificationData::DirectionLeftToR ight ? "ltr" : "rtl"); | 134 notification->setDir(data.direction == WebNotificationData::DirectionLeftToR ight ? "ltr" : "rtl"); |
127 notification->setLang(data.lang); | 135 notification->setLang(data.lang); |
128 notification->setBody(data.body); | 136 notification->setBody(data.body); |
129 notification->setTag(data.tag); | 137 notification->setTag(data.tag); |
130 notification->setSilent(data.silent); | 138 notification->setSilent(data.silent); |
131 | 139 |
132 if (!data.icon.isEmpty()) | 140 if (!data.icon.isEmpty()) |
133 notification->setIconUrl(data.icon); | 141 notification->setIconUrl(data.icon); |
134 | 142 |
135 if (!data.vibrate.isEmpty()) { | 143 if (!data.vibrate.isEmpty()) |
136 NavigatorVibration::VibrationPattern pattern; | 144 notification->m_vibrate.appendRange(data.vibrate.begin(), data.vibrate.e nd()); |
Peter Beverloo
2015/07/30 16:24:07
Please don't do this. Everything uses setters and
johnme
2015/07/31 15:10:10
Done.
| |
137 pattern.appendRange(data.vibrate.begin(), data.vibrate.end()); | |
138 notification->setVibrate(pattern); | |
139 } | |
140 | 145 |
141 const WebVector<char>& dataBytes = data.data; | 146 const WebVector<char>& dataBytes = data.data; |
142 if (!dataBytes.isEmpty()) { | 147 if (!dataBytes.isEmpty()) { |
143 notification->setSerializedData(SerializedScriptValueFactory::instance() .createFromWireBytes(dataBytes.data(), dataBytes.size())); | 148 notification->setSerializedData(SerializedScriptValueFactory::instance() .createFromWireBytes(dataBytes.data(), dataBytes.size())); |
144 notification->serializedData()->registerMemoryAllocatedWithCurrentScript Context(); | 149 notification->serializedData()->registerMemoryAllocatedWithCurrentScript Context(); |
145 } | 150 } |
146 | 151 |
152 webActionsToActions(data.actions, notification->m_actions); | |
Peter Beverloo
2015/07/30 16:24:07
Dito.
johnme
2015/07/31 15:10:10
Done.
| |
153 | |
147 notification->setState(NotificationStateShowing); | 154 notification->setState(NotificationStateShowing); |
148 notification->suspendIfNeeded(); | 155 notification->suspendIfNeeded(); |
149 return notification; | 156 return notification; |
150 } | 157 } |
151 | 158 |
152 Notification::Notification(const String& title, ExecutionContext* context) | 159 Notification::Notification(const String& title, ExecutionContext* context) |
153 : ActiveDOMObject(context) | 160 : ActiveDOMObject(context) |
154 , m_title(title) | 161 , m_title(title) |
155 , m_dir("auto") | 162 , m_dir("auto") |
156 , m_silent(false) | 163 , m_silent(false) |
(...skipping 27 matching lines...) Expand all Loading... | |
184 SecurityOrigin* origin = executionContext()->securityOrigin(); | 191 SecurityOrigin* origin = executionContext()->securityOrigin(); |
185 ASSERT(origin); | 192 ASSERT(origin); |
186 | 193 |
187 // FIXME: Do CSP checks on the associated notification icon. | 194 // FIXME: Do CSP checks on the associated notification icon. |
188 WebNotificationData::Direction dir = m_dir == "rtl" ? WebNotificationData::D irectionRightToLeft : WebNotificationData::DirectionLeftToRight; | 195 WebNotificationData::Direction dir = m_dir == "rtl" ? WebNotificationData::D irectionRightToLeft : WebNotificationData::DirectionLeftToRight; |
189 | 196 |
190 // The lifetime and availability of non-persistent notifications is tied to the page | 197 // 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. | 198 // they were created by, and thus the data doesn't have to be known to the e mbedder. |
192 Vector<char> emptyDataWireBytes; | 199 Vector<char> emptyDataWireBytes; |
193 | 200 |
194 WebNotificationData notificationData(m_title, dir, m_lang, m_body, m_tag, m_ iconUrl, m_vibrate, m_silent, emptyDataWireBytes); | 201 WebVector<WebNotificationAction> webActions; |
202 actionsToWebActions(m_actions, webActions); | |
203 | |
204 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); | 205 notificationManager()->show(WebSecurityOrigin(origin), notificationData, thi s); |
196 | 206 |
197 m_state = NotificationStateShowing; | 207 m_state = NotificationStateShowing; |
198 } | 208 } |
199 | 209 |
200 void Notification::close() | 210 void Notification::close() |
201 { | 211 { |
202 if (m_state != NotificationStateShowing) | 212 if (m_state != NotificationStateShowing) |
203 return; | 213 return; |
204 | 214 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
239 { | 249 { |
240 // The notification will be showing when the user initiated the close, or it will be | 250 // The notification will be showing when the user initiated the close, or it will be |
241 // closing if the developer initiated the close. | 251 // closing if the developer initiated the close. |
242 if (m_state != NotificationStateShowing && m_state != NotificationStateClosi ng) | 252 if (m_state != NotificationStateShowing && m_state != NotificationStateClosi ng) |
243 return; | 253 return; |
244 | 254 |
245 m_state = NotificationStateClosed; | 255 m_state = NotificationStateClosed; |
246 dispatchEvent(Event::create(EventTypeNames::close)); | 256 dispatchEvent(Event::create(EventTypeNames::close)); |
247 } | 257 } |
248 | 258 |
249 NavigatorVibration::VibrationPattern Notification::vibrate(bool& isNull) const | 259 const NavigatorVibration::VibrationPattern& Notification::vibrate(bool& isNull) const |
250 { | 260 { |
251 isNull = m_vibrate.isEmpty(); | 261 isNull = m_vibrate.isEmpty(); |
252 return m_vibrate; | 262 return m_vibrate; |
253 } | 263 } |
254 | 264 |
255 TextDirection Notification::direction() const | 265 TextDirection Notification::direction() const |
256 { | 266 { |
257 // FIXME: Resolve dir()=="auto" against the document. | 267 // FIXME: Resolve dir()=="auto" against the document. |
258 return dir() == "rtl" ? RTL : LTR; | 268 return dir() == "rtl" ? RTL : LTR; |
259 } | 269 } |
(...skipping 27 matching lines...) Expand all Loading... | |
287 } | 297 } |
288 | 298 |
289 void Notification::requestPermission(ExecutionContext* context, NotificationPerm issionCallback* callback) | 299 void Notification::requestPermission(ExecutionContext* context, NotificationPerm issionCallback* callback) |
290 { | 300 { |
291 // FIXME: Assert that this code-path will only be reached for Document envir onments | 301 // FIXME: Assert that this code-path will only be reached for Document envir onments |
292 // when Blink supports [Exposed] annotations on class members in IDL definit ions. | 302 // when Blink supports [Exposed] annotations on class members in IDL definit ions. |
293 if (NotificationPermissionClient* permissionClient = NotificationPermissionC lient::from(context)) | 303 if (NotificationPermissionClient* permissionClient = NotificationPermissionC lient::from(context)) |
294 permissionClient->requestPermission(context, callback); | 304 permissionClient->requestPermission(context, callback); |
295 } | 305 } |
296 | 306 |
307 void Notification::webActionsToActions(const WebVector<WebNotificationAction>& w ebActions, Vector<NotificationAction>& actions) | |
308 { | |
309 actions.clear(); | |
310 actions.grow(webActions.size()); | |
311 for (size_t i = 0; i < webActions.size(); ++i) { | |
312 actions[i].setTitle(webActions[i].title); | |
313 } | |
314 } | |
315 | |
297 bool Notification::dispatchEventInternal(PassRefPtrWillBeRawPtr<Event> event) | 316 bool Notification::dispatchEventInternal(PassRefPtrWillBeRawPtr<Event> event) |
298 { | 317 { |
299 ASSERT(executionContext()->isContextThread()); | 318 ASSERT(executionContext()->isContextThread()); |
300 return EventTarget::dispatchEventInternal(event); | 319 return EventTarget::dispatchEventInternal(event); |
301 } | 320 } |
302 | 321 |
303 const AtomicString& Notification::interfaceName() const | 322 const AtomicString& Notification::interfaceName() const |
304 { | 323 { |
305 return EventTargetNames::Notification; | 324 return EventTargetNames::Notification; |
306 } | 325 } |
(...skipping 20 matching lines...) Expand all Loading... | |
327 return ScriptValue(scriptState, m_serializedData->deserialize(scriptState->i solate())); | 346 return ScriptValue(scriptState, m_serializedData->deserialize(scriptState->i solate())); |
328 } | 347 } |
329 | 348 |
330 DEFINE_TRACE(Notification) | 349 DEFINE_TRACE(Notification) |
331 { | 350 { |
332 RefCountedGarbageCollectedEventTargetWithInlineData<Notification>::trace(vis itor); | 351 RefCountedGarbageCollectedEventTargetWithInlineData<Notification>::trace(vis itor); |
333 ActiveDOMObject::trace(visitor); | 352 ActiveDOMObject::trace(visitor); |
334 } | 353 } |
335 | 354 |
336 } // namespace blink | 355 } // namespace blink |
OLD | NEW |