# Fake API


# Install

Go to the location you want the repo to be created
Windows cd C:\Repositories\vip\ Or whatever location you choose.
Mac /Repositories/vip/ Or whatever location you choose.

Clone the Repo into desired location.
git clone https://github.com/variable-importer-pro/jsPlug.git This should create the git repo C:\Repositories\vip\jsplug (ap per chosen location)
Make a symlink of the extension in the Adobes Extensions folder.
By using the symlink one can update the extension by either using the update button on the extension or using git pull.
Illustrator should not need restarting (usually) but you will need to click the ↻ restart button on the extension.

🤚 To Make a symbolic link into the admin extensions folder you need to have admin rights in CMD / Terminal.
Windows CMD mklink /D "C:\Program Files\Common Files\Adobe\CEP\extensions\com.creative-scripts.var.fake" "C:\Repositories\vip\jsplug\com.creative-scripts.var.fake"
Windows Powershell cmd /c mklink /D "C:\Program Files\Common Files\Adobe\CEP\extensions\com.creative-scripts.var.fake" "C:\Repositories\vip\jsplug\com.creative-scripts.var.fake"
Mac sudo ln -s "/Repositories/vip/com.creative-scripts.var.fake" "/Library/Application Support/Adobe/CEP/extensions/com.creative-scripts.var.fake"
Restart Illustrator

# Update

If you were good boys and followed the Install instructions above you can either press the extensions update button or do a git pull. Then click on the extensions ↻ restart button.

# Into

This "API" is written as a demonstration of:

  1. The messages we what to send to the real plugin.
  2. The action to be done.
  3. The message we want back from the real plugin.

Note

The demo is not demonstrating how we want things to be coded.
It ignores the URL encode and decode issue.
The parameters in the Fake API can be passes as either a JSON object or a JSON string. The real will only work with JSON strings All methods has equivalent methods for both JS and JSX engines

# setTags

For setting a collection with tags.
For now it works only on selected items but the plan is to implement for a collection.

Note

All tags are set and get by setting / getting the items _v_tag_ The item tags are all URI encoded in the value of this tag. It is for Tom to URI encode and decode all the tags, the plugin (Ten) will not be expected to encode or decode the tags

// jsx engine
/*
 * @param {object} parameters
 * @param {[string]} parameters.tags The URI encoded tags
 * @param {[DOM]} [parameters.collection=app.selection] The collection from where to get the items, the collection can only be set by the C++ side, if there's a need we could set it from the js side using an array of uuid
 * @param {boolean} [parameters.replace=false] If to remove existing tags
 * @param {string} [parameters.uid] The uid of the command
 * @returns {object} {error, [uid], result}
 */
fake.sendScriptMessage('VIProUtils', 'setTags', '{tags: ["foo", "bar", "baz"], uid: 123}');
// Result
// => {error:null, uid:123, result:"Tags Set [foo,bar,baz]"}
// TO set the tag to こんにちは one needs to URI encode
fake.sendScriptMessage('VIProUtils', 'setTags', '{tags: ["%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF"], uid: 123}');

// js engine
fake.scriptEvent('com.vip.event.setTags', '{tags: ["foo", "bar", "baz"], uid: 123}')
// Result
// type: com.vip.event.setTags.result
// data: {"error":null,"uid":123,"result":"Tags Set [foo,bar,baz]"}

# replaceTags

/**
 *
 *
 * @param {object} parameters
 * @param {[string]} parameters.tags The URI encoded tags
 * @param {[DOM]} [parameters.collection=app.selection] The collection from where to get the items
 * @param {string} [parameters.uid] The uid of the command
 * @returns {object} {error, [uid], result}
 */
// The selections tags will be replaced with the new specified tags
fake.sendScriptMessage('VIProUtils', 'replaceTags', '{tags: ["newFoo", "newBar"], uid: 123}');
fake.scriptEvent('com.vip.event.replaceTags', '{tags: ["newFoo", "newBar"], uid: 123}');



Calls setTags setting replace to true so that the objects existing tags are replaced.


# getTags

For getting the tags of a collection, default collection is app.selection.

// jsx engine
/*
 * @param {object} parameters
 * @param {[string]} parameters.collection An array of pageItems, Default app.selection
 * @param {string} [parameters.uid] The uid of the command
 * @param {boolean} [parameters.mixed  = false] if the items have mixed tags the only returns "mixed" flag Default false
 * @returns {object} {error, [uid], tags, mixed}
 */
fake.sendScriptMessage('VIProUtils', 'getTags', '{uid: 123}');
// Result
// => {mixed:true, tags:["green", "baz", "bar", "red", "%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF"], error:null, uid:123}
fake.sendScriptMessage('VIProUtils', 'getTags', '{uid: 123, mixed: true}');
// Result
// => {mixed:true, tags:[], error:null, uid:123} // The tags are not return because the mixed parameter was set to true and the collection had mix tags.
fake.sendScriptMessage('VIProUtils', 'getTags', '{uid: 123, mixed: true}');
// {mixed:false, tags:["green"], error:null, uid:123} // The tags are return even though the mixed parameter was set to true because the collection all contained the same tags
// js engine
fake.scriptEvent('com.vip.event.getTags', '{uid: 123}')
// Result
// Multiple objects selected with mixed tags
// type: com.vip.event.getTags.result
// data: {"mixed":true,"tags":["green","baz","bar","red","foo"],"error":null,"uid":123}

