Commit ac928976 authored by mlamouri@chromium.org's avatar mlamouri@chromium.org

Detect <link rel='manifest'> and notify embedder.

WebFrameClient gets a dispatchManifestChange method that will
be called by the FrameLoaderClient when the manifest
information might have changed. The embedder is not aware of
the manifest URL.

BUG=366145

Review URL: https://codereview.chromium.org/249633002

git-svn-id: svn://svn.chromium.org/blink/trunk@173664 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent cd389f6a
......@@ -2451,6 +2451,8 @@
'html/LabelableElement.cpp',
'html/LabelsNodeList.cpp',
'html/LabelsNodeList.h',
'html/LinkManifest.cpp',
'html/LinkManifest.h',
'html/LinkRelAttribute.cpp',
'html/LinkRelAttribute.h',
'html/LinkResource.cpp',
......
......@@ -43,6 +43,7 @@
#include "core/frame/FrameView.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/html/LinkManifest.h"
#include "core/html/imports/LinkImport.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
......@@ -206,9 +207,11 @@ LinkResource* HTMLLinkElement::linkResourceToProcess()
}
if (!m_link) {
if (m_relAttribute.isImport() && RuntimeEnabledFeatures::htmlImportsEnabled())
if (m_relAttribute.isImport() && RuntimeEnabledFeatures::htmlImportsEnabled()) {
m_link = LinkImport::create(this);
else {
} else if (m_relAttribute.isManifest() && RuntimeEnabledFeatures::manifestEnabled()) {
m_link = LinkManifest::create(this);
} else {
OwnPtrWillBeRawPtr<LinkStyle> link = LinkStyle::create(this);
if (fastHasAttribute(disabledAttr))
link->setDisabledState(true);
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "config.h"
#include "core/html/LinkManifest.h"
#include "core/dom/Document.h"
#include "core/frame/LocalFrame.h"
#include "core/html/HTMLLinkElement.h"
#include "core/loader/FrameLoaderClient.h"
namespace WebCore {
PassOwnPtrWillBeRawPtr<LinkManifest> LinkManifest::create(HTMLLinkElement* owner)
{
return adoptPtrWillBeNoop(new LinkManifest(owner));
}
LinkManifest::LinkManifest(HTMLLinkElement* owner)
: LinkResource(owner)
{
}
LinkManifest::~LinkManifest()
{
}
void LinkManifest::process()
{
if (!m_owner || !m_owner->document().frame())
return;
m_owner->document().frame()->loader().client()->dispatchDidChangeManifest();
}
bool LinkManifest::hasLoaded() const
{
return false;
}
void LinkManifest::ownerRemoved()
{
process();
}
} // namespace WebCore
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef LinkManifest_h
#define LinkManifest_h
#include "core/html/LinkResource.h"
#include "wtf/FastAllocBase.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/RefPtr.h"
namespace WebCore {
class HTMLLinkElement;
class LinkManifest FINAL : public LinkResource {
WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
static PassOwnPtrWillBeRawPtr<LinkManifest> create(HTMLLinkElement* owner);
virtual ~LinkManifest();
// LinkResource
virtual void process() OVERRIDE;
virtual Type type() const OVERRIDE { return Manifest; }
virtual bool hasLoaded() const OVERRIDE;
virtual void ownerRemoved() OVERRIDE;
private:
explicit LinkManifest(HTMLLinkElement* owner);
};
}
#endif // LinkManifest_h
......@@ -46,6 +46,7 @@ LinkRelAttribute::LinkRelAttribute(const String& rel)
, m_isLinkPrerender(false)
, m_isLinkNext(false)
, m_isImport(false)
, m_isManifest(false)
{
if (rel.isEmpty())
return;
......@@ -84,6 +85,8 @@ LinkRelAttribute::LinkRelAttribute(const String& rel)
} else if (equalIgnoringCase(*it, "apple-touch-icon-precomposed")) {
if (RuntimeEnabledFeatures::touchIconLoadingEnabled())
m_iconType = TouchPrecomposedIcon;
} else if (equalIgnoringCase(*it, "manifest")) {
m_isManifest = true;
}
}
}
......
......@@ -50,6 +50,7 @@ public:
bool isLinkPrerender() const { return m_isLinkPrerender; }
bool isLinkNext() const { return m_isLinkNext; }
bool isImport() const { return m_isImport; }
bool isManifest() const { return m_isManifest; }
private:
IconType m_iconType;
......@@ -61,6 +62,7 @@ private:
bool m_isLinkPrerender : 1;
bool m_isLinkNext : 1;
bool m_isImport : 1;
bool m_isManifest : 1;
};
}
......
......@@ -45,7 +45,8 @@ class LinkResource : public NoBaseWillBeGarbageCollectedFinalized<LinkResource>
public:
enum Type {
Style,
Import
Import,
Manifest
};
explicit LinkResource(HTMLLinkElement*);
......
......@@ -229,6 +229,8 @@ namespace WebCore {
virtual void didStopAllLoaders() { }
virtual void dispatchDidChangeManifest() { }
virtual bool isFrameLoaderClientImpl() const { return false; }
};
......
......@@ -72,6 +72,7 @@ LangAttributeAwareFormControlUI
LayerSquashing status=test
PrefixedEncryptedMedia status=stable
LocalStorage status=stable
Manifest status=test
Media status=stable
MediaController depends_on=Media, status=experimental
MediaQueryParser status=test
......
......@@ -809,4 +809,10 @@ void FrameLoaderClientImpl::didStopAllLoaders()
m_webFrame->client()->didAbortLoading(m_webFrame);
}
void FrameLoaderClientImpl::dispatchDidChangeManifest()
{
if (m_webFrame->client())
m_webFrame->client()->didChangeManifest(m_webFrame);
}
} // namespace blink
......@@ -159,6 +159,8 @@ public:
virtual void didStopAllLoaders() OVERRIDE;
virtual void dispatchDidChangeManifest() OVERRIDE;
private:
virtual bool isFrameLoaderClientImpl() const OVERRIDE { return true; }
......
......@@ -5403,4 +5403,29 @@ TEST_F(WebFrameTest, HasVisibleContentOnHiddenFrames)
}
}
class ManifestChangeWebFrameClient : public FrameTestHelpers::TestWebFrameClient {
public:
ManifestChangeWebFrameClient() : m_manifestChangeCount(0) { }
virtual void didChangeManifest(WebLocalFrame*) OVERRIDE
{
++m_manifestChangeCount;
}
int manifestChangeCount() { return m_manifestChangeCount; }
private:
int m_manifestChangeCount;
};
TEST_F(WebFrameTest, NotifyManifestChange)
{
registerMockedHttpURLLoad("link-manifest-change.html");
ManifestChangeWebFrameClient webFrameClient;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "link-manifest-change.html", true, &webFrameClient);
EXPECT_EQ(14, webFrameClient.manifestChangeCount());
}
} // namespace
<!DOCTYPE html>
<!-- This file is meant to test how many times the WebFrameClient will be
notified of a change in the current manifest URL associated with the document. -->
<html>
<head>
<link rel='manifest' href=''>
<link rel='manifest'>
<link rel='manifest foo'>
<link rel='manifest' crossorigin foo bar>
<!-- 4 times (= 4) -->
</head>
<body>
<link rel='manifest'>
<!-- 1 time (= 5) -->
</body>
<script>
function createLink(href, rel) {
var link = document.createElement('link');
link.href = href;
link.rel = rel;
return link;
}
var links = document.getElementsByTagName('link');
var link = document.createElement('link');
document.head.appendChild(createLink('foo.json', 'manifest'));
document.head.appendChild(createLink('foo.json', ''));
document.head.appendChild(createLink('foo.json', 'manifest'));
document.head.insertBefore(createLink('foo.json', 'manifest'), links[0]);
// 3 times (= 8)
links[0].crossOrigin = 'use-credentials';
links[0].media = '';
links[0].type = 'image/gif';
// 2 times (= 10)
links[0].href = 'bar.json';
links[0].rel = 'blah';
links[0].rel = 'manifest';
// 3 times (= 13)
document.head.removeChild(links[0]);
// 1 time (= 14)
</script>
</html>
......@@ -262,6 +262,10 @@ public:
// WARNING: This method may be called very frequently.
virtual void didUpdateCurrentHistoryItem(WebLocalFrame*) { }
// The frame's manifest has changed.
virtual void didChangeManifest(WebLocalFrame*) { }
// Misc ----------------------------------------------------------------
// Called to retrieve the provider of desktop notifications.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment