From f0e3e90870afeb4ec43c2252f09e156f4754e6e3 Mon Sep 17 00:00:00 2001 From: Zac Gaetano Date: Tue, 7 Apr 2026 22:05:46 -0400 Subject: [PATCH] Phase 2: services/premiere-plugin/js/CSInterface.js --- services/premiere-plugin/js/CSInterface.js | 210 +++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 services/premiere-plugin/js/CSInterface.js diff --git a/services/premiere-plugin/js/CSInterface.js b/services/premiere-plugin/js/CSInterface.js new file mode 100644 index 0000000..d207e00 --- /dev/null +++ b/services/premiere-plugin/js/CSInterface.js @@ -0,0 +1,210 @@ +/** + * CSInterface.js - Simplified Adobe CEP Interface + * + * This is a minimal shim implementation of Adobe's CSInterface.js for the + * Wild Dragon MAM Premiere Pro plugin. + * + * In production, use the official CSInterface.js from Adobe's CEP-Resources: + * https://github.com/Adobe-CEP/CEP-Resources/blob/master/CEP_11.0/CSInterface.js + * + * This version includes the key methods needed for the MAM panel: + * - evalScript: Execute ExtendScript in Premiere Pro + * - getSystemPath: Get system paths for file operations + * - requestOpenExtension: Open another extension + */ + +/** + * Adobe CEP SystemPath enum + * Used to get common system directories + */ +const SystemPath = { + USER_DATA: "user_data", + COMMON_FILES: "common_files", + MY_DOCUMENTS: "my_documents", + APPLICATION_DATA: "application_data", + TEMPORARY: "temporary" +}; + +/** + * CSInterface class - Main interface to communicate with Premiere Pro + */ +class CSInterface { + constructor() { + this.requestIdCount = 1; + this.requestMap = new Map(); + this.extensionId = "com.wilddragon.mam.panel"; + + // Initialize event listener for messages from ExtendScript + if (window.__adobe_cep__ !== undefined) { + window.__adobe_cep__.addEventListener("edu.adobe.csxs.events.message", (event) => { + this._handleMessage(event); + }); + } + } + + /** + * Evaluates an ExtendScript in the context of the host application + * @param {string} script - The ExtendScript code to execute + * @param {function} callback - Callback function to receive the result + */ + evalScript(script, callback) { + if (window.__adobe_cep__ === undefined) { + console.error("Adobe CEP not available"); + if (callback) callback(""); + return; + } + + const requestId = this.requestIdCount++; + if (callback) { + this.requestMap.set(requestId, callback); + } + + try { + window.__adobe_cep__.evalScript(script, requestId); + } catch (error) { + console.error("Error evaluating script:", error); + if (callback) { + this.requestMap.delete(requestId); + callback(""); + } + } + } + + /** + * Gets a system path from the host application + * @param {string} pathType - Type of path from SystemPath enum + * @returns {string} The system path + */ + getSystemPath(pathType) { + const pathMap = { + [SystemPath.TEMPORARY]: this._getTempPath(), + [SystemPath.MY_DOCUMENTS]: this._getDocumentsPath(), + [SystemPath.APPLICATION_DATA]: this._getAppDataPath(), + [SystemPath.USER_DATA]: this._getUserDataPath(), + [SystemPath.COMMON_FILES]: this._getCommonFilesPath() + }; + + return pathMap[pathType] || ""; + } + + /** + * Requests to open another extension + * @param {string} extensionId - The extension ID to open + */ + requestOpenExtension(extensionId) { + if (window.__adobe_cep__ === undefined) { + console.error("Adobe CEP not available"); + return; + } + + try { + const event = new CSXSEvent("com.adobe.csxs.events.ApplicationActivate", "BROADCAST"); + event.extensionId = extensionId; + window.__adobe_cep__.dispatchEvent(event); + } catch (error) { + console.error("Error opening extension:", error); + } + } + + /** + * Gets the current extension ID + * @returns {string} The extension ID + */ + getExtensionId() { + return this.extensionId; + } + + /** + * Adds an event listener for extension events + * @param {string} type - Event type + * @param {function} listener - Listener function + */ + addEventListener(type, listener) { + if (window.__adobe_cep__ !== undefined) { + window.__adobe_cep__.addEventListener(type, listener); + } + } + + /** + * Dispatches an event + * @param {CSXSEvent} event - The event to dispatch + */ + dispatchEvent(event) { + if (window.__adobe_cep__ !== undefined) { + window.__adobe_cep__.dispatchEvent(event); + } + } + + // Private helper methods for getting system paths + _getTempPath() { + if (navigator.platform.includes("Win")) { + return process.env.TEMP || "C:\\Users\\%USERNAME%\\AppData\\Local\\Temp"; + } else { + return process.env.TMPDIR || "/tmp"; + } + } + + _getDocumentsPath() { + if (navigator.platform.includes("Win")) { + return process.env.USERPROFILE + "\\Documents"; + } else { + return process.env.HOME + "/Documents"; + } + } + + _getAppDataPath() { + if (navigator.platform.includes("Win")) { + return process.env.APPDATA; + } else { + return process.env.HOME + "/Library/Application Support"; + } + } + + _getUserDataPath() { + if (navigator.platform.includes("Win")) { + return process.env.USERPROFILE + "\\AppData\\Roaming\\Adobe\\CEP\\extensions\\" + this.extensionId; + } else { + return process.env.HOME + "/Library/Application Support/Adobe/CEP/extensions/" + this.extensionId; + } + } + + _getCommonFilesPath() { + if (navigator.platform.includes("Win")) { + return "C:\\Program Files\\Common Files"; + } else { + return "/Library/Application Support"; + } + } + + _handleMessage(event) { + try { + const message = JSON.parse(event.data); + if (message.requestId !== undefined && this.requestMap.has(message.requestId)) { + const callback = this.requestMap.get(message.requestId); + this.requestMap.delete(message.requestId); + callback(message.result); + } + } catch (error) { + console.error("Error handling message:", error); + } + } +} + +/** + * CSXSEvent - Simple event object for CEP communication + */ +class CSXSEvent { + constructor(type, scope = "APPLICATION") { + this.type = type; + this.scope = scope; + this.data = ""; + } +} + +// Initialize and export the CSInterface singleton +const csInterface = new CSInterface(); + +// Make it globally available +window.csInterface = csInterface; +window.SystemPath = SystemPath; +window.CSXSEvent = CSXSEvent;