整理ps插件,加入重命名插件

This commit is contained in:
tianmo committed 2026-08-19 15:52:12 +08:00
1 parent 3b74c36083
commit 0905159c6e
15 files changed
+7115

No files matched your search

+312
View File
@@ -0,0 +1,312 @@
(function () {
"use strict";
var scriptList = document.getElementById("scriptList");
var emptyState = document.getElementById("emptyState");
var statusText = document.getElementById("statusText");
var searchInput = document.getElementById("searchInput");
var refreshButton = document.getElementById("refreshButton");
var openFolderButton = document.getElementById("openFolderButton");
var runExternalButton = document.getElementById("runExternalButton");
var scripts = [];
var extensionPathToken = "";
function getExtensionPath() {
if (!window.__adobe_cep__ || !window.__adobe_cep__.getSystemPath) {
return "";
}
var path = window.__adobe_cep__.getSystemPath("extension") || "";
path = decodeURI(path);
if (/^file:\/\/\/[A-Za-z]:/i.test(path)) {
path = path.substring(8);
} else if (/^file:\/\//i.test(path)) {
path = path.substring(7);
}
return path;
}
function setStatus(message, isError) {
statusText.textContent = message || "";
statusText.className = isError ? "status error" : "status";
statusText.title = message || "";
}
function evalHost(code, callback) {
if (!window.__adobe_cep__ || !window.__adobe_cep__.evalScript) {
callback("ERROR|当前页面不在 Photoshop CEP 环境中运行");
return;
}
window.__adobe_cep__.evalScript(code, callback);
}
function buildListCode() {
return '(function(){try{' +
'var folder=new Folder(decodeURIComponent("' + extensionPathToken + '")+"/jsx/scripts");' +
'if(!folder.exists){return "ERROR|脚本文件夹不存在:"+folder.fsName;}' +
'var result=[];' +
'function walk(current,prefix,depth){' +
'if(depth>20){return;}' +
'var entries=current.getFiles();' +
'entries.sort(function(a,b){' +
'var af=a instanceof Folder;var bf=b instanceof Folder;' +
'if(af!==bf){return af?-1:1;}' +
'var left=File.decode(a.displayName).toLowerCase();' +
'var right=File.decode(b.displayName).toLowerCase();' +
'return left<right?-1:(left>right?1:0);' +
'});' +
'for(var i=0;i<entries.length;i++){' +
'var entry=entries[i];' +
'if(entry instanceof Folder){' +
'var folderName=File.decode(entry.name);' +
'if(!entry.alias&&folderName.charAt(0)!=="."){' +
'walk(entry,prefix+folderName+"/",depth+1);' +
'}' +
'}else if(entry.name&&/\\.jsx$/i.test(entry.name)){' +
'var fileName=File.decode(entry.name);' +
'var label=File.decode(entry.displayName)' +
'.replace(/\\.jsx$/i,"").replace(/_/g," ");' +
'result.push(encodeURIComponent(label)+"|"+' +
'encodeURIComponent(prefix+fileName));' +
'}' +
'}' +
'}' +
'walk(folder,"",0);' +
'return result.join("\\n");' +
'}catch(error){return "ERROR|读取脚本列表失败:"+error.message;}}())';
}
function buildRunCode(encodedRelativePath) {
return '(function(){try{' +
'var folder=new Folder(decodeURIComponent("' + extensionPathToken + '")+"/jsx/scripts");' +
'var relativePath=decodeURIComponent("' + encodedRelativePath + '");' +
'var parts=relativePath.split("/");' +
'if(relativePath.charAt(0)==="/"||relativePath.indexOf("\\\\")!==-1||' +
'!/\\.jsx$/i.test(relativePath)){' +
'return "ERROR|脚本路径不安全";' +
'}' +
'for(var i=0;i<parts.length;i++){' +
'if(!parts[i]||parts[i]==="."||parts[i]===".."){return "ERROR|脚本路径不安全";}' +
'}' +
'var file=new File(folder.fsName+"/"+relativePath);' +
'if(!file.exists){return "ERROR|找不到脚本:"+relativePath;}' +
'$.evalFile(file);return "OK";' +
'}catch(error){return "ERROR|运行失败:"+error.message+"(第 "+error.line+" 行)";}}())';
}
function buildOpenFolderCode() {
return '(function(){try{' +
'var folder=new Folder(decodeURIComponent("' + extensionPathToken + '")+"/jsx/scripts");' +
'if(!folder.exists&&!folder.create()){' +
'return "ERROR|无法创建脚本文件夹:"+folder.fsName;' +
'}' +
'if(!folder.execute()){return "ERROR|无法打开脚本文件夹:"+folder.fsName;}' +
'return "OK";' +
'}catch(error){return "ERROR|无法打开脚本文件夹:"+error.message;}}())';
}
function buildExternalScriptCode() {
return '(function(){try{' +
'var file=File.openDialog("选择要运行的 Photoshop JSX 脚本");' +
'if(file===null){return "CANCEL";}' +
'if(!/\\.jsx$/i.test(file.name)){return "ERROR|请选择扩展名为 .jsx 的文件";}' +
'$.evalFile(file);return "OK";' +
'}catch(error){return "ERROR|运行失败:"+error.message+"(第 "+error.line+" 行)";}}())';
}
function parseScriptList(raw) {
if (raw === "EvalScript error.") {
throw new Error("Photoshop 拒绝执行目录扫描,请重新打开面板");
}
if (!raw) {
return [];
}
if (raw.indexOf("ERROR|") === 0) {
throw new Error(raw.substring(6));
}
var result = [];
var lines = raw.split("\n");
for (var i = 0; i < lines.length; i++) {
if (!lines[i]) {
continue;
}
var parts = lines[i].split("|");
if (parts.length >= 2) {
result.push({
label: decodeURIComponent(parts[0]),
relativePath: decodeURIComponent(parts[1])
});
}
}
return result;
}
function runBundledScript(script) {
var buttons = scriptList.querySelectorAll("button");
for (var i = 0; i < buttons.length; i++) {
buttons[i].disabled = true;
}
setStatus("正在运行:" + script.label, false);
evalHost(buildRunCode(encodeURIComponent(script.relativePath)), function (result) {
for (var j = 0; j < buttons.length; j++) {
buttons[j].disabled = false;
}
if (result && result.indexOf("ERROR|") === 0) {
setStatus(result.substring(6), true);
} else if (result === "EvalScript error.") {
setStatus("脚本运行失败,请检查 JSX 语法", true);
} else {
setStatus("已完成:" + script.label, false);
}
});
}
function makeTreeNode() {
return {folders: {}, scripts: []};
}
function addScriptToTree(root, script) {
var parts = script.relativePath.split("/");
parts.pop();
var node = root;
for (var i = 0; i < parts.length; i++) {
if (!node.folders[parts[i]]) {
node.folders[parts[i]] = makeTreeNode();
}
node = node.folders[parts[i]];
}
node.scripts.push(script);
}
function countScripts(node) {
var count = node.scripts.length;
var names = Object.keys(node.folders);
for (var i = 0; i < names.length; i++) {
count += countScripts(node.folders[names[i]]);
}
return count;
}
function createScriptButton(script) {
var button = document.createElement("button");
button.type = "button";
button.className = "script-button";
button.textContent = script.label;
button.title = script.relativePath;
button.addEventListener("click", function () {
runBundledScript(script);
});
return button;
}
function appendTree(node, container, depth, expandAll) {
var folderNames = Object.keys(node.folders).sort(function (a, b) {
var left = a.toLowerCase();
var right = b.toLowerCase();
return left < right ? -1 : (left > right ? 1 : 0);
});
for (var i = 0; i < folderNames.length; i++) {
var folderName = folderNames[i];
var childNode = node.folders[folderName];
var details = document.createElement("details");
details.className = "folder-group";
details.open = expandAll;
var summary = document.createElement("summary");
summary.className = "folder-summary";
summary.textContent = folderName + "(" + countScripts(childNode) + ")";
var content = document.createElement("div");
content.className = "folder-content";
appendTree(childNode, content, depth + 1, expandAll);
details.appendChild(summary);
details.appendChild(content);
container.appendChild(details);
}
for (var j = 0; j < node.scripts.length; j++) {
container.appendChild(createScriptButton(node.scripts[j]));
}
}
function renderScripts() {
var query = searchInput.value.toLowerCase().replace(/^\s+|\s+$/g, "");
scriptList.innerHTML = "";
var visibleCount = 0;
var root = makeTreeNode();
for (var i = 0; i < scripts.length; i++) {
var searchable = (scripts[i].label + " " + scripts[i].relativePath).toLowerCase();
if (query && searchable.indexOf(query) === -1) {
continue;
}
visibleCount++;
addScriptToTree(root, scripts[i]);
}
appendTree(root, scriptList, 0, query.length > 0);
emptyState.hidden = visibleCount !== 0;
}
function loadScripts() {
refreshButton.disabled = true;
setStatus("正在读取脚本…", false);
evalHost(buildListCode(), function (raw) {
refreshButton.disabled = false;
try {
scripts = parseScriptList(raw);
renderScripts();
setStatus("已载入 " + scripts.length + " 个脚本", false);
} catch (error) {
scripts = [];
renderScripts();
setStatus(error.message, true);
}
});
}
refreshButton.addEventListener("click", loadScripts);
searchInput.addEventListener("input", renderScripts);
openFolderButton.addEventListener("click", function () {
evalHost(buildOpenFolderCode(), function (result) {
if (result && result.indexOf("ERROR|") === 0) {
setStatus(result.substring(6), true);
} else if (result === "EvalScript error.") {
setStatus("无法执行打开文件夹命令", true);
} else {
setStatus("已打开脚本文件夹", false);
}
});
});
runExternalButton.addEventListener("click", function () {
setStatus("请选择一个 JSX 文件…", false);
evalHost(buildExternalScriptCode(), function (result) {
if (result && result.indexOf("ERROR|") === 0) {
setStatus(result.substring(6), true);
} else if (result === "CANCEL") {
setStatus("已取消", false);
} else if (result === "EvalScript error.") {
setStatus("外部脚本运行失败", true);
} else {
setStatus("外部脚本已运行", false);
}
});
});
var extensionPath = getExtensionPath();
extensionPathToken = encodeURIComponent(extensionPath);
if (!extensionPath) {
setStatus("无法获取扩展目录,请重启 Photoshop", true);
} else {
loadScripts();
}
}());