| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552 | 
							- #import "DWKWebView.h"
 
- #import "JSBUtil.h"
 
- #import "DSCallInfo.h"
 
- #import "InternalApis.h"
 
- #import <objc/message.h>
 
- @protocol ScriptDelegate <NSObject>
 
- -(NSString *)call:(NSString*) method :(NSString*) argStr;
 
- @end
 
- @interface InternalScriptsHandler : NSObject<WKScriptMessageHandler>
 
- @property (nonatomic, weak) id<ScriptDelegate> handler;
 
- @end
 
- @implementation InternalScriptsHandler
 
- - (instancetype)initWithHandler:(id<ScriptDelegate>)handler {
 
-     self = [super init];
 
-     if (self) {
 
-         _handler = handler;
 
-     }
 
-     return self;
 
- }
 
- - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
 
- {
 
-     NSDictionary *dict = message.body;
 
-     if ([dict isKindOfClass:[NSDictionary class]]) {
 
-         NSString *method = dict[@"method"];
 
-         NSString *arg = dict[@"arg"];
 
-         if (self.handler && method && arg) {
 
-             [self.handler call:method :arg];
 
-         }
 
-     }
 
- }
 
- @end
 
- @implementation DWKWebView
 
- {
 
-     void (^alertHandler)(void);
 
-     void (^confirmHandler)(BOOL);
 
-     void (^promptHandler)(NSString *);
 
-     void(^javascriptCloseWindowListener)(void);
 
-     int dialogType;
 
-     int callId;
 
-     bool jsDialogBlock;
 
-     NSMutableDictionary<NSString *,id> *javaScriptNamespaceInterfaces;
 
-     NSMutableDictionary *handerMap;
 
-     NSMutableArray<DSCallInfo *> * callInfoList;
 
-     NSDictionary<NSString*,NSString*> *dialogTextDic;
 
-     UITextField *txtName;
 
-     UInt64 lastCallTime ;
 
-     NSString *jsCache;
 
-     bool isPending;
 
-     bool isDebug;
 
- }
 
