前言
原计划这篇文章要写开发工具和调试环境的,但是后来发现如果不先介绍CEP面板的基本结构的话,会对调试环境的配置的理解有障碍,于是本篇文章介绍一下CEP插件的基本分层结构和文件目录结构。
分层结构
CEP的全称是Common Extensibility Platform,是Adobe在CC2014版本一起推出的扩展开发平台,在CC2014及以前,相对应的面板插件开发,是基于Flash开发平台,后来随着web的发展以及flash的逐渐没落,adobe随记放弃了使用flash来开发插件,拥抱web开发模式,CEP的插件开发,即全部采用的web开发技术。
Adobe通过在Photoshop中嵌入了一个浏览器框架CEF(Chromium Embeded Framework),使得我们可以通过像开发网页一样来开发插件面板,用到的技术和网页开发的技术基本是一致的,也即是
HTML + CSS + JAVASCRIPT
面板负责呈现基本的内容和交互提供给用户,实际控制PS则依然用的宿主自身提供的脚本引擎,也即是Extension Script,分层结构图如下
运行结构
需要注意的一个地方是,Extension Script是运行在Ps的脚本引擎下的,它是EcmaScript的一个子集,它实现的是EcmaScript 3的标准,而运行在CEF下的Javascript是通过Google V8引擎来驱动的,它实现的是EcmaScript 5标准,两者是有一些差异的,最简单的理解,就是JSX里头包含的js特性要更少一些,比如不支持箭头函数,Array 对象没有 indexOf 方法等等,在实际开发的时候,不要想当然、随心所欲的写……
另外,PS在嵌入CEF的时候,同时在浏览器环境下嵌入了Node运行环境,于是你可以在开发网页的时候,使用nodejs的一些功能,比如你可以在面板中通过nodejs访问本地文件等等,在后续文章中专门来做介绍。
JSX中,脚本引擎也提供了本地路径访问的能力(File/Folder对象),这个也在后续的文章中介绍。
通信方式
由于面板和JSX是运行在不同的脚本环境下的,这就需要他们之间有一个通信的渠道,这样才能通过CEF中的JS来控制JSX,进而操作PS
CEF -> JS -> JSX -> Photoshop
JS -> JSX
为了能够让运行在浏览器中的JS,可以访问JSX脚本,adobe提供了一个基础库来实现CSInterface.js
注意
CSInterface.js是有版本的概念的,它随着PS的版本发布,不断在发布更新,高版本的CSInterface.js文件,在低版本的Ps中会有一些功能不可用,比如上面链接的版本是CEP_9.x,对应的是CC2018及以上的版本,在挑选该文件的时候需要特别注意
通过该基础库的api,我们可以直接运行JSX的代码
var cs = new CSInterface();
cs.evalScript(`alert(app.documents.length)`);
上面是一个非常简单的例子,实际使用中,我们会用到更多复杂的运用方式,后续文章中会在详细介绍。
JSX -> JS
反过来,如果要从JSX发送一些数据给JS层,有两种途径
1.代码执行的返回结果
还是上面那个例子,我们改造一下
var cs = new CSInterface();
cs.evalScript(`app.documents.length`, function (result) {
console.log(result);
});
evalScript方法的第二个参数,即是JSX运行的结果返回,通过这种方式,可以直接从JSX获取到执行结果,并返回到JS层。
2.事件派发
上面的方法只有在JS调用JSX的时候进行返回,当我们需要在某些特定场景主动发送数据给JS的时候,可以通过事件发送的方式来实现
// JSX
var eventObj = new CSXSEvent();
eventObj.type = "your-event-type";
eventObj.data = 'pass data from here';
eventObj.dispatch();
上面的data即是需要发送的数据,type的值可以自己定义,在JS层通过监听对应的事件来获取数据
// JS
var cs = new CSInterface();
cs.addEventListener("your-event-type", (event) => {
var data = event.data;
console.log(data); // output: pass data from here
});
面板的目录结构
CEP面板的文件结构,本质上是一堆web文件的集合,即html/css/js/jsx和一些图片等资源,除了有一个指定的目录文件规则之外,其它的目录结构可以自己定义,一版常见的目录结构如下
panel-name
| - CSXS
| - | - manifest.xml
| - js
| - css
| - jsx
| - index.html
面板的目录结构,只有一条规则,即根目录下必须有一个叫CSXS文件夹,该文件夹下必须有一个manifest.xml文件,我们接下来详细介绍一下该文件
manifest.xml定义了此面板的一些基本信息,比如id,version,入口文件等,下面是Ps自带的Library插件面板的manifest.xml文件,为了简要说明,我删掉了一些内容
<?xml version="1.0" encoding="UTF-8"?>
<ExtensionManifest Version="7.0" ExtensionBundleId="com.adobe.DesignLibraries.angular.2015.1" ExtensionBundleVersion="3.14.242"
ExtensionBundleName="DesignLibrary" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" DevBundleVersion="3.14.0">
<ExtensionList>
<!-- 插件面板的ID,一版是com.xxx.xxx的形式,Version是插件的版本 -->
<Extension Id="com.adobe.DesignLibraries.angular" Version="1.0" />
</ExtensionList>
<ExecutionEnvironment>
<HostList>
<!-- 支持的宿主,比如Photoshop: PSXS,InDesign: IDSN 等等 -->
<!-- Version是支持的宿主版本范围 -->
<Host Name="PHXS" Version="[22.0,99.9]" />
<Host Name="PHSP" Version="[22.0,99.9]" />
</HostList>
<LocaleList>
<Locale Code="All" />
</LocaleList>
<RequiredRuntimeList>
<!-- 支持的CSinterface的对应的版本 -->
<RequiredRuntime Name="CSXS" Version="5.0" />
</RequiredRuntimeList>
</ExecutionEnvironment>
<DispatchInfoList>
<Extension Id="com.adobe.DesignLibraries.angular">
<DispatchInfo>
<Resources>
<!-- 面板的html文件路径 -->
<MainPath>./index.html</MainPath>
<CEFCommandLine>
<!-- CEF的启动参数 -->
<Parameter>--high-dpi-support=1</Parameter>
<Parameter>--enable-nodejs</Parameter>
<Parameter>--mixed-context</Parameter>
<Parameter>--disable-accelerated-video-decode</Parameter>
<Parameter>--disable-threaded-scrolling</Parameter>
<Parameter>--disable-pinch</Parameter>
</CEFCommandLine>
<ScriptPath>./jsx/core.jsx</ScriptPath>
</Resources>
<Lifecycle>
<AutoVisible>true</AutoVisible>
</Lifecycle>
<UI>
<Type>Panel</Type> <!-- 面板类型 -->
<Menu>%DL_LIBRARIES_PANEL_NAME</Menu> <!-- 面板名称 -->
<Geometry>
<!-- 面板尺寸 -->
<Size>
<Height>300</Height>
<Width>245</Width>
</Size>
<MinSize>
<Height>165</Height>
<Width>245</Width>
</MinSize>
<MaxSize>
<Height>7680</Height>
<Width>7680</Width>
</MaxSize>
</Geometry>
<Icons>
<!-- 不同主题下的面板图标 -->
<Icon Type="Normal">./images/IconLight.png</Icon>
<Icon Type="RollOver">./images/IconLight.png</Icon>
<Icon Type="DarkNormal">./images/IconDark.png</Icon>
<Icon Type="DarkRollOver">./images/IconDark.png</Icon>
</Icons>
</UI>
</DispatchInfo>
</Extension>
</DispatchInfoList>
</ExtensionManifest>
该配置的大多数内容都在上面注释中体现了,这里重点提几个地方
<HostList>
<Host Name="PHXS" Version="[22.0,99.9]" />
<Host Name="PHSP" Version="[22.0,99.9]" />
</HostList>
Version字段的含义是支持的宿主版本区间,版本号你可以通过Ps的关于来查看,比如22.0对应的是CC2021的版本
[22.0, 99.9]的含义是,支持从CC2021开始及往后的PS的版本,也可以省略后面的99.9,比如这样
<HostList>
<Host Name="PHXS" Version="22.0" />
</HostList>
比如你想要支持的Ps版本是CC2015到CC2021,就可以这么写
<HostList>
<Host Name="PHXS" Version="[16.0, 22.0]" />
</HostList>
版本/版本号/CEP版本/CSXS的对应关系如下
PS版本 |
版本号 |
CEP版本 |
CSXS |
CC2015 |
16.0 |
6.x |
CSXS.6 |
CC2016 |
17.0 |
7.x |
CSXS.7 |
CC2017 |
18.0 |
8.x |
CSXS.8 |
CC2018 |
19.0 |
9.x |
CSXS.9 |
CC2019 |
20.0 |
10.x |
CSXS.10 |
CC2020 |
21.0 |
11.x |
CSXS.11 |
CC2021 |
22.0 |
12.x |
CSXS.12 |
第二个要注意的地方是CEF的启动参数
<CEFCommandLine>
<Parameter>--high-dpi-support=1</Parameter>
<Parameter>--enable-nodejs</Parameter>
<Parameter>--mixed-context</Parameter>
<Parameter>--disable-accelerated-video-decode</Parameter>
<Parameter>--disable-threaded-scrolling</Parameter>
<Parameter>--disable-pinch</Parameter>
</CEFCommandLine>
这些参数是在Ps加载插件面板,启动浏览器时候给提供的参数,其中重点关注的是 –enable-nodejs ,这个选项如果不加的话,你就不能再浏览器里头使用nodejs的特性了。
第三个是面板的类型 Type,面板提供了4这种类型, Panel, Model, Modeless, invsible,不同的类型在不同的场景会使用到,一般常用的是Panel类型,其它类型我们会在后续文章中涉及到时候再介绍。
结束
下一篇,我们继续介绍CEP开发的工具挑选和调试环境配置,敬请期待