初始化

This commit is contained in:
SmallMain
2022-06-25 00:23:03 +08:00
commit ef0589e8e5
2264 changed files with 617829 additions and 0 deletions

View File

@@ -0,0 +1,173 @@
/****************************************************************************
Copyright (c) 2014-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "WebView.h"
#include "platform/CCFileUtils.h"
#include "platform/CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS && !defined(CC_PLATFORM_OS_TVOS)
#include "WebViewImpl-ios.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include "WebViewImpl-android.h"
#else
static_assert(false, "WebView only supported on iOS & Android");
#endif
NS_CC_BEGIN
WebView::WebView()
: _impl(new WebViewImpl(this)),
_onJSCallback(nullptr),
_onShouldStartLoading(nullptr),
_onDidFinishLoading(nullptr),
_onDidFailLoading(nullptr) {
}
WebView::~WebView() {
CC_SAFE_DELETE(_impl);
}
WebView *WebView::create() {
auto webView = new(std::nothrow) WebView();
if (webView) {
webView->autorelease();
return webView;
}
CC_SAFE_DELETE(webView);
return nullptr;
}
void WebView::setJavascriptInterfaceScheme(const std::string &scheme) {
_impl->setJavascriptInterfaceScheme(scheme);
}
void WebView::loadData(const cocos2d::Data &data,
const std::string &MIMEType,
const std::string &encoding,
const std::string &baseURL) {
_impl->loadData(data, MIMEType, encoding, baseURL);
}
void WebView::loadHTMLString(const std::string &string, const std::string &baseURL) {
_impl->loadHTMLString(string, baseURL);
}
void WebView::loadURL(const std::string &url) {
_impl->loadURL(url);
}
void WebView::loadFile(const std::string &fileName) {
_impl->loadFile(fileName);
}
void WebView::stopLoading() {
_impl->stopLoading();
}
void WebView::reload() {
_impl->reload();
}
bool WebView::canGoBack() {
return _impl->canGoBack();
}
bool WebView::canGoForward() {
return _impl->canGoForward();
}
void WebView::goBack() {
_impl->goBack();
}
void WebView::goForward() {
_impl->goForward();
}
void WebView::evaluateJS(const std::string &js) {
_impl->evaluateJS(js);
}
void WebView::setScalesPageToFit(bool const scalesPageToFit) {
_impl->setScalesPageToFit(scalesPageToFit);
}
void WebView::setVisible(bool visible) {
_impl->setVisible(visible);
}
void WebView::setFrame(float x, float y, float width, float height) {
_impl->setFrame(x, y, width, height);
}
void WebView::setBounces(bool bounces) {
_impl->setBounces(bounces);
}
void WebView::setBackgroundTransparent(bool isTransparent) {
_impl->setBackgroundTransparent(isTransparent);
}
void WebView::setOnDidFailLoading(const ccWebViewCallback &callback) {
_onDidFailLoading = callback;
}
void WebView::setOnDidFinishLoading(const ccWebViewCallback &callback) {
_onDidFinishLoading = callback;
}
void WebView::setOnShouldStartLoading(
const std::function<bool(WebView *sender, const std::string &url)> &callback) {
_onShouldStartLoading = callback;
}
void WebView::setOnJSCallback(const ccWebViewCallback &callback) {
_onJSCallback = callback;
}
std::function<bool(WebView
*sender,
const std::string &url
)>
WebView::getOnShouldStartLoading() const {
return _onShouldStartLoading;
}
WebView::ccWebViewCallback WebView::getOnDidFailLoading() const {
return _onDidFailLoading;
}
WebView::ccWebViewCallback WebView::getOnDidFinishLoading() const {
return _onDidFinishLoading;
}
WebView::ccWebViewCallback WebView::getOnJSCallback() const {
return _onJSCallback;
}
} //namespace cocos2d
/// @endcond

View File

@@ -0,0 +1,246 @@
/****************************************************************************
Copyright (c) 2014-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include <functional>
#include "base/ccMacros.h"
#include "base/CCRef.h"
#include "base/CCData.h"
#include "base/ccConfig.h"
/**
* @addtogroup ui
* @{
*/
NS_CC_BEGIN
class WebViewImpl;
/**
* @brief A View that displays web pages.
*
* @note WebView displays web pages base on system widget.
* It's mean WebView displays web pages above all graphical elements of cocos2d-x.
* @js NA
*/
class WebView : public Ref {
public:
/**
* Allocates and initializes a WebView.
*/
static WebView *create();
/**
* Set javascript interface scheme.
*
* @see WebView::setOnJSCallback()
*/
void setJavascriptInterfaceScheme(const std::string &scheme);
/**
* Sets the main page contents, MIME type, content encoding, and base URL.
*
* @param data The content for the main page.
* @param MIMEType The MIME type of the data.
* @param encoding The encoding of the data.
* @param baseURL The base URL for the content.
*/
void loadData(const cocos2d::Data &data,
const std::string &MIMEType,
const std::string &encoding,
const std::string &baseURL);
/**
* Sets the main page content and base URL.
*
* @param string The content for the main page.
* @param baseURL The base URL for the content.
*/
void loadHTMLString(const std::string &string, const std::string &baseURL = "");
/**
* Loads the given URL.
*
* @param url Content URL.
*/
void loadURL(const std::string &url);
/**
* Loads the given fileName.
*
* @param fileName Content fileName.
*/
void loadFile(const std::string &fileName);
/**
* Stops the current load.
*/
void stopLoading();
/**
* Reloads the current URL.
*/
void reload();
/**
* Gets whether this WebView has a back history item.
*
* @return WebView has a back history item.
*/
bool canGoBack();
/**
* Gets whether this WebView has a forward history item.
*
* @return WebView has a forward history item.
*/
bool canGoForward();
/**
* Goes back in the history.
*/
void goBack();
/**
* Goes forward in the history.
*/
void goForward();
/**
* Evaluates JavaScript in the context of the currently displayed page.
*/
void evaluateJS(const std::string &js);
/**
* Set WebView should support zooming. The default value is false.
*/
void setScalesPageToFit(const bool scalesPageToFit);
/**
* Call before a web view begins loading.
*
* @param callback The web view that is about to load new content.
* @return YES if the web view should begin loading content; otherwise, NO.
*/
void setOnShouldStartLoading(
const std::function<bool(WebView *sender, const std::string &url)> &callback);
/**
* A callback which will be called when a WebView event happens.
*/
typedef std::function<void(WebView *sender, const std::string &url)> ccWebViewCallback;
/**
* Call after a web view finishes loading.
*
* @param callback The web view that has finished loading.
*/
void setOnDidFinishLoading(const ccWebViewCallback &callback);
/**
* Call if a web view failed to load content.
*
* @param callback The web view that has failed loading.
*/
void setOnDidFailLoading(const ccWebViewCallback &callback);
/**
* This callback called when load URL that start with javascript interface scheme.
*/
void setOnJSCallback(const ccWebViewCallback &callback);
/**
* Get the callback when WebView is about to start.
*/
std::function<bool(WebView *sender, const std::string &url)>
getOnShouldStartLoading() const;
/**
* Get the callback when WebView has finished loading.
*/
ccWebViewCallback getOnDidFinishLoading() const;
/**
* Get the callback when WebView has failed loading.
*/
ccWebViewCallback getOnDidFailLoading() const;
/**
*Get the Javascript callback.
*/
ccWebViewCallback getOnJSCallback() const;
/**
* Set whether the webview bounces at end of scroll of WebView.
*/
void setBounces(bool bounce);
/**
* Toggle visibility of WebView.
*/
virtual void setVisible(bool visible);
/**
* Set the rect of WebView.
*/
virtual void setFrame(float x, float y, float width, float height);
/**
* Set the background transparent
*/
virtual void setBackgroundTransparent(bool isTransparent);
protected:
std::function<bool(WebView *sender, const std::string &url)> _onShouldStartLoading;
ccWebViewCallback _onDidFinishLoading;
ccWebViewCallback _onDidFailLoading;
ccWebViewCallback _onJSCallback;
CC_CONSTRUCTOR_ACCESS:
/**
* Default constructor.
*/
WebView();
/**
* Default destructor.
*/
virtual ~WebView();
private:
WebViewImpl *_impl;
friend class WebViewImpl;
};
NS_CC_END

