Search code examples
macossafarinpapi

NPObject not distinguished by JavaScript


In my plugin code, I create an array of 'devices' and return it to JavaScript. The device in the array is an instance of a NPObject. The array can be successfully created and the device instances can be pushed in. However, 'undefined' value is returned when the JavaScript calls the property of the device object.

The html code is:

<html>
<head>
<title>Netscape Core Animation Movie Plug-In</title>
<script language="javascript" type="text/javascript">
function devicelist(){
    var plug=document.getElementById('plugin');
    var devices=plug.getDevice();
    var tab='<table>';

    for(var device in devices){
        tab+='<tr><td>'+device.name+'</td><td>'+device.address+'</td></tr>';
    }

    tab+='</table>';

    document.getElementById('pluginlist').innerHTML=tab;
}

</script>

</head>
<body>
<div>
<embed width="848" height="480" id="plugin" movieurl="http://movies.apple.com/media/us/ipad/2011/tours/apple-ipad2-feature-us-20110302_r848-9cie.mov" type="test/x-netscape-core-animation-movie-plugin"></embed>
<p>JavaScript Controller</p>
<button onclick="devicelist()">Devices </button>
<div id="pluginlist"></div>
</div>
</body>
</html>

I create the array when the 'getDevice' method of plugin object is called.

static bool mainNPObjectInvoke(NPObject *obj, NPIdentifier identifier, const NPVariant *args, uint32_t argCount, NPVariant *result)
{
    MainNPObject *mainObject = (MainNPObject *)obj;

    if (identifier == methodIdentifiers[METHOD_ID_GET_DEVICES])
    {
        NPObject *windowObj = NULL;
        browser->getvalue(mainObject->npp, NPNVWindowNPObject, &windowObj);

        NPVariant devices;
        NPIdentifier name = browser->getstringidentifier("Array");
        browser->invoke(mainObject->npp, windowObj, name, NULL, 0, &devices);

        for (int i = 0; i < 3; i++)
        {
            Device *device = [[Device alloc] init];
            device.name = [NSString stringWithFormat:@"device%.2d", i];
            device.address = @"127.0.0.1";
            NPObject *deviceObj = createDeviceNPObject(mainObject->npp, device);
            //browser->retainobject(deviceObj);

            NPVariant *arg = browser->memalloc(sizeof(NPVariant));
            OBJECT_TO_NPVARIANT(deviceObj, *arg);

            NPVariant result;
            browser->invoke(mainObject->npp, devices.value.objectValue, browser->getstringidentifier("push"), arg, 1, &result);
        }

        browser->retainobject(devices.value.objectValue);
        OBJECT_TO_NPVARIANT(devices.value.objectValue, *result);

        browser->releaseobject(windowObj);

        return true;
    }

    return false;
}

Is there anything special I shall do to make the JavaScript know that the array has instances of NPObject?


Solution

  • It looks like you are misusing the for loop. The for loop will iterate all keys of an objects prototype chain rather than the values. This is the proper usage:

    function devicelist(){
        var plug=document.getElementById('plugin');
        var devices=plug.getDevice(), device;
        var tab='<table>';
    
        for (var prop in devices) {
            if (devices.hasOwnProperty(prop)) {
                device = devices[prop];
                tab += '<tr><td>'+device.name+'</td><td>'+device.address+'</td></tr>';
            }
        }
    
        tab+='</table>';
    
        document.getElementById('pluginlist').innerHTML=tab;
    }