# getByTags

For getting a collection with tags.

// jsx engine
/*
 * @param {object} parameters
 * @param {[string]} parameters.tags The tags
 * @param {[DOM]} [parameters.collection Default all page items] The collection from where to get the items 
 * @param {string} [parameters.uid] The uid of the command
 * @param {boolean} [parameters.all  = false] The if only to get items with all containing all the tags Default false
 * @returns {object} {error, [uid], result, collection, uuid}
 */
fake.sendScriptMessage('VIProUtils', 'getByTags', '{tags:["round", "red"], uid: 1234}');
// Result
// => {error:null, uid:1234, result:"collection", collection:[{}, {}, {}, {}, {}], uuid:["626", "626", "600", "571", "538"]}
// uid is the uid that was sent using sendScriptMessage
// uuid is a collection of the uuid of the each page items containing the tags
// by default the items containing any of the tags will be included

fake.sendScriptMessage('VIProUtils', 'getByTags', '{tags:["round", "red"], uid: 1234, all: true}');
// Result
// The "all" parameter was set to true so only items containing all the tags are returned
// => {error:null, uid:1234, result:"collection", collection:[{}], uuid:["626"]}

// js engine
fake.scriptEvent('com.vip.event.getByTags', '{tags:["round", "red"], uid: 1234}');
// Result
// type: com.vip.event.getByTags.result
// data: {"error":null,"uid":1234,"result":"collection","collection":[],"uuid":["626","626","600","571","538"]}
// NOTE: "collection":[] and not [{}, {}, {}, {}, {}] as we can't pass the DOM items to the CEP engine

# selectByTags

For selecting a items containing tags.
By default the selection will be set to all items containing any of the given tags. By setting the "all" parameter to true, only items tagged with all the given tags will be selected. By setting the "add" parameter to true, items tagged will be added to the current selection and not replace the current selection.

// jsx engine
/*
 * @param {object} parameters
 * @param {[string]} parameters.tags The tags
 * @param {[DOM]} [parameters.collection Default all page items] The collection from where to get the items 
 * @param {string} [parameters.uid] The uid of the command
 * @param {boolean} [parameters.all  = false] The if only to get items with all containing all the tags Default false
 * @param {boolean} [parameters.add  = false] Adds to current selection
 * @returns {object} {error, uid, result}
 */
fake.sendScriptMessage('VIProUtils', 'selectByTags', '{tags:["round", "red"], collection: app.documents[0].layers[0].pageItems, uid: 1234}');
// Result
// => {error:null, uid:1234, result:"Selected tagged round,red"}
// by default items containing any of the tags will be included

fake.sendScriptMessage('VIProUtils', 'selectByTags', '{tags:["round", "red"], uid: 1234, all: true}');
// Result
// The "all" parameter was set to true so only items containing all the tags are returned
// => {error:null, uid:1234, result:"Selected tagged round,red"}
fake.sendScriptMessage('VIProUtils', 'selectByTags', '{tags:["round", "red"], uid: 1234, all: true, add: true}');
// Result
// The "add" parameter was set to true the tagged items are added to the selection and do not replace the selection.
// => {error:null, uid:1234, result:"Selected tagged round,red"}

// js engine
fake.scriptEvent('com.vip.event.selectByTags', '{tags:["round", "red"], uid: 1234}');
// Result
// type: com.vip.event.selectByTags.result
// data: {"error":null,"uid":1234,"result":"Selected tagged round,red"}

# removeTags & removeTagsSelected

For removing our namespace tags from all or only selected items. One can choose an array or tags to remove or to remove all of them.

// jsx engine
/*
 * @param {object} parameters
 * @param {[string]} parameters.tags The tags to remove
 * @param {boolean} [parameters.all = false] If to remove all tags
 * @param {string} [parameters.uid] The uid of the command
 * @returns {object} {error, [uid], result}
 */
fake.sendScriptMessage('VIProUtils', 'removeTagsSelected', '{tags:["round", "red"], uid: 1234}');
// Result
// => {error:null, uid:1234, result:"Tags removed [round, red]"}
// uid is the uid that was sent using sendScriptMessage
// Only the listed tags are removed and only from the selected items.

fake.sendScriptMessage('VIProUtils', 'removeTagsSelected', '{all: true, uid: 1234}');
// Result
// => {error:null, uid:234, result:"All tags removed"}
// uid is the uid that was sent using sendScriptMessage
// All of our namespace tags are removed from the selected items.

fake.sendScriptMessage('VIProUtils', 'removeTags', '{tags:["round", "red"], uid: 1234}');
// Result
// => {error:null, uid:1234, result:"Tags removed [round, red]"}
// uid is the uid that was sent using sendScriptMessage
// The listed tags are removed from all items.

fake.sendScriptMessage('VIProUtils', 'removeTags', '{all: true, uid: 1234}');
// Result
// => {error:null, uid:1234, result:"All tags removed"}
// uid is the uid that was sent using sendScriptMessage
// All of our namespace tags are removed from all items.