View File

@@ -0,0 +1,290 @@
/****************************************************************************
Copyright (c) 2014-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include <cstdlib>
#include <string>
#include <unordered_map>
#include "WebView-inl.h"
#include "platform/CCFileUtils.h"
#include "platform/android/jni/JniHelper.h"
static const std::string className = "org/cocos2dx/lib/Cocos2dxWebViewHelper";
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,"",__VA_ARGS__)
static const std::string s_defaultBaseUrl = "file:///android_asset/";
static const std::string s_sdRootBaseUrl = "file://";
static std::string getFixedBaseUrl(const std::string &baseUrl) {
std::string fixedBaseUrl;
if (baseUrl.empty()) {
fixedBaseUrl = s_defaultBaseUrl;
} else if (baseUrl.find(s_sdRootBaseUrl) != std::string::npos) {
fixedBaseUrl = baseUrl;
} else if (baseUrl.c_str()[0] != '/') {
if (baseUrl.find("assets/") == 0) {
fixedBaseUrl = s_defaultBaseUrl + baseUrl.c_str()[7];
} else {
fixedBaseUrl = s_defaultBaseUrl + baseUrl;
}
} else {
fixedBaseUrl = s_sdRootBaseUrl + baseUrl;
}
if (fixedBaseUrl.c_str()[fixedBaseUrl.length() - 1] != '/') {
fixedBaseUrl += "/";
}
return fixedBaseUrl;
}
extern "C" {
/*
* Class: org_cocos2dx_lib_Cocos2dxWebViewHelper
* Method: shouldStartLoading
* Signature: (ILjava/lang/String;)Z
*/
JNIEXPORT jboolean JNICALL
Java_org_cocos2dx_lib_Cocos2dxWebViewHelper_shouldStartLoading(JNIEnv *env, jclass, jint index,
jstring jurl) {
auto charUrl = env->GetStringUTFChars(jurl, NULL);
std::string url = charUrl;
env->ReleaseStringUTFChars(jurl, charUrl);
return cocos2d::WebViewImpl::shouldStartLoading(index, url);
}
/*
* Class: org_cocos2dx_lib_Cocos2dxWebViewHelper
* Method: didFinishLoading
* Signature: (ILjava/lang/String;)V
*/
JNIEXPORT void JNICALL
Java_org_cocos2dx_lib_Cocos2dxWebViewHelper_didFinishLoading(JNIEnv *env, jclass, jint index,
jstring jurl) {
// LOGD("didFinishLoading");
auto charUrl = env->GetStringUTFChars(jurl, NULL);
std::string url = charUrl;
env->ReleaseStringUTFChars(jurl, charUrl);
cocos2d::WebViewImpl::didFinishLoading(index, url);
}
/*
* Class: org_cocos2dx_lib_Cocos2dxWebViewHelper
* Method: didFailLoading
* Signature: (ILjava/lang/String;)V
*/
JNIEXPORT void JNICALL
Java_org_cocos2dx_lib_Cocos2dxWebViewHelper_didFailLoading(JNIEnv *env, jclass, jint index,
jstring jurl) {
// LOGD("didFailLoading");
auto charUrl = env->GetStringUTFChars(jurl, NULL);
std::string url = charUrl;
env->ReleaseStringUTFChars(jurl, charUrl);
cocos2d::WebViewImpl::didFailLoading(index, url);
}
/*
* Class: org_cocos2dx_lib_Cocos2dxWebViewHelper
* Method: onJsCallback
* Signature: (ILjava/lang/String;)V
*/
JNIEXPORT void JNICALL
Java_org_cocos2dx_lib_Cocos2dxWebViewHelper_onJsCallback(JNIEnv *env, jclass, jint index,
jstring jmessage) {
// LOGD("jsCallback");
auto charMessage = env->GetStringUTFChars(jmessage, NULL);
std::string message = charMessage;
env->ReleaseStringUTFChars(jmessage, charMessage);
cocos2d::WebViewImpl::onJsCallback(index, message);
}
}
namespace {
int createWebViewJNI() {
cocos2d::JniMethodInfo t;
if (cocos2d::JniHelper::getStaticMethodInfo(t, className.c_str(), "createWebView", "()I")) {
// LOGD("error: %s,%d",__func__,__LINE__);
jint viewTag = t.env->CallStaticIntMethod(t.classID, t.methodID);
t.env->DeleteLocalRef(t.classID);
return viewTag;
}
return -1;
}
std::string getUrlStringByFileName(const std::string &fileName) {
// LOGD("error: %s,%d",__func__,__LINE__);
const std::string basePath("file:///android_asset/");
std::string fullPath = cocos2d::FileUtils::getInstance()->fullPathForFilename(fileName);
const std::string assetsPath("assets/");
std::string urlString;
if (fullPath.find(assetsPath) != std::string::npos) {
urlString = fullPath.replace(fullPath.find_first_of(assetsPath), assetsPath.length(),
basePath);
} else {
urlString = fullPath;
}
return urlString;
}
} // namespace
namespace cocos2d {
static std::unordered_map<int, WebViewImpl *> s_WebViewImpls;
WebViewImpl::WebViewImpl(WebView *webView) : _viewTag(-1), _webView(webView) {
_viewTag = createWebViewJNI();
s_WebViewImpls[_viewTag] = this;
}
WebViewImpl::~WebViewImpl() {
JniHelper::callStaticVoidMethod(className, "removeWebView", _viewTag);
s_WebViewImpls.erase(_viewTag);
}
void WebViewImpl::loadData(const Data &data, const std::string &MIMEType,
const std::string &encoding, const std::string &baseURL) {
std::string dataString(reinterpret_cast<char *>(data.getBytes()),
static_cast<unsigned int>(data.getSize()));
JniHelper::callStaticVoidMethod(className, "setJavascriptInterfaceScheme", _viewTag,
dataString, MIMEType, encoding, baseURL);
}
void WebViewImpl::loadHTMLString(const std::string &string, const std::string &baseURL) {
JniHelper::callStaticVoidMethod(className, "loadHTMLString", _viewTag, string, baseURL);
}
void WebViewImpl::loadURL(const std::string &url) {
JniHelper::callStaticVoidMethod(className, "loadUrl", _viewTag, url);
}
void WebViewImpl::loadFile(const std::string &fileName) {
auto fullPath = getUrlStringByFileName(fileName);
JniHelper::callStaticVoidMethod(className, "loadFile", _viewTag, fullPath);
}
void WebViewImpl::stopLoading() {
JniHelper::callStaticVoidMethod(className, "stopLoading", _viewTag);
}
void WebViewImpl::reload() {
JniHelper::callStaticVoidMethod(className, "reload", _viewTag);
}
bool WebViewImpl::canGoBack() {
return JniHelper::callStaticBooleanMethod(className, "canGoBack", _viewTag);
}
bool WebViewImpl::canGoForward() {
return JniHelper::callStaticBooleanMethod(className, "canGoForward", _viewTag);
}
void WebViewImpl::goBack() {
JniHelper::callStaticVoidMethod(className, "goBack", _viewTag);
}
void WebViewImpl::goForward() {
JniHelper::callStaticVoidMethod(className, "goForward", _viewTag);
}
void WebViewImpl::setJavascriptInterfaceScheme(const std::string &scheme) {
JniHelper::callStaticVoidMethod(className, "setJavascriptInterfaceScheme", _viewTag,
scheme);
}
void WebViewImpl::evaluateJS(const std::string &js) {
JniHelper::callStaticVoidMethod(className, "evaluateJS", _viewTag, js);
}
void WebViewImpl::setScalesPageToFit(const bool scalesPageToFit) {
JniHelper::callStaticVoidMethod(className, "setScalesPageToFit", _viewTag, scalesPageToFit);
}
bool WebViewImpl::shouldStartLoading(const int viewTag, const std::string &url) {
bool allowLoad = true;
auto it = s_WebViewImpls.find(viewTag);
if (it != s_WebViewImpls.end()) {
auto webView = it->second->_webView;
if (webView->_onShouldStartLoading) {
allowLoad = webView->_onShouldStartLoading(webView, url);
}
}
return allowLoad;
}
void WebViewImpl::didFinishLoading(const int viewTag, const std::string &url) {
auto it = s_WebViewImpls.find(viewTag);
if (it != s_WebViewImpls.end()) {
auto webView = it->second->_webView;
if (webView->_onDidFinishLoading) {
webView->_onDidFinishLoading(webView, url);
}
}
}
void WebViewImpl::didFailLoading(const int viewTag, const std::string &url) {
auto it = s_WebViewImpls.find(viewTag);
if (it != s_WebViewImpls.end()) {
auto webView = it->second->_webView;
if (webView->_onDidFailLoading) {
webView->_onDidFailLoading(webView, url);
}
}
}
void WebViewImpl::onJsCallback(const int viewTag, const std::string &message) {
auto it = s_WebViewImpls.find(viewTag);
if (it != s_WebViewImpls.end()) {
auto webView = it->second->_webView;
if (webView->_onJSCallback) {
webView->_onJSCallback(webView, message);
}
}
}
void WebViewImpl::setVisible(bool visible) {
JniHelper::callStaticVoidMethod(className, "setVisible", _viewTag, visible);
}
void WebViewImpl::setFrame(float x, float y, float width, float height) {
JniHelper::callStaticVoidMethod(className, "setWebViewRect", _viewTag,
(int) x, (int) y, (int) width, (int) height);
}
void WebViewImpl::setBounces(bool bounces) {
// empty function as this was mainly a fix for iOS
}
void WebViewImpl::setBackgroundTransparent(bool isTransparent) {
JniHelper::callStaticVoidMethod(className, "setBackgroundTransparent", _viewTag,
isTransparent);
}
} //namespace cocos2d

