| Index: third_party/WebKit/Source/modules/serviceworkers/FetchEvent.cpp | 
| diff --git a/third_party/WebKit/Source/modules/serviceworkers/FetchEvent.cpp b/third_party/WebKit/Source/modules/serviceworkers/FetchEvent.cpp | 
| index 8fbfe0a4f40226baeab272924e7e50b0ce705893..521f9467f6809e5c7950a4e8cbc63ab814f1e14b 100644 | 
| --- a/third_party/WebKit/Source/modules/serviceworkers/FetchEvent.cpp | 
| +++ b/third_party/WebKit/Source/modules/serviceworkers/FetchEvent.cpp | 
| @@ -4,10 +4,17 @@ | 
|  | 
| #include "modules/serviceworkers/FetchEvent.h" | 
|  | 
| +#include "bindings/core/v8/ScriptState.h" | 
| #include "bindings/core/v8/ToV8.h" | 
| #include "bindings/core/v8/V8HiddenValue.h" | 
| +#include "modules/fetch/BytesConsumerForDataConsumerHandle.h" | 
| #include "modules/fetch/Request.h" | 
| +#include "modules/fetch/Response.h" | 
| +#include "modules/serviceworkers/ServiceWorkerError.h" | 
| #include "modules/serviceworkers/ServiceWorkerGlobalScope.h" | 
| +#include "public/platform/modules/serviceworker/WebServiceWorkerError.h" | 
| +#include "public/platform/modules/serviceworker/WebServiceWorkerResponse.h" | 
| +#include "wtf/PtrUtil.h" | 
| #include "wtf/RefPtr.h" | 
|  | 
| namespace blink { | 
| @@ -15,16 +22,18 @@ namespace blink { | 
| FetchEvent* FetchEvent::create(ScriptState* scriptState, | 
| const AtomicString& type, | 
| const FetchEventInit& initializer) { | 
| -  return new FetchEvent(scriptState, type, initializer, nullptr, nullptr); | 
| +  return new FetchEvent(scriptState, type, initializer, nullptr, nullptr, | 
| +                        false); | 
| } | 
|  | 
| FetchEvent* FetchEvent::create(ScriptState* scriptState, | 
| const AtomicString& type, | 
| const FetchEventInit& initializer, | 
| RespondWithObserver* respondWithObserver, | 
| -                               WaitUntilObserver* waitUntilObserver) { | 
| +                               WaitUntilObserver* waitUntilObserver, | 
| +                               bool navigationPreloadSent) { | 
| return new FetchEvent(scriptState, type, initializer, respondWithObserver, | 
| -                        waitUntilObserver); | 
| +                        waitUntilObserver, navigationPreloadSent); | 
| } | 
|  | 
| Request* FetchEvent::request() const { | 
| @@ -47,6 +56,10 @@ void FetchEvent::respondWith(ScriptState* scriptState, | 
| m_observer->respondWith(scriptState, scriptPromise, exceptionState); | 
| } | 
|  | 
| +ScriptPromise FetchEvent::navigationPreload(ScriptState* scriptState) { | 
| +  return m_navigationPreloadProperty->promise(scriptState->world()); | 
| +} | 
| + | 
| const AtomicString& FetchEvent::interfaceName() const { | 
| return EventNames::FetchEvent; | 
| } | 
| @@ -55,9 +68,21 @@ FetchEvent::FetchEvent(ScriptState* scriptState, | 
| const AtomicString& type, | 
| const FetchEventInit& initializer, | 
| RespondWithObserver* respondWithObserver, | 
| -                       WaitUntilObserver* waitUntilObserver) | 
| +                       WaitUntilObserver* waitUntilObserver, | 
| +                       bool navigationPreloadSent) | 
| : ExtendableEvent(type, initializer, waitUntilObserver), | 
| -      m_observer(respondWithObserver) { | 
| +      m_scriptState(scriptState), | 
| +      m_observer(respondWithObserver), | 
| +      m_navigationPreloadProperty(new PreloadResponseProperty( | 
| +          scriptState->getExecutionContext(), | 
| +          this, | 
| +          PreloadResponseProperty::PreloadResponse)) { | 
| +  if (!navigationPreloadSent) { | 
| +    // TODO(horo): This behavior is still under the spec discussion. | 
| +    // https://github.com/w3c/ServiceWorker/issues/920#issuecomment-255874864 | 
| +    m_navigationPreloadProperty->resolve(nullptr); | 
| +  } | 
| + | 
| m_clientId = initializer.clientId(); | 
| m_isReload = initializer.isReload(); | 
| if (initializer.hasRequest()) { | 
| @@ -84,9 +109,43 @@ FetchEvent::FetchEvent(ScriptState* scriptState, | 
| } | 
| } | 
|  | 
| +void FetchEvent::onNavigationPreloadResponse( | 
| +    std::unique_ptr<WebServiceWorkerResponse> response, | 
| +    std::unique_ptr<WebDataConsumerHandle> dataConsumeHandle) { | 
| +  if (!m_scriptState->contextIsValid()) | 
| +    return; | 
| +  DCHECK(m_navigationPreloadProperty); | 
| +  ScriptState::Scope scope(m_scriptState.get()); | 
| +  FetchResponseData* responseData = | 
| +      FetchResponseData::createWithBuffer(new BodyStreamBuffer( | 
| +          m_scriptState.get(), new BytesConsumerForDataConsumerHandle( | 
| +                                   m_scriptState->getExecutionContext(), | 
| +                                   std::move(dataConsumeHandle)))); | 
| +  responseData->setURL(response->url()); | 
| +  responseData->setStatus(response->status()); | 
| +  responseData->setStatusMessage(response->statusText()); | 
| +  responseData->setResponseTime(response->responseTime()); | 
| +  for (const auto& header : response->headers()) | 
| +    responseData->headerList()->append(header.key, header.value); | 
| +  FetchResponseData* taintedResponse = | 
| +      responseData->createBasicFilteredResponse(); | 
| +  m_navigationPreloadProperty->resolve( | 
| +      Response::create(m_scriptState->getExecutionContext(), taintedResponse)); | 
| +} | 
| + | 
| +void FetchEvent::onNavigationPreloadError( | 
| +    std::unique_ptr<WebServiceWorkerError> error) { | 
| +  if (!m_scriptState->contextIsValid()) | 
| +    return; | 
| +  DCHECK(m_navigationPreloadProperty); | 
| +  m_navigationPreloadProperty->reject( | 
| +      ServiceWorkerError::take(nullptr, *error.get())); | 
| +} | 
| + | 
| DEFINE_TRACE(FetchEvent) { | 
| visitor->trace(m_observer); | 
| visitor->trace(m_request); | 
| +  visitor->trace(m_navigationPreloadProperty); | 
| ExtendableEvent::trace(visitor); | 
| } | 
|  | 
|  |