// js engine
fake.scriptEvent('com.vip.event.removeTagsSelected', '{tags:["round", "red"], uid: 1234}');
// Result
// type: com.vip.event.removeTagsSelected.result
// data: {error:null, uid:1234, result:"Tags removed [round, red]"}

fake.scriptEvent('com.vip.event.removeTags', '{all: true, uid: 1234}');
// Result
// type: com.vip.event.removeTagsSelected.result
// data: {error:null, uid:1234, result:"All tags removed"}

# makeSwatch

For creating and changing swatches

// jsx engine
/*
 * @param {string} [params.name] Name will replace the name of existing swatch, Should no swatch be specified, name will be used as the swatch name.
 * @param {(string | number | {})} params.swatch For creating new swatches a string of the swatch name. To replace existing swatch can also be the index or DOM reference
 * @param {number [] | {} | boolean} params.rgb if boolean true then when possible use the swatches current values otherwise replace current values with [r, g, b] or {r, g, b} values
 * @param {number [] | {} | boolean} params.cmyk if boolean true then when possible use the swatches current values otherwise replace current values with [c, m, y, k] or {c, m, y, k} values
 * @param {number [] | {} | boolean} params.lab if boolean true then when possible use the swatches current values otherwise replace current values with [l, a, b] or {l, a, b} values. Lab is always spot spot.
 * @param {number [] | {} | boolean} params.gray if boolean true then when possible use the swatches current values otherwise replace current values with [gray] or {gray} values. Gray is always process.
 * @param {object} [params.doc] The document of the swatch.
 * @param {'global' | 'spot' | 'process'} params.model defines spot / process kind, overrides params.spot and params.process settings.
 * @param {boolean} params.spot if spot false then process will will be considered false and the swatch will be process. If true then will be spot, if process true then a global process spot else a spot spot.
 * @param {boolean} params.process Swatch will be set to process, if spot is also true then a global (spot) process otherwise a non spot process
 * @param {'process' | 'global' | 'spot'} params.type Can be used instead of setting spot and process parameters. 'process' === spot: false, process: true,'global' === spot: true, process: true, 'spot' === spot: true, process: false
 * @returns swatch
*/
fake.sendScriptMessage('VIProUtils', 'makeSwatch', '{name: "Green RGB", type: "rgb", model: "global", colors: {green: 255}, uid: 1234}');
fake.sendScriptMessage('VIProUtils', 'makeSwatch', '{name: "Red LAB", type: "lab", model: "spot", colors: {l: 100, a: 127, b: 127}, uid: 1234}');
// Note lab will always be a spot color regardless of the model setting
fake.sendScriptMessage('VIProUtils', 'makeSwatch', '{swatch: "Green RGB", name: "Green LAB", type: "lab", uid: 1234}');
// Will convert the existing "Green RGB" for a rgb global to a lab spot. The swatch will be renamed to "Green LAB"
fake.sendScriptMessage('VIProUtils', 'makeSwatch', '{name: "Yellow CMYK", type: "cmyk", model: "process", colors: {yellow: 100}, uid: 1234}');
fake.sendScriptMessage('VIProUtils', 'makeSwatch', '{name: "Cyan CMYK", type: "cmyk", model: "spot", colors: {cyan: 100}, uid: 1234}');
fake.sendScriptMessage('VIProUtils', 'makeSwatch', '{swatch: "Cyan CMYK", model: "process", uid: 1234}');
fake.sendScriptMessage('VIProUtils', 'makeSwatch', '{swatch: "Cyan CMYK", name: "Spot Magenta", model: "spot", colors: {magenta:100}, uid: 1234}');
fake.sendScriptMessage('VIProUtils', 'makeSwatch', '{name: "Mid Gray", type: "gray", colors: {gray: 50}, uid: 1234}');
// Note gray will always be a process color regardless of the model setting

Example

If we want to change an existing rgb swatch "red" to a new lab swatch called "green" we can use

fake.sendScriptMessage(
'VIProUtils',
'makeSwatch', 
{
swatch: 'red',
name: 'green',
type:'lab',
colors:{l:100, a:-124, b:40},
uid:3423
})

logo
logo

# applyPaint

/*
 * @param {object} parameters
 * @param {[string]} parameters.tags The tags to apply paint to
 * @param {{}} [parameters.stroke] The stroke of the command
 * @param {boolean} [parameters.stroked] Should the item be stroked
 * @param {{}} [parameters.fill] The fill of the command
 * @param {{}} [parameters.filled] Should the item be filled
 * @param {string | {}} [parameters.fill.swatch] The fill swatch name or properties
 * @param {{}} [parameters.fill.color] The fill color properties
 * @param {string} [parameters.uid] The uid of the command
 * @param {boolean} [parameters.all = false] If to apply only to items will all the tags
 * @param {number} [parameters.stroke.dashOffset] The stroke dash offset
 * @param {[number]} [parameters.stroke.dashes] The stroke dash array
 * @param {'butt' | 'round' | 'projecting'} [parameters.stroke.cap] The stroke cap
 * @param {'miter' | 'round' | 'bevel'} [parameters.stroke.join] The stroke join
 * @param {number} [parameters.stroke.miterLimit] Whether a join is mitered (pointed) or beveled (squared-off)
 * @param {boolean} [parameters.stroke.overprint] Will art beneath a stroked object be overprinted?
 * @param {{}} [parameters.stroke.color] The stroke color
 * @param {string | {}} [parameters.stroke.swatch] The stroke swatch
 * @param {number} [parameters.stroke.width] The stroke width
 * @param {boolean} [parameters.stroke.adjustDashes] Adjust the dashes to place dashes in corners
 * @param {string} [parameters.fill.swatch.name]
 * @param {'lab' | 'rgb' | 'cmyk' | 'gray'} [parameters.fill.swatch.type]
 * @param {{}} [parameters.fill.swatch.colors] {red, green, blue, cyan, magenta, yellow, black , gray, l, a, b}
 * @param {boolean} [parameters.fill.swatch.overwrite]
 * @param {'process' | 'spot' | 'global'} [parameters.fill.swatch.model]
 * @param {'lab' | 'rgb' | 'cmyk' | 'gray'} [parameters.stroke.color.type]
 * @param {{}} [parameters.fill.color.colors] {red, green, blue, cyan, magenta, yellow, black , gray, l, a, b}
 * @param {number} [parameters.fill.swatch.tint]
 * @returns {object} {error | [uid] | result}
 */
fake.sendScriptMessage(
  'VIProUtils',
  'applyPaint', 
  {
    tags: ["red"],
    fill: {
      swatch: {name:"RGB Red"}
    },
    stroke: {
      dashes:[3,2,3],
      color: {type: 'rgb', colors:{ blue:255}},
      width: '1',
      adjustDashes: true,
      join: 'round'
    },
    uid:3423
  }
);
// Result {error:null, uid:3423, result:"stroke / fill applied"}

logo

# blur

/**
 *
 *
 * @param {object}  parameters
 * @param {[string]} parameters.tags The tags to apply effect
 * @param {boolean} [parameters.all=false] If to require all tags (true) or any of the tag (false)
 * @param {string} [parameters.type='gaussian']
 * @param {number} parameters.blur real number px of the blur
 * @returns
 */
// jsx engine
fake.sendScriptMessage('VIProUtils', 'blur', { tags: ['nose'], blur: 10 });
// js engine
fake.scriptEvent('com.vip.event.blur', '{ tags: ["nose"], blur: 10 , uid: 321}');


# dropshadow

/**
 *
 *
 * @param {object}  parameters
 * @param {[string]} parameters.tags The tags to apply effect
 * @param {boolean} [parameters.all=false] If to require all tags (true) or any of the tag (false)
 * @param {number} parameters.opacity opacity 0 - 1
 * @param {number} parameters.h horizontal offset in px
 * @param {number} parameters.v vertical offset in px
 * @param {number} parameters.blur blur in px
 * @param {number} [parameters.dark] darkness as % 0 - 100 either darkness or cmyk property is set, not both.
 * @param {number} parameters.blend blend mode UI index +
 * @param {[number]} [parameters.cmyk] Array [0 - 1, 0 - 1, 0 - 1, 0 - 1]
 * @returns
 */
// Add dropshadow with given CMYK color
fake.sendScriptMessage('VIProUtils', 'dropshadow', {tags:['pet', 'baby'], opacity:.9, h:3, v:3, blur:10, cmyk: [.1, .5,.5,.7]});
// Apply shadow using darkness of current colors
fake.sendScriptMessage('VIProUtils', 'dropshadow', {tags:['pet', 'baby'], opacity:.9, h:3, v:3, blur:10, dark: .5});
// JS engine
fake.scriptEvent('com.vip.event.dropshadow', "{tags:['pet', 'baby'], opacity:.9, h:3, v:3, blur:10, cmyk: [.1, .5,.5,.7]}");


# warp

/**
 *
 *
 * @param {object}  parameters
 * @param {[string]} parameters.tags The tags to apply effect
 * @param {boolean} [parameters.all=false] If to require all tags (true) or any of the tag (false)
 * @param {number} parameters.style 1 based UI index of effect
 * UI Style index
 * 1  Arc..., 2  Arc Lower... , 3  Arc Upper... , 4  Arch..., 5  Bulge...,    
 * 6  Shell Lower..., 7  Shell Upper..., 8  Flag..., 9  Wave..., 10  Fish...,  
 * 11  Rise..., 12  Fisheye..., 13  Inflate..., 14  Squeeze..., 15  Twist...
 * @param {number} parameters.bend DeformValue 0 - 1
 * @param {number} parameters.h horizontal -1 - 1
 * @param {number} parameters.v vertical -1 - 1
 * @returns
 * 
 */


fake.sendScriptMessage('VIProUtils', 'warp', {tags: ['mouth'], style: 1, bend: -.5});
// js engine
fake.scriptEvent('com.vip.event.warp' "tags: ['mouth'], style: 1, bend: -.5}");

Roo's mouth is a strait line with a warp arc applied to it.


# transform


