Last active
June 20, 2019 11:38
-
-
Save iconifyit/383dd6bdad7be335d95d3a0299c1274a to your computer and use it in GitHub Desktop.
This is an example of using a module pattern and closure together to build client-side CC/CEP extension modules.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @see https://github.com/Adobe-CEP/Samples/blob/master/XmpSamplePanel/js/xmp_bridge.js | |
*/ | |
/* | |
* ADOBE SYSTEMS INCORPORATED | |
* Copyright 2014 Adobe Systems Incorporated | |
* All Rights Reserved. | |
* | |
* NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the | |
* terms of the Adobe license agreement accompanying it. If you have received this file from a | |
* source other than Adobe, then your use, modification, or distribution of it requires the prior | |
* written permission of Adobe. | |
*/ | |
/*************************************************************************************** | |
* -- XMPBridge ------------------------------------------------------------------------ | |
* | |
* The ExtendScript libraries are not directly accessible from the CEP HTML5 JavaScript | |
* engine. Interactions with the application DOM or other ExtendScript components need | |
* to be tunneled through the CSInterface. That component supports submitting | |
* ExtendScript expressions to be evaluated within the application's scripting context | |
* and registering a callback function to capture the results. | |
* | |
* In order to provide a more convenient and high-level API the XMPBridge acts as a | |
* plain JavaScript proxy to the $.XMP utility that lives inside the ExtendScript | |
* environment. | |
* | |
* As the communication happens in an asynchronous fashion you need to make sure that | |
* you don't try to access XMP properties before the component is initialized properly | |
* (e.g. the setup() method has completed). To address this the XMPBridge provides | |
* an onInit() method, so you can register a callback that will be called once | |
* everything is ready to use. | |
* | |
* sample usage: | |
* | |
* XMPBridge.onInit(function(readyState) { | |
* | |
* if(!readyState.isError) { | |
* | |
* // now we're ready to go. | |
* XMPBridge.toNamespaceURI('NS_DC', function(namespaceUri) { | |
* XMPBridge.read(namespaceUri, 'title'); | |
* }); | |
* | |
* } else { | |
* // error handling. | |
* } | |
* | |
* }); | |
* | |
**************************************************************************************/ | |
var MyPlugin = (function(exports) { | |
var CS_INTERFACE = new CSInterface(); | |
var LOCAL_CACHE = {}; | |
// Private Methods ----------------------------------------------------------------------- | |
/** | |
* handle multi-line string arguments. | |
*/ | |
function escape(arg) { | |
return arg.replace(/\r\n?|\n/g, "\\n"); | |
} | |
/** | |
* helper function that constructs an ExtendScript expression dynamically from | |
* the arguments of its current invocation. All arguments are passed through | |
* the escapeArgument() function which supports basic validation. | |
* | |
* Expects the first argument to be a method/function name that is requested | |
* to be called. Any function argument will be registered as a callback. | |
*/ | |
function callExtendScript(method) { | |
var args = [].splice.call(arguments,1); | |
var callback = undefined; | |
var params = []; | |
for(var idx in args) { | |
var arg = args[idx]; | |
if(typeof(arg) == 'function') { | |
callback = arg; | |
} else { | |
params.push(escapeArgument(arg)); | |
} | |
} | |
var functionArgs = params.length ? '("' + params.join('","') + '")' : '()'; | |
var script = method + functionArgs; | |
/* | |
* evaluate against the ExtendScript context. | |
*/ | |
CS_INTERFACE.evalScript(script, callback); | |
} | |
// Public Methods ----------------------------------------------------------------------- | |
/** | |
* Initiates the setup process and accepts an event handler function that will be | |
* invoked once all components are ready to use. The callback is called with a single | |
* argument that reports any error that occurred during the initialization. | |
* | |
* e.g. sample readyState parameter: | |
* | |
* { | |
* isError: true, | |
* statusMessage "Application not supported." | |
* } | |
*/ | |
exports.onInit = (function() { | |
var readyState = undefined; | |
var callback = undefined; | |
// kick off setup phase regardless whether onInit() was called or not. | |
// Note: this is a self-executing function closure. | |
callExtendScript('theJsxMethod', CS_INTERFACE.getApplicationID(), function(result) { | |
callback && callback({ | |
isError : result != 'undefined' && result.trim() != '', | |
statusMessage : result | |
}); | |
}); | |
// The actual onInit() method. | |
// Will execute the initHandler immediately if setup() has already | |
// been completed or wait otherwise. | |
return function(initHandler) { | |
if (readyState) { | |
initHandler(readyState); | |
} | |
else { | |
callback = initHandler; | |
} | |
}; | |
})(); | |
/** | |
* @see $.MyClass#method() | |
*/ | |
exports.method = function() { | |
callExtendScript('$.MyClass#method'); | |
}; | |
return exports; | |
})(MyPlugin || {}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment