15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2011, Google Inc. All rights reserved.
3f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) * Copyright (C) 2014, Samsung Electronics. All rights reserved.
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    documentation and/or other materials provided with the distribution.
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DAMAGE.
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/navigatorcontentutils/NavigatorContentUtils.h"
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
30197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionState.h"
3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/ExceptionCode.h"
33d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/frame/LocalFrame.h"
341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/frame/Navigator.h"
3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/Page.h"
3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/HashSet.h"
375d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "wtf/text/StringBuilder.h"
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
39c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
41c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)static HashSet<String>* schemeWhitelist;
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
43c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)static void initCustomSchemeHandlerWhitelist()
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
45c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    schemeWhitelist = new HashSet<String>;
46c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    static const char* const schemes[] = {
4753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        "bitcoin",
48591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        "geo",
49f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        "im",
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        "irc",
51f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        "ircs",
52591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        "magnet",
53f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        "mailto",
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        "mms",
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        "news",
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        "nntp",
57591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        "sip",
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        "sms",
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        "smsto",
60591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        "ssh",
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        "tel",
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        "urn",
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        "webcal",
64e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        "wtai",
65591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        "xmpp",
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    };
67c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    for (size_t i = 0; i < WTF_ARRAY_LENGTH(schemes); ++i)
68c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        schemeWhitelist->add(schemes[i]);
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccistatic bool verifyCustomHandlerURL(const Document& document, const String& url, ExceptionState& exceptionState)
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
73e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    // The specification requires that it is a SyntaxError if the "%s" token is
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // not present.
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    static const char token[] = "%s";
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int index = url.find(token);
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (-1 == index) {
7809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        exceptionState.throwDOMException(SyntaxError, "The url provided ('" + url + "') does not contain '%s'.");
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
82e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    // It is also a SyntaxError if the custom handler URL, as created by removing
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // the "%s" token and prepending the base url, does not resolve.
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String newURL = url;
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    newURL.remove(index, WTF_ARRAY_LENGTH(token) - 1);
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    KURL kurl = document.completeURL(url);
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (kurl.isEmpty() || !kurl.isValid()) {
907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        exceptionState.throwDOMException(SyntaxError, "The custom handler URL created by removing '%s' and prepending '" + document.baseURL().string() + "' is invalid.");
917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return false;
927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
937242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
947242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // The specification says that the API throws SecurityError exception if the
957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // URL's origin differs from the document's origin.
967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!document.securityOrigin()->canRequest(kurl)) {
977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        exceptionState.throwSecurityError("Can only register custom handler in the document's origin.");
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
104c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)static bool isSchemeWhitelisted(const String& scheme)
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
106c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (!schemeWhitelist)
107c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        initCustomSchemeHandlerWhitelist();
1085d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
1095d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    StringBuilder builder;
1105d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    unsigned length = scheme.length();
1115d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    for (unsigned i = 0; i < length; ++i)
1125d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        builder.append(toASCIILower(scheme[i]));
1135d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
114c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return schemeWhitelist->contains(builder.toString());
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
117197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic bool verifyCustomHandlerScheme(const String& scheme, ExceptionState& exceptionState)
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
119197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (!isValidProtocol(scheme)) {
120197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        exceptionState.throwSecurityError("The scheme '" + scheme + "' is not valid protocol");
121197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return false;
122197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
123197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (scheme.startsWith("web+")) {
125e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        // The specification requires that the length of scheme is at least five characteres (including 'web+' prefix).
126197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (scheme.length() >= 5)
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return true;
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
129197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        exceptionState.throwSecurityError("The scheme '" + scheme + "' is less than five characters long.");
130f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        return false;
131f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
132f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
133c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (isSchemeWhitelisted(scheme))
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
135197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
136c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    exceptionState.throwSecurityError("The scheme '" + scheme + "' doesn't belong to the scheme whitelist. Please prefix non-whitelisted schemes with the string 'web+'.");
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
140d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)NavigatorContentUtils* NavigatorContentUtils::from(Page& page)
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
142f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    return static_cast<NavigatorContentUtils*>(WillBeHeapSupplement<Page>::from(page, supplementName()));
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)NavigatorContentUtils::~NavigatorContentUtils()
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
149f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo LiuPassOwnPtrWillBeRawPtr<NavigatorContentUtils> NavigatorContentUtils::create(PassOwnPtr<NavigatorContentUtilsClient> client)
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
151f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    return adoptPtrWillBeNoop(new NavigatorContentUtils(client));
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
154d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void NavigatorContentUtils::registerProtocolHandler(Navigator& navigator, const String& scheme, const String& url, const String& title, ExceptionState& exceptionState)
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
156d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!navigator.frame())
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    Document* document = navigator.frame()->document();
1607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(document);
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!verifyCustomHandlerURL(*document, url, exceptionState))
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
165197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (!verifyCustomHandlerScheme(scheme, exceptionState))
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
168d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(navigator.frame()->page());
1697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    NavigatorContentUtils::from(*navigator.frame()->page())->client()->registerProtocolHandler(scheme, document->completeURL(url), title);
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static String customHandlersStateString(const NavigatorContentUtilsClient::CustomHandlersState state)
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1743c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    DEFINE_STATIC_LOCAL(const String, newHandler, ("new"));
1753c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    DEFINE_STATIC_LOCAL(const String, registeredHandler, ("registered"));
1763c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    DEFINE_STATIC_LOCAL(const String, declinedHandler, ("declined"));
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (state) {
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case NavigatorContentUtilsClient::CustomHandlersNew:
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return newHandler;
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case NavigatorContentUtilsClient::CustomHandlersRegistered:
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return registeredHandler;
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case NavigatorContentUtilsClient::CustomHandlersDeclined:
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return declinedHandler;
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT_NOT_REACHED();
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return String();
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
191d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)String NavigatorContentUtils::isProtocolHandlerRegistered(Navigator& navigator, const String& scheme, const String& url, ExceptionState& exceptionState)
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DEFINE_STATIC_LOCAL(const String, declined, ("declined"));
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
195d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!navigator.frame())
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return declined;
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
198d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    Document* document = navigator.frame()->document();
19910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    ASSERT(document);
2006f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    if (document->activeDOMObjectsAreStopped())
2016f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        return declined;
2026f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
2037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!verifyCustomHandlerURL(*document, url, exceptionState))
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return declined;
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
206197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (!verifyCustomHandlerScheme(scheme, exceptionState))
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return declined;
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
209d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(navigator.frame()->page());
2107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return customHandlersStateString(NavigatorContentUtils::from(*navigator.frame()->page())->client()->isProtocolHandlerRegistered(scheme, document->completeURL(url)));
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
213d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void NavigatorContentUtils::unregisterProtocolHandler(Navigator& navigator, const String& scheme, const String& url, ExceptionState& exceptionState)
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
215d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!navigator.frame())
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    Document* document = navigator.frame()->document();
2197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(document);
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!verifyCustomHandlerURL(*document, url, exceptionState))
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
224197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (!verifyCustomHandlerScheme(scheme, exceptionState))
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
227d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(navigator.frame()->page());
2287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    NavigatorContentUtils::from(*navigator.frame()->page())->client()->unregisterProtocolHandler(scheme, document->completeURL(url));
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
231926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)const char* NavigatorContentUtils::supplementName()
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
233926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return "NavigatorContentUtils";
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
236aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdochvoid provideNavigatorContentUtilsTo(Page& page, PassOwnPtr<NavigatorContentUtilsClient> client)
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2386f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    NavigatorContentUtils::provideTo(page, NavigatorContentUtils::supplementName(), NavigatorContentUtils::create(client));
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
241c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
242