View File

@@ -0,0 +1,94 @@
/****************************************************************************
Copyright (c) 2014-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include <iosfwd>
#include <stdint.h>
#include "base/ccMacros.h"
#include "base/CCData.h"
NS_CC_BEGIN
class WebView;
class WebViewImpl {
public:
WebViewImpl(cocos2d::WebView *webView);
virtual ~WebViewImpl();
void setJavascriptInterfaceScheme(const std::string &scheme);
void loadData(const cocos2d::Data &data, const std::string &MIMEType,
const std::string &encoding, const std::string &baseURL);
void loadHTMLString(const std::string &string, const std::string &baseURL);
void loadURL(const std::string &url);
void loadFile(const std::string &fileName);
void stopLoading();
void reload();
bool canGoBack();
bool canGoForward();
void goBack();
void goForward();
void evaluateJS(const std::string &js);
void setScalesPageToFit(const bool scalesPageToFit);
virtual void setVisible(bool visible);
virtual void setFrame(float x, float y, float width, float height);
void setBounces(bool bounces);
void setBackgroundTransparent(bool isTransparent);
static bool shouldStartLoading(const int viewTag, const std::string &url);
static void didFinishLoading(const int viewTag, const std::string &url);
static void didFailLoading(const int viewTag, const std::string &url);
static void onJsCallback(const int viewTag, const std::string &message);
private:
int _viewTag;
WebView *_webView;
};
NS_CC_END

View File

@@ -0,0 +1,90 @@
/****************************************************************************
Copyright (c) 2014-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __COCOS2D_UI_WEBVIEWIMPL_IOS_H_
#define __COCOS2D_UI_WEBVIEWIMPL_IOS_H_
/// @cond DO_NOT_SHOW
#include <iosfwd>
@class UIWebViewWrapper;
namespace cocos2d {
class Data;
class WebView;
class WebViewImpl {
public:
WebViewImpl(WebView *webView);
virtual ~WebViewImpl();
void setJavascriptInterfaceScheme(const std::string &scheme);
void loadData(const cocos2d::Data &data,
const std::string &MIMEType,
const std::string &encoding,
const std::string &baseURL);
void loadHTMLString(const std::string &string, const std::string &baseURL);
void loadURL(const std::string &url);
void loadFile(const std::string &fileName);
void stopLoading();
void reload();
bool canGoBack();
bool canGoForward();
void goBack();
void goForward();
void evaluateJS(const std::string &js);
void setScalesPageToFit(const bool scalesPageToFit);
virtual void setVisible(bool visible);
virtual void setFrame(float x, float y, float width, float height);
void setBounces(bool bounces);
void setBackgroundTransparent(bool isTransparent);
private:
UIWebViewWrapper *_uiWebViewWrapper;
WebView *_webView;
};
}//namespace cocos2d
/// @endcond
#endif /* __COCOS2D_UI_WEBVIEWIMPL_IOS_H_ */

