0

I'm integrating a reCAPTCHA into my Cappuccino app and I have it all working besides this odd input functionality in the reCAPTCHA input text field: Only some keys seem to work, "qwrszcv" and a few other letters work fine, but most other keys don't work.

I borrowed some of the mapkit code to inject the reCAPTCHA script file in the head, then I inject the reCAPTCHA div into a custom CPView class I made.

Here is my constructor code:

- (id)initWithFrame:(CGRect)aFrame
{

    self = [super initWithFrame:aFrame];
    if (self != nil)
    {
        var DOMScriptElement = document.createElement("script");

        DOMScriptElement.src = "http://www.google.com/recaptcha/api/js/recaptcha_ajax.js";
        DOMScriptElement.type = "text/javascript";

        document.getElementsByTagName("head")[0].appendChild(DOMScriptElement);

        needsInitialization = YES;
        console.log(self);
    }
    return self;

}

And my initialization code:

- (id)initializeRecaptcha
{
    if (needsInitialization)
    {
        DOMRecaptchaElement = document.createElement("div");
        DOMRecaptchaElement.id = "recaptcha_div_id";


        var style = DOMRecaptchaElement.style,
            bounds = [self bounds],
            width = CGRectGetWidth(bounds),
            height = CGRectGetHeight(bounds);

        style.overflow = "hidden";
        style.position = "absolute";
        style.visibility = "visible";
        style.zIndex = 0;
        style.left = "0px";
        style.top = "0px";
        style.width = width + "px";
        style.height = height + "px";

        _DOMElement.appendChild(DOMRecaptchaElement);

        window.Recaptcha.create("my-recaptcha-key",
            "recaptcha_div_id",
            {
                theme: "clean",
                callback: window.Recaptcha.focus_response_field
            }
        );

        needsInitialization = NO;
    }
    else
    {
        window.Recaptcha.reload();
    }
}

I figure it has something to do with the way Cappuccino propagated events, but for the life of me I can't figure out a way to get this input to work.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
John Sparwasser
  • 1,015
  • 13
  • 26

2 Answers2

1

Cappuccino attaches key event listeners at the document level in order to handle keyboard shortcuts. I'm not sure why some characters are getting through and others are not, but I wouldn't be surprised if it somehow corresponded to potential Cappuccino keyboard shortcuts. You might want to check CPPlatformWindow+DOM.j for more details on this.

In the meantime, an easy solution to your actual problem is to just drop the whole recaptcha widget into an iframe (you could use CPWebView or make your own). Just remember that in your event handlers inside of iframes you may have to pump the event queue manually with [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; to let Cappuccino redisplay after you made changes from code outside of the run loop.

Alexander Ljungberg
  • 6,302
  • 4
  • 31
  • 37
  • Yea I was thinking about using a CPWebView, just thought the iframe might add unnecessary complexness. Is there really no way to have a custom input field without using an iframe in cappuccino? – John Sparwasser Feb 15 '12 at 17:23
  • There could very well be a way to do it. Just not sure it's worth the effort - an iframe is not that expensive. But if you really want to add it you should set some debug points in the Javascript debugger and load the debug version of your app using `index-debug.html`. Then trace the event handling from `CPPlatformWindow+DOM.j` down for a key which works vs one that does not. – Alexander Ljungberg Feb 15 '12 at 19:17
1

I found a fix. I copied code from the keyDown method in CPTextField that propagates the events to the browser window to the keyDown method in my custom view that holds the recaptcha:

- (void)keyDown:(CPEvent)anEvent
{
    [[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
    [self interpretKeyEvents:[anEvent]];
    [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
John Sparwasser
  • 1,015
  • 13
  • 26