/**
 *
 *
 * @param {object}  parameters
 * @param {[string]} parameters.tags The tags to apply effect
 * @param {boolean} [parameters.all=false] If to require all tags (true) or any of the tag (false)
 * @param {number}  [parameters.rotation=0] degrees (not rads) anti-clockwise
 * @param {number}  [parameters.shear=0] shear can be used in place of shearH,
 * @param {number}  [parameters.shearH=0] shearH should not be set if shear is set
 * @param {number}  [parameters.shearV=0]
 * @param {number}  [parameters.scaleH=1]
 * @param {number}  [parameters.scaleV=1]
 * @param {number}  [parameters.deltaX=0]
 * @param {number}  [parameters.deltaY=0]
 * @param {number}  [parameters.distance=0]
 * @param {number}  [parameters.angle=0]
 * @param {number}  [parameters.x]
 * @param {number}  [parameters.y]
 * @param {number}  [parameters.top]
 * @param {number}  [parameters.left]
 * @param {'DOCUMENTORIGIN', 'TOPLEFT', 'LEFT', 'BOTTOMLEFT', 'TOP', 'CENTER', 'BOTTOM', 'TOPRIGHT', 'RIGHT', 'BOTTOMRIGHT'}  [parameters.xyAnchorPoint='TOPLEFT'] anchor point for x and y
 * @param {boolean} [parameters.changePositions=true]
 * @param {boolean} [parameters.changeFillPatterns=true]
 * @param {boolean} [parameters.changeFillGradients=true]
 * @param {boolean} [parameters.changeStrokePattern=true]
 * @param {number}  [parameters.changeLineWidths=1] 0 - 100 The amount line widths are to be scaled
 * @param {'DOCUMENTORIGIN', 'TOPLEFT', 'LEFT', 'BOTTOMLEFT', 'TOP', 'CENTER', 'BOTTOM', 'TOPRIGHT', 'RIGHT', 'BOTTOMRIGHT'} [anchorPoint='CENTER'] anchor point for rotations, shear, scale
 * @returns result
 */

fake.sendScriptMessage('VIProUtils', 'transform', "{tags:['baby'], x: 200, y: -200, xyAnchorPoint: 't', shear:45, rotate: 145, scaleH: 2, anchorPoint:'br'}")
// js engine
fake.scriptEvent('com.vip.event.transform', "{tags:['baby'], x: 200, y: -200, xyAnchorPoint: 't', shear:45, rotate: 145, scaleH: 2, anchorPoint:'br'}")

Note: firstly the shear, scale, and rotation are applied as per the anchorPoint then the positioning is applied. If x and y are given then their anchorPoint is set using xyAnchorPoint


# rotate

/**
*
*
* @param {object} parameters
* @param {[string]} parameters.tags
* @param {number} parameters.rotation degrees
* @param {number} [parameters.uid]
* @returns
*/
fake.sendScriptMessage('VIProUtils', 'rotate', "{tags: ['sky'], rotation:90}")
//js engine
fake.scriptEvent('com.vip.event.rotate', "{tags: ['sky'], rotation:90}")
// looks the same as
fake.scriptEvent('com.vip.event.transform', "{tags: ['sky'], rotation:90, changeFillGradients: true}");
// and
fake.scriptEvent('com.vip.event.transform', "{tags: ['sky'], rotation:90}");
// compare with
fake.scriptEvent('com.vip.event.transform', "{tags: ['sky'], rotation:90, changeFillGradients: false}");



# shear

/**
 *
 *
 * @param {object} parameters
 * @param {[string]} parameters.tags
 * @param {number} parameters.shear degrees
 * @param {'DOCUMENTORIGIN', 'TOPLEFT', 'LEFT', 'BOTTOMLEFT', 'TOP', 'CENTER', 'BOTTOM', 'TOPRIGHT', 'RIGHT', 'BOTTOMRIGHT'} [anchorPoint='CENTER'] anchor point
 * @param {number} [parameters.uid]
 * @returns
 */
