整理ps插件,加入重命名插件
This commit is contained in:
1 parent
3b74c36083
commit
0905159c6e
15 files changed
+7115
No files matched your search
@@ -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();
|
||||
}
|
||||
}());
|
||||
Reference in new issue
Block a user