Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(401)

Side by Side Diff: Source/modules/notifications/Notification.cpp

Issue 1263043002: Add NotificationOptions.actions so websites can provide buttons (blink) (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Tweak SW test Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698