BOOL DTRenameSelector ( Class _class, SEL _oldSelector, SEL _newSelector ) { Method method = nil ; // First, look for the methods method = class_getInstanceMethod ( _class, _oldSelector ) ; if ( method == nil ) return NO ; method - >method_name = _newSelector; return YES ; }
BOOL DTRenameSelector ( Class _class, SEL _oldSelector, SEL _newSelector ) { Method method = nil ; // First, look for the methods method = class_getInstanceMethod ( _class, _oldSelector ) ; if ( method == nil ) return NO ; method - >method_name = _newSelector; return YES ; }
BOOL DTRenameSelector ( Class _class, SEL _oldSelector, SEL _newSelector ) { Method method = nil ; // First, look for the methods method = class_getInstanceMethod ( _class, _oldSelector ) ; if ( method == nil ) return NO ; method - >method_name = _newSelector; return YES ; }
BOOL DTRenameSelector ( Class _class, SEL _oldSelector, SEL _newSelector ) { Method method = nil ; // First, look for the methods method = class_getInstanceMethod ( _class, _oldSelector ) ; if ( method == nil ) return NO ; method - >method_name = _newSelector; return YES ; }
BOOL DTRenameSelector ( Class _class, SEL _oldSelector, SEL _newSelector ) { Method method = nil ; // First, look for the methods method = class_getInstanceMethod ( _class, _oldSelector ) ; if ( method == nil ) return NO ; method - >method_name = _newSelector; return YES ; }
BOOL DTRenameSelector ( Class _class, SEL _oldSelector, SEL _newSelector ) { Method method = nil ; // First, look for the methods method = class_getInstanceMethod ( _class, _oldSelector ) ; if ( method == nil ) return NO ; method - >method_name = _newSelector; return YES ; }
BOOL DTRenameSelector ( Class _class, SEL _oldSelector, SEL _newSelector ) { Method method = nil ; // First, look for the methods method = class_getInstanceMethod ( _class, _oldSelector ) ; if ( method == nil ) return NO ; method - >method_name = _newSelector; return YES ; }
BOOL DTRenameSelector ( Class _class, SEL _oldSelector, SEL _newSelector ) { Method method = nil ; // First, look for the methods method = class_getInstanceMethod ( _class, _oldSelector ) ; if ( method == nil ) return NO ; method - >method_name = _newSelector; return YES ; }
BOOL DTRenameSelector ( Class _class, SEL _oldSelector, SEL _newSelector ) { Method method = nil ; // First, look for the methods method = class_getInstanceMethod ( _class, _oldSelector ) ; if ( method == nil ) return NO ; method - >method_name = _newSelector; return YES ; }
BOOL DTRenameSelector ( Class _class, SEL _oldSelector, SEL _newSelector ) { Method method = nil ; // First, look for the methods method = class_getInstanceMethod ( _class, _oldSelector ) ; if ( method == nil ) return NO ; method - >method_name = _newSelector; return YES ; }
- static NSArray * webView_contextMenuItemsForElement_defaultMenuItems_ ( id self, SEL _cmd,
- id * sender, NSDictionary * element, NSArray * defaultMenuItems )
- {
- return [ self
- _sxp_orig_webView : sender
- contextMenuItemsForElement : element
- defaultMenuItems : defaultMenuItems ] ;
- }
- static SXPPlugin * Plugin = nil ;
- @implementation SXPPlugin
- + ( SXPPlugin * ) sharedInstance
- {
- @synchronized ( self ) {
- if ( ! Plugin )
- Plugin = [ [ SXPPlugin alloc ] init ] ;
- }
- return plugin;
- }
- - ( void ) swizzle
- {
- Class BrowserWebView = objc_getClass ( "BrowserWebView" ) ;
- if ( BrowserWebView ) {
- class_addMethod (
- BrowserWebView,
- @selector ( _sxp_fake_webView : contextMenuItemsForElement : defaultMenuItems :) ,
- ( IMP ) webView_contextMenuItemsForElement_defaultMenuItems_,
- "@@: @@@" ) ;
- DTRenameSelector (
- BrowserWebView,
- @selector ( webView : contextMenuItemsForElement : defaultMenuItems :) ,
- @selector ( _sxp_orig_webView : contextMenuItemsForElement : defaultMenuItems :) ) ;
- DTRenameSelector (
- BrowserWebView,
- @selector ( _sxp_fake_webView : contextMenuItemsForElement : defaultMenuItems :) ,
- @selector ( webView : contextMenuItemsForElement : defaultMenuItems :) ) ;
- } else {
- NSLog ( @ "Failed to get BrowserWebView class" ) ;
- }
- }
- + ( void ) load
- {
- SXPPlugin * plugin = [ SXPPlugin sharedInstance ] ;
- [ plugin swizzle ] ;
- }
- @end
- - ( id ) init
- {
- if ( ( self = [ super init ] ) ) {
- // init menu
- NSMenu * m = [ [ NSMenu alloc ] initWithTitle : @ "XPath" ] ;
- NSMenuItem * mi = [ [ NSMenuItem alloc ]
- initWithTitle : @ "XPath for node"
- action : @selector ( onMenu :)
- keyEquivalent : @ "" ] ;
- [ mi setTarget : self ] ;
- [ m addItem : mi ] ;
- [ mi release ] ;
- mi = [ [ NSMenuItem alloc ]
- initWithTitle : @ "Show browser"
- action : @selector ( onMenuBrowser :)
- keyEquivalent : @ "" ] ;
- [ mi setTarget : self ] ;
- [ m addItem : mi ] ;
- [ mi release ] ;
- _myMenuItem = [ [ NSMenuItem alloc ]
- initWithTitle : @ "XPath"
- action : nil
- keyEquivalent : @ "" ] ;
- [ _myMenuItem setSubmenu : m ] ;
- [ m release ] ;
- [ _myMenuItem setEnabled : YES ] ;
- }
- return self;
- }
NSMenuItem *_myMenuItem;
and make it available via the property: @property (readonly) NSMenuItem *myMenuItem;
. Now we can get to this menu from our function (which is executed in the context of BrowserWebView):
- static NSArray * webView_contextMenuItemsForElement_defaultMenuItems_ ( id self, SEL _cmd,
- id * sender, NSDictionary * element, NSArray * defaultMenuItems )
- {
- [ SXPPlugin sharedInstance ] .ctx = element;
- NSArray * itms = [ self
- _sxp_orig_webView : sender
- contextMenuItemsForElement : element
- defaultMenuItems : defaultMenuItems ] ;
- NSMutableArray * itms2 = [ NSMutableArray arrayWithArray : itms ] ;
- [ itms2 addObject : [ NSMenuItem separatorItem ] ] ;
- [ itms2 addObject : [ [ SXPPlugin sharedInstance ] myMenuItem ] ] ;
- return itms2;
- }
[NSBundle loadNibNamed:@"XPathBrowser" owner:self];
everything we need on the main class, and in init we add the xib load: [NSBundle loadNibNamed:@"XPathBrowser" owner:self];
.
- - ( void ) onMenu : ( id ) sender
- {
- [ window makeKeyAndOrderFront : self ] ;
- NSString * xp = [ self xpathForNode : [ _ctx objectForKey : @ "WebElementDOMNode" ] ] ;
- [ xpathField setStringValue : xp ] ;
- [ self onEvaluate : self ] ;
- }
- - ( void ) onMenuBrowser : ( id ) sender
- {
- [ window makeKeyAndOrderFront : self ] ;
- }
- - ( void ) onEvaluate : ( id ) sender
- {
- NSString * xp = [ xpathField stringValue ] ;
- WebFrame * frame = [ _ctx objectForKey : @ "WebElementFrame" ] ;
- WebView * view = [ frame webView ] ;
- NSString * js = [ NSString
- stringWithFormat : @ "document.evaluate ( \" % @ \ " , document, null, XPathResult.ANY_TYPE, null)" , xp ] ;
- id o = [ [ view windowScriptObject ] evaluateWebScript : js ] ;
- [ _nodes release ] ;
- _nodes = nil ;
- if ( ! [ [ o class ] isEqual : [ WebUndefined class ] ] ) {
- NSMutableArray * nodes = [ NSMutableArray array ] ;
- id n = [ o iterateNext ] ;
- while ( n ) {
- [ nodes addObject : [ self dictForNode : n ] ] ;
- n = [ o iterateNext ] ;
- }
- _nodes = [ nodes retain ] ;
- } ;
- [ outlineView reloadData ] ;
- }
Source: https://habr.com/ru/post/65368/
All Articles