View File

@@ -0,0 +1,395 @@
/****************************************************************************
Copyright (c) 2014-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "platform/CCPlatformConfig.h"
// Webview not available on tvOS
#if (USE_WEB_VIEW > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) && !defined(CC_TARGET_OS_TVOS)
#import <WebKit/WKWebView.h>
#import <WebKit/WKUIDelegate.h>
#import <WebKit/WKNavigationDelegate.h>
#include "WebView-inl.h"
#include "platform/CCApplication.h"
#include "platform/ios/CCEAGLView-ios.h"
#include "platform/CCFileUtils.h"
@interface UIWebViewWrapper : NSObject
@property (nonatomic) std::function<bool(std::string url)> shouldStartLoading;
@property (nonatomic) std::function<void(std::string url)> didFinishLoading;
@property (nonatomic) std::function<void(std::string url)> didFailLoading;
@property (nonatomic) std::function<void(std::string url)> onJsCallback;
@property(nonatomic, readonly, getter=canGoBack) BOOL canGoBack;
@property(nonatomic, readonly, getter=canGoForward) BOOL canGoForward;
+ (instancetype)webViewWrapper;
- (void)setVisible:(bool)visible;
- (void)setBounces:(bool)bounces;
- (void)setFrameWithX:(float)x y:(float)y width:(float)width height:(float)height;
- (void)setJavascriptInterfaceScheme:(const std::string &)scheme;
- (void)loadData:(const std::string &)data MIMEType:(const std::string &)MIMEType textEncodingName:(const std::string &)encodingName baseURL:(const std::string &)baseURL;
- (void)loadHTMLString:(const std::string &)string baseURL:(const std::string &)baseURL;
- (void)loadUrl:(const std::string &)urlString;
- (void)loadFile:(const std::string &)filePath;
- (void)stopLoading;
- (void)reload;
- (void)evaluateJS:(const std::string &)js;
- (void)goBack;
- (void)goForward;
- (void)setScalesPageToFit:(const bool)scalesPageToFit;
- (void)setBackgroundTransparent:(const bool)isTransparent;
@end
@interface UIWebViewWrapper () <WKUIDelegate, WKNavigationDelegate>
@property(nonatomic, assign) WKWebView *uiWebView;
@property(nonatomic, copy) NSString *jsScheme;
@end
@implementation UIWebViewWrapper {
}
+ (instancetype)webViewWrapper {
return [[[self alloc] init] autorelease];
}
- (instancetype)init {
self = [super init];
if (self) {
self.uiWebView = nil;
self.shouldStartLoading = nullptr;
self.didFinishLoading = nullptr;
self.didFailLoading = nullptr;
}
return self;
}
- (void)dealloc {
self.uiWebView.UIDelegate = nil;
[self.uiWebView removeFromSuperview];
[self.uiWebView release];
self.jsScheme = nil;
[super dealloc];
}
- (void)setupWebView {
if (!self.uiWebView) {
self.uiWebView = [[WKWebView alloc] init];
self.uiWebView.UIDelegate = self;
self.uiWebView.navigationDelegate = self;
}
if (!self.uiWebView.superview) {
auto eaglview = (CCEAGLView*)cocos2d::Application::getInstance()->getView();
[eaglview addSubview:self.uiWebView];
}
}
- (void)setVisible:(bool)visible {
self.uiWebView.hidden = !visible;
}
- (void)setBounces:(bool)bounces {
self.uiWebView.scrollView.bounces = bounces;
}
- (void)setFrameWithX:(float)x y:(float)y width:(float)width height:(float)height {
if (!self.uiWebView) {[self setupWebView];}
CGRect newFrame = CGRectMake(x, y, width, height);
if (!CGRectEqualToRect(self.uiWebView.frame, newFrame)) {
self.uiWebView.frame = CGRectMake(x, y, width, height);
}
}
- (void)setJavascriptInterfaceScheme:(const std::string &)scheme {
self.jsScheme = @(scheme.c_str());
}
- (void)loadData:(const std::string &)data MIMEType:(const std::string &)MIMEType textEncodingName:(const std::string &)encodingName baseURL:(const std::string &)baseURL {
auto path = [[NSBundle mainBundle] resourcePath];
path = [path stringByAppendingPathComponent:@(baseURL.c_str() )];
auto url = [NSURL fileURLWithPath:path];
[self.uiWebView loadData:[NSData dataWithBytes:data.c_str() length:data.length()]
MIMEType:@(MIMEType.c_str())
characterEncodingName:@(encodingName.c_str())
baseURL:url];
}
- (void)loadHTMLString:(const std::string &)string baseURL:(const std::string &)baseURL {
if (!self.uiWebView) {[self setupWebView];}
auto path = [[NSBundle mainBundle] resourcePath];
path = [path stringByAppendingPathComponent:@(baseURL.c_str() )];
auto url = [NSURL fileURLWithPath:path];
[self.uiWebView loadHTMLString:@(string.c_str()) baseURL:url];
}
- (void)loadUrl:(const std::string &)urlString {
if (!self.uiWebView) {[self setupWebView];}
NSURL *url = [NSURL URLWithString:@(urlString.c_str())];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.uiWebView loadRequest:request];
}
- (void)loadFile:(const std::string &)filePath {
if (!self.uiWebView) {[self setupWebView];}
NSURL *url = [NSURL fileURLWithPath:@(filePath.c_str())];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.uiWebView loadRequest:request];
}
- (void)stopLoading {
[self.uiWebView stopLoading];
}
- (void)reload {
[self.uiWebView reload];
}
- (BOOL)canGoForward {
return self.uiWebView.canGoForward;
}
- (BOOL)canGoBack {
return self.uiWebView.canGoBack;
}
- (void)goBack {
[self.uiWebView goBack];
}
- (void)goForward {
[self.uiWebView goForward];
}
- (void)evaluateJS:(const std::string &)js {
if (!self.uiWebView) {[self setupWebView];}
[self.uiWebView evaluateJavaScript:@(js.c_str()) completionHandler:nil];
}
- (void)setScalesPageToFit:(const bool)scalesPageToFit {
// TODO: there is not corresponding API in WK.
// https://stackoverflow.com/questions/26295277/wkwebview-equivalent-for-uiwebviews-scalespagetofit/43048514 seems has a solution,
// but it doesn't support setting it dynamically. If we want to set this feature dynamically, then it will be too complex.
}
- (void)setBackgroundTransparent:(const bool)isTransparent {
if (!self.uiWebView) {[self setupWebView];}
[self.uiWebView setOpaque:isTransparent ? NO : YES];
[self.uiWebView setBackgroundColor:isTransparent ? [UIColor clearColor] : [UIColor whiteColor]];
}
#pragma mark - WKNavigationDelegate
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSString *url = [[navigationAction request].URL.absoluteString stringByRemovingPercentEncoding];
NSString* scheme = [navigationAction request].URL.scheme;
if ([scheme isEqualToString:self.jsScheme]) {
self.onJsCallback(url.UTF8String);
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
if (self.shouldStartLoading && url) {
if (self.shouldStartLoading(url.UTF8String) )
decisionHandler(WKNavigationActionPolicyAllow);
else
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
decisionHandler(WKNavigationActionPolicyAllow);
}
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
if (self.didFinishLoading) {
NSString *url = [webView.URL absoluteString];
self.didFinishLoading([url UTF8String]);
}
}
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
if (self.didFailLoading) {
NSString *errorInfo = error.userInfo[NSURLErrorFailingURLStringErrorKey];
if (errorInfo) {
self.didFailLoading([errorInfo UTF8String]);
}
}
}
#pragma WKUIDelegate
// Implement js alert function.
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)())completionHandler
{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"Ok"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action) {
completionHandler();
}]];
auto rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
[rootViewController presentViewController:alertController animated:YES completion:^{}];
}
@end
namespace cocos2d {
WebViewImpl::WebViewImpl(WebView *webView)
: _uiWebViewWrapper([UIWebViewWrapper webViewWrapper]),
_webView(webView) {
[_uiWebViewWrapper retain];
_uiWebViewWrapper.shouldStartLoading = [this](std::string url) {
if (this->_webView->_onShouldStartLoading) {
return this->_webView->_onShouldStartLoading(this->_webView, url);
}
return true;
};
_uiWebViewWrapper.didFinishLoading = [this](std::string url) {
if (this->_webView->_onDidFinishLoading) {
this->_webView->_onDidFinishLoading(this->_webView, url);
}
};
_uiWebViewWrapper.didFailLoading = [this](std::string url) {
if (this->_webView->_onDidFailLoading) {
this->_webView->_onDidFailLoading(this->_webView, url);
}
};
_uiWebViewWrapper.onJsCallback = [this](std::string url) {
if (this->_webView->_onJSCallback) {
this->_webView->_onJSCallback(this->_webView, url);
}
};
}
WebViewImpl::~WebViewImpl(){
[_uiWebViewWrapper release];
_uiWebViewWrapper = nullptr;
}
void WebViewImpl::setJavascriptInterfaceScheme(const std::string &scheme) {
[_uiWebViewWrapper setJavascriptInterfaceScheme:scheme];
}
void WebViewImpl::loadData(const Data &data,
const std::string &MIMEType,
const std::string &encoding,
const std::string &baseURL) {
std::string dataString(reinterpret_cast<char *>(data.getBytes()), static_cast<unsigned int>(data.getSize()));
[_uiWebViewWrapper loadData:dataString MIMEType:MIMEType textEncodingName:encoding baseURL:baseURL];
}
void WebViewImpl::loadHTMLString(const std::string &string, const std::string &baseURL) {
[_uiWebViewWrapper loadHTMLString:string baseURL:baseURL];
}
void WebViewImpl::loadURL(const std::string &url) {
[_uiWebViewWrapper loadUrl:url];
}
void WebViewImpl::loadFile(const std::string &fileName) {
auto fullPath = cocos2d::FileUtils::getInstance()->fullPathForFilename(fileName);
[_uiWebViewWrapper loadFile:fullPath];
}
void WebViewImpl::stopLoading() {
[_uiWebViewWrapper stopLoading];
}
void WebViewImpl::reload() {
[_uiWebViewWrapper reload];
}
bool WebViewImpl::canGoBack() {
return _uiWebViewWrapper.canGoBack;
}
bool WebViewImpl::canGoForward() {
return _uiWebViewWrapper.canGoForward;
}
void WebViewImpl::goBack() {
[_uiWebViewWrapper goBack];
}
void WebViewImpl::goForward() {
[_uiWebViewWrapper goForward];
}
void WebViewImpl::evaluateJS(const std::string &js) {
[_uiWebViewWrapper evaluateJS:js];
}
void WebViewImpl::setBounces(bool bounces) {
[_uiWebViewWrapper setBounces:bounces];
}
void WebViewImpl::setScalesPageToFit(const bool scalesPageToFit) {
[_uiWebViewWrapper setScalesPageToFit:scalesPageToFit];
}
void WebViewImpl::setVisible(bool visible){
[_uiWebViewWrapper setVisible:visible];
}
void WebViewImpl::setFrame(float x, float y, float width, float height){
auto eaglview = (CCEAGLView*)cocos2d::Application::getInstance()->getView();
auto scaleFactor = [eaglview contentScaleFactor];
[_uiWebViewWrapper setFrameWithX:x/scaleFactor
y:y/scaleFactor
width:width/scaleFactor
height:height/scaleFactor];
}
void WebViewImpl::setBackgroundTransparent(bool isTransparent){
[_uiWebViewWrapper setBackgroundTransparent:isTransparent];
}
} //namespace cocos2d
#endif // (USE_WEB_VIEW > 0) && (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) && !defined(CC_TARGET_OS_TVOS)