RW9 API -[RWTextView pluginForTextView:]

Hey guys,

I’ve identified a completely undocumented and undefined method that I’d like to remove in RW9. From what I can tell it may be implemented by Stacks and Collage2.

The method in question is

-[RWTextView pluginForTextView:]

@isaiah Can you check if your plugins implement it and if so, what for?

If the plugin doesn’t implement this method, the plugin for the current page is returned which seems sensible.

If anyone else thinks their plugins implement it, please do chime in!

Cheers
Tom

1 Like

@isaiah I’m going to start sorting this out next Monday 27th April so if you have any reservations feel free to jump in.

as recently as RW6 (no idea of current status) this method was required to get the AddLink and RemoveLink buttons working correctly.
i think something to do with the sheet using the RWTextView delegate maybe?

most plugins subclass RWTextView to get the nice styled text view toolbar. i did a search on my drive and turned up 62 repository directories that have an implementation of that code somewhere.

here’s the history i found about it. good stuff…

RWTextView

at one time RWTextView used to called this from the addLink button:

	RWLinkPanel *linkPanel = [RWLinkPanel panelWithDelegate:self plugin:[self plugin]];
	[linkPanel presentPanelWithLink:link parent:[self window]];

the [self plugin] method is implemented by RWTextView to hunt for the plugin via this delegate.

i’m pretty sure that code was part of an example styled text plugin – and i believe every one of my plugins implements it. and i suspect some of the loghound plugins with styled text and toolbars implement it too.

my notes

here are my old notes on the subject. i don’t know if are (or even were) accurate. :

This is a super special case.
The addlink of the textView likes to find out
the plugin through this delegate mechanism
so we set ourselves to be the textview delegate (in awakeFromNib)
and then return our plugin outlet when asked.
seems disturbingly overcomplicated – this whole chain is just
to provide the link panel with the document window

RWStyledTextView

in the very old days (2006-ish, i’m guessing) the styled text plugin was provided as an example plugins and this was the code that was in that plugin:

- (NSObject <RWPlugin> *)pluginForTextView:(RWTextView*)textView
{
	if(textView == self.textView)
	{
		return [self plugin];
	}
	else
	{
		NSLog(@"warning: -[RWStyledTextView pluginForTextView:] called with bogus text view %@ (our textView is %@); returning nil", textView, self.textView);
		return nil;
	}
}
1 Like

Yeah like you said, this code is way over complicated, and I think other developers have tried a few times to fix it which just compounded the problem.

That code you posted from the very old days (2006)… yeah that’s still there! And it’s identical.

Do any of the plugins implement something different for -pluginForTextView: or is it just that default implementation?

This is the code that needs fixing… it’s pretty ugly and error prone.
RWTextView

- (id)plugin
{
	id plugin = nil;
	
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
    
    SEL sel = @selector(pluginForTextView:);
    
#pragma clang diagnostic pop
    
	if (self.pluginDelegate && [self.pluginDelegate respondsToSelector:sel]) {
		plugin = [self.pluginDelegate performSelector:sel withObject:self];
	}
	else if ([[self delegate] respondsToSelector:sel]) {
		plugin = [[self delegate] performSelector:sel withObject:self];
	}
	else {
		// Fallback for those cases when the protocol method isn't implemented.
		
		id controller = [[self window] windowController] ?: [[NSApp mainWindow] windowController];
		id page = [[controller document] performSelector:@selector(selectedPage)];
		
		plugin = [page performSelector:@selector(plugin)];
	}
	
	return plugin;
}