123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485 |
- /****************************************************************************
- 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 (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) && !defined(CC_TARGET_OS_TVOS)
- #include "ui/UIWebViewImpl-ios.h"
- #include "renderer/CCRenderer.h"
- #include "base/CCDirector.h"
- #include "platform/CCGLView.h"
- #include "platform/ios/CCEAGLView-ios.h"
- #include "platform/CCFileUtils.h"
- #include "ui/UIWebView.h"
- #import <JavaScriptCore/JavaScriptCore.h>
- static std::string getFixedBaseUrl(const std::string& baseUrl)
- {
- std::string fixedBaseUrl;
- if (baseUrl.empty() || baseUrl.at(0) != '/') {
- fixedBaseUrl = [[[NSBundle mainBundle] resourcePath] UTF8String];
- fixedBaseUrl += "/";
- fixedBaseUrl += baseUrl;
- }
- else {
- fixedBaseUrl = baseUrl;
- }
-
- size_t pos = 0;
- while ((pos = fixedBaseUrl.find(" ")) != std::string::npos) {
- fixedBaseUrl.replace(pos, 1, "%20");
- }
-
- if (fixedBaseUrl.at(fixedBaseUrl.length() - 1) != '/') {
- fixedBaseUrl += "/";
- }
-
- return fixedBaseUrl;
- }
- @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)newWebViewWrapper;
- - (void)setVisible:(bool)visible;
- - (void)setBounces:(bool)bounces;
- - (void)setOpacityWebView:(float)opacity;
- - (float)getOpacityWebView;
- - (void)setBackgroundTransparent;
- - (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 cleanCachedData:(BOOL) needCleanCachedData;
- - (void)loadFile:(const std::string &)filePath;
- - (void)postUrl:(const std::string &)url data:(const std::string &)data;
- - (void)stopLoading;
- - (void)reload;
- - (void)evaluateJS:(const std::string &)js;
- - (void)goBack;
- - (void)goForward;
- - (void)OpenApp:(const std::string &)js;
- - (void)setScalesPageToFit:(const bool)scalesPageToFit;
- @end
- @interface UIWebViewWrapper () <UIWebViewDelegate>
- @property(nonatomic, retain) UIWebView *uiWebView;
- @property(nonatomic) JSContext* jsContext;
- @property(nonatomic, copy) NSString *jsScheme;
- @end
- @implementation UIWebViewWrapper {
-
- }
- + (instancetype) newWebViewWrapper {
- return [[self alloc] init];
- }
- - (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.delegate = nil;
- [self.uiWebView removeFromSuperview];
- [self.uiWebView release];
- self.uiWebView = nil;
- self.jsScheme = nil;
- [super dealloc];
- }
- - (void)setupWebView {
- if (!self.uiWebView) {
- self.uiWebView = [[UIWebView alloc] init];
- self.uiWebView.delegate = self;
- self.uiWebView.scrollView.bounces = NO;
- }
- if (!self.uiWebView.superview) {
- auto view = cocos2d::Director::getInstance()->getOpenGLView();
- auto eaglview = (CCEAGLView *) view->getEAGLView();
- [eaglview addSubview:self.uiWebView];
- }
- }
- - (void)setVisible:(bool)visible {
- if (!self.uiWebView) {[self setupWebView];}
- self.uiWebView.hidden = !visible;
- }
- - (void)setBounces:(bool)bounces {
- self.uiWebView.scrollView.bounces = bounces;
- }
- - (void)setOpacityWebView:(float)opacity {
- if (!self.uiWebView) {[self setupWebView];}
- self.uiWebView.alpha=opacity;
- [self.uiWebView setOpaque:NO];
- }
- -(float) getOpacityWebView{
- return self.uiWebView.alpha;
- }
- -(void) setBackgroundTransparent{
- if (!self.uiWebView) {[self setupWebView];}
- [self.uiWebView setOpaque:NO];
- [self.uiWebView setBackgroundColor:[UIColor clearColor]];
- }
- - (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 {
- [self.uiWebView loadData:[NSData dataWithBytes:data.c_str() length:data.length()]
- MIMEType:@(MIMEType.c_str())
- textEncodingName:@(encodingName.c_str())
- baseURL:[NSURL URLWithString:@(getFixedBaseUrl(baseURL).c_str())]];
- }
- - (void)loadHTMLString:(const std::string &)string baseURL:(const std::string &)baseURL {
- if (!self.uiWebView) {[self setupWebView];}
- [self.uiWebView loadHTMLString:@(string.c_str()) baseURL:[NSURL URLWithString:@(getFixedBaseUrl(baseURL).c_str())]];
- }
- - (void)loadUrl:(const std::string &)urlString cleanCachedData:(BOOL) needCleanCachedData {
- if (!self.uiWebView) {[self setupWebView];}
- NSURL *url = [NSURL URLWithString:@(urlString.c_str())];
- NSURLRequest *request = nil;
- if (needCleanCachedData)
- request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
- else
- 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)postUrl:(const std::string &)url data:(const std::string &)data{
- if (!self.uiWebView) {[self setupWebView];}
- NSURL *url2 = [NSURL URLWithString: @(url.c_str())];
- NSString *body = [[NSString alloc] initWithUTF8String:data.c_str()];
- NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL: url2];
- [request setHTTPMethod: @"POST"];
- [request setHTTPBody: [body dataUsingEncoding: NSUTF8StringEncoding]];
- [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)OpenApp:(const std::string &)js
- {
- NSLog(@"OpenApp %@",js.c_str());
- }
- - (void)evaluateJS:(const std::string &)js {
- if (!self.uiWebView) {[self setupWebView];}
- [self.uiWebView stringByEvaluatingJavaScriptFromString:@(js.c_str())];
- }
- - (void)setScalesPageToFit:(const bool)scalesPageToFit {
- if (!self.uiWebView) {[self setupWebView];}
- self.uiWebView.scalesPageToFit = scalesPageToFit;
- }
- #pragma mark - UIWebViewDelegate
- - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
- NSString *url = [[request URL] absoluteString];
- if ([[[request URL] scheme] isEqualToString:self.jsScheme]) {
- self.onJsCallback([url UTF8String]);
- return NO;
- }
- if (self.shouldStartLoading && url) {
- return self.shouldStartLoading([url UTF8String]);
- }
- return YES;
- }
- - (void)webViewDidFinishLoad:(UIWebView *)webView {
- if (self.didFinishLoading) {
- NSString *url = [[webView.request URL] absoluteString];
- self.didFinishLoading([url UTF8String]);
- }
-
- _jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
- _jsContext[@"OpenAppEx"] = ^(NSString* str) {
- NSArray *args = [JSContext currentArguments];
-
- dispatch_async(dispatch_get_main_queue(), ^{
- self.onJsCallback([str UTF8String]);
- });
- };
-
- _jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
- context.exception = exceptionValue;
- NSLog(@"Òì³£ÐÅÏ¢£º%@", exceptionValue);
- };
-
- }
- - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
- if (self.didFailLoading) {
- NSString *url = error.userInfo[NSURLErrorFailingURLStringErrorKey];
- if (url) {
- self.didFailLoading([url UTF8String]);
- }
- }
- }
- @end
- namespace cocos2d {
- namespace experimental {
- namespace ui{
- WebViewImpl::WebViewImpl(WebView *webView)
- : _uiWebViewWrapper([UIWebViewWrapper newWebViewWrapper]),
- _webView(webView) {
-
- _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) {
- this->loadURL(url, false);
- }
- void WebViewImpl::loadURL(const std::string &url, bool cleanCachedData) {
- [_uiWebViewWrapper loadUrl:url cleanCachedData:cleanCachedData];
- }
- void WebViewImpl::loadFile(const std::string &fileName) {
- auto fullPath = cocos2d::FileUtils::getInstance()->fullPathForFilename(fileName);
- [_uiWebViewWrapper loadFile:fullPath];
- }
- void WebViewImpl::PostURL(const std::string &url, const std::string &data)
- {
- [_uiWebViewWrapper postUrl:url data:data];
- }
- 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::draw(cocos2d::Renderer *renderer, cocos2d::Mat4 const &transform, uint32_t flags) {
- if (flags & cocos2d::Node::FLAGS_TRANSFORM_DIRTY) {
-
- auto director = cocos2d::Director::getInstance();
- auto glView = director->getOpenGLView();
- auto frameSize = glView->getFrameSize();
-
- auto scaleFactor = [static_cast<CCEAGLView *>(glView->getEAGLView()) contentScaleFactor];
- auto winSize = director->getWinSize();
- auto leftBottom = this->_webView->convertToWorldSpace(cocos2d::Vec2::ZERO);
- auto rightTop = this->_webView->convertToWorldSpace(cocos2d::Vec2(this->_webView->getContentSize().width, this->_webView->getContentSize().height));
- auto x = (frameSize.width / 2 + (leftBottom.x - winSize.width / 2) * glView->getScaleX()) / scaleFactor;
- auto y = (frameSize.height / 2 - (rightTop.y - winSize.height / 2) * glView->getScaleY()) / scaleFactor;
- auto width = (rightTop.x - leftBottom.x) * glView->getScaleX() / scaleFactor;
- auto height = (rightTop.y - leftBottom.y) * glView->getScaleY() / scaleFactor;
- [_uiWebViewWrapper setFrameWithX:x
- y:y
- width:width
- height:height];
- }
- }
- void WebViewImpl::setVisible(bool visible){
- [_uiWebViewWrapper setVisible:visible];
- }
-
- void WebViewImpl::setOpacityWebView(float opacity){
- [_uiWebViewWrapper setOpacityWebView: opacity];
- }
-
- float WebViewImpl::getOpacityWebView() const{
- return [_uiWebViewWrapper getOpacityWebView];
- }
- void WebViewImpl::setBackgroundTransparent(){
- [_uiWebViewWrapper setBackgroundTransparent];
- }
-
- } // namespace ui
- } // namespace experimental
- } //namespace cocos2d
- #endif // CC_TARGET_PLATFORM == CC_PLATFORM_IOS
|