fake.sendScriptMessage('VIProUtils', 'shear', "{tags: ['pet', 'baby'], shear: 30, anchorPoint: 'bl'}")
// js engine
fake.scriptEvent('com.vip.event.shear', "{tags: ['pet', 'baby'], shear: 30, anchorPoint: 'bl'}"'


# position

/**
 *
 *
 * @param {object}  parameters
 * @param {number}  parameters.tags
 * @param {number}  [parameters.deltaX=0]
 * @param {number}  [parameters.deltaY=0]
 * @param {number}  [parameters.distance=0]
 * @param {number}  [parameters.angle=0]
 * @param {number}  [parameters.x]
 * @param {number}  [parameters.y]
 * @param {number}  [parameters.top]
 * @param {number}  [parameters.left]
 * @param {'DOCUMENTORIGIN', 'TOPLEFT', 'LEFT', 'BOTTOMLEFT', 'TOP', 'CENTER', 'BOTTOM', 'TOPRIGHT', 'RIGHT', 'BOTTOMRIGHT'}  [parameters.xyAnchorPoint='TOPLEFT']
 * @param {boolean} [parameters.changePositions=true]
 * @param {boolean} [parameters.changeFillPatterns=true]
 * @param {boolean} [parameters.changeFillGradients=true]
 * @param {boolean} [parameters.changeStrokePattern=true]
 * @param {number}  [parameters.changeLineWidths=1] 0 - 100 The amount line widths are to be scaled
 * @returns result
 */
fake.scriptEvent('com.vip.event.position', "{tags: ['pet'], x: 30, y: -200,xyAnchorPoint: 'bl'}"); // Only x and y take into consideration the anchor point
fake.scriptEvent('com.vip.event.position', "{tags: ['pet'], left: 30, top: -200}");
fake.scriptEvent('com.vip.event.position', "{tags: ['pet'], distance: 300, angle: 30}");

# translate

/**
 *
 *
 * @param {object} parameters
 * @param {[string]} parameters.tags
 * @param {number}  [parameters.deltaX=0]
 * @param {number}  [parameters.deltaY=0]
 * @param {number}  [parameters.distance=0]
 * @param {number}  [parameters.angle=0]
 * @param {boolean} [parameters.transformObjects=true]
 * @param {boolean} [parameters.changeFillPatterns=true]
 * @param {boolean} [parameters.changeFillGradients=true]
 * @param {boolean} [parameters.changeStrokePattern=true]
 * @param {number} [parameters.uid]
 * @returns
 */
fake.scriptEvent('com.vip.event.translate', "{tags: ['pet'], deltaX: 30, deltaY: -200,xyAnchorPoint: 'bl'}"); // Only x and y take into consideration the anchor point
fake.scriptEvent('com.vip.event.translate', "{tags: ['pet'], distance: 300, angle: 30}");

# resize

/**
 *
 *
 * @param {object} parameters
 * @param {[string]} parameters.tags
 * @param {number}  [parameters.scaleX=0]
 * @param {number}  [parameters.scaleY=0]
 * @param {number}  [parameters.height=0]
 * @param {number}  [parameters.width=0]
 * @param {boolean} [parameters.changePositions=true]
 * @param {boolean} [parameters.changeFillPatterns=true]
 * @param {boolean} [parameters.changeFillGradients=true]
 * @param {boolean} [parameters.changeStrokePattern=true]
 * @param {number}  [parameters.changeLineWidths=1] 0 - 100 The amount line widths are to be scaled
 * @param {'DOCUMENTORIGIN', 'TOPLEFT', 'LEFT', 'BOTTOMLEFT', 'TOP', 'CENTER', 'BOTTOM', 'TOPRIGHT', 'RIGHT', 'BOTTOMRIGHT'} [anchorPoint='CENTER'] anchor point
 * @param {number} [parameters.uid]
 * @returns
 */
// TODO add extraSize parameters
fake.scriptEvent('com.vip.event.resize', "{tags: ['pet'], width: 30, height: 200, anchorPoint: 'bl'}");
fake.scriptEvent('com.vip.event.resize', "{tags: ['pet'], scaleX: 2, scaleY: 2, anchorPoint: 'bl'}");

# zOrder

/**
 *
 *
 * @param {object} parameters
 * @param {[string]} parameters.tags 
 * @param {number} parameters.movement 3 FRONT - 0 BACK
 * @param {number} [parameters.uid]
 * @returns
 */
fakePrivate.zOrder = function (parameters) {

# remove

/**
*
*
* @param {object} parameters
* @param {[string]} parameters.tags
* @param {boolean} parameters.all
* @param {number} [parameters.uid]
* @returns
*/
fakePrivate.remove = function (parameters) {

# bringInPerspective

/**
 *
 *
 * @param {object} parameters
 * @param {[string]} parameters.tags
 * @param {boolean} parameters.all
 * @param {number} [parameters.x]
 * @param {number} [parameters.y]
 * @param {'NO' | 'LEFT' | 'RIGHT' | 'FLOOR'} parameters.plane
 * @param {number} [parameters.uid]
 * @returns
 */
fakePrivate.bringInPerspective = function (parameters) {

# move

/**
*
*
* @param {object} parameters
* @param {[string]} parameters.tags
* @param {boolean} parameters.all
* @param {number} [parameters.layer]
* @param {number} [parameters.layerIndex]
* @param {string} [parameters.objectName]
* @param {string} [parameters.objectIndex]
* @param {[string]} [parameters.objectTags]
* @param {boolean} [parameters.allTags]
* @param {number} [parameters.uuid]
* @param {'INSIDE', 'PLACEAFTER', 'PLACEATBEGINNING', 'PLACEATEND', 'PLACEBEFORE'} parameters.location
* @param {boolean} [parameters.duplicate]
* @param {[string]} [parameters.newTags]
* @param {boolean} [parameters.replaceTags]
* @param {number} [parameters.uid]
* @returns
*/

fakePrivate.move = function (parameters) {

# duplicate

/**
*
*
* @param {object} parameters
* @param {[string]} parameters.tags
* @param {boolean} parameters.all
* @param {number} [parameters.layer]
* @param {number} [parameters.layerIndex]
* @param {string} [parameters.objectName]
* @param {string} [parameters.objectIndex]
* @param {[string]} [parameters.objectTags]
* @param {boolean} [parameters.allTags]
* @param {number} [parameters.uuid]
* @param {'INSIDE', 'PLACEAFTER', 'PLACEATBEGINNING', 'PLACEATEND', 'PLACEBEFORE'} parameters.location
* @param {[string]} [parameters.newTags]
* @param {boolean} [parameters.replaceTags]
* @param {number} [parameters.uid]
* @returns
*/

fake.sendScriptMessage('VIProUtils', 'duplicate', "{tags: ['pet'], newTags:['baby'], replace: true, location: 'PLACEATBEGINNING'}");
// JS engine
fake.scriptEvent('com.vip.event.duplicate', "{tags: ['pet'], newTags:['baby'], replace: true, location: 'PLACEATBEGINNING'}");

# swapImage

/**
 *
 *
 * @param {object} parameters
 * @param {[string]} parameters.tags
 * @param {string} parameters.path image path
 * @param {number | string} [parameters.uid]
 * @returns
 */
// JS engine
fake.scriptEvent('com.vip.event.swapImage', `{tags: ['myPicky'], path: 'path/to/Roo in DC.png'}`);

# fill

/**
 *
 *
 * @param {object} parameters
 * @param {[string]} parameters.tags
 * @param {object} [parameters.swatch]
 * @param {object} [parameters.color]
 * @param {boolean} [parameters.filled]
 * @param {boolean} [parameters.evenOdd]
 * @param {number | string} [parameters.uid]
 * @param {string} [parameters.swatch.name]
 * @param {'lab' | 'rgb' | 'cmyk' | 'gray'} [parameters.swatch.type]
 * @param {{}} [parameters.swatch.colors] {red, green, blue, cyan, magenta, yellow, black , gray, l, a, b}
 * @param {boolean} [parameters.swatch.overwrite]
 * @param {'process' | 'spot' | 'global'} [parameters.swatch.model]
 * @param {number} [parameters.swatch.tint]
 * @param {'lab' | 'rgb' | 'cmyk' | 'gray'} [parameters.swatch.type]
 * @param {{}} [parameters.swatch.colors] {red, green, blue, cyan, magenta, yellow, black , gray, l, a, b}
 * @param {boolean} [parameters.swatch.overwrite]
 * @param {'process' | 'spot' | 'global'} [parameters.swatch.model]
 * @returns

 */
// Compare with the applyPaint method
fake.sendScriptMessage(
  'VIProUtils',
  'fill', 
  {
    tags: ["red"],
    swatch: {name:"RGB Red"},
    uid:3423
  }
);
// js engine
fake.scriptEvent('com.vip.event.fill', '{ tags: ["green"], color:{type: "rgb", spot: true, colors:{g: 255}}, uid: 321}');


# stroke

/**
 *
 *
 * @param {object} parameters
 * @param {[string]} parameters.tags
 * @param {{}} [parameters.stroke] The stroke of the command
 * @param {boolean} [parameters.stroked] Should the item be stroked
 * @param {number} [parameters.dashOffset] The stroke dash offset
 * @param {[number]} [parameters.dashes] The stroke dash array
 * @param {'butt' | 'round' | 'projecting'} [parameters.cap] The stroke cap
 * @param {'miter' | 'round' | 'bevel'} [parameters.join] The stroke join
 * @param {number} [parameters.miterLimit] Whether a join is mitered (pointed) or beveled (squared-off)
 * @param {boolean} [parameters.overprint] Will art beneath a stroked object be overprinted?
 * @param {{}} [parameters.color] The stroke color
 * @param {string | {}} [parameters.swatch] The stroke swatch
 * @param {number} [parameters.width] The stroke width
 * @param {boolean} [parameters.adjustDashes] Adjust the dashes to place dashes in corners
 * @param {'lab' | 'rgb' | 'cmyk' | 'gray'} [parameters.color.type]
 * @param {string} [parameters.swatch.name]
 * @param {'lab' | 'rgb' | 'cmyk' | 'gray'} [parameters.swatch.type]
 * @param {{}} [parameters.swatch.colors] {red, green, blue, cyan, magenta, yellow, black , gray, l, a, b}
 * @param {boolean} [parameters.swatch.overwrite]
 * @param {'process' | 'spot' | 'global'} [parameters.swatch.model]
 * @param {number} [parameters.swatch.tint]
 * @param {'lab' | 'rgb' | 'cmyk' | 'gray'} [parameters.swatch.type]
 * @param {{}} [parameters.swatch.colors] {red, green, blue, cyan, magenta, yellow, black , gray, l, a, b}
 * @param {boolean} [parameters.swatch.overwrite]
 * @param {'process' | 'spot' | 'global'} [parameters.swatch.model]
 * @param {number | string} [parameters.uid]
 * @returns

 */
// TODO overprint
// Compare with the applyPaint method
fake.sendScriptMessage(`
  'VIProUtils',
  'stroke', 
  {
    tags: ["heaven"],
    dashes:[3,2,3],
    color: {type: 'rgb', colors:{ blue:255}},
    width: '1',
    adjustDashes: true,
    join: 'round',
    uid:3423
  }`
);
// js engine
fake.scriptEvent('com.vip.event.stroke',
  ` {
      tags: ["heaven"],
      dashes:[3,2,3],
      color: {type: 'rgb', colors:{ blue:255}},
      width: '1',
      adjustDashes: true,
      join: 'round',
      uid:3423
    }`
  );

# getList getSymbolList getArtStyleList

fakePrivate.getList = function (parameters, list) {
  var uid;
  if (parameters) {
    uid = parameters.uid;
  }
  try {
    return { error: null, uid: uid, result: app.sendScriptMessage('VIProUtils', list, '').split(/,/) };
  } catch (err) {
    return { error: err, uid: uid, result: [] };
  }
};

fakePrivate.getSymbolList = function (parameters) {
  var uid;
  if (parameters) {
    uid = parameters.uid;
  }
  try {
    return {
      error: null,
      uid: uid,
      result: app.sendScriptMessage('VIProUtils', 'getSymbolList', '').split(/,/)
    };
  } catch (err) {
    return { error: err, uid: uid, result: [] };
  }
};

fakePrivate.getArtStyleList = function (parameters) {
  var uid;
  if (parameters) {
    uid = parameters.uid;
  }
  try {
    return {
      error: null,
      uid: uid,
      result: app.sendScriptMessage('VIProUtils', 'getArtStyleList', '').split(/,/)
    };
  } catch (err) {
    return { error: err, uid: uid, result: [] };
  }
};

# controller


//    ___         _           _ _
//   / __|___ _ _| |_ _ _ ___| | |___ _ _
//  | (__/ _ \ ' \  _| '_/ _ \ | / -_) '_|
//   \___\___/_||_\__|_| \___/_|_\___|_|
//

/**
 *
 *
 * @param {String <VIProUtils>} caller The plugin name VIProUtils
 * @param {string} selector The command that is parsed by the fake scriptMessage / scriptEvent
 * @param {string} message A JSON string with the command parameters
 */
function Message(caller, selector, message, emitEvent) {
  try {
    if (caller !== 'VIProUtils') {
      return;
    }
    var error = kNoErr;
    var msg = '';

    // Convert JSON message string into an object.
    // We probably always want to only pass objects even for setTags and the like
    // We can be pretty string on what needs to be passed because it's all going to be done by Tom ;-)
    // // __log(message, __log.rColor() + __log.rColor('color', true))
    var parameters = JSON.parse(message);
    // The jsx default of the switch does not work so we need to "manually" check to see if the selector is wishful thinking.
    if (!fake.selectors[selector]) {
      result = {
        error:
          selector + ' is not recognized\n' + 'The current selectors are:\n' + fake.selectorsArray.join('\n')
      };
      if (parameters && parameters.uid !== undefined) {
        result.uid = parameters.uid;
      }
      __log(result);
      return result;
    }
    // __log(parameters, __log.rColor() + __log.rColor('color', true))
    // Check for parsing error
    if (('' + parameters).slice(0, 7) === 'ERROR: ') {
      // We need to find a better method than this.
      (msg = '{error: "' + parameters), '", caller: "' + caller + '", message: "' + message + '"}';
      if (emitEvent) {
        dispatchEvent('com.vip.fake.jsonError', msg);
      }
      __error(msg);
      return msg;
    }

    // TODO Must add uid to error messages
    // Separate error into message, line, uid
    switch (selector) {
      case 'setTags':
      case 'replaceTags':
      case 'getTags':
      case 'getByTags':
      case 'selectByTags':
      case 'removeTags':
      case 'removeTagsSelected':
      case 'applyPaint':
      case 'makeSwatch':
      case 'blur':
      case 'dropshadow':
      case 'transform':
      case 'warp':
      case 'zOrder':
      case 'swapImage':
      case 'fill':
      case 'stroke':
      case 'rotate':
      case 'shear':
      case 'translate':
      case 'resize':
      case 'position':
      case 'remove':
      case 'move':
      case 'bringInPerspective':
      case 'duplicate':
        try {
          msg = fakePrivate[selector](parameters);
          if (emitEvent) {
            dispatchEvent('com.vip.event.' + selector + '.result', msg);
          }
        } catch (error) {
          if (emitEvent) {
            dispatchEvent('com.vip.event.' + selector + '.result', error);
          }
        }
        break;
      case 'getSymbolList': // doesn't add extra 'quotes'
      case 'getArtStyleList': // adds extra 'quotes' BUG
      case 'getLiveEffectList': // adds extra 'quotes' BUG
        try {
          msg = fakePrivate.getList(parameters, selector);
          if (emitEvent) {
            dispatchEvent('com.vip.event.' + selector + '.result', msg);
          }
        } catch (error) {
          if (emitEvent) {
            dispatchEvent('com.vip.event.' + selector + '.result', error);
          }
        }
        break;
      case 'removeNthPaint':
        // app.selection[0].sendScriptMessage("VIProUtils","removeNthPaint","2");
        break;
      case 'getPaintAndStroke':
        // This one is not working
        break;
      case 'version':
        break;
      case 'ready':
        break;
      default:
        mgs = { error: 'No such command "' + selector + '"', uid: parameters.uid };
        break;
    }
    if (!emitEvent) {
      __log(msg, 'color:yellow');
    }
    return msg || error;
  } catch (err) {
    __error(err);
    return err;
  }
}

('Fake Plugin Loaded V 0.0.0.8');

# Next events to document

  • applyPaint
  • getSymbolList
  • getArtStyleList
  • getLiveEffectList
  • removeNthPaint
  • getPaintAndStroke
  • version
  • ready

Note

I am temporally listing these functions here for now out of convenience.
They don't belong here because this page is about methods that go between the CEP / JSX and CPP engines.

# User functions to document

  • rgb()
  • cmyk()
  • lab()
  • gray()
  • swatch() ?
  • random()
  • var()
  • val()
  • Any other ideas?