From eff17eef1faeb1ecd663c6847b8f83c95e64408d Mon Sep 17 00:00:00 2001 From: dli Date: Tue, 22 May 2018 11:27:38 +0800 Subject: [PATCH] add plugin for iOS --- Core/plugin/base/ios/plugin_builder.mm | 19 +++ Core/plugin/base/ios/plugin_impl.h | 20 +++ Core/plugin/base/ios/plugin_impl.mm | 58 +++++++ Core/plugin/base/plugin.cc | 9 ++ Core/plugin/base/plugin.h | 27 ++++ Core/plugin/base/plugin_builder.h | 13 ++ Core/plugin/base/plugin_manager.cc | 70 +++++++++ Core/plugin/base/plugin_manager.h | 33 ++++ Core/plugin/impl/clipboard/clipboard.js | 9 ++ .../impl/net_info/ios/net_info_plugin.h | 11 ++ .../impl/net_info/ios/net_info_plugin.mm | 143 ++++++++++++++++++ Core/plugin/impl/net_info/netinfo.js | 16 ++ Core/plugin/plugin.js | 26 ++++ Core/runtime/global.cc | 10 +- Core/runtime/global.h | 8 +- Core/runtime/js/js_context.h | 2 +- iOS/assets.bundle/plugin.js | 0 iOS/lynx.xcodeproj/project.pbxproj | 102 +++++++++++++ iOS/lynx/base/ui_action_collector.mm | 2 +- 19 files changed, 574 insertions(+), 4 deletions(-) create mode 100644 Core/plugin/base/ios/plugin_builder.mm create mode 100644 Core/plugin/base/ios/plugin_impl.h create mode 100644 Core/plugin/base/ios/plugin_impl.mm create mode 100644 Core/plugin/base/plugin.cc create mode 100644 Core/plugin/base/plugin.h create mode 100644 Core/plugin/base/plugin_builder.h create mode 100644 Core/plugin/base/plugin_manager.cc create mode 100644 Core/plugin/base/plugin_manager.h create mode 100644 Core/plugin/impl/clipboard/clipboard.js create mode 100644 Core/plugin/impl/net_info/ios/net_info_plugin.h create mode 100644 Core/plugin/impl/net_info/ios/net_info_plugin.mm create mode 100644 Core/plugin/impl/net_info/netinfo.js create mode 100644 Core/plugin/plugin.js create mode 100644 iOS/assets.bundle/plugin.js diff --git a/Core/plugin/base/ios/plugin_builder.mm b/Core/plugin/base/ios/plugin_builder.mm new file mode 100644 index 00000000..86e8fe68 --- /dev/null +++ b/Core/plugin/base/ios/plugin_builder.mm @@ -0,0 +1,19 @@ +// +// plugin_register.m +// lynx +// +// Created by dli on 2018/5/20. +// Copyright © 2018年 lynx. All rights reserved. +// + + +#include "plugin/base/plugin_manager.h" +#include "plugin/base/plugin_builder.h" + +#import "plugin/impl/net_info/ios/net_info_plugin.h" + +namespace plugin { + void PluginBuilder::build(PluginManager* manager) { + [NetInfoPlugin createWithManager:manager]; + } +} diff --git a/Core/plugin/base/ios/plugin_impl.h b/Core/plugin/base/ios/plugin_impl.h new file mode 100644 index 00000000..48fc9a70 --- /dev/null +++ b/Core/plugin/base/ios/plugin_impl.h @@ -0,0 +1,20 @@ +#ifndef LYNX_PLUGIN_BASE_IOS_PLUGIN_MANAGER_H_ +#define LYNX_PLUGIN_BASE_IOS_PLUGIN_MANAGER_H_ + +#include "plugin/base/plugin.h" +#include "plugin/base/plugin_manager.h" + +@protocol PluginProtocol + +@required +-(void) Exec:(NSArray*)args; + +@end + + +@interface LynxPlugin : NSObject +-(id) initWithName:(NSString*)name pluginManager:(plugin::PluginManager*)manager; +-(void) Return:(NSNumber*) methodId resultType:(plugin::Plugin::ResultType)type argments:(NSArray*)args; +@end + +#endif // LYNX_PLUGIN_BASE_IOS_PLUGIN_MANAGER_H_ diff --git a/Core/plugin/base/ios/plugin_impl.mm b/Core/plugin/base/ios/plugin_impl.mm new file mode 100644 index 00000000..07600f99 --- /dev/null +++ b/Core/plugin/base/ios/plugin_impl.mm @@ -0,0 +1,58 @@ +#include "plugin/base/plugin.h" +#include "plugin/base/ios/plugin_impl.h" +#include "plugin/base/plugin_manager.h" +#include "base/log/logging.h" +#include "base/ios/oc_helper.h" + +#include + +namespace plugin { + class PluginImpl : public Plugin { + public: + PluginImpl(const char* name, PluginManager* manager, LynxPlugin* instance) : Plugin(manager), instance_(instance){ + manager->Register(name, this); + } + + virtual void Exec(base::ScopedPtr args) { + NSArray* array = base::ios::OCHelper::ConvertToOCArray(args.Get()); + [instance_ Exec:array]; + } + + private: + LynxPlugin* instance_; + }; +} + +@implementation LynxPlugin { + plugin::Plugin* delegate_; +} + +-(id) initWithName:(NSString*)name pluginManager:(plugin::PluginManager*)manager { + self = [super init]; + if(self != nil) { + delegate_ = new plugin::PluginImpl([name UTF8String], manager, self); + } + return self; +} + +-(void) Exec:(NSArray*)args { + NSString* methodName = [NSString stringWithFormat:@"%@:arguments:", [args objectAtIndex:1]]; + SEL normalSelector = NSSelectorFromString(methodName); + if ([self respondsToSelector:normalSelector]) { + ((void (*)(id, SEL, id, id))objc_msgSend)(self, normalSelector, [args objectAtIndex:2], [args objectAtIndex:3]); + } else { + NSLog(@"ERROR: Method '%@' not defined in Plugin '%@'", methodName, [args objectAtIndex:0]); + } +} + +-(void) Return:(NSNumber*) methodId resultType:(plugin::Plugin::ResultType)type argments:(NSArray*)args { + base::ScopedPtr array = base::ios::OCHelper::ConvertToLynxArray(args); + delegate_->Return([methodId intValue], type, array); +} + + + +@end + + + diff --git a/Core/plugin/base/plugin.cc b/Core/plugin/base/plugin.cc new file mode 100644 index 00000000..c9196800 --- /dev/null +++ b/Core/plugin/base/plugin.cc @@ -0,0 +1,9 @@ +#include "plugin/base/plugin.h" +#include "plugin/base/plugin_manager.h" + +namespace plugin { + void Plugin::Return(int method_id, ResultType type, base::ScopedPtr args){ + manager_->Return(method_id, type, args); + } +} + diff --git a/Core/plugin/base/plugin.h b/Core/plugin/base/plugin.h new file mode 100644 index 00000000..edd1e157 --- /dev/null +++ b/Core/plugin/base/plugin.h @@ -0,0 +1,27 @@ +#ifndef LYNX_PLUGIN_PLUGIN_H_ +#define LYNX_PLUGIN_PLUGIN_H_ + +#include "runtime/base/lynx_value.h" +#include "runtime/base/lynx_array.h" + +namespace plugin { + class PluginManager; + class Plugin { + public: + enum ResultType { + ResultType_Fail, + ResultType_Success, + ResultType_Event + }; + + Plugin(PluginManager* manager):manager_(manager){} + virtual ~Plugin(){} + virtual void Exec(base::ScopedPtr args){} + void AddEventListener(base::ScopedPtr args){} + void Return(int method_id, ResultType type, base::ScopedPtr args); + private: + PluginManager* manager_; + }; +} + +#endif diff --git a/Core/plugin/base/plugin_builder.h b/Core/plugin/base/plugin_builder.h new file mode 100644 index 00000000..31c04bc4 --- /dev/null +++ b/Core/plugin/base/plugin_builder.h @@ -0,0 +1,13 @@ + +#ifndef LYNX_PLUGIN_PLUGIN_BUILDER_H_ +#define LYNX_PLUGIN_PLUGIN_BUILDER_H_ + +namespace plugin { + class PluginManager; + class PluginBuilder { + public: + static void build(PluginManager* manager); + }; +} + +#endif diff --git a/Core/plugin/base/plugin_manager.cc b/Core/plugin/base/plugin_manager.cc new file mode 100644 index 00000000..2be2002d --- /dev/null +++ b/Core/plugin/base/plugin_manager.cc @@ -0,0 +1,70 @@ +#include "plugin/base/plugin_manager.h" + +#include "plugin/base/plugin.h" +#include "runtime/base/lynx_value.h" +#include "runtime/base/lynx_array.h" +#include "runtime/js/class_template.h" + +#include "base/log/logging.h" + +#include "plugin/base/plugin_builder.h" + +namespace plugin { + + #define FOR_EACH_METHOD_BINDING(V) \ + V(PluginManager, Exec) \ + V(PluginManager, Init) \ + + // Defines methods and fields + FOR_EACH_METHOD_BINDING(DEFINE_METHOD_CALLBACK) + + // Defines default ClassTemplate + DEFINE_CLASS_TEMPLATE_START(PluginManager) + EXPOSE_CONSTRUCTOR(true) + FOR_EACH_METHOD_BINDING(REGISTER_METHOD_CALLBACK) + DEFINE_CLASS_TEMPLATE_END + + PluginManager::PluginManager(jscore::JSContext* context) : LynxObject(context, DEFAULT_CLASS_TEMPLATE(context)), context_(context){ + + } + + PluginManager::~PluginManager() { + + } + + void PluginManager::Register(const char* name, Plugin* plugin) { + plugins_.add(name, plugin); + } + + base::ScopedPtr PluginManager::Init(base::ScopedPtr& array) { + PluginBuilder::build(this); + callback_.Reset(array->Get(0)->data_.lynx_function); + return base::ScopedPtr(NULL); + } + + base::ScopedPtr PluginManager::Exec(base::ScopedPtr& array) { + std::string module_name(array->Get(0)->data_.str); + Plugins::iterator iter = plugins_.find(module_name); + if(iter == plugins_.end()) { + DLOG(ERROR) << ""; + return base::ScopedPtr(NULL); + } + iter->second->Exec(array); + return base::ScopedPtr(NULL); + } + + void PluginManager::Return(int method_id, Plugin::ResultType type, base::ScopedPtr& result){ + if(context_) { + context_->runtime()->thread_manager()->RunOnJSThread(base::Bind(&PluginManager::ReturnOnJSThread, + base::ScopedRefPtr(this), method_id, type, result)); + } + } + + void PluginManager::ReturnOnJSThread(int method_id, Plugin::ResultType type, base::ScopedPtr result) { + base::ScopedPtr args(lynx_new jscore::LynxArray); + args->Push(jscore::LynxValue::MakeInt(method_id).Release()); + args->Push(jscore::LynxValue::MakeInt(type).Release()); + args->Push(result.Release()); + callback_->Run(this, args.Get()); + } +} diff --git a/Core/plugin/base/plugin_manager.h b/Core/plugin/base/plugin_manager.h new file mode 100644 index 00000000..9cc12e48 --- /dev/null +++ b/Core/plugin/base/plugin_manager.h @@ -0,0 +1,33 @@ +#ifndef LYNX_PLUGIN_PLUGIN_MANAGER_H_ +#define LYNX_PLUGIN_PLUGIN_MANAGER_H_ + +#include "runtime/base/lynx_object.h" +#include "runtime/runtime.h" +#include "base/scoped_ptr_map.h" +#include "plugin/base/plugin.h" + +namespace plugin { + + class PluginManager : public jscore::LynxObject { + public: + PluginManager(jscore::JSContext* context); + virtual ~PluginManager(); + + base::ScopedPtr Init(base::ScopedPtr& array); + base::ScopedPtr Exec(base::ScopedPtr& array); + void Return(int method_id, Plugin::ResultType type, base::ScopedPtr& result); + void Register(const char* name, Plugin* plugin); + private: + void ReturnOnJSThread(int method_id, Plugin::ResultType type, base::ScopedPtr result); + + typedef base::ScopedPtrMap Plugins; + Plugins plugins_; + + base::ScopedPtr callback_; + + jscore::JSContext* context_; + private: + DISALLOW_COPY_AND_ASSIGN(PluginManager); + }; +} +#endif diff --git a/Core/plugin/impl/clipboard/clipboard.js b/Core/plugin/impl/clipboard/clipboard.js new file mode 100644 index 00000000..5c01b28d --- /dev/null +++ b/Core/plugin/impl/clipboard/clipboard.js @@ -0,0 +1,9 @@ +var Clipboard = {} +Clipboard.getString = function(callback) { + exec('NetInfo', 'getString', [], callback, null) +} + +Clipboard.setString = function(content) { + exec('NetInfo', 'setString', [content], null, null) +} + diff --git a/Core/plugin/impl/net_info/ios/net_info_plugin.h b/Core/plugin/impl/net_info/ios/net_info_plugin.h new file mode 100644 index 00000000..7e799085 --- /dev/null +++ b/Core/plugin/impl/net_info/ios/net_info_plugin.h @@ -0,0 +1,11 @@ +#include "plugin/base/ios/plugin_impl.h" + +#include "plugin/base/plugin_manager.h" + +@interface NetInfoPlugin : LynxPlugin + +@property (atomic, readwrite) NSString* networkStatus; + ++(void) createWithManager: (plugin::PluginManager*)manager; + +@end diff --git a/Core/plugin/impl/net_info/ios/net_info_plugin.mm b/Core/plugin/impl/net_info/ios/net_info_plugin.mm new file mode 100644 index 00000000..a213bf08 --- /dev/null +++ b/Core/plugin/impl/net_info/ios/net_info_plugin.mm @@ -0,0 +1,143 @@ +// +// net_info_plugin.m +// lynx +// +// Created by dli on 2018/5/20. +// Copyright © 2018年 lynx. All rights reserved. +// + +#import +#import +#import +#import "AFNetworkReachabilityManager.h" + +#include "plugin/impl/net_info/ios/net_info_plugin.h" + +@implementation NetInfoPlugin + + ++(void) createWithManager: (plugin::PluginManager*)manager { + [[NetInfoPlugin alloc] initWithManager:manager]; +} + +-(id) initWithManager: (plugin::PluginManager*)manager { + self = [super initWithName:@"NetInfo" pluginManager:manager]; + if(self != nil) { + self.networkStatus = @"unknown"; + [self startNetworkStatusObserver]; + } + return self; +} + +-(void) dealloc { + [self stopNetworkStatusObserver]; +} + +-(void) getConnectInfo: (NSNumber*)methodId arguments:(NSArray*) args { + dispatch_sync(dispatch_get_main_queue(), ^{ + NSMutableArray* result = [[NSMutableArray alloc]init]; + [result addObject:[self networkingStatesFromStatebar]]; + [self Return:methodId resultType:plugin::Plugin::ResultType_Success argments:result]; + }); +} + +-(void) startNetworkStatusObserver { + AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager]; + [mgr setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { + switch (status) { + case AFNetworkReachabilityStatusUnknown://未知网络 + _networkStatus = @"unknown"; + break; + case AFNetworkReachabilityStatusNotReachable://没有网络(断网) + _networkStatus = @"none"; + break; + case AFNetworkReachabilityStatusReachableViaWWAN://手机自带网络 + _networkStatus = [self getCellularStates]; + break; + case AFNetworkReachabilityStatusReachableViaWiFi:// WIFI + _networkStatus = @"wifi"; + break; + default: + _networkStatus = @"unknown"; + break; + } + + }]; + [mgr startMonitoring]; +} + +-(void) stopNetworkStatusObserver { + AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager]; + [mgr stopMonitoring]; +} + +- (NSString *)getCellularStates{ + if ([[[UIDevice currentDevice] systemVersion] compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending) { + CTTelephonyNetworkInfo *telephonyInfo = [CTTelephonyNetworkInfo new]; + if ([telephonyInfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyGPRS]) { + return @"2g"; + } else if ([telephonyInfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyEdge]) { + return @"2g"; + } else if ([telephonyInfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyWCDMA]) { + return @"3g"; + } else if ([telephonyInfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyHSDPA]) { + return @"3g"; + } else if ([telephonyInfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyHSUPA]) { + return @"3g"; + } else if ([telephonyInfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMA1x]) { + return @"3g"; + } else if ([telephonyInfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORev0]) { + return @"3g"; + } else if ([telephonyInfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORevA]) { + return @"3g"; + } else if ([telephonyInfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORevB]) { + return @"3g"; + } else if ([telephonyInfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyeHRPD]) { + return @"3g"; + } else if ([telephonyInfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyLTE]) { + return @"4g"; + } + } + return @"cellular"; +} + +- (NSString *)networkingStatesFromStatebar { + // 状态栏是由当前app控制的,首先获取当前app + UIApplication *app = [UIApplication sharedApplication]; + NSArray *children = [[[app valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews]; + int type = 0; + for (id child in children) { + if ([child isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]]) { + type = [[child valueForKeyPath:@"dataNetworkType"] intValue]; + } + } + NSString *state = @"unknown"; + + switch (type) { + case 0: + state = @"none"; + break; + case 1: + state = @"2G"; + break; + case 2: + state = @"3G"; + break; + case 3: + state = @"4G"; + break; + case 4: + state = @"4G"; + break; + case 5: + state = @"wifi"; + break; + default: + state = @"unknown"; + break; + } + + return state; +} + +@end diff --git a/Core/plugin/impl/net_info/netinfo.js b/Core/plugin/impl/net_info/netinfo.js new file mode 100644 index 00000000..02eda14f --- /dev/null +++ b/Core/plugin/impl/net_info/netinfo.js @@ -0,0 +1,16 @@ +var NetInfo = {} +NetInfo.getConnectInfo = function(callback) { + exec('NetInfo', 'getConnectInfo', [], callback, null) +} + +NetInfo.isConnected = function(callback) { + exec('NetInfo', 'isConnected', [], callback, null) +} + +NetInfo.addEventListener = function(event, callback) { + exec('NetInfo', 'addEventListener', [event, callback], null, null) +} + +NetInfo.removeEventListener = function(event, callback) { + exec('NetInfo', 'removeEventListener', [event, callback], null, null) +} diff --git a/Core/plugin/plugin.js b/Core/plugin/plugin.js new file mode 100644 index 00000000..2d82c10c --- /dev/null +++ b/Core/plugin/plugin.js @@ -0,0 +1,26 @@ + +function exec(module, method, args, onSuccess, onFail) { + var callbackId = plugin.callbackId++ + if (onSuccess || onFail) { + plugin.callbacks[callbackId] = {success:onSuccess, fail:onFail}; + } + plugin.exec(module, method, callbackId, args) +} + +function callbackFromNative(callbackId, status, args) { + + var callback = plugin.callbacks[callbackId]; + if (callback) { + if (status === 0) { + callback.fail.apply(null, args); + } else if (status === 1) { + callback.success.apply(null, args); + } + delete plugin.callbacks[callbackId]; + } +} + +plugin.callbackId = 0 +plugin.callbacks = {} +plugin.init(callbackFromNative) + diff --git a/Core/runtime/global.cc b/Core/runtime/global.cc index 740bcb73..90e5cbd9 100644 --- a/Core/runtime/global.cc +++ b/Core/runtime/global.cc @@ -12,6 +12,7 @@ #include "runtime/base/lynx_array.h" #include "runtime/js/defines.h" #include "runtime/js/js_context.h" +#include "plugin/base/plugin_manager.h" namespace jscore { @@ -27,7 +28,8 @@ namespace jscore { V(Global, Navigator) \ V(Global, Screen) \ V(Global, Loader) \ - V(Global, Document) + V(Global, Document) \ + V(Global, Plugin) // Defines methods and fields FOR_EACH_METHOD_BINDING(DEFINE_METHOD_CALLBACK) @@ -66,6 +68,9 @@ namespace jscore { loader_->ProtectJSObject(); document_ = lynx_new Document(context_); document_->ProtectJSObject(); + + plugin_ = lynx_new plugin::PluginManager(context_); + plugin_->ProtectJSObject(); } base::ScopedPtr Global::SetTimeout(base::ScopedPtr &array) { @@ -125,5 +130,8 @@ namespace jscore { return LynxValue::MakeObject(document()); } + base::ScopedPtr Global::GetPlugin() { + return LynxValue::MakeObject(plugin()); + } } diff --git a/Core/runtime/global.h b/Core/runtime/global.h index 15bb9f95..d8186c4c 100644 --- a/Core/runtime/global.h +++ b/Core/runtime/global.h @@ -5,6 +5,10 @@ #include "runtime/base/lynx_object.h" +namespace plugin{ + class PluginManager; +} + namespace jscore { class Console; class Navigator; @@ -22,6 +26,7 @@ namespace jscore { inline Screen* screen() { return screen_.Get(); } inline Loader* loader() { return loader_.Get(); } inline Document* document() { return document_.Get(); } + inline plugin::PluginManager* plugin() { return plugin_.Get(); } base::ScopedPtr SetTimeout(base::ScopedPtr &array); base::ScopedPtr SetInterval(base::ScopedPtr &array); @@ -34,6 +39,7 @@ namespace jscore { base::ScopedPtr GetScreen(); base::ScopedPtr GetLoader(); base::ScopedPtr GetDocument(); + base::ScopedPtr GetPlugin(); private: base::ScopedRefPtr console_; @@ -41,7 +47,7 @@ namespace jscore { base::ScopedRefPtr screen_; base::ScopedRefPtr loader_; base::ScopedRefPtr document_; - + base::ScopedRefPtr plugin_; DISALLOW_COPY_AND_ASSIGN(Global); }; } diff --git a/Core/runtime/js/js_context.h b/Core/runtime/js/js_context.h index a7609c61..a88e191d 100644 --- a/Core/runtime/js/js_context.h +++ b/Core/runtime/js/js_context.h @@ -13,7 +13,7 @@ namespace jscore { class Runtime; class Global; class LynxObjectPlatform; -class JSContext : public base::RefCountPtr { +class JSContext : public base::RefCountPtr { public: JSContext(); diff --git a/iOS/assets.bundle/plugin.js b/iOS/assets.bundle/plugin.js new file mode 100644 index 00000000..e69de29b diff --git a/iOS/lynx.xcodeproj/project.pbxproj b/iOS/lynx.xcodeproj/project.pbxproj index 076c6052..283cb03b 100644 --- a/iOS/lynx.xcodeproj/project.pbxproj +++ b/iOS/lynx.xcodeproj/project.pbxproj @@ -19,6 +19,15 @@ 421438F7207DF52E00ECF750 /* application_info.mm in Sources */ = {isa = PBXBuildFile; fileRef = 421438EE207DF52D00ECF750 /* application_info.mm */; }; 421438F8207DF52E00ECF750 /* page_info.mm in Sources */ = {isa = PBXBuildFile; fileRef = 421438F2207DF52D00ECF750 /* page_info.mm */; }; 421438F9207DF52E00ECF750 /* resource_manager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 421438F4207DF52D00ECF750 /* resource_manager.mm */; }; + 4214C31720B17EEC005EC1ED /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4214C31620B17EEC005EC1ED /* CoreTelephony.framework */; }; + 4214C32F20B2D4D3005EC1ED /* netinfo.js in Resources */ = {isa = PBXBuildFile; fileRef = 4214C31F20B2D4D3005EC1ED /* netinfo.js */; }; + 4214C33020B2D4D3005EC1ED /* clipboard.js in Resources */ = {isa = PBXBuildFile; fileRef = 4214C32120B2D4D3005EC1ED /* clipboard.js */; }; + 4214C33120B2D4D3005EC1ED /* plugin.js in Resources */ = {isa = PBXBuildFile; fileRef = 4214C32220B2D4D3005EC1ED /* plugin.js */; }; + 4214C33220B2D4D3005EC1ED /* plugin_manager.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4214C32520B2D4D3005EC1ED /* plugin_manager.cc */; }; + 4214C33320B2D4D3005EC1ED /* plugin.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4214C32720B2D4D3005EC1ED /* plugin.cc */; }; + 4214C33420B2D4D3005EC1ED /* plugin_builder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4214C32920B2D4D3005EC1ED /* plugin_builder.mm */; }; + 4214C33520B2D4D3005EC1ED /* plugin_impl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4214C32B20B2D4D3005EC1ED /* plugin_impl.mm */; }; + 4214C33920B2D5D3005EC1ED /* net_info_plugin.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4214C33720B2D5D3005EC1ED /* net_info_plugin.mm */; }; 42178E7F20994E7B001B8A48 /* builtin.cc in Sources */ = {isa = PBXBuildFile; fileRef = 42177F5B20994E6A001B8A48 /* builtin.cc */; }; 42178E8020994E7B001B8A48 /* table.cc in Sources */ = {isa = PBXBuildFile; fileRef = 42177F5C20994E6A001B8A48 /* table.cc */; }; 42178E8120994E7B001B8A48 /* function.cc in Sources */ = {isa = PBXBuildFile; fileRef = 42177F5F20994E6A001B8A48 /* function.cc */; }; @@ -453,6 +462,20 @@ 421438F3207DF52D00ECF750 /* application_info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = application_info.h; sourceTree = ""; }; 421438F4207DF52D00ECF750 /* resource_manager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = resource_manager.mm; sourceTree = ""; }; 421438F5207DF52D00ECF750 /* resource_reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resource_reader.h; sourceTree = ""; }; + 4214C31620B17EEC005EC1ED /* CoreTelephony.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreTelephony.framework; path = System/Library/Frameworks/CoreTelephony.framework; sourceTree = SDKROOT; }; + 4214C31F20B2D4D3005EC1ED /* netinfo.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = netinfo.js; sourceTree = ""; }; + 4214C32120B2D4D3005EC1ED /* clipboard.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = clipboard.js; sourceTree = ""; }; + 4214C32220B2D4D3005EC1ED /* plugin.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = plugin.js; sourceTree = ""; }; + 4214C32420B2D4D3005EC1ED /* plugin_builder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = plugin_builder.h; sourceTree = ""; }; + 4214C32520B2D4D3005EC1ED /* plugin_manager.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = plugin_manager.cc; sourceTree = ""; }; + 4214C32620B2D4D3005EC1ED /* plugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = plugin.h; sourceTree = ""; }; + 4214C32720B2D4D3005EC1ED /* plugin.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = plugin.cc; sourceTree = ""; }; + 4214C32920B2D4D3005EC1ED /* plugin_builder.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = plugin_builder.mm; sourceTree = ""; }; + 4214C32A20B2D4D3005EC1ED /* plugin_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = plugin_impl.h; sourceTree = ""; }; + 4214C32B20B2D4D3005EC1ED /* plugin_impl.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = plugin_impl.mm; sourceTree = ""; }; + 4214C32D20B2D4D3005EC1ED /* plugin_manager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = plugin_manager.h; sourceTree = ""; }; + 4214C33720B2D5D3005EC1ED /* net_info_plugin.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = net_info_plugin.mm; sourceTree = ""; }; + 4214C33820B2D5D3005EC1ED /* net_info_plugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = net_info_plugin.h; sourceTree = ""; }; 42177F5920994E6A001B8A48 /* semantic_analysis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = semantic_analysis.h; sourceTree = ""; }; 42177F5A20994E6A001B8A48 /* utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utils.h; sourceTree = ""; }; 42177F5B20994E6A001B8A48 /* builtin.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = builtin.cc; sourceTree = ""; }; @@ -961,6 +984,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 4214C31720B17EEC005EC1ED /* CoreTelephony.framework in Frameworks */, BCE8BAAF1DF59F9A008B4A45 /* Foundation.framework in Frameworks */, BCE8BA7A1DF54DA0008B4A45 /* CoreFoundation.framework in Frameworks */, 42D7BD751DCB8C27000BE5A5 /* UIKit.framework in Frameworks */, @@ -1014,9 +1038,78 @@ path = app; sourceTree = ""; }; + 4214C31A20B2D4D3005EC1ED /* plugin */ = { + isa = PBXGroup; + children = ( + 4214C31B20B2D4D3005EC1ED /* impl */, + 4214C32220B2D4D3005EC1ED /* plugin.js */, + 4214C32320B2D4D3005EC1ED /* base */, + ); + path = plugin; + sourceTree = ""; + }; + 4214C31B20B2D4D3005EC1ED /* impl */ = { + isa = PBXGroup; + children = ( + 4214C32020B2D4D3005EC1ED /* clipboard */, + 4214C31C20B2D4D3005EC1ED /* net_info */, + ); + path = impl; + sourceTree = ""; + }; + 4214C31C20B2D4D3005EC1ED /* net_info */ = { + isa = PBXGroup; + children = ( + 4214C33620B2D5D3005EC1ED /* ios */, + 4214C31F20B2D4D3005EC1ED /* netinfo.js */, + ); + path = net_info; + sourceTree = ""; + }; + 4214C32020B2D4D3005EC1ED /* clipboard */ = { + isa = PBXGroup; + children = ( + 4214C32120B2D4D3005EC1ED /* clipboard.js */, + ); + path = clipboard; + sourceTree = ""; + }; + 4214C32320B2D4D3005EC1ED /* base */ = { + isa = PBXGroup; + children = ( + 4214C32420B2D4D3005EC1ED /* plugin_builder.h */, + 4214C32520B2D4D3005EC1ED /* plugin_manager.cc */, + 4214C32620B2D4D3005EC1ED /* plugin.h */, + 4214C32720B2D4D3005EC1ED /* plugin.cc */, + 4214C32820B2D4D3005EC1ED /* ios */, + 4214C32D20B2D4D3005EC1ED /* plugin_manager.h */, + ); + path = base; + sourceTree = ""; + }; + 4214C32820B2D4D3005EC1ED /* ios */ = { + isa = PBXGroup; + children = ( + 4214C32920B2D4D3005EC1ED /* plugin_builder.mm */, + 4214C32A20B2D4D3005EC1ED /* plugin_impl.h */, + 4214C32B20B2D4D3005EC1ED /* plugin_impl.mm */, + ); + path = ios; + sourceTree = ""; + }; + 4214C33620B2D5D3005EC1ED /* ios */ = { + isa = PBXGroup; + children = ( + 4214C33720B2D5D3005EC1ED /* net_info_plugin.mm */, + 4214C33820B2D5D3005EC1ED /* net_info_plugin.h */, + ); + path = ios; + sourceTree = ""; + }; 42177F3F20994E6A001B8A48 /* Core */ = { isa = PBXGroup; children = ( + 4214C31A20B2D4D3005EC1ED /* plugin */, 421795E520994EEA001B8A48 /* third_party */, 42177F5820994E6A001B8A48 /* lepus */, 42177F7F20994E6A001B8A48 /* net */, @@ -2024,6 +2117,7 @@ C87C9478FB7710D58B019813 /* Frameworks */ = { isa = PBXGroup; children = ( + 4214C31620B17EEC005EC1ED /* CoreTelephony.framework */, DC31330FD8AEB81CA3C6EA60 /* libPods-lynx.a */, ); name = Frameworks; @@ -2131,7 +2225,10 @@ 425BCA0320A69F3E008AAFC0 /* gtest-param-util-generated.h.pump in Resources */, 4217A90220994F04001B8A48 /* sconscript in Resources */, 4217A90420994F04001B8A48 /* json_valueiterator.inl in Resources */, + 4214C33120B2D4D3005EC1ED /* plugin.js in Resources */, 4217A90520994F04001B8A48 /* init.sh in Resources */, + 4214C33020B2D4D3005EC1ED /* clipboard.js in Resources */, + 4214C32F20B2D4D3005EC1ED /* netinfo.js in Resources */, 4217A90020994F04001B8A48 /* version.h.in in Resources */, BC9D343A1E1DEC92009BD30A /* Assets.xcassets in Resources */, 425BCA0120A69F3E008AAFC0 /* gtest-tuple.h.pump in Resources */, @@ -2407,6 +2504,7 @@ buildActionMask = 2147483647; files = ( BC5DBDB41F5EC7BE005A47E3 /* view_wrapper.mm in Sources */, + 4214C33520B2D4D3005EC1ED /* plugin_impl.mm in Sources */, 421438E5207DE59F00ECF750 /* coordinator_pretreatment.mm in Sources */, 42178E8B20994E7B001B8A48 /* url_request_context.cc in Sources */, BC31B01D1F6271BE00C0234C /* ui_event_action.mm in Sources */, @@ -2480,6 +2578,7 @@ 42178F0520994E7B001B8A48 /* element.cc in Sources */, 42178F2120994E7B001B8A48 /* command_collector.cc in Sources */, BC31B0291F6284D200C0234C /* render_tree_host_impl_bridge.mm in Sources */, + 4214C33220B2D4D3005EC1ED /* plugin_manager.cc in Sources */, 421795BA20994E84001B8A48 /* select_poller.cc in Sources */, BCDEC7D8209C518C000B0D50 /* class_template.cc in Sources */, 42178F4320994E7B001B8A48 /* input_stream.cc in Sources */, @@ -2536,6 +2635,8 @@ 42178E8920994E7B001B8A48 /* scanner.cc in Sources */, 42178F3F20994E7B001B8A48 /* body.cc in Sources */, BC8040951FCA5C620041CF01 /* module.mm in Sources */, + 4214C33920B2D5D3005EC1ED /* net_info_plugin.mm in Sources */, + 4214C33320B2D4D3005EC1ED /* plugin.cc in Sources */, 421795AD20994E84001B8A48 /* html_request_delegate.cc in Sources */, 42178F1020994E7B001B8A48 /* js_vm.cc in Sources */, 42178EC220994E7B001B8A48 /* websocket_errors.cc in Sources */, @@ -2545,6 +2646,7 @@ 421795D020994E85001B8A48 /* string_number_convert.cc in Sources */, 421795B920994E84001B8A48 /* utility.cc in Sources */, 42178EDB20994E7B001B8A48 /* css_color.cc in Sources */, + 4214C33420B2D4D3005EC1ED /* plugin_builder.mm in Sources */, BC31B0161F624F6D00C0234C /* lynx_ui_body.mm in Sources */, 42178F2F20994E7B001B8A48 /* extended_view.cc in Sources */, 421438E8207DE59F00ECF750 /* coordinator_action_executor.mm in Sources */, diff --git a/iOS/lynx/base/ui_action_collector.mm b/iOS/lynx/base/ui_action_collector.mm index e4e4c4f5..3fc0efff 100644 --- a/iOS/lynx/base/ui_action_collector.mm +++ b/iOS/lynx/base/ui_action_collector.mm @@ -49,7 +49,7 @@ - (void)collectAction:(LynxUIAction *)action { } - (BOOL)needDoAction { - return !(_eventActions.count == 0 && _updateDataActions.count == 0); + return !(_eventActions && _eventActions.count == 0 && _updateDataActions && _updateDataActions.count == 0); } - (void)doActions {