0

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?

cs2k
  • 127
  • 9
  • Your main issue is that you aren't using the for loop correctly, as mentioned below. You should also know that you have several memory leaks in the above code; when you call createDeviceNPObject it will retain it, and when you give it to the array (with "push") it will retain it's own copy, so you should release after you give it to the array. Also your retainobject call on the devices array is extra because it has already been retained once (when you created it) and thus you dont' need to retain it before you return it. see http://npapi.com/memory for a more complete explanation. – taxilian May 07 '12 at 04:07
  • 1
    Oh, thanks for pointing this out. Your excellent post does help a lot! – cs2k May 16 '12 at 03:43

1 Answers1

1

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;
}
ChaosPandion
  • 77,506
  • 18
  • 119
  • 157