Scripting Part 1
- by rbishop
Dynamic Scripting is a large topic, so let me get a couple of things out of the way first. If you aren't familiar with JavaScript, I can suggest CodeAcademy's JavaScript series. There are also many other websites and books that cover JavaScript from every possible angle.The second thing we need to deal with is JavaScript as a programming language versus a JavaScript environment running in a web browser. Many books, tutorials, and websites completely blur these two together but they are in fact completely separate. What does this really mean in relation to DRM? Since DRM isn't a web browser, there are no document, window, history, screen, or location objects. There are no events like mousedown or click. Trying to call alert('hello!') in DRM will just cause an error. Those concepts are all related to an HTML document (web page) and are part of the Browser Object Model or Document Object Model. DRM has its own object model that exposes DRM-related objects. In practice, feel free to use those sorts of tutorials or practice within your browser; Many of the concepts are directly translatable to writing scripts in DRM. Just don't try to call document.getElementById in your property definition!I think learning by example tends to work the best, so let's try getting a list of all the unique property values for a given node and its children.
var uniqueValues = {};
var childEnumerator = node.GetChildEnumerator();
while(childEnumerator.MoveNext()) {
var propValue = childEnumerator.GetCurrent().PropValue("Custom.testpropstr1");
print(propValue);
if(propValue != null && propValue != '' && !uniqueValues[propValue])
uniqueValues[propValue] = true;
}
var result = '';
for(var value in uniqueValues){
result += "Found value " + value + ",";
}
return result;
Now lets break this down piece by piece.
var uniqueValues = {};
This declares a variable and initializes it as a new empty Object. You could also have written var uniqueValues = new Object(); Why use an object here? JavaScript objects can also function as a list of keys and we'll use that later to store each property value as a key on the object.
var childEnumerator = node.GetChildEnumerator();
while(childEnumerator.MoveNext()) {
This gets an enumerator for the node's children. The enumerator allows us to loop through the children one by one. If we wanted to get a filtered list of children, we would instead use ChildrenWith(). When we reach the end of the child list, the enumerator will return false for MoveNext() and that will stop the loop.
var propValue = childEnumerator.GetCurrent().PropValue("Custom.testpropstr1");
print(propValue);
if(propValue != null && propValue != '' && !uniqueValues[propValue])
uniqueValues[propValue] = true;
}
This gets the node the enumerator is currently pointing at, then calls PropValue() on it to get the value of a property. We then make sure the prop value isn't null or the empty string, then we make sure the value doesn't already exist as a key. Assuming it doesn't we add it as a key with a value (true in this case because it makes checking for an existing value faster when the value exists).
A quick word on the print() function. When viewing the prop grid, running an export, or performing normal DRM operations it does nothing. If you have a lot of print() calls with complicated arguments it can slow your script down slightly, but otherwise has no effect. But when using the script editor, all the output of print() will be shown in the Warnings area. This gives you an extremely useful debugging tool to see what exactly a script is doing.
var result = '';
for(var value in uniqueValues){
result += "Found value " + value + ",";
}
return result;
Now we build a string by looping through all the keys in uniqueValues and adding that value to our string. The last step is to simply return the result.
Hopefully this small example demonstrates some of the core Dynamic Scripting concepts. Next time, we can try checking for node references in other hierarchies to see if they are using duplicate property values.