卡布奇诺:键盘事件在reCAPTCHA输入字段中被压扁

时间:2012-02-13 17:00:46

标签: javascript javascript-events recaptcha cappuccino objective-j

我正在将reCAPTCHA集成到我的Cappuccino应用程序中,除了reCAPTCHA输入文本字段中的这些奇怪的输入功能之外,我还可以使用它:只有一些键似乎可以工作,“qwrszcv”和其他一些字母工作正常,但是大多数其他键不起作用。

我借用了一些mapkit代码将reCAPTCHA脚本文件注入头部,然后将reCAPTCHA div注入我制作的自定义CPView类中。

这是我的构造函数代码:

- (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;

}

我的初始化代码:

- (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();
    }
}

我认为它与卡布奇诺传播事件的方式有关,但对于我的生活,我无法找到一种方法来使这种输入起作用。

2 个答案:

答案 0 :(得分:1)

Cappuccino在文档级别附加关键事件侦听器,以便处理键盘快捷键。我不确定为什么有些角色会通过而其他角色却没有,但如果它以某种方式对应潜在的Cappuccino键盘快捷键,我不会感到惊讶。您可能需要查看CPPlatformWindow+DOM.j以了解详情。

与此同时,解决实际问题的一个简单方法就是将整个recaptcha小部件放入iframe(您可以使用CPWebView或自己创建)。请记住,在iframe内部的事件处理程序中,您可能必须使用[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];手动抽取事件队列,以便在从运行循环外部的代码进行更改后重新显示Cappuccino。

答案 1 :(得分:1)

我找到了解决办法。我从CPTextField中的keyDown方法复制了代码,该代码将事件传播到浏览器窗口,到我自定义视图中的keyDown方法,该方法包含recaptcha:

- (void)keyDown:(CPEvent)anEvent
{
    [[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
    [self interpretKeyEvents:[anEvent]];
    [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}