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