- -(instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration
 
- {
 
-     txtName=nil;
 
-     dialogType=0;
 
-     callId=0;
 
-     alertHandler=nil;
 
-     confirmHandler=nil;
 
-     promptHandler=nil;
 
-     jsDialogBlock=true;
 
-     callInfoList=[NSMutableArray array];
 
-     javaScriptNamespaceInterfaces=[NSMutableDictionary dictionary];
 
-     handerMap=[NSMutableDictionary dictionary];
 
-     lastCallTime = 0;
 
-     jsCache=@"";
 
-     isPending=false;
 
-     isDebug=false;
 
-     dialogTextDic=@{};
 
-     
 
-     InternalScriptsHandler *internal = [[InternalScriptsHandler alloc] initWithHandler:(id<ScriptDelegate>)self];
 
-     
 
-     WKUserScript *script = [[WKUserScript alloc] initWithSource:@"window._dswk=true;"
 
-                                                   injectionTime:WKUserScriptInjectionTimeAtDocumentStart
 
-                                                forMainFrameOnly:YES];
 
-     
 
-     [configuration.userContentController addUserScript:script];
 
-     [configuration.userContentController addScriptMessageHandler:internal name:@"asyncBridge"];
 
-     self = [super initWithFrame:frame configuration: configuration];
 
-     if (self) {
 
-         super.UIDelegate=self;
 
-     }
 
-     // add internal Javascript Object
 
-     InternalApis *  interalApis= [[InternalApis alloc] init];
 
-     interalApis.webview=self;
 
-     [self addJavascriptObject:interalApis namespace:@"_dsb"];
 
-     return self;
 
- }
 
- - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt
 
-     defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame
 
- completionHandler:(void (^)(NSString * _Nullable result))completionHandler
 
- {
 
-     NSString * prefix=@"_dsbridge=";
 
-     if ([prompt hasPrefix:prefix])
 
-     {
 
-         NSString *method= [prompt substringFromIndex:[prefix length]];
 
-         NSString *result=nil;
 
-         if(isDebug){
 
-             result =[self call:method :defaultText ];
 
-         }else{
 
-             @try {
 
-                 result =[self call:method :defaultText ];
 
-             }@catch(NSException *exception){
 
-                 NSLog(@"%@", exception);
 
-             }
 
-         }
 
-         completionHandler(result);
 
-         
 
-     }else {
 
-         if(!jsDialogBlock){
 
-             completionHandler(nil);
 
-         }
 
-         if(self.DSUIDelegate && [self.DSUIDelegate respondsToSelector:
 
-                                  @selector(webView:runJavaScriptTextInputPanelWithPrompt
 
-                                            :defaultText:initiatedByFrame
 
-                                            :completionHandler:)])
 
-         {
 
-             return [self.DSUIDelegate webView:webView runJavaScriptTextInputPanelWithPrompt:prompt
 
-                                   defaultText:defaultText
 
-                              initiatedByFrame:frame
 
-                             completionHandler:completionHandler];
 
-         }else{
 
-             dialogType=3;
 
-             if(jsDialogBlock){
 
-                 promptHandler=completionHandler;
 
-             }
 
-             UIAlertView *alert = [[UIAlertView alloc]
 
-                                   initWithTitle:prompt
 
-                                   message:@""
 
-                                   delegate:self
 
-                                   cancelButtonTitle:dialogTextDic[@"promptCancelBtn"]?dialogTextDic[@"promptCancelBtn"]:@"取消"
 
-                                   otherButtonTitles:dialogTextDic[@"promptOkBtn"]?dialogTextDic[@"promptOkBtn"]:@"确定",
 
-                                   nil];
 
-             [alert setAlertViewStyle:UIAlertViewStylePlainTextInput];
 
-             txtName = [alert textFieldAtIndex:0];
 
-             txtName.text=defaultText;
 
-             [alert show];
 
-         }
 
-     }
 
- }
 
- - (WKNavigation *)loadData:(NSData *)data MIMEType:(NSString *)MIMEType characterEncodingName:(NSString *)characterEncodingName baseURL:(NSURL *)baseURL {
 
-     [self resetCallInfoList];
 
-     return [super loadData:data MIMEType:MIMEType characterEncodingName:characterEncodingName baseURL:baseURL];
 
- }
 
- - (WKNavigation *)loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL {
 
-     [self resetCallInfoList];
 
-     return [super loadHTMLString:string baseURL:baseURL];
 
- }
 
- - (WKNavigation *)loadRequest:(NSURLRequest *)request {
 
-     [self resetCallInfoList];
 
-     return [super loadRequest:request];
 
- }
 
- - (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message
 
- initiatedByFrame:(WKFrameInfo *)frame
 
- completionHandler:(void (^)(void))completionHandler
 
- {
 
-     if(!jsDialogBlock){
 
-         completionHandler();
 
-     }
 
-     if( self.DSUIDelegate &&  [self.DSUIDelegate respondsToSelector:
 
-                                @selector(webView:runJavaScriptAlertPanelWithMessage
 
-                                          :initiatedByFrame:completionHandler:)])
 
-     {
 
-         return [self.DSUIDelegate webView:webView runJavaScriptAlertPanelWithMessage:message
 
-                          initiatedByFrame:frame
 
-                         completionHandler:completionHandler];
 
-     }else{
 
-         dialogType=1;
 
-         if(jsDialogBlock){
 
-             alertHandler=completionHandler;
 
-         }
 
-         UIAlertView *alertView =
 
-         [[UIAlertView alloc] initWithTitle:dialogTextDic[@"alertTitle"]?dialogTextDic[@"alertTitle"]:@"提示"
 
-                                    message:message
 
-                                   delegate:self
 
-                          cancelButtonTitle:dialogTextDic[@"alertBtn"]?dialogTextDic[@"alertBtn"]:@"确定"
 
-                          otherButtonTitles:nil,nil];
 
-         [alertView show];
 
-     }
 
- }
 
- -(void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message
 
- initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler
 
- {
 
-     if(!jsDialogBlock){
 
-         completionHandler(YES);
 
-     }
 
-     if( self.DSUIDelegate&& [self.DSUIDelegate respondsToSelector:
 
-                             @selector(webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:completionHandler:)])
 
-     {
 
-         return[self.DSUIDelegate webView:webView runJavaScriptConfirmPanelWithMessage:message
 
-                         initiatedByFrame:frame
 
-                        completionHandler:completionHandler];
 
-     }else{
 
-         dialogType=2;
 
-         if(jsDialogBlock){
 
-             confirmHandler=completionHandler;
 
-         }
 
-         UIAlertView *alertView =
 
-         [[UIAlertView alloc] initWithTitle:dialogTextDic[@"confirmTitle"]?dialogTextDic[@"confirmTitle"]:@"提示"
 
-                                    message:message
 
-                                   delegate:self
 
-                          cancelButtonTitle:dialogTextDic[@"confirmCancelBtn"]?dialogTextDic[@"confirmCancelBtn"]:@"取消"
 
-                          otherButtonTitles:dialogTextDic[@"confirmOkBtn"]?dialogTextDic[@"confirmOkBtn"]:@"确定", nil];
 
-         [alertView show];
 
-     }
 
- }
 
- - (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures{
 
-     if( self.DSUIDelegate && [self.DSUIDelegate respondsToSelector:
 
-                               @selector(webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures:)]){
 
-         return [self.DSUIDelegate webView:webView createWebViewWithConfiguration:configuration forNavigationAction:navigationAction windowFeatures:windowFeatures];
 
-     }
 
-     return  nil;
 
- }
 
- - (void)webViewDidClose:(WKWebView *)webView{
 
-     if( self.DSUIDelegate && [self.DSUIDelegate respondsToSelector:
 
-                               @selector(webViewDidClose:)]){
 
-         [self.DSUIDelegate webViewDidClose:webView];
 
-     }
 
- }
 
- - (BOOL)webView:(WKWebView *)webView shouldPreviewElement:(WKPreviewElementInfo *)elementInfo{
 
-     if( self.DSUIDelegate
 
-        && [self.DSUIDelegate respondsToSelector:
 
-            @selector(webView:shouldPreviewElement:)]){
 
-            return [self.DSUIDelegate webView:webView shouldPreviewElement:elementInfo];
 
-        }
 
-     return NO;
 
- }
 
- - (UIViewController *)webView:(WKWebView *)webView previewingViewControllerForElement:(WKPreviewElementInfo *)elementInfo defaultActions:(NSArray<id<WKPreviewActionItem>> *)previewActions{
 
-     if( self.DSUIDelegate &&
 
-        [self.DSUIDelegate respondsToSelector:@selector(webView:previewingViewControllerForElement:defaultActions:)]){
 
-         return [self.DSUIDelegate
 
-                 webView:webView
 
-                 previewingViewControllerForElement:elementInfo
 
-                 defaultActions:previewActions
 
-                 ];
 
-     }
 
-     return  nil;
 
- }
 
- - (void)webView:(WKWebView *)webView commitPreviewingViewController:(UIViewController *)previewingViewController{
 
-     if( self.DSUIDelegate
 
-        && [self.DSUIDelegate respondsToSelector:@selector(webView:commitPreviewingViewController:)]){
 
-         return [self.DSUIDelegate webView:webView commitPreviewingViewController:previewingViewController];
 
-     }
 
- }
 
- - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
 
- {
 
-     if(dialogType==1 && alertHandler){
 
-         alertHandler();
 
-         alertHandler=nil;
 
-     }else if(dialogType==2 && confirmHandler){
 
-         confirmHandler(buttonIndex==1?YES:NO);
 
-         confirmHandler=nil;
 
-     }else if(dialogType==3 && promptHandler && txtName) {
 
-         if(buttonIndex==1){
 
-             promptHandler([txtName text]);
 
-         }else{
 
-             promptHandler(@"");
 
-         }
 
-         promptHandler=nil;
 
-         txtName=nil;
 
-     }
 
- }
 
- - (void) evalJavascript:(int) delay{
 
-     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_MSEC)), dispatch_get_main_queue(), ^{
 
-         @synchronized(self){
 
-             if([jsCache length]!=0){
 
-                 [self evaluateJavaScript :jsCache completionHandler:nil];
 
-                 isPending=false;
 
-                 jsCache=@"";
 
-                 lastCallTime=[[NSDate date] timeIntervalSince1970]*1000;
 
-             }
 
-         }
 
-     });
 
- }
 
- -(NSString *)call:(NSString*) method :(NSString*) argStr
 
- {
 
-     NSArray *nameStr=[JSBUtil parseNamespace:[method stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
 
-     id JavascriptInterfaceObject=javaScriptNamespaceInterfaces[nameStr[0]];
 
-     NSString *error=[NSString stringWithFormat:@"Error! \n Method %@ is not invoked, since there is not a implementation for it",method];
 
-     NSMutableDictionary*result =[NSMutableDictionary dictionaryWithDictionary:@{@"code":@-1,@"data":@""}];
 
-     if(!JavascriptInterfaceObject){
 
-         NSLog(@"Js bridge  called, but can't find a corresponded JavascriptObject , please check your code!");
 
-     }else{
 
-         method=nameStr[1];
 
-         NSString *methodOne = [JSBUtil methodByNameArg:1 selName:method class:[JavascriptInterfaceObject class]];
 
-         NSString *methodTwo = [JSBUtil methodByNameArg:2 selName:method class:[JavascriptInterfaceObject class]];
 
-         SEL sel=NSSelectorFromString(methodOne);
 
-         SEL selasyn=NSSelectorFromString(methodTwo);
 
-         NSDictionary * args=[JSBUtil jsonStringToObject:argStr];
 
-         id arg=args[@"data"];
 
-         if(arg==[NSNull null]){
 
-             arg=nil;
 
-         }
 
-         NSString * cb;
 
-         do{
 
-             if(args && (cb= args[@"_dscbstub"])){
 
-                 if([JavascriptInterfaceObject respondsToSelector:selasyn]){
 
-                     __weak typeof(self) weakSelf = self;
 
-                     void (^completionHandler)(id,BOOL) = ^(id value,BOOL complete){
 
-                         NSString *del=@"";
 
-                         result[@"code"]=@0;
 
-                         if(value!=nil){
 
-                             result[@"data"]=value;
 
-                         }
 
-                         value=[JSBUtil objToJsonString:result];
 
-                         value=[value stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
 
-                         
 
-                         if(complete){
 
-                             del=[@"delete window." stringByAppendingString:cb];
 
-                         }
 
-                         NSString*js=[NSString stringWithFormat:@"try {%@(JSON.parse(decodeURIComponent(\"%@\")).data);%@; } catch(e){};",cb,(value == nil) ? @"" : value,del];
 
-                         __strong typeof(self) strongSelf = weakSelf;
 
-                         @synchronized(self)
 
-                         {
 
-                             UInt64  t=[[NSDate date] timeIntervalSince1970]*1000;
 
-                             jsCache=[jsCache stringByAppendingString:js];
 
-                             if(t-lastCallTime<50){
 
-                                 if(!isPending){
 
-                                     [strongSelf evalJavascript:50];
 
-                                     isPending=true;
 
-                                 }
 
-                             }else{
 
-                                 [strongSelf evalJavascript:0];
 
-                             }
 
-                         }
 
-                         
 
-                     };
 
-                     
 
-                     void(*action)(id,SEL,id,id) = (void(*)(id,SEL,id,id))objc_msgSend;
 
-                     action(JavascriptInterfaceObject,selasyn,arg,completionHandler);
 
-                     break;
 
-                 }
 
-             }else if([JavascriptInterfaceObject respondsToSelector:sel]){
 
-                 id ret;
 
-                 id(*action)(id,SEL,id) = (id(*)(id,SEL,id))objc_msgSend;
 
-                 ret=action(JavascriptInterfaceObject,sel,arg);
 
-                 [result setValue:@0 forKey:@"code"];
 
-                 if(ret!=nil){
 
-                     [result setValue:ret forKey:@"data"];
 
-                 }
 
-                 break;
 
-             }
 
-             NSString*js=[error stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
 
-             if(isDebug){
 
-                 js=[NSString stringWithFormat:@"window.alert(decodeURIComponent(\"%@\"));",js];
 
-                 [self evaluateJavaScript :js completionHandler:nil];
 
-             }
 
-             NSLog(@"%@",error);
 
-         }while (0);
 
-     }
 
-     return [JSBUtil objToJsonString:result];
 
- }
 
- - (void)setJavascriptCloseWindowListener:(void (^)(void))callback
 
- {
 
-     javascriptCloseWindowListener=callback;
 
- }
 
- - (void)setDebugMode:(bool)debug{
 
-     isDebug=debug;
 
- }
 
- - (void)resetCallInfoList {
 
-     callInfoList = [NSMutableArray array];
 
- }
 
- - (void)loadUrl: (NSString *)url
 
- {
 
-     NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
 
-     [self loadRequest:request];
 
- }
 
- - (void)callHandler:(NSString *)methodName arguments:(NSArray *)args{
 
-     [self callHandler:methodName arguments:args completionHandler:nil];
 
- }
 
- - (void)callHandler:(NSString *)methodName completionHandler:(void (^)(id _Nullable))completionHandler{
 
-     [self callHandler:methodName arguments:nil completionHandler:completionHandler];
 
- }
 
- -(void)callHandler:(NSString *)methodName arguments:(NSArray *)args completionHandler:(void (^)(id  _Nullable value))completionHandler
 
- {
 
-     DSCallInfo *callInfo=[[DSCallInfo alloc] init];
 
-     callInfo.id=[NSNumber numberWithInt: callId++];
 
-     callInfo.args=args==nil?@[]:args;
 
-     callInfo.method=methodName;
 
-     if(completionHandler){
 
-         [handerMap setObject:completionHandler forKey:callInfo.id];
 
-     }
 
-     if(callInfoList!=nil){
 
-         [callInfoList addObject:callInfo];
 
-     }else{
 
-         [self dispatchJavascriptCall:callInfo];
 
-     }
 
- }
 
- - (void)dispatchStartupQueue{
 
-     if(callInfoList==nil) return;
 
-     for (DSCallInfo * callInfo in callInfoList) {
 
-         [self dispatchJavascriptCall:callInfo];
 
-     }
 
-     callInfoList=nil;
 
- }
 
- - (void) dispatchJavascriptCall:(DSCallInfo*) info{
 
-     NSString * json=[JSBUtil objToJsonString:@{@"method":info.method,@"callbackId":info.id,
 
-                                                @"data":[JSBUtil objToJsonString: info.args]}];
 
-     [self evaluateJavaScript:[NSString stringWithFormat:@"window._handleMessageFromNative(%@)",json]
 
-            completionHandler:nil];
 
- }
 
- - (void) addJavascriptObject:(id)object namespace:(NSString *)namespace{
 
-     if(namespace==nil){
 
-         namespace=@"";
 
-     }
 
-     if(object!=NULL){
 
-         [javaScriptNamespaceInterfaces setObject:object forKey:namespace];
 
-     }
 
- }
 
- - (void) removeJavascriptObject:(NSString *)namespace {
 
-     if(namespace==nil){
 
-         namespace=@"";
 
-     }
 
-     [javaScriptNamespaceInterfaces removeObjectForKey:namespace];
 
- }
 
- - (void)customJavascriptDialogLabelTitles:(NSDictionary *)dic{
 
-     if(dic){
 
-         dialogTextDic=dic;
 
-     }
 
- }
 
- - (id)onMessage:(NSDictionary *)msg type:(int)type{
 
-     id ret=nil;
 
-     switch (type) {
 
-         case DSB_API_HASNATIVEMETHOD:
 
-             ret= [self hasNativeMethod:msg]?@1:@0;
 
-             break;
 
-         case DSB_API_CLOSEPAGE:
 
-             [self closePage:msg];
 
-             break;
 
-         case DSB_API_RETURNVALUE:
 
-             ret=[self returnValue:msg];
 
-             break;
 
-         case DSB_API_DSINIT:
 
-             ret=[self dsinit:msg];
 
-             break;
 
-         case DSB_API_DISABLESAFETYALERTBOX:
 
-             [self disableJavascriptDialogBlock:[msg[@"disable"] boolValue]];
 
-             break;
 
-         default:
 
-             break;
 
-     }
 
-     return ret;
 
- }
 
- - (bool) hasNativeMethod:(NSDictionary *) args
 
- {
 
-     NSArray *nameStr=[JSBUtil parseNamespace:[args[@"name"]stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
 
-     NSString * type= [args[@"type"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
 
-     id JavascriptInterfaceObject= [javaScriptNamespaceInterfaces objectForKey:nameStr[0]];
 
-     if(JavascriptInterfaceObject){
 
-         bool syn=[JSBUtil methodByNameArg:1 selName:nameStr[1] class:[JavascriptInterfaceObject class]]!=nil;
 
-         bool asyn=[JSBUtil methodByNameArg:2 selName:nameStr[1] class:[JavascriptInterfaceObject class]]!=nil;
 
-         if(([@"all" isEqualToString:type]&&(syn||asyn))
 
-            ||([@"asyn" isEqualToString:type]&&asyn)
 
-            ||([@"syn" isEqualToString:type]&&syn)
 
-            ){
 
-             return true;
 
-         }
 
-     }
 
-     return false;
 
- }
 
- - (id) closePage:(NSDictionary *) args{
 
-     if(javascriptCloseWindowListener){
 
-         javascriptCloseWindowListener();
 
-     }
 
-     return nil;
 
- }
 
- - (id) returnValue:(NSDictionary *) args{
 
-     void (^ completionHandler)(NSString *  _Nullable)= handerMap[args[@"id"]];
 
-     if(completionHandler){
 
-         if(isDebug){
 
-             completionHandler(args[@"data"]);
 
-         }else{
 
-             @try{
 
-                 completionHandler(args[@"data"]);
 
-             }@catch (NSException *e){
 
-                 NSLog(@"%@",e);
 
-             }
 
-         }
 
-         
 
-         id complete = args[@"complete"];
 
-         if (complete && ![complete boolValue]) {
 
-         } else {
 
-             [handerMap removeObjectForKey:args[@"id"]];
 
-         }
 
-     }
 
-     return nil;
 
- }
 
- - (id) dsinit:(NSDictionary *) args{
 
-     [self dispatchStartupQueue];
 
-     return nil;
 
- }
 
- - (void) disableJavascriptDialogBlock:(bool) disable{
 
-     jsDialogBlock=!disable;
 
- }
 
- - (void)hasJavascriptMethod:(NSString *)handlerName methodExistCallback:(void (^)(bool exist))callback{
 
-     [self callHandler:@"_hasJavascriptMethod" arguments:@[handlerName] completionHandler:^(NSNumber* _Nullable value) {
 
-         callback([value boolValue]);
 
-     }];
 
- }
 
- @end
 
 
  |