54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/scripts/cylinder.js:
--------------------------------------------------------------------------------
1 | // cylinder
2 | // for plainCanvas v.1.1.2 or later
3 | (function() {
4 | paper.setup("canvas");
5 | with(paper){
6 | var tool = new Tool();
7 |
8 | var v0 = new Point(0, 0);
9 | var v1 = new Point(1, 0);
10 |
11 | var grs; // groups
12 |
13 | // ----------------------------------------------
14 | var values = {
15 | diameter: 10,
16 | height: 30,
17 | interval: 20,
18 | lineWidth: 1.0,
19 | jitter: 18,
20 | ok: 0
21 | };
22 | optionManager.setupOptionsUI(["diameter", "height", "interval", "lineWidth", "jitter"], values);
23 |
24 | // ----------------------------------------------
25 | tool.onMouseDown = function(event){
26 | values.ok = optionManager.getOptionsFromUI(values);
27 | tool.minDistance = values.interval;
28 | grs = new Group();
29 | drawCylinder(event.point);
30 | }
31 | // ----------------------------------------------
32 | tool.onMouseDrag = function(event){
33 | if(values.ok == 0) return;
34 |
35 | drawCylinder(event.point.add( v1.rotate(Math.random() * 360, v0 )
36 | .multiply(Math.random() * values.jitter)));
37 | }
38 | // ----------------------------------------------
39 | tool.onMouseUp = function(){
40 | if(values.ok == 0) return;
41 |
42 | if(grs){
43 | if(grs.children.length < 1){
44 | grs.remove();
45 | } else {
46 | undoManager.keep(grs);
47 | }
48 | grs = null;
49 | }
50 | }
51 | // ----------------------------------------------
52 | function drawCylinder(pnt){
53 | var d = values.diameter;
54 | var r = values.diameter / 2; // radius
55 | var h = values.height;
56 | var w = values.lineWidth;
57 | var w2 = w / 2;
58 |
59 | var rad_v = (Math.random() * 0.8 + 0.1) * Math.PI / 2;
60 | var sn = Math.sin(rad_v);
61 | var cs = Math.cos(rad_v);
62 |
63 | var t = Math.random() * 360;
64 |
65 | h *= cs / sn;
66 |
67 | var gr = new Group();
68 |
69 | var path = make_a_path(w, new Color(1));
70 | path.moveTo(v0);
71 | path.arcTo( new Point(r, r), new Point(d, 0));
72 | path.lineTo(new Point(d, -h));
73 | path.arcTo( new Point(r, -h-r), new Point(0, -h));
74 | path.closePath();
75 | gr.addChild(path);
76 |
77 | var path1 = make_a_path(w2, new Color(1));
78 | path1.moveTo(v0);
79 | path1.arcTo(new Point(r, -r), new Point(d, 0));
80 | gr.addChild(path1);
81 |
82 | gr.translate(-r, h / 2);
83 | gr.scale(1, sn);
84 | gr.rotate(t);
85 | gr.translate(pnt);
86 |
87 | if( ! grs) grs = new Group();
88 | grs.addChild(gr);
89 | }
90 | // ----------------------------------------------
91 | function make_a_path(w, c){
92 | var path = new Path({
93 | closed: false,
94 | strokeWidth: w,
95 | strokeColor: new Color(0),
96 | fillColor: c
97 | });
98 | return path;
99 | }
100 | } // with(paper){
101 | })();
102 |
--------------------------------------------------------------------------------
/com.shspage.csxs.plaincanvas/js/undoManager.js:
--------------------------------------------------------------------------------
1 | /*
2 | undoManager
3 | v.1.0
4 |
5 | undoManager.keep(item);
6 | ... regist an item as a target of undo/redo
7 |
8 | undoManager.undo();
9 | ... perform undo
10 | (it just makes the last item kept invisible)
11 |
12 | undoManager.redo();
13 | ... preform redo
14 | (it makes the last item undoed visible)
15 |
16 | undoManager.clearHistory();
17 | ... clears undo/redo storage.
18 | (also removes invisible items in the history)
19 |
20 |
21 | undoManager.keep([item, item, item...], "dd");
22 | ... regist items as targets of undo/redo
23 |
24 | undoManager.keep(item, "m");
25 | ... regist a translation of an item as a target of undo/redo
26 | */
27 |
28 | var undoManager = (function() {
29 | 'use strict';
30 |
31 | var _UNDO_LIMIT = 200;
32 |
33 | var _MODE_DRAW = "d";
34 | var _MODE_DRAW_ITEMS = "dd";
35 | var _MODE_MOVE = "m";
36 |
37 |
38 | var _undoRedoSystemArray = function( name ){
39 | this.name = name;
40 | this.r = [];
41 | };
42 | _undoRedoSystemArray.prototype = {
43 | clear : function(limit, remove_visible_item){
44 | if(!limit) limit = 0;
45 | if(!remove_visible_item) remove_visible_item = false;
46 |
47 | var arr;
48 | var typ;
49 | var itm;
50 |
51 | while(this.r.length > limit){
52 | arr = this.r.shift();
53 | typ = arr[0];
54 | itm = arr[1];
55 | if(typ == _MODE_DRAW_ITEMS){
56 | if(itm){
57 | for(var i = itm.length - 1; i >= 0; i--){
58 | if(itm[i] && (remove_visible_item || !itm[i].visible)){
59 | itm[i].remove();
60 | }
61 | }
62 | }
63 | } else {
64 | if(itm && (remove_visible_item || !itm.visible)){
65 | itm.remove();
66 | }
67 | }
68 | }
69 | },
70 |
71 | store : function(arr){
72 | this.r.push(arr);
73 | if(_UNDO_LIMIT > 0 && this.name == "undo"){
74 | this.clear(_UNDO_LIMIT, true);
75 | }
76 | }
77 | };
78 |
79 | var undoArray = new _undoRedoSystemArray("undo");
80 | var redoArray = new _undoRedoSystemArray("redo");
81 |
82 | var _perform = function( arr, is_undo ){
83 | var itm = arr[1];
84 | if(arr[0] == _MODE_DRAW){
85 | if(itm){
86 | itm.visible = ! itm.visible;
87 | }
88 |
89 | } else if(arr[0] == _MODE_DRAW_ITEMS){
90 | // itm = [item, item,...
91 | for(var i = itm.length - 1; i >= 0; i--){
92 | if(itm[i]){
93 | itm[i].visible = ! itm[i].visible;
94 | }
95 | }
96 |
97 | } else if(arr[0] == _MODE_MOVE){
98 | itm.translate(is_undo ? arr[2] : arr[3]);
99 | }
100 | }
101 |
102 | var undo = function(){
103 | if(undoArray.r.length > 0){
104 | var arr = undoArray.r.pop();
105 | _perform( arr, true );
106 | redoArray.store( arr );
107 | }
108 | }
109 |
110 | var redo = function(){
111 | if(redoArray.r.length > 0){
112 | var arr = redoArray.r.pop();
113 | _perform( arr, false );
114 | undoArray.store( arr );
115 | }
116 | }
117 |
118 | var keep = function(item, mode){
119 | if(!mode) mode = _MODE_DRAW;
120 | undoArray.store([mode, item]);
121 | redoArray.clear();
122 | }
123 |
124 | var clearHistory = function(){
125 | undoArray.clear();
126 | redoArray.clear();
127 | }
128 |
129 | return {
130 | undo : undo,
131 | redo : redo,
132 | keep : keep,
133 | clearHistory : clearHistory
134 | }
135 | })();
136 |
--------------------------------------------------------------------------------
/scripts/cube.js:
--------------------------------------------------------------------------------
1 | // cube
2 | // for plainCanvas v.1.1.2 or later
3 | (function() {
4 | paper.setup("canvas");
5 | with(paper){
6 | var tool = new Tool();
7 |
8 | var v0 = new Point(0, 0);
9 | var v1 = new Point(1, 0);
10 |
11 | var grs; // group
12 |
13 | // ----------------------------------------------
14 | var values = {
15 | cubeSize: 10,
16 | interval: 10,
17 | jitter: 10,
18 | ok : 1,
19 | };
20 |
21 | optionManager.setupOptionsUI(["cubeSize", "interval", "jitter"], values);
22 |
23 | // ----------------------------------------------
24 | tool.onMouseDown = function(event){
25 | values.ok = optionManager.getOptionsFromUI(values);
26 |
27 | if(values.ok){
28 | tool.minDistance = values.interval;
29 | grs = new Group();
30 | drawCube(event.point);
31 | }
32 | }
33 | // ----------------------------------------------
34 | tool.onMouseDrag = function(event){
35 | if(values.ok){
36 | drawCube(event.point.add( v1.rotate(Math.random() * 360, v0 )
37 | .multiply(Math.random() * values.jitter)));
38 | }
39 | }
40 | // ----------------------------------------------
41 | tool.onMouseUp = function(){
42 | if(values.ok){
43 | if(grs){
44 | if(grs.children.length < 1){
45 | grs.remove();
46 | } else {
47 | undoManager.keep(grs);
48 | }
49 | grs = null;
50 | }
51 | }
52 | }
53 | // ----------------------------------------------
54 | function points2segments(points){
55 | for(var i = 0; i < points.length; i++){
56 | points[i] = new Segment(points[i]);
57 | }
58 | return points;
59 | }
60 | // ----------------------------------------------
61 | function drawCube(pnt){
62 | var radian_v = (Math.random() * 0.7 + 0.15) * Math.PI / 2;
63 | var angle_h = (Math.random() - 0.5) * (90 * 0.85);
64 | var radius = values.cubeSize / Math.sqrt(2);
65 | var v = new Point(1, 0);
66 | var v2 = v.rotate(angle_h).multiply(radius);
67 | var sn = Math.sin(radian_v);
68 | var p_sn = new Point(1, sn);
69 |
70 | var face_top = [v2.multiply(p_sn),
71 | v2.rotate(90).multiply(p_sn),
72 | v2.rotate(180).multiply(p_sn),
73 | v2.rotate(-90).multiply(p_sn)];
74 |
75 | var cs = values.cubeSize * Math.cos(radian_v);
76 | var p_cs = new Point(0, -cs);
77 |
78 | var face_side = [v2.rotate(180).multiply(p_sn).add(p_cs),
79 | v2.rotate(-90).multiply(p_sn).add(p_cs),
80 | v2.multiply(p_sn).add(p_cs)];
81 |
82 | var path = make_a_path(1, new Color(1));
83 |
84 | path.closed = true;
85 | path.strokeJoin = 'round';
86 |
87 | var gr = new Group();
88 | gr.insertChild(0, path);
89 | path.segments = points2segments(
90 | [face_top[0], face_top[1], face_top[2],
91 | face_side[0], face_side[1], face_side[2]]);
92 |
93 |
94 | path = make_a_path(0.5, null);
95 | gr.addChild(path);
96 | path.segments = points2segments([face_top[0], face_top[3]]);
97 |
98 | path = make_a_path(0.5, null);
99 | gr.addChild(path);
100 | path.segments = points2segments([face_top[2], face_top[3]]);
101 |
102 | path = make_a_path(0.5, null);
103 | gr.addChild(path);
104 | path.segments = points2segments([face_side[1], face_top[3]]);
105 |
106 | gr.position = gr.position.add(new Point(0, cs / 2));
107 | gr.rotate( Math.random() * 360 );
108 | gr.position = gr.position.add(pnt);
109 | if( ! grs) grs = new Group();
110 | grs.addChild(gr);
111 | }
112 | // ----------------------------------------------
113 | function make_a_path(w, c){
114 | var path = new Path({
115 | closed: false,
116 | strokeWidth: w,
117 | strokeColor: new Color(0),
118 | fillColor: c
119 | });
120 | return path;
121 | }
122 | } // with(paper){
123 | })();
124 |
--------------------------------------------------------------------------------
/com.shspage.csxs.plaincanvas/js/themeManager.js:
--------------------------------------------------------------------------------
1 | /*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */
2 | /*global window, document, CSInterface*/
3 |
4 |
5 | /*
6 |
7 | Responsible for overwriting CSS at runtime according to CC app
8 | settings as defined by the end user.
9 |
10 | */
11 |
12 | var themeManager = (function () {
13 | 'use strict';
14 |
15 | /**
16 | * Convert the Color object to string in hexadecimal format;
17 | */
18 | function toHex(color, delta) {
19 |
20 | function computeValue(value, delta) {
21 | var computedValue = !isNaN(delta) ? value + delta : value;
22 | if (computedValue < 0) {
23 | computedValue = 0;
24 | } else if (computedValue > 255) {
25 | computedValue = 255;
26 | }
27 |
28 | computedValue = Math.floor(computedValue);
29 |
30 | computedValue = computedValue.toString(16);
31 | return computedValue.length === 1 ? "0" + computedValue : computedValue;
32 | }
33 |
34 | var hex = "";
35 | if (color) {
36 | hex = computeValue(color.red, delta) + computeValue(color.green, delta) + computeValue(color.blue, delta);
37 | }
38 | return hex;
39 | }
40 |
41 |
42 | function reverseColor(color, delta) {
43 | return toHex({
44 | red: Math.abs(255 - color.red),
45 | green: Math.abs(255 - color.green),
46 | blue: Math.abs(255 - color.blue)
47 | },
48 | delta);
49 | }
50 |
51 |
52 | function addRule(stylesheetId, selector, rule) {
53 | var stylesheet = document.getElementById(stylesheetId);
54 |
55 | if (stylesheet) {
56 | stylesheet = stylesheet.sheet;
57 | if (stylesheet.addRule) {
58 | stylesheet.addRule(selector, rule);
59 | } else if (stylesheet.insertRule) {
60 | stylesheet.insertRule(selector + ' { ' + rule + ' }', stylesheet.cssRules.length);
61 | }
62 | }
63 | }
64 |
65 |
66 |
67 | /**
68 | * Update the theme with the AppSkinInfo retrieved from the host product.
69 | */
70 | function updateThemeWithAppSkinInfo(appSkinInfo) {
71 |
72 | var panelBgColor = appSkinInfo.panelBackgroundColor.color;
73 | var bgdColor = toHex(panelBgColor);
74 |
75 | var darkBgdColor = toHex(panelBgColor, 20);
76 |
77 | var fontColor = "F0F0F0";
78 | if (panelBgColor.red > 122) {
79 | fontColor = "000000";
80 | }
81 | var lightBgdColor = toHex(panelBgColor, -100);
82 |
83 | var styleId = "hostStyle";
84 |
85 | addRule(styleId, ".hostElt", "background-color:" + "#" + bgdColor);
86 | addRule(styleId, ".hostElt", "font-size:" + appSkinInfo.baseFontSize + "px;");
87 | addRule(styleId, ".hostElt", "font-family:" + appSkinInfo.baseFontFamily);
88 | addRule(styleId, ".hostElt", "color:" + "#" + fontColor);
89 |
90 | addRule(styleId, ".hostBgd", "background-color:" + "#" + bgdColor);
91 | addRule(styleId, ".hostBgdDark", "background-color: " + "#" + darkBgdColor);
92 | addRule(styleId, ".hostBgdLight", "background-color: " + "#" + lightBgdColor);
93 | addRule(styleId, ".hostFontSize", "font-size:" + appSkinInfo.baseFontSize + "px;");
94 | addRule(styleId, ".hostFontFamily", "font-family:" + appSkinInfo.baseFontFamily);
95 | addRule(styleId, ".hostFontColor", "color:" + "#" + fontColor);
96 |
97 | addRule(styleId, ".hostFont", "font-size:" + appSkinInfo.baseFontSize + "px;");
98 | addRule(styleId, ".hostFont", "font-family:" + appSkinInfo.baseFontFamily);
99 | addRule(styleId, ".hostFont", "color:" + "#" + fontColor);
100 |
101 | addRule(styleId, ".hostButton", "background-color:" + "#" + darkBgdColor);
102 | addRule(styleId, ".hostButton:hover", "background-color:" + "#" + bgdColor);
103 | addRule(styleId, ".hostButton:active", "background-color:" + "#" + darkBgdColor);
104 | addRule(styleId, ".hostButton", "border-color: " + "#" + lightBgdColor);
105 | }
106 |
107 |
108 | function onAppThemeColorChanged(event) {
109 | var skinInfo = JSON.parse(window.__adobe_cep__.getHostEnvironment()).appSkinInfo;
110 | updateThemeWithAppSkinInfo(skinInfo);
111 | }
112 |
113 |
114 | function init() {
115 |
116 | var csInterface = new CSInterface();
117 |
118 | updateThemeWithAppSkinInfo(csInterface.hostEnvironment.appSkinInfo);
119 |
120 | csInterface.addEventListener(CSInterface.THEME_COLOR_CHANGED_EVENT, onAppThemeColorChanged);
121 | }
122 |
123 | return {
124 | init: init
125 | };
126 |
127 | }());
128 |
--------------------------------------------------------------------------------
/com.shspage.csxs.plaincanvas/js/optionManager.js:
--------------------------------------------------------------------------------
1 | /*
2 | optionManager
3 | v.1.1
4 |
5 | // ----------------------
6 | // functions for UI and optional values
7 | // ----------------------
8 | setupOptionsUI(titles, options)
9 | ... titles: titles for input text boxes, an array of string. max = 5
10 | options: an object which has properties with a name of each title.
11 | each value must be a number.
12 | ex. setupOptionsUI(["item1", "item2", "item3"], options)
13 | -> 4th and 5th text boxes are hidden.
14 | -> options = { "item1":0, "item2":1, ... }
15 | ... sets up option UI. maximum number of text boxes is 5.
16 | ... "options" can be an array of number. if you want to use a title
17 | different from the property name of "options", use this style.
18 |
19 | getOptionsFromUI(options)
20 | ... options: an object
21 | ... gets values from option UI, and set as properties of options
22 | with a name of the title of the each input text box.
23 | if there's a invalid value, shows an alert and return 0.
24 | otherwise return 1.
25 | ... if "options" is undefined, returns an array of values.
26 | ( on error, returns null )
27 |
28 | resetOptions()
29 | ... resets option UI to default status
30 |
31 | noOption()
32 | ... hides the UIs for option
33 | // ----------------------
34 | */
35 |
36 | var optionManager = (function() {
37 | 'use strict';
38 |
39 | var OPTION_COUNT = 5;
40 |
41 | // ----------------------
42 | // functions for UI and optional values
43 | // ----------------------
44 | var setupOptionsUI = function(titles, options) {
45 | if(options instanceof Array){
46 | // obsolete style
47 | // ex. titles:["item1","item2","item3"], options:[1,2,3]
48 | _setupOptionsUI_main(titles, options);
49 | return;
50 | }
51 |
52 | var values = [];
53 | for(var i = 0; i < titles.length; i++){
54 | values.push(options[titles[i]]);
55 | }
56 | _setupOptionsUI_main(titles, values);
57 | }
58 |
59 | var _setupOptionsUI_main = function(titles, values) {
60 | if(!titles || titles.length < 1){
61 | document.getElementById("div_no_option").style.display = "block";
62 | document.getElementById("div_options").style.display = "none";
63 | } else {
64 | document.getElementById("div_no_option").style.display = "none";
65 | for(var i = 1; i <= OPTION_COUNT; i++){
66 | if(i > titles.length){
67 | document.getElementById("td" + i).innerText = "";
68 | document.getElementById("input" + i).style.display = "none";
69 | } else {
70 | document.getElementById("td" + i).innerText = titles[i-1];
71 | document.getElementById("input" + i).value = values[i-1];
72 | }
73 | }
74 | }
75 | }
76 | // ----
77 | var getOptionsFromUI = function(options) {
78 | if(!options){
79 | return _getOptionsFromUI_returnArray();
80 | }
81 |
82 | for(var i = 1; i <= OPTION_COUNT; i++){
83 | try{
84 | var title = document.getElementById("td" + i).innerText;
85 | if(title != ""){
86 | var v = document.getElementById("input" + i).value;
87 | v = eval(v) - 0;
88 | options[title] = v;
89 | }
90 | } catch(e){
91 | alert(e);
92 | return 0;
93 | }
94 | }
95 | return 1;
96 | }
97 | // ----
98 | // reset the status of the UIs for option
99 | var resetOptions = function() {
100 | document.getElementById("table_options").style.display = "block";
101 | for(var i = 1; i <= OPTION_COUNT; i++){
102 | document.getElementById("td" + i).innerText = "item" + i;
103 | document.getElementById("input" + i).style.display = "block";
104 | document.getElementById("input" + i).value = 0;
105 | }
106 |
107 | document.getElementById("div_no_option").style.display = "none";
108 | }
109 |
110 | // ----
111 | // hides the UIs for option
112 | var noOption = function(){
113 | document.getElementById("table_options").style.display = "none";
114 | document.getElementById("div_no_option").style.display = "block";
115 | }
116 |
117 | // ------------------------------------
118 | // obsolete
119 | var _getOptionsFromUI_returnArray = function() {
120 | var optionalValues = [];
121 |
122 | for(var i = 1; i <= OPTION_COUNT; i++){
123 | try{
124 | var v = document.getElementById("input" + i).value;
125 | v = eval(v) - 0;
126 | optionalValues.push(v);
127 | } catch(e){
128 | alert(e);
129 | return null;
130 | }
131 | }
132 |
133 | return optionalValues;
134 | }
135 |
136 |
137 | // ------------------------------------
138 | return {
139 | setupOptionsUI : setupOptionsUI,
140 | getOptionsFromUI : getOptionsFromUI,
141 | resetOptions : resetOptions,
142 | noOption : noOption
143 | }
144 | })();
145 |
--------------------------------------------------------------------------------
/README_ja.md:
--------------------------------------------------------------------------------
1 | # plainCanvas
2 |
3 | Adobe Illustrator (CC 2014-) 用の add-on です。以下のことが可能です。
4 |
5 | * [paper.js](http://paperjs.org) 用に書かれた JavaScript ファイルを読み込んで実行する。
6 | (初期状態では、ドラッグで線を描くツールが使用できます。)
7 | * add-on パネル上に作成した画像を、アートボードに書き出す。
8 | * アートボード上のパスを、add-on パネル上に取り込む。
9 |
10 | 
11 |
12 | ### 導入方法
13 | 諸々のスクリプトを読み込んで実行するという性格上、デバッグ機能を利用することを想定しています。このため、導入には通常のadd-onと異なる手順が必要です。
14 |
15 | 1. [CEP 10 HTML Extension Cookbook](https://github.com/Adobe-CEP/CEP-Resources/blob/master/CEP_10.x/Documentation/CEP%2010.0%20HTML%20Extension%20Cookbook.md#cep-10-html-extension-cookbook) の [Debugging Unsigned Extensions](https://github.com/Adobe-CEP/CEP-Resources/blob/master/CEP_10.x/Documentation/CEP%2010.0%20HTML%20Extension%20Cookbook.md#debugging-unsigned-extensions) にしたがって、debug mode flagを設定してください。(CSXS.10とありますが、数字はイラレのバージョンにより異なります。例えば Ai 2024(28.2)では CSXS.11 です。)
16 | 2. [CEP 10 HTML Extension Cookbook](https://github.com/Adobe-CEP/CEP-Resources/blob/master/CEP_10.x/Documentation/CEP%2010.0%20HTML%20Extension%20Cookbook.md#cep-10-html-extension-cookbook) の [Extension Folders](https://github.com/Adobe-CEP/CEP-Resources/blob/master/CEP_10.x/Documentation/CEP%2010.0%20HTML%20Extension%20Cookbook.md#extension-folders) にしたがって、com.shspage.csxs.plaincanvas フォルダを、extensions フォルダに置いてください。
17 | 3. Illustrator を実行して、メニューの ウィンドウ -> エクステンション の中にある plainCanvas を選んでください。
18 |
19 | ### パネル上のボタンについて
20 | * __in__ : Illustratorで選択されているパスが、パネル上に取り込まれます。
21 | * __out__ : パネル上のパスが、アートボードに書き出されます。
22 | * __run__ : 実行機能があるスクリプトを実行します。
23 | * __opt__ : オプション入力欄を表示/非表示します。入力できるオプションがない場合、no option と表示されます。
24 | * __<__ : 直前の描画を取り消します。
25 | * __>__ : 直前に取り消した描画をやり直します。
26 | * __CL__ : パネル上の描画をクリアします。
27 | * __DB__ : 既定のブラウザでデバッグツールを開きます。
28 | * __RL__ : パネルをリロードします。( hostscript.jsx はリロードされません。)
29 | * __load__ : スクリプトファイルを選択するダイアログを表示します。
30 |
31 | ### スクリプトファイルの読み込み
32 | * 読み込みたいスクリプトファイルを、パネルへドラッグ&ドロップしてください。
33 | __load__ ボタンでスクリプトファイルを選択することもできます。
34 | * 読み込み完了後、パネル上の描画はクリアされます。
35 |
36 | ### 読み込んで実行できる JavaScript スクリプト
37 | * [scripts](https://github.com/shspage/plainCanvas/tree/master/scripts) フォルダにサンプルスクリプトがあります。
38 | * javascript として記述してください (paperscript ではなく)。詳しくは、http://paperjs.org の、チュートリアル "[Using JavaScript Directly](http://paperjs.org/tutorials/getting-started/using-javascript-directly/)" をご覧下さい。
39 | __例:__ new Path() -> new paper.Path() // または "with(paper){" ステートメントを使うなど
40 | __例:__ point1 + point2 -> point1.add(point2)
41 | __例:__ function onMouseDown(event) -> tool.onMouseDown = function(event)
42 | * 文字コードは utf-8 で作成してください。(js/main.js 内の SCRIPT_ENCODING で変更することもできます。変更した場合は、index.htmlのcharset も変更してください。)
43 | * パネルのオプション入力欄を利用する場合、または、 オプション入力欄を非表示にする場合、optionManager.js のメソッドが利用できます。使用方法については同ファイル内の説明やサンプルスクリプトをご覧下さい。
44 | * object の描画が完了した時点で以下を実行すると、undo/redoの対象にできます。("object" は描画したオブジェクトを示す変数に置き換えてください。)
45 | ```javascript
46 | undoManager.keep(object);
47 | ```
48 | undo は、対象にしたオブジェクトを不可視にすることで行われるため、paper.project 上には存在したままです。ただし、undoManager.js の UNDO_LIMIT を超えた場合は古いものから削除されます。また、不可視オブジェクトは書き出されません。
49 | * 読み込んだスクリプトファイルは、index.html 内に新たに生成した script タグの内容として挿入されます。
50 |
51 |
52 | ### 色の扱い
53 | * canvas は CMYKカラーを扱えないため、CMYKカラーを取り込んだ場合はRGBに変換して表示します。このため、元の色と違って見える場合があります。元のCMYKの値はメモリに保持しており(*1)、書き出す際には元の色になります。
54 | (*1: js/main.js の ALWAYS_EXPORT_RGB が false の場合)
55 | * js/main.js の ALWAYS_EXPORT_RGB が true の場合、paper.Color.type == "gray" の色は RGBColor で書き出されます。
56 | * 取り込み/書き出しの処理は、グラデーション、特色 に対応していません。
57 |
58 | ### アートボードへの書き出し
59 | * canvas 上の paper.Path インスタンスの、以下の属性が書き出されます。
60 | _segments, strokeWidth, strokeColor, fillColor, opacity_
61 |
62 | ### パスの取り込み
63 | * アートボード上の選択範囲に含まれる PathItem の以下の属性が取り込まれます。
64 | _pathPoints, strokeWidth, strokeColor, fillColor_
65 | * グループと複合パスは解除された状態で取り込まれます。
66 |
67 | ### 画像の読み込み
68 | * パネルへのドラッグ&ドロップ、または__load__ ボタンによって画像を読み込むことができます。対応画像形式は jpeg, png です。
69 | * 画像読み込み後にパネル右上に表示される[hide image]をクリックすると画像を非表示にできます。再度クリックすると表示します。
70 | * 読み込んだ画像は __paper.project.activeLayer.data.raster__ に保持され、スクリプトで利用することができます。
71 | * 画像は、スクリプトファイルの読み込みや CL・RLボタンによる画面クリアの際に破棄されます。
72 |
73 | ### 変更履歴
74 | #### v.1.2.2
75 | * 画像読み込みに対応。
76 | #### v.1.2.1
77 | * スクリプト読み込みエラー アラートと実行エラー アラートを追加しました。
78 | #### v.1.2.0
79 | * ライブラリ類を更新。
80 | #### v.1.1.8
81 | * runボタンを追加。runボタン用のサンプルスクリプトを追加。
82 | * 修正:前回と同じ名前のスクリプトファイルを読み込んだ際に、変更が反映されます。
83 | #### v.1.1.7
84 | * loadボタンでもスクリプトファイルを読み込めるようにしました。
85 | #### v.1.1.6
86 | * manifest.xml で対応バージョンの上限を 99.9 に変更
87 | #### v.1.1.4
88 | * manifest.xml で対応バージョンの上限を 24.9 に変更
89 | #### v.1.1.3
90 | * グレーカラーのインポート/エクスポートでの問題を修正
91 | #### v.1.1.2
92 | * loadボタンを廃止し、スクリプトファイルのドロップを常に受け付けるようにしました。
93 | * paper.js の基本オブジェクトをグローバルにしました。これに合わせてサンプルスクリプトも更新しました。
94 | * パネルの最大サイズを2000×2000に拡大しました。
95 | #### v.1.1.1
96 | * 読み込み時以外、パネルへのドロップを受け付けないようにしました。
97 | #### v.1.1.0
98 | * パネル上のドラッグでテキストが選択されないようにしました。
99 | * スクリプトファイルをドラッグ&ドロップで読み込むようにしました。
100 |
101 | ### TODO / 既知の問題
102 | * TODO: 外部スクリプトファイルの読み込み方法を再検討する。
103 | * アートボードから取り込んだ図形の白黒が反転する場合がある。
104 | * 書き出した際に、アートボードから取り込んだものとcanvas上で描画したものの前後関係が正しくない場合がある。
105 | * TODO: アートボードとのやりとりに importSVG, exportSVG を使う?
106 |
107 | ### ライセンス、その他
108 | * ※ 改変して公開する場合は、必ず __バンドルID__ を変更してください。(バンドルID … CSXS/manifest.xml および.debug 内の com.shspage.csxs.plaincanvas。)
109 | * MIT ライセンスの下で公開しています。詳細はLICENSE.txtをご覧下さい。
110 | ただし、以下の使用ライブラリは、それぞれのライセンスに従います。
111 |
112 | * Paper.js v0.12.17 - The Swiss Army Knife of Vector Graphics Scripting.
113 | http://paperjs.org/
114 | Copyright (c) 2011 - 2020, Jürg Lehni & Jonathan Puckey
115 | http://juerglehni.com/ & https://puckey.studio/
116 | All rights reserved.
117 |
118 | * Creative Cloud Extension Builder for Brackets
119 | https://github.com/davidderaedt/CC-Extension-Builder-for-Brackets
120 | Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved.
121 |
122 |
--------------------------------------------------------------------------------
/scripts/fiddlehead.js:
--------------------------------------------------------------------------------
1 | // fiddlehead (zenmai)
2 | // for plainCanvas v.1.1.2 or later
3 | (function() {
4 | paper.setup("canvas");
5 | with(paper){
6 | var tool = new Tool();
7 |
8 | var hlen = 4 * (Math.sqrt(2) - 1) / 3;
9 | var hpi = 90;
10 | var qpi = hpi / 2;
11 | var po = new Point(0,0);
12 |
13 | var line, lastPnt, gr;
14 | var angleRange, stemLen, spiralRadius, lineWidth;
15 | var interval, growDir, lineCol;
16 |
17 | function setupOptions(){
18 | angleRange = 45;
19 | stemLen = 100;
20 | spiralRadius = 10;
21 | lineWidth = 0.5;
22 |
23 | // init
24 | interval = spiralRadius / 2;
25 | growDir = 1; // 1:normal, 2:drawing direction
26 | lineCol = "black"; //new Color(1); //or selectedLineCol_or_Black();
27 |
28 | stemLen /= 2;
29 | spiralRadius /= 2;
30 |
31 | optionManager.setupOptionsUI(["stem length", "spiral radius", "interval", "angle range", "direction(1,2)"],
32 | [stemLen*2, spiralRadius*2, interval, angleRange, growDir]);
33 | }
34 | setupOptions();
35 |
36 | // ---------------------
37 | function getOptions(){
38 | var opt = optionManager.getOptionsFromUI();
39 | if(opt != null){
40 | for(var i=0; i 0){
73 | v = (event.delta).normalize();
74 | if(growDir > 1) v = v.rotate(hpi);
75 | }
76 | makeline();
77 |
78 | zenmai(v.rotate(hpi), event);
79 | }
80 | // --------------------------
81 | tool.onMouseUp = function(event){
82 | if(gr){
83 | if(gr.children.length < 2){
84 | if(gr.children.length == 1) gr.firstChild.moveAbove(gr);
85 | gr.remove();
86 | } else {
87 | if(undoManager) undoManager.keep(gr);
88 | }
89 | gr = null;
90 | }
91 | lastPnt = null;
92 | line = null;
93 | }
94 | // --------------------------
95 | function makeline(){
96 | line = new Path({
97 | fillColor: null,
98 | strokeColor: lineCol,
99 | strokeWidth: lineWidth
100 | });
101 | if(!gr) gr = new Group();
102 | gr.addChild(line);
103 | }
104 | // --------------------------
105 | function zenmai(v, event){
106 | var m = Math.random() + 1;
107 | var len = stemLen * m;
108 | var hlen = len/3;
109 | // 1st point
110 | line.segments = [new Segment(lastPnt,
111 | po,
112 | v.multiply(hlen))];
113 | // 2nd point
114 | v = v.rotate(angleRange * (Math.random()-0.5));
115 | var p = lastPnt.add( v.multiply(len));
116 | line.add(new Segment(p,
117 | v.rotate(angleRange * (Math.random()-0.5)) * (-hlen),
118 | po));
119 |
120 | addSpiral(line.segments, spiralRadius * m, 0.85, 12, (Math.random() < 0.5));
121 | }
122 | // --------------------------
123 | function addSpiral(segs,
124 | r, // first radius
125 | m, // rate
126 | n, // number of segments
127 | rl){ // turn right (t/f)
128 | var qp = rl ? -qpi : qpi;
129 |
130 | var len = segs.length - 1;
131 | if(len < 1) return;
132 | var p = segs[len].point;
133 | // define v
134 | var v;
135 | if(segs[len].handleIn.equals(po)){
136 | with(segs[len - 1]){
137 | if(p.equals(point)) return;
138 | if(p.equals(point.add(handleOut))){
139 | v = (p.subtract(point)).normalize();
140 | } else {
141 | v = (p.subtract(point.add(handleOut))).normalize();
142 | }
143 | }
144 | } else {
145 | v = (segs[len].handleIn.multiply(-1)).normalize();
146 | }
147 | // make spiral
148 | var seg;
149 | var h = r * hlen;
150 | segs[len].handleOut = v.multiply(h);
151 | for(var i=0; i 0){
88 | s = s.replace(/0+$/,"");
89 | return s.replace(/\.$/,"");
90 | }
91 | }
92 |
93 | // serialize a color object to draw on a canvas
94 | function serializeColor(col){
95 | if(col.typename == "NoColor"){
96 | return ["N", 0, 0, 0, 0];
97 | } else if(col.typename == "GrayColor"){
98 | return ["G", _f2s(col.gray / 100), 0, 0, 0];
99 | } else if(col.typename == "RGBColor"){
100 | return ["RGB", _f2s(col.red / 255), _f2s(col.green / 255), _f2s(col.blue / 255), 0];
101 | } else if(col.typename == "CMYKColor"){
102 | return ["CMYK", _f2s(col.cyan), _f2s(col.magenta), _f2s(col.yellow), _f2s(col.black)];
103 | } else {
104 | // GradientColor, SpotColor etc.
105 | return ["UNKNOWN", 0, 0, 0, 0];
106 | }
107 | }
108 |
109 | // find the top-left point of paths
110 | function getTopLeftOfPaths(paths){
111 | if(paths.length < 1) return [0,0];
112 |
113 | var top = paths[0].top;
114 | var left = paths[0].left;
115 |
116 | for(var i = 0, iEnd = paths.length; i < iEnd; i++){
117 |
118 | var cb = paths[i].controlBounds; // left, top, right, bottom
119 |
120 | if(cb[1] > top) top = cb[1];
121 | if(cb[0] < left) left = cb[0];
122 | }
123 | return [top, left];
124 | }
125 |
126 | // serialize an array of pathItems to draw on a canvas
127 | function serializePaths(){
128 | var paths = extractSelectedPaths();
129 | var data = [];
130 |
131 | var MARGIN_TOP = 50;
132 | var MARGIN_LEFT = 25;
133 |
134 | var top_left = getTopLeftOfPaths(paths);
135 | var top = top_left[0] + MARGIN_TOP;
136 | var left = top_left[1] - MARGIN_LEFT;
137 |
138 | for(var i = paths.length - 1; i >= 0; i--){
139 | var r = ["@"]; // "@" is a mark that means the beginning of a path
140 | var p = paths[i];
141 |
142 | r.push(p.closed ? "1" : "0");
143 |
144 | r.push([p.filled ? "1" : "0",
145 | serializeColor(p.fillColor)]);
146 |
147 | r.push([p.stroked && p.strokeColor.typename != "NoColor" ? "1" : "0",
148 | _f2s(p.strokeWidth),
149 | serializeColor(p.strokeColor)]);
150 |
151 | for(var j = 0, jEnd = p.pathPoints.length; j < jEnd; j++){
152 | var ppt = p.pathPoints[j];
153 | var anc = ppt.anchor;
154 | r.push([_f2s(anc[0] - left), _f2s(anc[1] - top),
155 | _f2s(ppt.rightDirection[0] - anc[0]),
156 | _f2s(ppt.rightDirection[1] - anc[1]),
157 | _f2s(ppt.leftDirection[0] - anc[0]),
158 | _f2s(ppt.leftDirection[1] - anc[1])]);
159 | // ignore pointType becauses paper js doesn't have this property
160 | }
161 |
162 | data[data.length] = r;
163 | }
164 |
165 | // "data" is passed to callback function as a comma separated string
166 | return data;
167 | }
168 |
169 | function extractSelectedPaths(items, paths){
170 | if(!items) items = app.activeDocument.selection;
171 | if(!paths) paths = [];
172 | for(var i = 0, iEnd = items.length; i < iEnd; i++){
173 | if(items[i].typename == "PathItem"){
174 | paths.push(items[i]);
175 | } else if(items[i].typename == "GroupItem"){
176 | extractSelectedPaths(items[i].pageItems, paths);
177 | } else if(items[i].tyepname == "CompoundPathItem"){
178 | extractSelectedPaths(items[i].pathItems, paths);
179 | }
180 | }
181 | return paths;
182 | }
183 |
--------------------------------------------------------------------------------
/com.shspage.csxs.plaincanvas/js/libs/paperjs-v0.12.17/node/extend.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
3 | * http://paperjs.org/
4 | *
5 | * Copyright (c) 2011 - 2020, Jürg Lehni & Jonathan Puckey
6 | * http://juerglehni.com/ & https://puckey.studio/
7 | *
8 | * Distributed under the MIT license. See LICENSE file for details.
9 | *
10 | * All rights reserved.
11 | */
12 |
13 | var fs = require('fs'),
14 | path = require('path');
15 |
16 | module.exports = function(paper) {
17 | if (paper.PaperScript) {
18 | var sourceMapSupport = 'require("source-map-support").install(paper.PaperScript.sourceMapSupport);\n',
19 | sourceMaps = {};
20 |
21 | paper.PaperScript.sourceMapSupport = {
22 | retrieveSourceMap: function(source) {
23 | var map = sourceMaps[source];
24 | return map ? { url: source, map: map } : null;
25 | }
26 | };
27 |
28 | // Register the .pjs extension for automatic compilation as PaperScript
29 | require.extensions['.pjs'] = function(module, filename) {
30 | // Requiring a PaperScript on Node.js returns an initialize method which
31 | // needs to receive a Canvas object when called and returns the
32 | // PaperScope.
33 | module.exports = function(canvas) {
34 | var source = fs.readFileSync(filename, 'utf8'),
35 | code = sourceMapSupport + source,
36 | compiled = paper.PaperScript.compile(code, {
37 | url: filename,
38 | source: source,
39 | sourceMaps: true,
40 | offset: -1 // remove sourceMapSupport...
41 | }),
42 | scope = new paper.PaperScope();
43 | // Keep track of sourceMaps so retrieveSourceMap() can link them up
44 | scope.setup(canvas);
45 | scope.__filename = filename;
46 | scope.__dirname = path.dirname(filename);
47 | // Expose core methods and values
48 | scope.require = require;
49 | scope.console = console;
50 | sourceMaps[filename] = compiled.map;
51 | paper.PaperScript.execute(compiled, scope);
52 | return scope;
53 | };
54 | };
55 | }
56 |
57 | paper.PaperScope.inject({
58 | createCanvas: function(width, height, type) {
59 | // Do not use CanvasProvider.getCanvas(), since we may be changing
60 | // the underlying node-canvas when requesting PDF support, and don't
61 | // want to release it after back into the pool.
62 | var canvas = paper.document.createElement('canvas');
63 | canvas.width = width;
64 | canvas.height = height;
65 | canvas.type = type;
66 | return canvas;
67 | },
68 |
69 | /**
70 | * @deprecated, use use {@link #createCanvas(width, height)} instead.
71 | */
72 | Canvas: '#createCanvas'
73 | });
74 |
75 | // Override requestAnimationFrame() to avoid setInterval() timers.
76 | // NOTE: In Node.js, we only support manual updating for now, but
77 | // View#exportFrames() below offers a way to emulate animations by exporting
78 | // them frame by frame at the given frame-rate.
79 | paper.DomEvent.requestAnimationFrame = function(callback) {
80 | };
81 |
82 | // Node.js based image exporting code.
83 | paper.CanvasView.inject({
84 | // DOCS: CanvasView#exportFrames(options);
85 | exportFrames: function(options) {
86 | options = paper.Base.set({
87 | fps: 30,
88 | prefix: 'frame-',
89 | amount: 1,
90 | format: 'png' // Supported: 'png' or 'jpeg'
91 | }, options);
92 | if (!options.directory)
93 | throw new Error('Missing options.directory');
94 | if (options.format && !/^(jpeg|png)$/.test(options.format))
95 | throw new Error('Unsupported format. Use "png" or "jpeg"');
96 | var view = this,
97 | count = 0,
98 | frameDuration = 1 / options.fps,
99 | startTime = Date.now(),
100 | lastTime = startTime,
101 | padding = options.padding || ((options.amount - 1) + '').length,
102 | paddedStr = Array(padding + 1).join('0');
103 |
104 | // Start exporting frames by exporting the first frame:
105 | exportFrame(options);
106 |
107 | function exportFrame() {
108 | // Convert to a Base object, for #toString()
109 | view.emit('frame', new paper.Base({
110 | delta: frameDuration,
111 | time: frameDuration * count,
112 | count: count
113 | }));
114 | var file = path.join(options.directory,
115 | options.prefix + (paddedStr + count).slice(-padding)
116 | + '.' + options.format);
117 | var out = view.exportImage(file, function() {
118 | // Once the file has been closed, export the next fame:
119 | var then = Date.now();
120 | if (options.onProgress) {
121 | options.onProgress({
122 | count: count,
123 | amount: options.amount,
124 | percentage: Math.round((count + 1) / options.amount
125 | * 10000) / 100,
126 | time: then - startTime,
127 | delta: then - lastTime
128 | });
129 | }
130 | lastTime = then;
131 | if (++count < options.amount) {
132 | exportFrame();
133 | } else {
134 | // Call onComplete handler when finished:
135 | if (options.onComplete) {
136 | options.onComplete();
137 | }
138 | }
139 | });
140 | }
141 | },
142 |
143 | // DOCS: CanvasView#exportImage(path, callback);
144 | exportImage: function(path, callback) {
145 | this.update();
146 | var out = fs.createWriteStream(path),
147 | format = /\.jp(e?)g$/.test(path) ? 'jpeg' : 'png',
148 | stream = this._element[format + 'Stream']();
149 | stream.pipe(out);
150 | if (callback) {
151 | out.on('close', callback);
152 | }
153 | return out;
154 | }
155 | });
156 | };
157 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # plainCanvas
2 |
3 | Adobe Illustrator (CC 2014-) add-on with following functions.
4 | (Japanese README is [here](https://github.com/shspage/plainCanvas/blob/master/README_ja.md))
5 |
6 | * loads and executes a script file written for [paper.js](http://paperjs.org).
7 | (at the initial state, you can use a simple drawing tool.)
8 | * exports the image created on the panel onto the artboard.
9 | * imports selected paths on the artboard onto the panel.
10 |
11 | 
12 |
13 | ### Installation
14 | Because of the character of this add-on that loads external script files, it is released with an assumtion of doing debugs. Installation steps are as follows.
15 |
16 | 1. Setting the __debug mode flag__ refer to Adobe's document - [Debugging Unsigned Extensions](https://github.com/Adobe-CEP/CEP-Resources/blob/master/CEP_10.x/Documentation/CEP%2010.0%20HTML%20Extension%20Cookbook.md#debugging-unsigned-extensions).
17 | (It says "CSXS.10", but the number varies depending on the Illustrator's version. ex."CSXS.11" for Ai 2024(28.2))
18 | 2. Put the folder "com.shspage.csxs.plaincanvas" in the right folder refer to Adobe's document - [Extension Folders](https://github.com/Adobe-CEP/CEP-Resources/blob/master/CEP_10.x/Documentation/CEP%2010.0%20HTML%20Extension%20Cookbook.md#extension-folders).
19 | 3. Launch Illustrator and navigate Window -> Extensions fo find plainCanvas.
20 |
21 |
22 | ### buttons on the panel
23 | * __in__ : imports selected paths on the artboard onto the canvas
24 | * __out__ : exports the image created on the canvas onto the artboard
25 | * __run__ : executes a script that has an executable function
26 | * __opt__ : shows/hides the form for optional values
27 | * __<__ : undo
28 | * __>__ : redo
29 | * __CL__ : clears the canvas
30 | * __DB__ : opens the debug tool with a default browser.
31 | * __RL__ : reloads the extention panel
32 | * __load__ : opens a dialog to select a script file to lead
33 |
34 | ### loading a script file
35 | * Drag and drop a script file you want to load onto the panel.
36 | You can also use __load__ button to select a script file.
37 | * Drawing on the panel will be cleared after loading is complete.
38 |
39 | ### script files that can be loaded
40 | * There're some sample scripts in "[scripts](https://github.com/shspage/plainCanvas/tree/master/scripts)" folder.
41 | * Write in __JavaScript__ (not paperscript). For details, see "[Using JavaScript Directly](http://paperjs.org/tutorials/getting-started/using-javascript-directly/)" in http://paperjs.org.
42 | __ex:__ new Path() -> new paper.Path() // or use "with(paper){" statement
43 | __ex:__ point1 + point2 -> point1.add(point2)
44 | __ex:__ function onMouseDown(event) -> tool.onMouseDown = function(event)
45 | * Set the character encoding to __UTF-8__.
46 | * You can use the UIs for optional values with simple methods. see "js/optionManager.js".
47 | * You can set a drawn object as a target for undo/redo by calling the method like this.
48 | ```javascript
49 | undoManager.keep(object);
50 | ```
51 | Note that undoed objects are just hidden, and still exists in the current paper.project.
52 |
53 |
54 |
55 | ### colors
56 | * Since html5 canvas uses RGB color, imported CMYK and GRAY colors may look different from they look on the artboard.
57 | * If ALWAYS_EXPORT_RGB (js/main.js) is set false, the original CMYK colors are kept in memory
58 | and are applied when they are exported. (When DefaultColorSpace of the artboard
59 | is CMYK.)
60 | * If ALWAYS_EXPORT_RGB is true, GRAY colors are exported in RGB.
61 | * Gradient color and spot color are not supported for now.
62 |
63 | ### exports to an artboard
64 | * Following attributes of paper.Path instance on the canvas are exported.
65 | _segments, strokeWidth, strokeColor, fillColor, opacity_
66 |
67 | ### imports from an artboard
68 | * Following attributes of selected PathItems are imported.
69 | _pathPoints, strokeWidth, strokeColor, fillColor._
70 | * Grouped paths and compoundpaths are imported in released condition.
71 |
72 | ### Loading images
73 | * You can load images by dragging and dropping them onto the panel or by using the __load__ button. Supported image formats are jpeg and png.
74 | * You can hide the image by clicking [hide image] displayed at the top right of the panel after loading the image. Click again to display.
75 | * The loaded image is stored in __paper.project.activeLayer.data.raster__ and can be used in scripts.
76 | * The loaded image is discarded when loading a script file or clearing the screen using the CL/RL buttons.
77 |
78 |
79 | ### changelog
80 | #### v.1.2.2
81 | * Supports image loading.
82 | #### v.1.2.1
83 | * Added script loading error alert and run error alert.
84 | #### v.1.2.0
85 | * updated libraries
86 | #### v.1.1.8
87 | * Added "run" button. Added sample script for "run" button.
88 | * Fix: Even if you load a script file with the same name as one currently loaded, the changes will take effect.
89 | #### v.1.1.7
90 | * The "load" button is back.
91 | #### v.1.1.6
92 | * Set the upper limit of supported versions to 99.9 in manifest.xml.
93 | #### v.1.1.4
94 | * Set the upper limit of supported versions to 24.9 in manifest.xml.
95 | #### v.1.1.3
96 | * Fixed grayColor import/export issue.
97 | #### v.1.1.2
98 | * Removed the "load" button. A drop of a script file is always accepted.
99 | * Simplified optionManager methods. Updated the contents of the sample script accordingly.
100 | * Expanded the maximum panel size to 2000 x 2000 pixels.
101 | #### v.1.1.1
102 | * Improved to invalidate drop to panel except when loading.
103 | #### v.1.1.0
104 | * Improved to prevent the text on the panel from being selected by dragging.
105 | * The script file is loaded by drag-and-drop to the panel.
106 |
107 | ### TODO / known issues
108 | * TODO: Review the external script file reading method.
109 | * When exporting, there may be cases where the context of things captured from the artboard and those drawn on the canvas are incorrect.
110 | * TODO: use importSVG, exportSVG to exchange data with artboard ?
111 |
112 | ### License
113 | * When you distribute a modified version, make sure changing the __bundle ID__.
114 | It is represented as "com.shspage.csxs.plaincanvas" in CSXS/manifest.xml and .debug.
115 | * Copyright (c) 2015 Hiroyuki Sato. All rights reserved.
116 | http://shspage.com/
117 | This software is distributed under the MIT License.
118 | See the LICENSE.txt for details.
119 | This software uses the following libraries that may have
120 | licenses differing from that of the software itself. You can find the
121 | libraries and their respective licenses below.
122 |
123 | * Paper.js v0.12.17 - The Swiss Army Knife of Vector Graphics Scripting.
124 | http://paperjs.org/
125 | Copyright (c) 2011 - 2020, Jürg Lehni & Jonathan Puckey
126 | http://juerglehni.com/ & https://puckey.studio/
127 | All rights reserved.
128 |
129 | * Creative Cloud Extension Builder for Brackets
130 | https://github.com/davidderaedt/CC-Extension-Builder-for-Brackets
131 | Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved.
132 |
133 |
--------------------------------------------------------------------------------
/com.shspage.csxs.plaincanvas/js/main.js:
--------------------------------------------------------------------------------
1 | /*global $, window, location, CSInterface, SystemPath, themeManager, paper, optionManager, undoManager, runPaperScript*/
2 |
3 | (function () {
4 | 'use strict';
5 |
6 | // if true, show "debug" button and "reload" button
7 | var DEBUG_MODE = true;
8 |
9 | // Since html5 canvas uses RGB color, imported CMYK and GRAY colors
10 | // may look different from how they look on the artboard.
11 | // * If ALWAYS_EXPORT_RGB is false, the original CMYK colors are kept in memory
12 | // and are applied when they are exported. (When DefaultColorSpace of the artboard
13 | // is CMYK.)
14 | // * If ALWAYS_EXPORT_RGB is true, GRAY colors are exported in RGB.
15 | var ALWAYS_EXPORT_RGB = false;
16 |
17 | // port number defined in ".debug" file
18 | var DEBUG_TOOL_PORT_NUMBER = "8080";
19 |
20 | // encoding of a script file which is loaded
21 | var SCRIPT_ENCODING = "utf-8";
22 |
23 | // holds various values
24 | var _spec = {
25 | inputFileName : "",
26 | inputFileObj : null
27 | }
28 |
29 |
30 | var csInterface = new CSInterface();
31 |
32 | // Opens the chrome developer tools in host app
33 | function showDevTools() {
34 | if(confirm("open the debug tool?")){
35 | csInterface.openURLInDefaultBrowser("http://localhost:" + DEBUG_TOOL_PORT_NUMBER);
36 | }
37 | }
38 | // Reloads extension panel
39 | function reloadPanel() {
40 | if(confirm("reload the panel?")){
41 | location.reload();
42 | }
43 | }
44 |
45 |
46 | // ----------------------
47 | // functions for CMYK colors
48 | // ----------------------
49 | // Since paper.js can't handle CMYK colors, these functions
50 | // keep values of them in "_ids" object, associated with
51 | // id of paper.Item.
52 |
53 | // _ids
54 | // key: id of paper.Item
55 | // value: CMYK instance
56 | var _ids = {};
57 |
58 | var CMYK = function(){
59 | // each value is comma separated cmyk values. ex:"50.5,20,0,100"
60 | this.fill;
61 | this.stroke;
62 | }
63 | // ----
64 | var registCmykColor = function(id, cmykSpec, is_fill){
65 | if(!(id in _ids)) _ids[id] = new CMYK();
66 |
67 | if(is_fill){
68 | _ids[id].fill = cmykSpec; // ex:"50.5,20,0,100"
69 | } else {
70 | _ids[id].stroke = cmykSpec;
71 | }
72 | }
73 | // ----
74 | var getRegistedColor = function(id, is_fill){
75 | if(id in _ids){
76 | if(is_fill){
77 | if(_ids[id].fill) return "," + _ids[id].fill;
78 | } else {
79 | if(_ids[id].stroke) return "," + _ids[id].stroke;
80 | }
81 | }
82 | return "";
83 | }
84 |
85 | // ----------------------
86 | // functions to serialize/unserialize objects
87 | // ----------------------
88 | // shorten the length of a string form of a float value
89 | function f2s(f){
90 | var s = f.toFixed(4);
91 | if(s.indexOf(".") > 0){
92 | s = s.replace(/0+$/,"");
93 | return s.replace(/\.$/,"");
94 | }
95 | }
96 |
97 | // parseFloat
98 | function pf(s){ return parseFloat(s); }
99 |
100 | // get paths on canvas
101 | function getPathsOnCanvas(){
102 | var lay = paper.project.activeLayer;
103 | var paths = [];
104 | if(lay) getPathsOnCanvas_sub(paths, lay);
105 | return paths;
106 | }
107 |
108 | // sub function of getPathsOnCanvas
109 | function getPathsOnCanvas_sub(paths, gr){
110 | for(var i = gr.children.length - 1; i >= 0; i--){
111 | if(gr.children[i] instanceof paper.Path
112 | && gr.children[i].visible){ // items undoed by undoManager are invisible
113 | paths.push(gr.children[i]);
114 | } else if(gr.children[i] instanceof paper.Group){
115 | getPathsOnCanvas_sub(paths, gr.children[i]);
116 | }
117 | }
118 | }
119 |
120 | // corrects the range of the color
121 | function correctRange(v, maxval){
122 | return Math.max(0, Math.min(v, maxval));
123 | }
124 |
125 | // serialize a color of a paper object
126 | function serializePaperColor(col, c_id, is_fill){
127 | var s = "";
128 | var v;
129 | if(col.type == "gray"){
130 | v = correctRange(col.gray, 1);
131 | s = f2s(v * 255);
132 | s = ALWAYS_EXPORT_RGB
133 | ? s +","+ s +","+ s
134 | : f2s((1 - v) * 100);
135 | } else if(col.type == "rgb"){
136 | s = f2s(correctRange(col.red, 1) * 255) +","+
137 | f2s(correctRange(col.green, 1) * 255) +","+
138 | f2s(correctRange(col.blue, 1) * 255);
139 | if( ! ALWAYS_EXPORT_RGB) s += getRegistedColor(c_id, is_fill);
140 | } else{
141 | s = ALWAYS_EXPORT_RGB ? "0,0,0" : "0,0"; // black
142 | }
143 | return s;
144 | }
145 |
146 | // create a RGB type paper.Color instance from CMYK specification
147 | // it's inaccurate and just for displaying the color tentatively
148 | function cmyk2rgbColor(cmyk){ // cmyk: [c, m, y, k]
149 | var c = pf(cmyk[0]) / 100; var m = pf(cmyk[1]) / 100;
150 | var y = pf(cmyk[2]) / 100; var k = pf(cmyk[3]) / 100;
151 |
152 | var r = 1 - Math.min(1, c * (1 - k) + k);
153 | var g = 1 - Math.min(1, m * (1 - k) + k);
154 | var b = 1 - Math.min(1, y * (1 - k) + k);
155 | return new paper.Color(r, g, b);
156 | }
157 |
158 | // create a paper.Color instance from a serialized AI color
159 | function getPaperColorFromResult(p_id, color_type, c1, c2, c3, c4, is_fill) {
160 | var col;
161 | if(color_type == "N"){ // N,0,0,0,0,
162 | col = null;
163 | } else if(color_type == "G"){
164 | col = new paper.Color(1 - pf(c1));
165 | } else if(color_type == "RGB"){
166 | col = new paper.Color(pf(c1), pf(c2), pf(c3));
167 | } else if(color_type == "CMYK"){
168 | var colorSpec = [c1, c2, c3, c4];
169 | if( ! ALWAYS_EXPORT_RGB) registCmykColor(p_id, colorSpec.join(","), is_fill)
170 | col = cmyk2rgbColor(colorSpec);
171 | } else {
172 | col = new paper.Color(0);
173 | }
174 | return col;
175 | }
176 |
177 | // ----------------------
178 | // functions to load a script file
179 | // ----------------------
180 | function handleFileSelect(evt){
181 | evt.stopPropagation();
182 | evt.preventDefault();
183 | var files = evt.dataTransfer.files;
184 | if(files.length > 0){
185 | var fileobj = files[0];
186 | var type = fileobj.type;
187 |
188 | if(type != "application/x-javascript"
189 | && type != "application/javascript"
190 | && type != "text/javascript"
191 | && type != "image/png"
192 | && type != "image/jpeg"){
193 |
194 | if(type == ""){
195 | type = "(unknown type)";
196 | }
197 |
198 | alert("Please select a JavaScript file, or a png/jpeg Image.\n"
199 | + "Selected file is \"" + type + "\".");
200 | return false;
201 | }
202 |
203 | // confirm
204 | _spec.inputFileObj = fileobj;
205 | $("#span_dropzone_text").text("load " + fileobj.name + " ?")
206 | $("#div_dropzone").show();
207 | $("#div_screen").show();
208 | }
209 | }
210 | function handleDragOver(evt){
211 | evt.stopPropagation();
212 | evt.preventDefault();
213 | evt.dataTransfer.dropEffect = "copy";
214 | }
215 |
216 | // ----
217 | function removeRaster(){
218 | var image = document.getElementById("raster");
219 | if(image){
220 | image.remove();
221 | }
222 | if(paper.project.activeLayer.data.raster){
223 | paper.project.activeLayer.data.raster.remove();
224 | paper.project.activeLayer.data.raster = null;
225 | }
226 | $("#raster_indicator").text("");
227 | }
228 |
229 | function clearCanvas(){
230 | if(undoManager) undoManager.clearHistory();
231 | removeRaster();
232 | if(paper.project){
233 | var cs = paper.project.activeLayer.children;
234 | for(var i = cs.length - 1; i >= 0; i--){
235 | cs[i].remove();
236 | }
237 | }
238 | _ids = {};
239 | }
240 |
241 | // load a script file and insert its contents into the document
242 | function insertPaperScript(fileobj){
243 | _spec.inputFileName = fileobj.name;
244 |
245 | var fr = new FileReader();
246 | fr.onload = function(e){
247 | var data = e.target.result;
248 | try {
249 | Function(data);
250 | } catch(err){
251 | console.log(err);
252 | alert("Failed to load : " + err.name + "\n" + err.message);
253 | return;
254 | }
255 |
256 | clearCanvas();
257 | paper.remove();
258 |
259 | optionManager.resetOptions();
260 | runPaperScript = undefined;
261 |
262 | $("#script_paper").remove();
263 | var script = document.createElement("script");
264 | script.setAttribute("id","script_paper");
265 | script.type = "text/javascript";
266 | script.innerHTML = e.target.result;
267 | document.body.appendChild( script );
268 |
269 | $("#script_filename").text(_spec.inputFileName);
270 | }
271 | fr.readAsText(fileobj, SCRIPT_ENCODING);
272 | }
273 |
274 | // load an image
275 | function insertRaster(fileobj){
276 | var fr = new FileReader();
277 | fr.onload = function (e) {
278 | removeRaster();
279 | var image = document.createElement('img');
280 | image.setAttribute("id","raster");
281 | image.onload = function () {
282 | var raster = new paper.Raster(image);
283 | raster.sendToBack();
284 | raster.fitBounds(new paper.Rectangle(0,0,
285 | window.innerWidth, window.innerHeight));
286 | raster.visible = true;
287 | paper.project.activeLayer.data.raster = raster;
288 | $("#raster_indicator").text(" [hide image]");
289 | };
290 | image.src = e.target.result;
291 | document.body.appendChild( image );
292 | };
293 | fr.readAsDataURL(fileobj);
294 | }
295 | // ----------------------
296 | // initialize the extension
297 | // ----------------------
298 | function init() {
299 | themeManager.init();
300 |
301 | if(DEBUG_MODE){
302 | $("#btn_debug").show();
303 | $("#btn_reload").show();
304 | $("#btn_debug").click(showDevTools);
305 | $("#btn_reload").click(reloadPanel);
306 | }
307 |
308 | document.addEventListener('dragover', handleDragOver);
309 | document.addEventListener('drop', handleFileSelect);
310 |
311 | // in button
312 | // serialize paths selected in artboard
313 | // and convert it into paths as paper object
314 | $("#btn_in").click(function () {
315 | csInterface.evalScript('serializePaths()', function(result){
316 | if(paper.project == null) return;
317 | if(result == "") return;
318 |
319 | var r = result.split(",");
320 | var p;
321 | var i = 0;
322 | var rlen = r.length;
323 |
324 | while(i < rlen){
325 | if(r[i] == "@"){
326 | p = new paper.Path();
327 | p.closed = r[++i] == "1";
328 |
329 | // fill
330 | if(r[++i] == "1"){ // filled
331 | p.fillColor = getPaperColorFromResult(
332 | p.id, r[++i],r[++i],r[++i],r[++i],r[++i], true);
333 | i++;
334 | } else {
335 | i += 6;
336 | }
337 |
338 | // stroke
339 | if(r[i++] == "1"){ // stroked
340 | p.strokeWidth = pf(r[i]);
341 | p.strokeColor = getPaperColorFromResult(
342 | p.id, r[++i],r[++i],r[++i],r[++i],r[++i], false);
343 | i++;
344 | } else {
345 | p.strokeWidth = 0;
346 | p.strokeColor = null;
347 | i += 6;
348 | }
349 |
350 | } else {
351 | var anc = new paper.Point(pf(r[i++]), -pf(r[i++]));
352 | var handleOut = new paper.Point(pf(r[i++]), -pf(r[i++]));
353 | var handleIn = new paper.Point(pf(r[i++]), -pf(r[i++]));
354 | var seg = new paper.Segment(anc, handleIn, handleOut);
355 | p.add(seg);
356 | }
357 | }
358 | });
359 | });
360 |
361 | // out button
362 | // serialize paths on a canvas as a series of code
363 | // and eval it to draw the paths on an artboard
364 | $("#btn_out").click(function () {
365 | var paths = getPathsOnCanvas();
366 | var code = "(function(){";
367 |
368 | if(paths.length < 1){
369 | code += "alert('There is nothing to output');";
370 | } else {
371 | code += "if(isBadCondition()) return;";
372 | code += "var ";
373 |
374 | for(var i = paths.length - 1; i >= 0; i--){
375 | var c = paths[i];
376 | code += "m=new M();";
377 |
378 | if(c.closed) code += "m.C();";
379 |
380 | if(c.fillColor != null){
381 | code += "m.Fc(" + serializePaperColor(c.fillColor, c.id, true) + ");";
382 | }
383 |
384 | if(c.strokeColor != null && c.strokeWidth > 0){
385 | code += "m.W(" + f2s(c.strokeWidth) +");";
386 | code += "m.Sc(" + serializePaperColor(c.strokeColor, c.id, false) + ");";
387 | }
388 |
389 | if(c.opacity < 1){
390 | code += "m.Op(" + f2s(c.opacity * 100.0) + ");";
391 | }
392 | for(var j = 0, jEnd = c.segments.length; j < jEnd; j++){
393 | var seg = c.segments[j];
394 | code += "m.B(" + f2s(seg.point.x) + "," + f2s(-seg.point.y)
395 | + "," + f2s(seg.handleIn.x) + "," + f2s(-seg.handleIn.y)
396 | + "," + f2s(seg.handleOut.x) + "," + f2s(-seg.handleOut.y) + ");";
397 | }
398 | }
399 | }
400 | code += "})();";
401 |
402 | //console.log(code);
403 | csInterface.evalScript(code);
404 | });
405 |
406 | // run button
407 | $("#btn_run").click(function(){
408 | if(runPaperScript){
409 | try {
410 | runPaperScript();
411 | } catch(err){
412 | console.log(err);
413 | alert("ERROR : " + err.name + "\n" + err.message);
414 | }
415 | } else {
416 | alert("nothing to run");
417 | }
418 | });
419 |
420 | // option button
421 | // show or hide controls for optional values
422 | $("#btn_opt").click(function () {
423 | $("#div_options").toggle();
424 | $("#div_screen").toggle();
425 | });
426 |
427 | // undo ( < ) button
428 | // you need to call undoManager.keep( *item* ) previously
429 | // to regist an *item* as a target of undo/redo
430 | $("#btn_undo").click(function(e){
431 | if(undoManager) undoManager.undo();
432 | });
433 |
434 | // redo ( > ) button
435 | $("#btn_redo").click(function(e){
436 | if(undoManager) undoManager.redo();
437 | });
438 |
439 | // clear button
440 | $("#btn_clear").click(function(e){
441 | if(confirm("clear the canvas?")){
442 | clearCanvas();
443 | }
444 | });
445 |
446 | $("#btn_file_ok").click(function(e){
447 | if(_spec.inputFileObj != null){
448 | if(_spec.inputFileObj.type.startsWith("image")){
449 | insertRaster(_spec.inputFileObj);
450 | } else {
451 | insertPaperScript(_spec.inputFileObj);
452 | }
453 | $("#div_dropzone").hide();
454 | $("#div_screen").hide();
455 | _spec.inputFileObj = null;
456 | }
457 | });
458 | $("#btn_file_cancel").click(function(e){
459 | $("#div_dropzone").hide();
460 | $("#div_screen").hide();
461 | _spec.inputFileObj = null;
462 | });
463 |
464 | $("#fileSelect").change(function(e){
465 | var fileobj = e.target.files[0];
466 | var type = fileobj.type;
467 | if(type == "application/x-javascript"
468 | || type == "application/javascript"
469 | || type == "text/javascript"){
470 | insertPaperScript(fileobj);
471 | } else if(type == "image/png"
472 | || type == "image/jpeg"){
473 | insertRaster(fileobj);
474 | } else {
475 | alert("Select a JavaScript file or a png/jpeg Image.\n"
476 | + "Selected file is \"" + type + "\".");
477 | return false;
478 | }
479 | this.value = null;
480 | });
481 |
482 | $("#btn_file").click(function(e){
483 | $("#fileSelect").click();
484 | });
485 |
486 | // toggles visibility of loaded image
487 | $("#raster_indicator").click(function(e){
488 | var raster = paper.project.activeLayer.data.raster;
489 | if(raster){
490 | if(raster.visible){
491 | raster.visible = false;
492 | $("#raster_indicator").text(" [show image]");
493 | } else {
494 | raster.visible = true;
495 | $("#raster_indicator").text(" [hide image]");
496 | }
497 | }
498 | });
499 | }
500 |
501 | init();
502 |
503 | }());
504 |
505 |
--------------------------------------------------------------------------------
/com.shspage.csxs.plaincanvas/js/libs/CSInterface.js:
--------------------------------------------------------------------------------
1 | /**************************************************************************************************
2 | *
3 | * ADOBE SYSTEMS INCORPORATED
4 | * Copyright 2013 Adobe Systems Incorporated
5 | * All Rights Reserved.
6 | *
7 | * NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the
8 | * terms of the Adobe license agreement accompanying it. If you have received this file from a
9 | * source other than Adobe, then your use, modification, or distribution of it requires the prior
10 | * written permission of Adobe.
11 | *
12 | **************************************************************************************************/
13 |
14 | /** CSInterface - v5.2.0 */
15 |
16 | /**
17 | * Stores constants for the window types supported by the CSXS infrastructure.
18 | */
19 | function CSXSWindowType()
20 | {
21 | };
22 |
23 | /** Constant for the CSXS window type Panel. */
24 | CSXSWindowType._PANEL = "Panel";
25 |
26 | /** Constant for the CSXS window type Modeless. */
27 | CSXSWindowType._MODELESS = "Modeless";
28 |
29 | /** Constant for the CSXS window type ModalDialog. */
30 | CSXSWindowType._MODAL_DIALOG = "ModalDialog";
31 |
32 | /** EvalScript error message */
33 | EvalScript_ErrMessage = "EvalScript error.";
34 |
35 | /**
36 | * @class Version
37 | * Defines a version number with major, minor, micro, and special
38 | * components. The major, minor and micro values are numeric; the special
39 | * value can be any string.
40 | *
41 | * @param major The major version component, a positive integer up to nine digits long.
42 | * @param minor The minor version component, a positive integer up to nine digits long.
43 | * @param micro The micro version component, a positive integer up to nine digits long.
44 | * @param special The special version component, an arbitrary string.
45 | *
46 | * @return A new \c Version object.
47 | */
48 | function Version(major, minor, micro, special)
49 | {
50 | this.major = major;
51 | this.minor = minor;
52 | this.micro = micro;
53 | this.special = special;
54 | };
55 |
56 | /**
57 | * The maximum value allowed for a numeric version component.
58 | * This reflects the maximum value allowed in PlugPlug and the manifest schema.
59 | */
60 | Version.MAX_NUM = 999999999;
61 |
62 | /**
63 | * @class VersionBound
64 | * Defines a boundary for a version range, which associates a \c Version object
65 | * with a flag for whether it is an inclusive or exclusive boundary.
66 | *
67 | * @param version The \c #Version object.
68 | * @param inclusive True if this boundary is inclusive, false if it is exclusive.
69 | *
70 | * @return A new \c VersionBound object.
71 | */
72 | function VersionBound(version, inclusive)
73 | {
74 | this.version = version;
75 | this.inclusive = inclusive;
76 | };
77 |
78 | /**
79 | * @class VersionRange
80 | * Defines a range of versions using a lower boundary and optional upper boundary.
81 | *
82 | * @param lowerBound The \c #VersionBound object.
83 | * @param upperBound The \c #VersionBound object, or null for a range with no upper boundary.
84 | *
85 | * @return A new \c VersionRange object.
86 | */
87 | function VersionRange(lowerBound, upperBound)
88 | {
89 | this.lowerBound = lowerBound;
90 | this.upperBound = upperBound;
91 | };
92 |
93 | /**
94 | * @class Runtime
95 | * Represents a runtime related to the CEP infrastructure.
96 | * Extensions can declare dependencies on particular
97 | * CEP runtime versions in the extension manifest.
98 | *
99 | * @param name The runtime name.
100 | * @param version A \c #VersionRange object that defines a range of valid versions.
101 | *
102 | * @return A new \c Runtime object.
103 | */
104 | function Runtime(name, versionRange)
105 | {
106 | this.name = name;
107 | this.versionRange = versionRange;
108 | };
109 |
110 | /**
111 | * @class Extension
112 | * Encapsulates a CEP-based extension to an Adobe application.
113 | *
114 | * @param id The unique identifier of this extension.
115 | * @param name The localizable display name of this extension.
116 | * @param mainPath The path of the "index.html" file.
117 | * @param basePath The base path of this extension.
118 | * @param windowType The window type of the main window of this extension.
119 | Valid values are defined by \c #CSXSWindowType.
120 | * @param width The default width in pixels of the main window of this extension.
121 | * @param height The default height in pixels of the main window of this extension.
122 | * @param minWidth The minimum width in pixels of the main window of this extension.
123 | * @param minHeight The minimum height in pixels of the main window of this extension.
124 | * @param maxWidth The maximum width in pixels of the main window of this extension.
125 | * @param maxHeight The maximum height in pixels of the main window of this extension.
126 | * @param defaultExtensionDataXml The extension data contained in the default \c ExtensionDispatchInfo section of the extension manifest.
127 | * @param specialExtensionDataXml The extension data contained in the application-specific \c ExtensionDispatchInfo section of the extension manifest.
128 | * @param requiredRuntimeList An array of \c Runtime objects for runtimes required by this extension.
129 | * @param isAutoVisible True if this extension is visible on loading.
130 | * @param isPluginExtension True if this extension has been deployed in the Plugins folder of the host application.
131 | *
132 | * @return A new \c Extension object.
133 | */
134 | function Extension(id, name, mainPath, basePath, windowType, width, height, minWidth, minHeight, maxWidth, maxHeight,
135 | defaultExtensionDataXml, specialExtensionDataXml, requiredRuntimeList, isAutoVisible, isPluginExtension)
136 | {
137 | this.id = id;
138 | this.name = name;
139 | this.mainPath = mainPath;
140 | this.basePath = basePath;
141 | this.windowType = windowType;
142 | this.width = width;
143 | this.height = height;
144 | this.minWidth = minWidth;
145 | this.minHeight = minHeight;
146 | this.maxWidth = maxWidth;
147 | this.maxHeight = maxHeight;
148 | this.defaultExtensionDataXml = defaultExtensionDataXml;
149 | this.specialExtensionDataXml = specialExtensionDataXml;
150 | this.requiredRuntimeList = requiredRuntimeList;
151 | this.isAutoVisible = isAutoVisible;
152 | this.isPluginExtension = isPluginExtension;
153 | };
154 |
155 | /**
156 | * @class CSEvent
157 | * A standard JavaScript event, the base class for CEP events.
158 | *
159 | * @param type The name of the event type.
160 | * @param scope The scope of event, can be "GLOBAL" or "APPLICATION".
161 | * @param appId The unique identifier of the application that generated the event.
162 | * @param extensionId The unique identifier of the extension that generated the event.
163 | *
164 | * @return A new \c CSEvent object
165 | */
166 | function CSEvent(type, scope, appId, extensionId)
167 | {
168 | this.type = type;
169 | this.scope = scope;
170 | this.appId = appId;
171 | this.extensionId = extensionId;
172 | };
173 |
174 | /** Event-specific data. */
175 | CSEvent.prototype.data = "";
176 |
177 | /**
178 | * @class SystemPath
179 | * Stores operating-system-specific location constants for use in the
180 | * \c #CSInterface.getSystemPath() method.
181 | * @return A new \c SystemPath object.
182 | */
183 | function SystemPath()
184 | {
185 | };
186 |
187 | /** The path to user data. */
188 | SystemPath.USER_DATA = "userData";
189 |
190 | /** The path to common files for Adobe applications. */
191 | SystemPath.COMMON_FILES = "commonFiles";
192 |
193 | /** The path to the user's default document folder. */
194 | SystemPath.MY_DOCUMENTS = "myDocuments";
195 |
196 | /** @deprecated. Use \c #SystemPath.Extension. */
197 | SystemPath.APPLICATION = "application";
198 |
199 | /** The path to current extension. */
200 | SystemPath.EXTENSION = "extension";
201 |
202 | /** The path to hosting application's executable. */
203 | SystemPath.HOST_APPLICATION = "hostApplication";
204 |
205 | /**
206 | * @class ColorType
207 | * Stores color-type constants.
208 | */
209 | function ColorType()
210 | {
211 | };
212 |
213 | /** RGB color type. */
214 | ColorType.RGB = "rgb";
215 |
216 | /** Gradient color type. */
217 | ColorType.GRADIENT = "gradient";
218 |
219 | /** Null color type. */
220 | ColorType.NONE = "none";
221 |
222 | /**
223 | * @class RGBColor
224 | * Stores an RGB color with red, green, blue, and alpha values.
225 | * All values are in the range [0.0 to 255.0]. Invalid numeric values are
226 | * converted to numbers within this range.
227 | *
228 | * @param red The red value, in the range [0.0 to 255.0].
229 | * @param green The green value, in the range [0.0 to 255.0].
230 | * @param blue The blue value, in the range [0.0 to 255.0].
231 | * @param alpha The alpha (transparency) value, in the range [0.0 to 255.0].
232 | * The default, 255.0, means that the color is fully opaque.
233 | *
234 | * @return A new RGBColor object.
235 | */
236 | function RGBColor(red, green, blue, alpha)
237 | {
238 | this.red = red;
239 | this.green = green;
240 | this.blue = blue;
241 | this.alpha = alpha;
242 | };
243 |
244 | /**
245 | * @class Direction
246 | * A point value in which the y component is 0 and the x component
247 | * is positive or negative for a right or left direction,
248 | * or the x component is 0 and the y component is positive or negative for
249 | * an up or down direction.
250 | *
251 | * @param x The horizontal component of the point.
252 | * @param y The vertical component of the point.
253 | *
254 | * @return A new \c Direction object.
255 | */
256 | function Direction(x, y)
257 | {
258 | this.x = x;
259 | this.y = y;
260 | };
261 |
262 | /**
263 | * @class GradientStop
264 | * Stores gradient stop information.
265 | *
266 | * @param offset The offset of the gradient stop, in the range [0.0 to 1.0].
267 | * @param rgbColor The color of the gradient at this point, an \c #RGBColor object.
268 | *
269 | * @return GradientStop object.
270 | */
271 | function GradientStop(offset, rgbColor)
272 | {
273 | this.offset = offset;
274 | this.rgbColor = rgbColor;
275 | };
276 |
277 | /**
278 | * @class GradientColor
279 | * Stores gradient color information.
280 | *
281 | * @param type The gradient type, must be "linear".
282 | * @param direction A \c #Direction object for the direction of the gradient
283 | (up, down, right, or left).
284 | * @param numStops The number of stops in the gradient.
285 | * @param gradientStopList An array of \c #GradientStop objects.
286 | *
287 | * @return A new \c GradientColor object.
288 | */
289 | function GradientColor(type, direction, numStops, arrGradientStop)
290 | {
291 | this.type = type;
292 | this.direction = direction;
293 | this.numStops = numStops;
294 | this.arrGradientStop = arrGradientStop;
295 | };
296 |
297 | /**
298 | * @class UIColor
299 | * Stores color information, including the type, anti-alias level, and specific color
300 | * values in a color object of an appropriate type.
301 | *
302 | * @param type The color type, 1 for "rgb" and 2 for "gradient".
303 | The supplied color object must correspond to this type.
304 | * @param antialiasLevel The anti-alias level constant.
305 | * @param color A \c #RGBColor or \c #GradientColor object containing specific color information.
306 | *
307 | * @return A new \c UIColor object.
308 | */
309 | function UIColor(type, antialiasLevel, color)
310 | {
311 | this.type = type;
312 | this.antialiasLevel = antialiasLevel;
313 | this.color = color;
314 | };
315 |
316 | /**
317 | * @class AppSkinInfo
318 | * Stores window-skin properties, such as color and font. All color parameter values are \c #UIColor objects except that systemHighlightColor is \c #RGBColor object.
319 | *
320 | * @param baseFontFamily The base font family of the application.
321 | * @param baseFontSize The base font size of the application.
322 | * @param appBarBackgroundColor The application bar background color.
323 | * @param panelBackgroundColor The background color of the extension panel.
324 | * @param appBarBackgroundColorSRGB The application bar background color, as sRGB.
325 | * @param panelBackgroundColorSRGB The background color of the extension panel, as sRGB.
326 | * @param systemHighlightColor The operating-system highlight color, as sRGB.
327 | *
328 | * @return AppSkinInfo object.
329 | */
330 | function AppSkinInfo(baseFontFamily, baseFontSize, appBarBackgroundColor, panelBackgroundColor, appBarBackgroundColorSRGB, panelBackgroundColorSRGB, systemHighlightColor)
331 | {
332 | this.baseFontFamily = baseFontFamily;
333 | this.baseFontSize = baseFontSize;
334 | this.appBarBackgroundColor = appBarBackgroundColor;
335 | this.panelBackgroundColor = panelBackgroundColor;
336 | this.appBarBackgroundColorSRGB = appBarBackgroundColorSRGB;
337 | this.panelBackgroundColorSRGB = panelBackgroundColorSRGB;
338 | this.systemHighlightColor = systemHighlightColor;
339 | };
340 |
341 | /**
342 | * @class HostEnvironment
343 | * Stores information about the environment in which the extension is loaded.
344 | *
345 | * @param appName The application's name.
346 | * @param appVersion The application's version.
347 | * @param appLocale The application's current license locale.
348 | * @param appUILocale The application's current UI locale.
349 | * @param appId The application's unique identifier.
350 | * @param isAppOnline True if the application is currently online.
351 | * @param appSkinInfo An \c #AppSkinInfo object containing the application's default color and font styles.
352 | *
353 | * @return A new \c HostEnvironment object.
354 | */
355 | function HostEnvironment(appName, appVersion, appLocale, appUILocale, appId, isAppOnline, appSkinInfo)
356 | {
357 | this.appName = appName;
358 | this.appVersion = appVersion;
359 | this.appLocale = appLocale;
360 | this.appUILocale = appUILocale;
361 | this.appId = appId;
362 | this.isAppOnline = isAppOnline;
363 | this.appSkinInfo = appSkinInfo;
364 | };
365 |
366 | /**
367 | * @class HostCapabilities
368 | * Stores information about the host capabilities.
369 | *
370 | * @param EXTENDED_PANEL_MENU True if the application supports panel menu.
371 | * @param EXTENDED_PANEL_ICONS True if the application supports panel icon.
372 | * @param DELEGATE_APE_ENGINE True if the application supports delegated APE engine.
373 | * @param SUPPORT_HTML_EXTENSIONS True if the application supports HTML extensions.
374 | * @param DISABLE_FLASH_EXTENSIONS True if the application disables FLASH extensions.
375 | *
376 | * @return A new \c HostCapabilities object.
377 | */
378 | function HostCapabilities(EXTENDED_PANEL_MENU, EXTENDED_PANEL_ICONS, DELEGATE_APE_ENGINE, SUPPORT_HTML_EXTENSIONS, DISABLE_FLASH_EXTENSIONS)
379 | {
380 | this.EXTENDED_PANEL_MENU = EXTENDED_PANEL_MENU;
381 | this.EXTENDED_PANEL_ICONS = EXTENDED_PANEL_ICONS;
382 | this.DELEGATE_APE_ENGINE = DELEGATE_APE_ENGINE;
383 | this.SUPPORT_HTML_EXTENSIONS = SUPPORT_HTML_EXTENSIONS;
384 | this.DISABLE_FLASH_EXTENSIONS = DISABLE_FLASH_EXTENSIONS; // Since 5.0.0
385 | };
386 |
387 | /**
388 | * @class ApiVersion
389 | * Stores current api version.
390 | *
391 | * Since 4.2.0
392 | *
393 | * @param major The major version
394 | * @param minor The minor version.
395 | * @param micro The micro version.
396 | *
397 | * @return ApiVersion object.
398 | */
399 | function ApiVersion(major, minor, micro)
400 | {
401 | this.major = major;
402 | this.minor = minor;
403 | this.micro = micro;
404 | };
405 |
406 | /**
407 | * @class MenuItemStatus
408 | * Stores flyout menu item status
409 | *
410 | * Since 5.2.0
411 | *
412 | * @param menuItemLabel The menu item label.
413 | * @param enabled True if user wants to enable the menu item.
414 | * @param checked True if user wants to check the menu item.
415 | *
416 | * @return MenuItemStatus object.
417 | */
418 | function MenuItemStatus(menuItemLabel, enabled, checked)
419 | {
420 | this.menuItemLabel = menuItemLabel;
421 | this.enabled = enabled;
422 | this.checked = checked;
423 | };
424 |
425 | /**
426 | * @class ContextMenuItemStatus
427 | * Stores the status of the context menu item.
428 | *
429 | * Since 5.2.0
430 | *
431 | * @param menuItemID The menu item id.
432 | * @param enabled True if user wants to enable the menu item.
433 | * @param checked True if user wants to check the menu item.
434 | *
435 | * @return MenuItemStatus object.
436 | */
437 | function ContextMenuItemStatus(menuItemID, enabled, checked)
438 | {
439 | this.menuItemID = menuItemID;
440 | this.enabled = enabled;
441 | this.checked = checked;
442 | };
443 | //------------------------------ CSInterface ----------------------------------
444 |
445 | /**
446 | * @class CSInterface
447 | * This is the entry point to the CEP extensibility infrastructure.
448 | * Instantiate this object and use it to:
449 | *
450 | *
Access information about the host application in which an extension is running
451 | *
Launch an extension
452 | *
Register interest in event notifications, and dispatch events
453 | *
454 | *
455 | * @return A new \c CSInterface object
456 | */
457 | function CSInterface()
458 | {
459 | };
460 |
461 | /**
462 | * User can add this event listener to handle native application theme color changes.
463 | * Callback function gives extensions ability to fine-tune their theme color after the
464 | * global theme color has been changed.
465 | * The callback function should be like below:
466 | *
467 | * @example
468 | * // event is a CSEvent object, but user can ignore it.
469 | * function OnAppThemeColorChanged(event)
470 | * {
471 | * // Should get a latest HostEnvironment object from application.
472 | * var skinInfo = JSON.parse(window.__adobe_cep__.getHostEnvironment()).appSkinInfo;
473 | * // Gets the style information such as color info from the skinInfo,
474 | * // and redraw all UI controls of your extension according to the style info.
475 | * }
476 | */
477 | CSInterface.THEME_COLOR_CHANGED_EVENT = "com.adobe.csxs.events.ThemeColorChanged";
478 |
479 | /** The host environment data object. */
480 | CSInterface.prototype.hostEnvironment = JSON.parse(window.__adobe_cep__.getHostEnvironment());
481 |
482 | /** Retrieves information about the host environment in which the
483 | * extension is currently running.
484 | *
485 | * @return A \c #HostEnvironment object.
486 | */
487 | CSInterface.prototype.getHostEnvironment = function()
488 | {
489 | this.hostEnvironment = JSON.parse(window.__adobe_cep__.getHostEnvironment());
490 | return this.hostEnvironment;
491 | };
492 |
493 | /** Closes this extension. */
494 | CSInterface.prototype.closeExtension = function()
495 | {
496 | window.__adobe_cep__.closeExtension();
497 | };
498 |
499 | /**
500 | * Retrieves a path for which a constant is defined in the system.
501 | *
502 | * @param pathType The path-type constant defined in \c #SystemPath ,
503 | *
504 | * @return The platform-specific system path string.
505 | */
506 | CSInterface.prototype.getSystemPath = function(pathType)
507 | {
508 | var path = decodeURI(window.__adobe_cep__.getSystemPath(pathType));
509 | var OSVersion = this.getOSInformation();
510 | if (OSVersion.indexOf("Windows") >= 0)
511 | {
512 | path = path.replace("file:///", "");
513 | }
514 | else if (OSVersion.indexOf("Mac") >= 0)
515 | {
516 | path = path.replace("file://", "");
517 | }
518 | return path;
519 | };
520 |
521 | /**
522 | * Evaluates a JavaScript script, which can use the JavaScript DOM
523 | * of the host application.
524 | *
525 | * @param script The JavaScript script.
526 | * @param callback Optional. A callback function that receives the result of execution.
527 | * If execution fails, the callback function receives the error message \c EvalScript_ErrMessage.
528 | */
529 | CSInterface.prototype.evalScript = function(script, callback)
530 | {
531 | if(callback == null || callback == undefined)
532 | {
533 | callback = function(result){};
534 | }
535 | window.__adobe_cep__.evalScript(script, callback);
536 | };
537 |
538 | /**
539 | * Retrieves the unique identifier of the application.
540 | * in which the extension is currently running.
541 | *
542 | * @return The unique ID string.
543 | */
544 | CSInterface.prototype.getApplicationID = function()
545 | {
546 | var appId = this.hostEnvironment.appId;
547 | return appId;
548 | };
549 |
550 | /**
551 | * Retrieves host capability information for the application
552 | * in which the extension is currently running.
553 | *
554 | * @return A \c #HostCapabilities object.
555 | */
556 | CSInterface.prototype.getHostCapabilities = function()
557 | {
558 | var hostCapabilities = JSON.parse(window.__adobe_cep__.getHostCapabilities() );
559 | return hostCapabilities;
560 | };
561 |
562 | /**
563 | * Triggers a CEP event programmatically. Yoy can use it to dispatch
564 | * an event of a predefined type, or of a type you have defined.
565 | *
566 | * @param event A \c CSEvent object.
567 | */
568 | CSInterface.prototype.dispatchEvent = function(event)
569 | {
570 | if (typeof event.data == "object")
571 | {
572 | event.data = JSON.stringify(event.data);
573 | }
574 |
575 | window.__adobe_cep__.dispatchEvent(event);
576 | };
577 |
578 | /**
579 | * Registers an interest in a CEP event of a particular type, and
580 | * assigns an event handler.
581 | * The event infrastructure notifies your extension when events of this type occur,
582 | * passing the event object to the registered handler function.
583 | *
584 | * @param type The name of the event type of interest.
585 | * @param listener The JavaScript handler function or method.
586 | * @param obj Optional, the object containing the handler method, if any.
587 | * Default is null.
588 | */
589 | CSInterface.prototype.addEventListener = function(type, listener, obj)
590 | {
591 | window.__adobe_cep__.addEventListener(type, listener, obj);
592 | };
593 |
594 | /**
595 | * Removes a registered event listener.
596 | *
597 | * @param type The name of the event type of interest.
598 | * @param listener The JavaScript handler function or method that was registered.
599 | * @param obj Optional, the object containing the handler method, if any.
600 | * Default is null.
601 | */
602 | CSInterface.prototype.removeEventListener = function(type, listener, obj)
603 | {
604 | window.__adobe_cep__.removeEventListener(type, listener, obj);
605 | };
606 |
607 | /**
608 | * Loads and launches another extension, or activates the extension if it is already loaded.
609 | *
610 | * @param extensionId The extension's unique identifier.
611 | * @param startupParams Not currently used, pass "".
612 | *
613 | * @example
614 | * To launch the extension "help" with ID "HLP" from this extension, call:
615 | * requestOpenExtension("HLP", "");
616 | *
617 | */
618 | CSInterface.prototype.requestOpenExtension = function(extensionId, params)
619 | {
620 | window.__adobe_cep__.requestOpenExtension(extensionId, params);
621 | };
622 |
623 | /**
624 | * Retrieves the list of extensions currently loaded in the current host application.
625 | * The extension list is initialized once, and remains the same during the lifetime
626 | * of the CEP session.
627 | *
628 | * @param extensionIds Optional, an array of unique identifiers for extensions of interest.
629 | * If omitted, retrieves data for all extensions.
630 | *
631 | * @return Zero or more \c #Extension objects.
632 | */
633 | CSInterface.prototype.getExtensions = function(extensionIds)
634 | {
635 | var extensionIdsStr = JSON.stringify(extensionIds);
636 | var extensionsStr = window.__adobe_cep__.getExtensions(extensionIdsStr);
637 |
638 | var extensions = JSON.parse(extensionsStr);
639 | return extensions;
640 | };
641 |
642 | /**
643 | * Retrieves network-related preferences.
644 | *
645 | * @return A JavaScript object containing network preferences.
646 | */
647 | CSInterface.prototype.getNetworkPreferences = function()
648 | {
649 | var result = window.__adobe_cep__.getNetworkPreferences();
650 | var networkPre = JSON.parse(result);
651 |
652 | return networkPre;
653 | };
654 |
655 | /**
656 | * Initializes the resource bundle for this extension with property values
657 | * for the current application and locale.
658 | * To support multiple locales, you must define a property file for each locale,
659 | * containing keyed display-string values for that locale.
660 | * See localization documentation for Extension Builder and related products.
661 | *
662 | * Keys can be in the
663 | * form key.value="localized string", for use in HTML text elements.
664 | * For example, in this input element, the localized \c key.value string is displayed
665 | * instead of the empty \c value string:
666 | *
667 | *
668 | *
669 | * @return An object containing the resource bundle information.
670 | */
671 | CSInterface.prototype.initResourceBundle = function()
672 | {
673 | var resourceBundle = JSON.parse(window.__adobe_cep__.initResourceBundle());
674 | var resElms = document.querySelectorAll('[data-locale]');
675 | for (var n = 0; n < resElms.length; n++)
676 | {
677 | var resEl = resElms[n];
678 | // Get the resource key from the element.
679 | var resKey = resEl.getAttribute('data-locale');
680 | if (resKey)
681 | {
682 | // Get all the resources that start with the key.
683 | for (var key in resourceBundle)
684 | {
685 | if (key.indexOf(resKey) == 0)
686 | {
687 | var resValue = resourceBundle[key];
688 | if (key.length == resKey.length)
689 | {
690 | resEl.innerHTML = resValue;
691 | }
692 | else if ('.' == key.charAt(resKey.length))
693 | {
694 | var attrKey = key.substring(resKey.length + 1);
695 | resEl[attrKey] = resValue;
696 | }
697 | }
698 | }
699 | }
700 | }
701 | return resourceBundle;
702 | };
703 |
704 | /**
705 | * Writes installation information to a file.
706 | *
707 | * @return The file path.
708 | */
709 | CSInterface.prototype.dumpInstallationInfo = function()
710 | {
711 | return window.__adobe_cep__.dumpInstallationInfo();
712 | };
713 |
714 | /**
715 | * Retrieves version information for the current Operating System,
716 | * See http://www.useragentstring.com/pages/Chrome/ for Chrome \c navigator.userAgent values.
717 | *
718 | * @return A string containing the OS version, or "unknown Operation System".
719 | * If user customizes the User Agent by setting CEF command parameter "--user-agent", only
720 | * "Mac OS X" or "Windows" will be returned.
721 | */
722 | CSInterface.prototype.getOSInformation = function()
723 | {
724 | var userAgent = navigator.userAgent;
725 |
726 | if ((navigator.platform == "Win32") || (navigator.platform == "Windows"))
727 | {
728 | var winVersion = "Windows";
729 | var winBit = "";
730 | if (userAgent.indexOf("Windows") > -1)
731 | {
732 | if (userAgent.indexOf("Windows NT 5.0") > -1)
733 | {
734 | winVersion = "Windows 2000 ";
735 | }
736 | else if (userAgent.indexOf("Windows NT 5.1") > -1)
737 | {
738 | winVersion = "Windows XP ";
739 | }
740 | else if (userAgent.indexOf("Windows NT 5.2") > -1)
741 | {
742 | winVersion = "Windows Server 2003 ";
743 | }
744 | else if (userAgent.indexOf("Windows NT 6.0") > -1)
745 | {
746 | winVersion = "Windows Vista ";
747 | }
748 | else if (userAgent.indexOf("Windows NT 6.1") > -1)
749 | {
750 | winVersion = "Windows 7 ";
751 | }
752 | else if (userAgent.indexOf("Windows NT 6.2") > -1)
753 | {
754 | winVersion = "Windows 8 ";
755 | }
756 |
757 | if (userAgent.indexOf("WOW64") > -1)
758 | {
759 | winBit = "64-bit";
760 | }
761 | else
762 | {
763 | winBit = "32-bit";
764 | }
765 | }
766 |
767 | return winVersion + winBit;
768 | }
769 | else if ((navigator.platform == "MacIntel") || (navigator.platform == "Macintosh"))
770 | {
771 | var result = "Mac OS X";
772 | var agentStr = new String();
773 | agentStr = userAgent;
774 | if (agentStr.indexOf("Mac OS X") > -1)
775 | {
776 | var verLength = agentStr.indexOf(")") - agentStr.indexOf("Mac OS X");
777 | var verStr = agentStr.substr(agentStr.indexOf("Mac OS X"), verLength);
778 | result = verStr.replace("_", ".");
779 | result = result.replace("_", ".");
780 | }
781 |
782 | return result;
783 | }
784 |
785 | return "Unknown Operation System";
786 | };
787 |
788 | /**
789 | * Opens a page in the default system browser.
790 | *
791 | * Since 4.2.0
792 | *
793 | * @param url The URL of the page/file to open, or the email address.
794 | * Must use HTTP/HTTPS/file/mailto protocol. For example:
795 | * "http://www.adobe.com"
796 | * "https://github.com"
797 | * "file:///C:/log.txt"
798 | * "mailto:test@adobe.com"
799 | *
800 | * @return One of these error codes:\n
801 | *
\n
802 | *
NO_ERROR - 0
\n
803 | *
ERR_UNKNOWN - 1
\n
804 | *
ERR_INVALID_PARAMS - 2
\n
805 | *
ERR_INVALID_URL - 201
\n
806 | *
\n
807 | */
808 | CSInterface.prototype.openURLInDefaultBrowser = function(url)
809 | {
810 | return cep.util.openURLInDefaultBrowser(url);
811 | };
812 |
813 | /**
814 | * Retrieves extension ID.
815 | *
816 | * Since 4.2.0
817 | *
818 | * @return extension ID.
819 | */
820 | CSInterface.prototype.getExtensionID = function()
821 | {
822 | return window.__adobe_cep__.getExtensionId();
823 | };
824 |
825 | /**
826 | * Retrieves the scale factor of screen.
827 | * On Windows platform, the value of scale factor might be different from operating system's scale factor,
828 | * since host application may use its self-defined scale factor.
829 | *
830 | * Since 4.2.0
831 | *
832 | * @return One of the following integer.
833 | *
\n
834 | *
-1 means fail to get scale factor or this API has not been available on Windows yet
\n
835 | *
1 means normal screen
\n
836 | *
2 means HiDPI screen
\n
837 | *
\n
838 | */
839 | CSInterface.prototype.getScaleFactor = function()
840 | {
841 | return window.__adobe_cep__.getScaleFactor();
842 | };
843 |
844 | /**
845 | * Set a handler to detect any changes of scale factor. This only works on Mac.
846 | *
847 | * Since 4.2.0
848 | *
849 | * @param handler The function to be called when scale factor is changed.
850 | *
851 | */
852 | CSInterface.prototype.setScaleFactorChangedHandler = function(handler)
853 | {
854 | window.__adobe_cep__.setScaleFactorChangedHandler(handler);
855 | };
856 |
857 | /**
858 | * Retrieves current API version.
859 | *
860 | * Since 4.2.0
861 | *
862 | * @return ApiVersion object.
863 | *
864 | */
865 | CSInterface.prototype.getCurrentApiVersion = function()
866 | {
867 | var apiVersion = JSON.parse(window.__adobe_cep__.getCurrentApiVersion());
868 | return apiVersion;
869 | };
870 |
871 | /**
872 | * Set panel flyout menu by an XML.
873 | *
874 | * Since 5.2.0
875 | *
876 | * If user wants to be noticed when clicking an menu item, user needs to register "com.adobe.csxs.events.flyoutMenuClicked" Event by calling AddEventListener.
877 | * When an menu item is clicked, the event callback function will be called.
878 | * The "data" attribute of event is an object which contains "menuId" and "menuName" attributes.
879 | *
880 | * @param menu A XML string which describes menu structure.
881 | * An example menu XML:
882 | *
893 | *
894 | */
895 | CSInterface.prototype.setPanelFlyoutMenu = function(menu)
896 | {
897 | if ("string" != typeof menu)
898 | {
899 | return;
900 | }
901 |
902 | window.__adobe_cep__.invokeSync("setPanelFlyoutMenu", menu);
903 | };
904 |
905 | /**
906 | * Updates a menu item in the extension window's flyout menu, by setting the enabled
907 | * and selection status.
908 | *
909 | * Since 5.2.0
910 | *
911 | * @param menuItemLabel The menu item label.
912 | * @param enabled True to enable the item, false to disable it (gray it out).
913 | * @param checked True to select the item, false to deselect it.
914 | *
915 | * @return false when the host application does not support this functionality (HostCapabilities.EXTENDED_PANEL_MENU is false).
916 | * Fails silently if menu label is invalid.
917 | *
918 | * @see HostCapabilities.EXTENDED_PANEL_MENU
919 | */
920 | CSInterface.prototype.updatePanelMenuItem = function(menuItemLabel, enabled, checked)
921 | {
922 | var ret = false;
923 | if (this.getHostCapabilities().EXTENDED_PANEL_MENU)
924 | {
925 | var itemStatus = new MenuItemStatus(menuItemLabel, enabled, checked);
926 | ret = window.__adobe_cep__.invokeSync("updatePanelMenuItem", JSON.stringify(itemStatus));
927 | }
928 | return ret;
929 | };
930 |
931 |
932 | /**
933 | * Set context menu by XML string.
934 | *
935 | * Since 5.2.0
936 | *
937 | * There are a number of conventions used to communicate what type of menu item to create and how it should be handled.
938 | * - an item without menu ID or menu name is disabled and is not shown.
939 | * - if the item name is "---" (three hyphens) then it is treated as a separator. The menu ID in this case will always be NULL.
940 | * - Checkable attribute takes precedence over Checked attribute.
941 | *
942 | * @param menu A XML string which describes menu structure.
943 | * @param callback The callback function which is called when a menu item is clicked. The only parameter is the returned ID of clicked menu item.
944 | *
945 | * An example menu XML:
946 | *
957 | */
958 | CSInterface.prototype.setContextMenu = function(menu, callback)
959 | {
960 | if ("string" != typeof menu)
961 | {
962 | return;
963 | }
964 |
965 | window.__adobe_cep__.invokeAsync("setContextMenu", menu, callback);
966 | };
967 |
968 | /**
969 | * Updates a context menu item by setting the enabled and selection status.
970 | *
971 | * Since 5.2.0
972 | *
973 | * @param menuItemID The menu item ID.
974 | * @param enabled True to enable the item, false to disable it (gray it out).
975 | * @param checked True to select the item, false to deselect it.
976 | */
977 | CSInterface.prototype.updateContextMenuItem = function(menuItemID, enabled, checked)
978 | {
979 | var itemStatus = new ContextMenuItemStatus(menuItemID, enabled, checked);
980 | ret = window.__adobe_cep__.invokeSync("updateContextMenuItem", JSON.stringify(itemStatus));
981 | };
--------------------------------------------------------------------------------
/com.shspage.csxs.plaincanvas/js/libs/jquery-3.7.1.slim.min.js:
--------------------------------------------------------------------------------
1 | /*! jQuery v3.7.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-deprecated/ajax-event-alias,-effects,-effects/animatedSelector,-effects/Tween | (c) OpenJS Foundation and other contributors | jquery.org/license */
2 | !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},m=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||m).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-deprecated/ajax-event-alias,-effects,-effects/animatedSelector,-effects/Tween",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+ge+")"+ge+"*"),b=new RegExp(ge+"|>"),A=new RegExp(g),D=new RegExp("^"+t+"$"),N={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+d),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},L=/^(?:input|select|textarea|button)$/i,j=/^h\d$/i,O=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,P=/[+~]/,H=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),q=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},R=function(){V()},M=K(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{E.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){E={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,d=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==d&&9!==d&&11!==d)return n;if(!r&&(V(e),e=e||C,T)){if(11!==d&&(u=O.exec(t)))if(i=u[1]){if(9===d){if(!(a=e.getElementById(i)))return n;if(a.id===i)return E.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return E.call(n,a),n}else{if(u[2])return E.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return E.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||p&&p.test(t))){if(c=t,f=e,1===d&&(b.test(t)||m.test(t))){(f=P.test(t)&&X(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=k)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+G(l[o]);c=l.join(",")}try{return E.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>x.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function B(e){return e[k]=!0,e}function F(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function $(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&M(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function U(a){return B(function(o){return o=+o,B(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function X(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=C&&9===n.nodeType&&n.documentElement&&(r=(C=n).documentElement,T=!ce.isXMLDoc(C),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=C&&(t=C.defaultView)&&t.top!==t&&t.addEventListener("unload",R),le.getById=F(function(e){return r.appendChild(e).id=ce.expando,!C.getElementsByName||!C.getElementsByName(ce.expando).length}),le.disconnectedMatch=F(function(e){return i.call(e,"*")}),le.scope=F(function(){return C.querySelectorAll(":scope")}),le.cssHas=F(function(){try{return C.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(x.filter.ID=function(e){var t=e.replace(H,q);return function(e){return e.getAttribute("id")===t}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&T){var n=t.getElementById(e);return n?[n]:[]}}):(x.filter.ID=function(e){var n=e.replace(H,q);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&T){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),x.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},x.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&T)return t.getElementsByClassName(e)},p=[],F(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||p.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+k+"-]").length||p.push("~="),e.querySelectorAll("a#"+k+"+*").length||p.push(".#.+[+~]"),e.querySelectorAll(":checked").length||p.push(":checked"),(t=C.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&p.push(":enabled",":disabled"),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||p.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||p.push(":has"),p=p.length&&new RegExp(p.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===C||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),C}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),T&&!h[t+" "]&&(!p||!p.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(H,q),e[3]=(e[3]||e[4]||e[5]||"").replace(H,q),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return N.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&A.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(H,q).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||E,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:k.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:m,!0)),C.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=m.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,E=ce(m);var S=/^(?:parents|prev(?:Until|All))/,A={children:!0,contents:!0,next:!0,prev:!0};function D(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;re=m.createDocumentFragment().appendChild(m.createElement("div")),(be=m.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),re.appendChild(be),le.checkClone=re.cloneNode(!0).cloneNode(!0).lastChild.checked,re.innerHTML="",le.noCloneChecked=!!re.cloneNode(!0).lastChild.defaultValue,re.innerHTML="",le.option=!!re.lastChild;var Te={thead:[1,"