Web-Based Tagged Container Publishing
Here are the scripts and functions that make this publishing example possible.
The left column contains the decoded scripts and functions that process the shapes in the OmniGraffle document.
The right column contains the scripts and functions embedded in the webpage.
Decoded Function for Tagging Selected Solid With Metadata
This function is designed to take an argument that is an array of input data, namely the item’s user data key value (SKU), the user data value that is a URL to the larger image file on the server, and the shapes note string.
By wrapping the script in a function with an single argument, it can be “user-approved” during its first execution prompt so that following executions of the script wil be un-prompted. See the section on Script URLs regarding security procedures.
Tag the Selected Shape
(function setMetadataForItem(args){
itemSKUStr = args[0];
itemURLStr = args[1];
itemNotes = args[2];
slds = document.windows[0].selection.solids;
if (slds.length === 1){
slds[0].setUserData('SKU', itemSKUStr);
slds[0].setUserData('URL', itemURLStr);
slds[0].notes = itemNotes;
} else {
alertTitle = 'SELECTION ERROR';
alertMessage = 'Please select a single solid graphic.';
new Alert(alertTitle, alertMessage).show();
}
})(argument)
Decoded Script for Importing Images Into Tagged Containers
This script reads the value of the URL user data key to derive the url to the image file on the server. It then uses the Omni Automation FetchRequest API to asynchronously download and insert the linked image file.
Import Images into Tagged Shapes
(async () => {
try {
cnvs = document.windows[0].selection.canvas
shapez = cnvs.graphics.filter(graphk => {
return graphk instanceof Shape
})
if(shapez.length === 0){
throw {
name: "Missing Items",
message: "This canvas does not contain any shapes."
}
}
const dataKey = 'SKU'
const urlKey = 'URL'
for (shape of shapez){
const shapeDataKey = shape.userData[dataKey]
if(shapeDataKey){
const shapeURLStr = shape.userData[urlKey]
if(shapeURLStr){
request = URL.FetchRequest.fromString(shapeURLStr)
request.method = 'GET'
request.cache = "no-cache"
response = await request.fetch()
responseCode = response.statusCode
console.log(shapeDataKey, responseCode)
if(responseCode >= 200 && responseCode < 300){
shape.image = addImage(response.bodyData)
} else {
console.error(shapeDataKey, shapeURLStr)
}
}
}
}
}
catch(err){
new Alert(err.name, err.message).show()
}
})();
Decoded Notes Placement Script
This script prompts the user for the placement of the notes extracted from the selected shape’s metadata. THe script then replicates the selected shape to the indicated postion and fills it with the note text.
Notes Placement
(async () => {
try {
// default settings
defaultOffset = 12
defaultTextSize = 14
// prompt for placement location
alertTitle = "Notes Placement"
alertMessage = "Should the notes be placed to the left, right, or below the selected graphic solid?"
alert = new Alert(alertTitle, alertMessage)
alert.addOption("Right")
alert.addOption("Left")
alert.addOption("Below")
buttonIndex = await alert.show()
cnvs = document.windows[0].selection.canvas
slds = document.windows[0].selection.solids
shapez = document.windows[0].selection.solids
switch(buttonIndex){
case 0:
for(shape of shapez){
sName = shape.name
sNotes = shape.notes
cRect = shape.geometry
nRect = new Rect(cRect.maxX + defaultOffset, cRect.minY, cRect.width, cRect.height)
newShape = cnvs.addShape('Rectangle',nRect)
newShape.text = sNotes
newShape.name = sName
newShape.shadowColor = null
newShape.strokeType = null
newShape.fillType = null
newShape.autosizing = TextAutosizing.Overflow
newShape.textHorizontalAlignment = HorizontalTextAlignment.Left
newShape.textHorizontalPadding = 0
newShape.textVerticalPlacement = VerticalTextPlacement.Top
newShape.textVerticalPadding = 0
newShape.textSize = defaultTextSize
}
break;
case 1:
for(shape of shapez){
sName = shape.name
sNotes = shape.notes
cRect = shape.geometry
nRect = new Rect(cRect.minX - defaultOffset - cRect.width, cRect.minY, cRect.width, cRect.height)
newShape = cnvs.addShape('Rectangle',nRect)
newShape.text = sNotes
newShape.name = sName
newShape.shadowColor = null
newShape.strokeType = null
newShape.fillType = null
newShape.autosizing = TextAutosizing.Overflow
newShape.textHorizontalAlignment = HorizontalTextAlignment.Left
newShape.textHorizontalPadding = 0
newShape.textVerticalPlacement = VerticalTextPlacement.Top
newShape.textVerticalPadding = 0
newShape.textSize = defaultTextSize
}
break;
case 2:
for(shape of shapez){
sName = shape.name
sNotes = shape.notes
cRect = shape.geometry
nRect = new Rect(cRect.minX, cRect.maxY + defaultOffset, cRect.width, cRect.height)
aShape = cnvs.addShape('Rectangle',nRect)
aShape.text = sNotes
aShape.name = sName
aShape.shadowColor = null
aShape.strokeType = null
aShape.fillType = null
aShape.autosizing = TextAutosizing.Overflow
aShape.textHorizontalAlignment = HorizontalTextAlignment.Left
aShape.textHorizontalPadding = 0
aShape.textVerticalPlacement = VerticalTextPlacement.Top
aShape.textVerticalPadding = 0
aShape.textSize = defaultTextSize
}
break;
default:
console.log("DEFAULT OPTION")
}
}
catch(err){
new Alert(err.name, err.message).show()
}
})();
Scripts Embedded in Webpage
This function encodes the argument data (product SKU and Description) for the clicked or tapped product image. The argument data is embedded in the webpage with IDs that correspond the the SKU value of the item.
Encode the Function Argument
function encodeArgumentForURL(argumentData){
var encodedArgument = encodeURIComponent(argumentData);
return "&arg=" + encodedArgument;
}
This function appends the encoded argument data to the encoded tagging function. Then it appends the appropriate Omni Automation schema for OmniGraffle and returns the resulting Omni Automation Script URL.
Append Encoded Function with Encoded Argument
function combineScriptAndArgument(encodedArgument){
// the setMetadataForItem(args) function encoded already
encodedFunction = "omnigraffle://localhost/omnijs-run?script=%28function%20setMetadataForItem%28args%29%7B%0A%09itemSKUStr%20%3D%20args%5B0%5D%3B%0A%09itemURLStr%20%3D%20args%5B1%5D%3B%0A%09itemNotes%20%3D%20args%5B2%5D%3B%0A%09slds%20%3D%20document%2Ewindows%5B0%5D%2Eselection%2Esolids%3B%0A%09if%20%28slds%2Elength%20%3D%3D%3D%201%29%7B%0A%09%09slds%5B0%5D%2EsetUserData%28%27SKU%27%2C%20itemSKUStr%29%3B%0A%09%09slds%5B0%5D%2EsetUserData%28%27URL%27%2C%20itemURLStr%29%3B%0A%09%09slds%5B0%5D%2Enotes%20%3D%20itemNotes%3B%0A%09%7D%20else%20%7B%0A%09%09alertTitle%20%3D%20%27SELECTION%20ERROR%27%3B%0A%09%09alertMessage%20%3D%20%27Please%20select%20a%20single%20solid%20graphic%2E%27%3B%0A%09%09new%20Alert%28alertTitle%2C%20alertMessage%29%2Eshow%28%29%3B%0A%09%7D%0A%7D%29%28argument%29"
// append the encoded script argument (in this case and array)
scriptURL = encodedFunction + encodedArgument
return scriptURL
}
This embedded function extracts the relevant product data from the hidden DIVs tagged with the SKU of the clicked or tapped product, creates the URL to the image on the server, encodes the function argument, appends the argument to the encoded tagging function, creates the Omni Automation Script URL targeting OmniGraffle, and then executes the script URL!
Create and Execute Omni Automation Script URL
function createExecuteScriptURL(key, keyValue){
if (confirm('Click|Tap OK to tag the selected OmniGraffle graphic with this data key and data value:\n\n\t' + key + ':' + keyValue)){
// locate the description element
auxElement = document.getElementById(keyValue);
// get the key name for the description element
auxKeyName = auxElement.getAttribute("name");
// get the description content
notesValue = auxElement.innerHTML;
// construct the URL to the image file
imageURL = "https://omni-automation.com/omnigraffle/tagged-import/gfx/";
imageURL = imageURL + keyValue + ".jpg";
// create the script argument array
argumentData = JSON.stringify([keyValue, imageURL, notesValue])
// encode the argument
encodedArgument = encodeArgumentForURL(argumentData)
// combine the script and the argument
scriptURL = combineScriptAndArgument(encodedArgument)
// execute the Omni Automation script url
window.location = scriptURL;
}
}
This function creates and executes the Omni Automation Script URL for importing images into all tagged shapes. It is triggered by a button on the webpage.
Import Images into All Tagged Shapes
function importToTaggedGraphics(){
if (confirm('Click|Tap OK to import images from this webpage into the tagged graphics in the front OmniGraffle document.')){
const scriptCode = '%28async%20%28%29%20%3D%3E%20%7B%0A%09try%20%7B%09%09%0A%09%09cnvs%20%3D%20document%2Ewindows%5B0%5D%2Eselection%2Ecanvas%0A%09%09shapez%20%3D%20cnvs%2Egraphics%2Efilter%28graphk%20%3D%3E%20%7B%0A%09%09%09return%20graphk%20instanceof%20Shape%0A%09%09%7D%29%0A%09%09if%28shapez%2Elength%20%3D%3D%3D%200%29%7B%0A%09%09%09throw%20%7B%0A%09%09%09%09name%3A%20%22Missing%20Items%22%2C%0A%09%09%09%09message%3A%20%22This%20canvas%20does%20not%20contain%20any%20shapes%2E%22%0A%09%09%09%7D%0A%09%09%7D%0A%09%09%0A%09%09const%20dataKey%20%3D%20%27SKU%27%0A%09%09const%20urlKey%20%3D%20%27URL%27%09%09%09%09%09%0A%09%09%0A%09%09for%20%28shape%20of%20shapez%29%7B%0A%09%09%09const%20shapeDataKey%20%3D%20shape%2EuserData%5BdataKey%5D%0A%09%09%09if%28shapeDataKey%29%7B%0A%09%09%09%09const%20shapeURLStr%20%3D%20shape%2EuserData%5BurlKey%5D%0A%09%09%09%09if%28shapeURLStr%29%7B%0A%09%09%09%09%09request%20%3D%20URL%2EFetchRequest%2EfromString%28shapeURLStr%29%0A%09%09%09%09%09request%2Emethod%20%3D%20%27GET%27%0A%09%09%09%09%09request%2Ecache%20%3D%20%22no%2Dcache%22%0A%09%09%09%09%09response%20%3D%20await%20request%2Efetch%28%29%0A%09%09%09%09%09responseCode%20%3D%20response%2EstatusCode%0A%09%09%09%09%09console%2Elog%28shapeDataKey%2C%20responseCode%29%0A%09%09%09%09%09if%28responseCode%20%3E%3D%20200%20%26%26%20responseCode%20%3C%20300%29%7B%0A%09%09%09%09%09%09shape%2Eimage%20%3D%20addImage%28response%2EbodyData%29%0A%09%09%09%09%09%7D%20else%20%7B%0A%09%09%09%09%09%09console%2Eerror%28shapeDataKey%2C%20shapeURLStr%29%0A%09%09%09%09%09%7D%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D%0A%09%7D%0A%09catch%28err%29%7B%0A%09%09new%20Alert%28err%2Ename%2C%20err%2Emessage%29%2Eshow%28%29%0A%09%7D%0A%7D%29%28%29%3B';
const targetURL = "omnigraffle:///omnijs-run?script=" + scriptCode;
window.location = targetURL;
};
}
This function creates and executes the Omni Automation Script URL for importing images into only the selected tagged shapes. It is triggered by a button on the webpage.
Import Images into Selected Tagged Shapes
function importToSelectedTaggedGraphics(){
if (confirm('Click|Tap OK to import images from this webpage into the tagged graphics in the front OmniGraffle document.')){
const scriptCode = '%28async%20%28%29%20%3D%3E%20%7B%0A%09try%20%7B%09%09%0A%09%09cnvs%20%3D%20document%2Ewindows%5B0%5D%2Eselection%2Ecanvas%0A%09%09shapez%20%3D%20document%2Ewindows%5B0%5D%2Eselection%2Esolids%0A%09%09if%28shapez%2Elength%20%3D%3D%3D%200%29%7B%0A%09%09%09throw%20%7B%0A%09%09%09%09name%3A%20%22Missing%20Items%22%2C%0A%09%09%09%09message%3A%20%22Select%20the%20tagged%20shapes%20to%20import%20images%20into%2E%22%0A%09%09%09%7D%0A%09%09%7D%0A%09%09%0A%09%09const%20dataKey%20%3D%20%27SKU%27%0A%09%09const%20urlKey%20%3D%20%27URL%27%09%09%09%09%09%0A%09%09%0A%09%09for%20%28shape%20of%20shapez%29%7B%0A%09%09%09const%20shapeDataKey%20%3D%20shape%2EuserData%5BdataKey%5D%0A%09%09%09if%28shapeDataKey%29%7B%0A%09%09%09%09const%20shapeURLStr%20%3D%20shape%2EuserData%5BurlKey%5D%0A%09%09%09%09if%28shapeURLStr%29%7B%0A%09%09%09%09%09request%20%3D%20URL%2EFetchRequest%2EfromString%28shapeURLStr%29%0A%09%09%09%09%09request%2Emethod%20%3D%20%27GET%27%0A%09%09%09%09%09request%2Ecache%20%3D%20%22no%2Dcache%22%0A%09%09%09%09%09response%20%3D%20await%20request%2Efetch%28%29%0A%09%09%09%09%09responseCode%20%3D%20response%2EstatusCode%0A%09%09%09%09%09console%2Elog%28shapeDataKey%2C%20responseCode%29%0A%09%09%09%09%09if%28responseCode%20%3E%3D%20200%20%26%26%20responseCode%20%3C%20300%29%7B%0A%09%09%09%09%09%09shape%2Eimage%20%3D%20addImage%28response%2EbodyData%29%0A%09%09%09%09%09%7D%20else%20%7B%0A%09%09%09%09%09%09console%2Eerror%28shapeDataKey%2C%20shapeURLStr%29%0A%09%09%09%09%09%7D%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D%0A%09%7D%0A%09catch%28err%29%7B%0A%09%09new%20Alert%28err%2Ename%2C%20err%2Emessage%29%2Eshow%28%29%0A%09%7D%0A%7D%29%28%29%3B';
const targetURL = "omnigraffle:///omnijs-run?script=" + scriptCode;
window.location = targetURL;
};
}
This function creates and executes the Omni Automation Script URL for placing the notes of only the selected tagged shapes. It is triggered by a button on the webpage.
Place the Notes
function placeNotes(){
if (confirm('Extract and place the image notes of the selected tagged OmniGraffle image?')){
const scriptCode = '%28async%20%28%29%20%3D%3E%20%7B%0A%09try%20%7B%0A%09%09%2F%2F%20default%20settings%0A%09%09defaultOffset%20%3D%2012%0A%09%09defaultTextSize%20%3D%2014%0A%09%09%0A%09%09%2F%2F%20prompt%20for%20placement%20location%0A%09%09alertTitle%20%3D%20%22Notes%20Placement%22%0A%09%09alertMessage%20%3D%20%22Should%20the%20notes%20be%20placed%20to%20the%20left%2C%20right%2C%20or%20below%20the%20selected%20graphic%20solid%3F%22%0A%09%09alert%20%3D%20new%20Alert%28alertTitle%2C%20alertMessage%29%0A%09%09alert%2EaddOption%28%22Right%22%29%0A%09%09alert%2EaddOption%28%22Left%22%29%0A%09%09alert%2EaddOption%28%22Below%22%29%0A%09%09buttonIndex%20%3D%20await%20alert%2Eshow%28%29%0A%09%09%0A%09%09cnvs%20%3D%20document%2Ewindows%5B0%5D%2Eselection%2Ecanvas%0A%09%09slds%20%3D%20document%2Ewindows%5B0%5D%2Eselection%2Esolids%0A%09%09shapez%20%3D%20document%2Ewindows%5B0%5D%2Eselection%2Esolids%0A%09%09%0A%09%09switch%28buttonIndex%29%7B%0A%09%09%09case%200%3A%0A%09%09%09%09for%28shape%20of%20shapez%29%7B%0A%09%09%09%09%09sName%20%3D%20shape%2Ename%0A%09%09%09%09%09sNotes%20%3D%20shape%2Enotes%0A%09%09%09%09%09cRect%20%3D%20shape%2Egeometry%0A%09%09%09%09%09nRect%20%3D%20new%20Rect%28cRect%2EmaxX%20%2B%20defaultOffset%2C%20cRect%2EminY%2C%20cRect%2Ewidth%2C%20cRect%2Eheight%29%0A%09%09%09%09%09newShape%20%3D%20cnvs%2EaddShape%28%27Rectangle%27%2CnRect%29%0A%09%09%09%09%09newShape%2Etext%20%3D%20sNotes%0A%09%09%09%09%09newShape%2Ename%20%3D%20sName%0A%09%09%09%09%09newShape%2EshadowColor%20%3D%20null%0A%09%09%09%09%09newShape%2EstrokeType%20%3D%20null%0A%09%09%09%09%09newShape%2EfillType%20%3D%20null%0A%09%09%09%09%09newShape%2Eautosizing%20%3D%20TextAutosizing%2EOverflow%0A%09%09%09%09%09newShape%2EtextHorizontalAlignment%20%3D%20HorizontalTextAlignment%2ELeft%0A%09%09%09%09%09newShape%2EtextHorizontalPadding%20%3D%200%0A%09%09%09%09%09newShape%2EtextVerticalPlacement%20%3D%20VerticalTextPlacement%2ETop%0A%09%09%09%09%09newShape%2EtextVerticalPadding%20%3D%200%0A%09%09%09%09%09newShape%2EtextSize%20%3D%20defaultTextSize%0A%09%09%09%09%7D%0A%09%09%09%09break%3B%0A%09%09%09case%201%3A%0A%09%09%09%09for%28shape%20of%20shapez%29%7B%0A%09%09%09%09%09sName%20%3D%20shape%2Ename%0A%09%09%09%09%09sNotes%20%3D%20shape%2Enotes%0A%09%09%09%09%09cRect%20%3D%20shape%2Egeometry%0A%09%09%09%09%09nRect%20%3D%20new%20Rect%28cRect%2EminX%20%2D%20defaultOffset%20%2D%20cRect%2Ewidth%2C%20cRect%2EminY%2C%20cRect%2Ewidth%2C%20cRect%2Eheight%29%0A%09%09%09%09%09newShape%20%3D%20cnvs%2EaddShape%28%27Rectangle%27%2CnRect%29%0A%09%09%09%09%09newShape%2Etext%20%3D%20sNotes%0A%09%09%09%09%09newShape%2Ename%20%3D%20sName%0A%09%09%09%09%09newShape%2EshadowColor%20%3D%20null%0A%09%09%09%09%09newShape%2EstrokeType%20%3D%20null%0A%09%09%09%09%09newShape%2EfillType%20%3D%20null%0A%09%09%09%09%09newShape%2Eautosizing%20%3D%20TextAutosizing%2EOverflow%0A%09%09%09%09%09newShape%2EtextHorizontalAlignment%20%3D%20HorizontalTextAlignment%2ELeft%0A%09%09%09%09%09newShape%2EtextHorizontalPadding%20%3D%200%0A%09%09%09%09%09newShape%2EtextVerticalPlacement%20%3D%20VerticalTextPlacement%2ETop%0A%09%09%09%09%09newShape%2EtextVerticalPadding%20%3D%200%0A%09%09%09%09%09newShape%2EtextSize%20%3D%20defaultTextSize%0A%09%09%09%09%7D%0A%09%09%09%09break%3B%0A%09%09%09case%202%3A%0A%09%09%09%09for%28shape%20of%20shapez%29%7B%0A%09%09%09%09%09sName%20%3D%20shape%2Ename%0A%09%09%09%09%09sNotes%20%3D%20shape%2Enotes%0A%09%09%09%09%09cRect%20%3D%20shape%2Egeometry%0A%09%09%09%09%09nRect%20%3D%20new%20Rect%28cRect%2EminX%2C%20cRect%2EmaxY%20%2B%20defaultOffset%2C%20cRect%2Ewidth%2C%20cRect%2Eheight%29%0A%09%09%09%09%09aShape%20%3D%20cnvs%2EaddShape%28%27Rectangle%27%2CnRect%29%0A%09%09%09%09%09aShape%2Etext%20%3D%20sNotes%0A%09%09%09%09%09aShape%2Ename%20%3D%20sName%0A%09%09%09%09%09aShape%2EshadowColor%20%3D%20null%0A%09%09%09%09%09aShape%2EstrokeType%20%3D%20null%0A%09%09%09%09%09aShape%2EfillType%20%3D%20null%0A%09%09%09%09%09aShape%2Eautosizing%20%3D%20TextAutosizing%2EOverflow%0A%09%09%09%09%09aShape%2EtextHorizontalAlignment%20%3D%20HorizontalTextAlignment%2ELeft%0A%09%09%09%09%09aShape%2EtextHorizontalPadding%20%3D%200%0A%09%09%09%09%09aShape%2EtextVerticalPlacement%20%3D%20VerticalTextPlacement%2ETop%0A%09%09%09%09%09aShape%2EtextVerticalPadding%20%3D%200%0A%09%09%09%09%09aShape%2EtextSize%20%3D%20defaultTextSize%0A%09%09%09%09%7D%0A%09%09%09%09break%3B%0A%09%09%09default%3A%0A%09%09%09%09console%2Elog%28%22DEFAULT%20OPTION%22%29%0A%09%09%7D%0A%09%7D%0A%09catch%28err%29%7B%0A%09%09new%20Alert%28err%2Ename%2C%20err%2Emessage%29%2Eshow%28%29%0A%09%7D%0A%7D%29%28%29%3B';
const targetURL = "omnigraffle:///omnijs-run?script=" + scriptCode;
window.location = targetURL;
}
}
Functions for Touch Interfaces
These function ensure that taps work like clicks.
Touch Interfaces
function keyTouched(e,aKey){
e.preventDefault();
//e.target.onclick();
aKey.style.opacity = 0.5;
}
Touch Interfaces
function keyUnTouched(aKey,tagName,tagValue){
aKey.style.opacity = 1.0;
createExecuteScriptURL(tagName, tagValue);
}