1/*
2 * Copyright (C) 2014 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "UserMessageHandlersNamespace.h"
28
29#if ENABLE(USER_MESSAGE_HANDLERS)
30
31#include "DOMWrapperWorld.h"
32#include "Frame.h"
33#include "Page.h"
34#include "UserContentController.h"
35#include "UserMessageHandler.h"
36
37namespace WebCore {
38
39UserMessageHandlersNamespace::UserMessageHandlersNamespace(Frame& frame, UserContentProvider& userContentProvider)
40 : FrameDestructionObserver(&frame)
41 , m_userContentProvider(userContentProvider)
42{
43 m_userContentProvider->registerForUserMessageHandlerInvalidation(*this);
44}
45
46UserMessageHandlersNamespace::~UserMessageHandlersNamespace()
47{
48 m_userContentProvider->unregisterForUserMessageHandlerInvalidation(*this);
49}
50
51void UserMessageHandlersNamespace::didInvalidate(UserContentProvider& provider)
52{
53 auto oldMap = WTFMove(m_messageHandlers);
54
55 provider.forEachUserMessageHandler([&](const UserMessageHandlerDescriptor& descriptor) {
56 auto userMessageHandler = oldMap.take(std::make_pair(descriptor.name(), const_cast<DOMWrapperWorld*>(&descriptor.world())));
57 if (userMessageHandler) {
58 m_messageHandlers.add(std::make_pair(descriptor.name(), const_cast<DOMWrapperWorld*>(&descriptor.world())), userMessageHandler);
59 return;
60 }
61 });
62
63 for (auto& userMessageHandler : oldMap.values())
64 userMessageHandler->invalidateDescriptor();
65}
66
67Vector<AtomString> UserMessageHandlersNamespace::supportedPropertyNames() const
68{
69 // FIXME: Consider adding support for iterating the registered UserMessageHandlers. This would
70 // require adding support for passing the DOMWrapperWorld to supportedPropertyNames.
71 return { };
72}
73
74UserMessageHandler* UserMessageHandlersNamespace::namedItem(DOMWrapperWorld& world, const AtomString& name)
75{
76 Frame* frame = this->frame();
77 if (!frame)
78 return nullptr;
79
80 Page* page = frame->page();
81 if (!page)
82 return nullptr;
83
84 UserMessageHandler* handler = m_messageHandlers.get(std::pair<AtomString, RefPtr<DOMWrapperWorld>>(name, &world));
85 if (handler)
86 return handler;
87
88 page->userContentProvider().forEachUserMessageHandler([&](const UserMessageHandlerDescriptor& descriptor) {
89 if (descriptor.name() != name || &descriptor.world() != &world)
90 return;
91
92 ASSERT(!handler);
93
94 auto addResult = m_messageHandlers.add(std::make_pair(descriptor.name(), const_cast<DOMWrapperWorld*>(&descriptor.world())), UserMessageHandler::create(*frame, const_cast<UserMessageHandlerDescriptor&>(descriptor)));
95 handler = addResult.iterator->value.get();
96 });
97
98 return handler;
99}
100
101} // namespace WebCore
102
103#endif // ENABLE(USER_MESSAGE_HANDLERS)
104