1/* 2 * Copyright (C) 2013 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 "PageBanner.h" 28 29#if !PLATFORM(IOS) 30 31#include "WebPage.h" 32#include <WebCore/FrameView.h> 33#include <WebCore/GraphicsLayer.h> 34 35using namespace WebCore; 36 37namespace WebKit { 38 39PassRefPtr<PageBanner> PageBanner::create(CALayer *layer, int height, Client* client) 40{ 41 return adoptRef(new PageBanner(layer, height, client)); 42} 43 44PageBanner::PageBanner(CALayer *layer, int height, Client* client) 45 : m_type(NotSet) 46 , m_client(client) 47 , m_webPage(0) 48 , m_mouseDownInBanner(false) 49 , m_isHidden(false) 50 , m_layer(layer) 51 , m_height(height) 52{ 53} 54 55void PageBanner::addToPage(Type type, WebPage* webPage) 56{ 57 m_type = type; 58 m_webPage = webPage; 59 60 ASSERT(m_type != NotSet); 61 ASSERT(m_webPage); 62 63 switch (m_type) { 64 case Header: 65 m_webPage->corePage()->addHeaderWithHeight(m_height); 66 break; 67 case Footer: 68 m_webPage->corePage()->addFooterWithHeight(m_height); 69 break; 70 case NotSet: 71 ASSERT_NOT_REACHED(); 72 } 73} 74 75void PageBanner::didAddParentLayer(GraphicsLayer* parentLayer) 76{ 77 if (!parentLayer) 78 return; 79 80 m_layer.get().bounds = CGRectMake(0, 0, parentLayer->size().width(), parentLayer->size().height()); 81 [parentLayer->platformLayer() addSublayer:m_layer.get()]; 82} 83 84void PageBanner::detachFromPage() 85{ 86 if (!m_webPage) 87 return; 88 89 // m_webPage->corePage() can be null when this is called from WebPage::~WebPage() after 90 // the web page has been closed. 91 if (m_webPage->corePage()) { 92 // We can hide the banner by removing the parent layer that hosts it. 93 if (m_type == Header) 94 m_webPage->corePage()->addHeaderWithHeight(0); 95 else if (m_type == Footer) 96 m_webPage->corePage()->addFooterWithHeight(0); 97 } 98 99 m_type = NotSet; 100 m_webPage = 0; 101} 102 103void PageBanner::hide() 104{ 105 // We can hide the banner by removing the parent layer that hosts it. 106 if (m_type == Header) 107 m_webPage->corePage()->addHeaderWithHeight(0); 108 else if (m_type == Footer) 109 m_webPage->corePage()->addFooterWithHeight(0); 110 111 m_isHidden = true; 112} 113 114void PageBanner::showIfHidden() 115{ 116 if (!m_isHidden) 117 return; 118 m_isHidden = false; 119 120 // This will re-create a parent layer in the WebCore layer tree, and we will re-add 121 // m_layer as a child of it. 122 addToPage(m_type, m_webPage); 123} 124 125void PageBanner::didChangeDeviceScaleFactor(float scaleFactor) 126{ 127 m_layer.get().contentsScale = scaleFactor; 128 [m_layer setNeedsDisplay]; 129} 130 131bool PageBanner::mouseEvent(const WebMouseEvent& mouseEvent) 132{ 133 if (m_isHidden) 134 return false; 135 136 FrameView* frameView = m_webPage->mainFrameView(); 137 if (!frameView) 138 return false; 139 140 IntPoint positionInBannerSpace; 141 142 switch (m_type) { 143 case Header: { 144 positionInBannerSpace = frameView->rootViewToTotalContents(mouseEvent.position()); 145 break; 146 } 147 case Footer: { 148 positionInBannerSpace = frameView->rootViewToTotalContents(mouseEvent.position()) - IntSize(0, frameView->totalContentsSize().height() - m_height); 149 break; 150 } 151 case NotSet: 152 ASSERT_NOT_REACHED(); 153 } 154 155 if (!m_mouseDownInBanner && (positionInBannerSpace.y() < 0 || positionInBannerSpace.y() > m_height)) 156 return false; 157 158 if (mouseEvent.type() == WebEvent::MouseDown) 159 m_mouseDownInBanner = true; 160 else if (mouseEvent.type() == WebEvent::MouseUp) 161 m_mouseDownInBanner = false; 162 163 return m_client->mouseEvent(this, mouseEvent.type(), mouseEvent.button(), positionInBannerSpace); 164} 165 166CALayer *PageBanner::layer() 167{ 168 return m_layer.get(); 169} 170 171} // namespace WebKit 172 173#endif // !PLATFORM(IOS) 174