WebBrowserComponent Request


Hi Jules.

Can’t believe I’m the 1st to ask for this, but what about adding a callback pageFinishedLoading(String urlString)?



I think I didn’t add that because I couldn’t find a good way to do it across platforms… If anyone wants to do some research and figure out how it’s done on OSX and windows, I’d be glad to add it!


Still didn’t find a solution to the Mac browser, but for whoever seeks the Windows version, this is how I did it:

  1. Add an empty virtual pageFinishedLoading() to the WebBrowserComponent class (cause we still need to implement the Mac version)
	virtual void pageFinishedLoading(const String& url) {}
  1. In juce_win32_WebBrowserComponent.cpp, add the first ‘if’ to the Invoke() function:
        JUCE_COMRESULT Invoke (DISPID dispIdMember, REFIID /*riid*/, LCID /*lcid*/, WORD /*wFlags*/, DISPPARAMS* pDispParams,
                               VARIANT* /*pVarResult*/, EXCEPINFO* /*pExcepInfo*/, UINT* /*puArgErr*/)
			String url(pDispParams->rgvarg[0].pvarVal->bstrVal); 
			return S_OK;
            else if (dispIdMember == DISPID_BEFORENAVIGATE2)
                VARIANT* const vurl = pDispParams->rgvarg[5].pvarVal;
                String url;

                if ((vurl->vt & VT_BYREF) != 0)
                    url = *vurl->pbstrVal;
                    url = vurl->bstrVal;

                    = owner.pageAboutToLoad (url) ? VARIANT_FALSE
                                                  : VARIANT_TRUE;

                return S_OK;

            return E_NOTIMPL;


So here is how I did it in OSX (my first Objective-C lines…):

  1. Added the didFinishLoadForFrame() callback to the DownloadClickDetector:
@interface DownloadClickDetector   : NSObject
    juce::WebBrowserComponent* ownerComponent;

- (DownloadClickDetector*) initWithWebBrowserOwner: (juce::WebBrowserComponent*) ownerComponent;

- (void) webView: (WebView*) webView decidePolicyForNavigationAction: (NSDictionary*) actionInformation
                                                             request: (NSURLRequest*) request
                                                               frame: (WebFrame*) frame
                                                    decisionListener: (id<WebPolicyDecisionListener>) listener;

- (void) webView: (WebView*) webView didFinishLoadForFrame: (WebFrame*) frame;


@implementation DownloadClickDetector

- (DownloadClickDetector*) initWithWebBrowserOwner: (juce::WebBrowserComponent*) ownerComponent_
    [super init];
    ownerComponent = ownerComponent_;
    return self;

- (void) webView: (WebView*) sender decidePolicyForNavigationAction: (NSDictionary*) actionInformation
                                                            request: (NSURLRequest*) request
                                                              frame: (WebFrame*) frame
                                                   decisionListener: (id <WebPolicyDecisionListener>) listener
    (void) sender; (void) request; (void) frame;

    NSURL* url = [actionInformation valueForKey: nsStringLiteral ("WebActionOriginalURLKey")];

    if (ownerComponent->pageAboutToLoad (nsStringToJuce ([url absoluteString])))
        [listener use];
        [listener ignore];

- (void) webView: (WebView*) sender didFinishLoadForFrame: (WebFrame*) frame
    (void) sender; (void) frame;

	if([frame isEqual:[sender mainFrame]])
		NSURL* url = [[[frame dataSource] request] URL];
		ownerComponent->pageFinishedLoading(nsStringToJuce ([url absoluteString]));

  1. Added the clickListener also as a frame load delegator:

WebBrowserComponentInternal (WebBrowserComponent* owner):

        clickListener = [[DownloadClickDetector alloc] initWithWebBrowserOwner: owner];
        [webView setPolicyDelegate: clickListener];
	[webView setFrameLoadDelegate: clickListener];


       #if JUCE_MAC
        [webView setPolicyDelegate: nil];
	[webView setFrameLoadDelegate: nil];
        [clickListener release];


Thanks! I’ll see what I can do with that…