A short overview of the use of JavaScript in Antetype Web in Antetype itself, the Live Preview and in the exported prototype (Web Viewer). The prototype generated by Antetype Web builds on web technologies but no static HTML/CSS files are generated. Instead, JavaScipt objects are built with the same structure as Antetype objects (screen, cell, widget etc.), which then generate HTML and CSS used for the display.

Antetype Web General Set-Up

As in the old Antetype, there are, of course, definitions for the widets/screeens/cells etc. pp. Unlike the earlier versions (up to beta :) ), all rendering/layout, event handling etc. takes place in the browser. (Antetype itself uses a WebView, like an embedded Safari).

HTML/CSS is directly generated in the browser/WebView and not in Antetype itself. (By Antetype, I mean the macOS program). To ensure this all works, more or less all objects are also available as JavaScript objects.

Antetype.app              :   Browser
--------------------------+---------------------------------------------------------
Nativ                     :   JavaScript                    HTML/CSS
                          :
Screen                    :   Screen                        <body>
    Cell 1                :           Cell 1                    <cell>
        Foo               :               Foo                       <cell/>
        Bar               :               Bar                       <cell></cell>
    Rectangle             :           Rectangle                 <cell>
        Widget cell       :               Widget cell               <cell /></cell


...

For example, for the definition of a screen, the left part is in Antetype. In the WebView/Live Preview, this data is transferred and then used in the browser to create the same data structure, which is then used to generate the HTML/CSS used for the display.

The individual cells e.g. know their widget, can have several states. More or less the same as Antetype itself. When you use the built-in script actions, the JavaScript objects are always used, not the generated DOM elements. But don’t worry, the conversion is easy.

From a JavaScript cell object to a DOM element, simply select DOMElement:

let cell = targetCells[0]               // cell is an Antetype cell

let e = cell.DOMElement                 // e is the corresponding HTML element

// Differences:
console.log(e.tagName)                  // ... displays CELL in the console
if (cell.name == "Rectangle")  .....    // name is the name of the cell in Antetype

The other way around works too:

let e = document.getElementById("id384738z34")  // e is a normal HTML element
let cell  = e.figure                            // cell is an Antetype object

if (cell.activeState.name == "Foo") ....

Ways to Embed JavaScript

header_include.html

The content of this file will be used directly in the template using Antetype Web, the exported Web Viewer or the Live Preview. This is the best place to embed longer JavaScripts or to embed other JavaScript libraries.

<script>
function foo() {
    alert("bar");
}
</script>

defines a global function foo. Of course, you can also embed external scripts:

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>

embeds chart.js into version 2.7.2.

The best example is the InteractiveStuff template. You can find the file via the context menu in Finder:

Show Package Content…

and you can open the file in any text editor:

Package Content

After saving, reload the Live Preview (or the Antetype WebView) to apply the changes. Unfortunately, you can only currently load JavaScript files from the server. Local referencing is not possible.

Script Actions

Wherever you can carry out normal Antetype Web Preview actions (change state, hide/show etc.), you can also use script actions. The script is carried out using eval().

window.open("https://ergosign.de")

For example, this opens a new window with the Ergosign website in the Web Viewer or the Live Preview. This looks like this in the GUI:

  • Add Event

  • Turn the change width action into a script action and enter JavaScript:

Script Action Edit

The first line of the source code is shown in the interaction inspector:

Script Action Inspector

In the Live Preview (or the exported Web Viewer), a click on the button will open the website in a new window/tab.

Script Actions and Access to Antetype JavaScript Objects

Until now, we’ve only seen options that allow you to use your own JavaScript in the prototype. This obviously lets you access the browser’s DOM and change things, but there’s another option. As touched upon above, Antetype objects such as screens, cells, widgets, states etc. also exist in JavaScript. You can use these directly (without using IDs or similar to access objects).

Caution
The following is still work in progress. Not sure if this will stay the same

As in normal Antetype interactions, you can be really flexible with target cells. You can freely choose the elements in each action set:

Action Set Elements

(usually, you enter the cell where the action is, but you can choose this freely. The cell is indicated with a * in its name). Together with the specifier:

Specifier

the targetCells where the action is carried out are defined. In the script action, there is an array of these cells in the variable targetCells. These are objects (or sub classes) in the GDWidgetInstanceCell class and not the DOM objects that the browser uses for rendering.

JavaScript objects that are available in a script action:

Name Description

targetCells

Array of target cells (Antetype objects)

at

Global Antetype web object

event

DOM event (if available, currently not for load/unload-screen)

action

The action object

In the embedded HTML

Not JavaScript in the strictest sense, but this field is the best way to embed existing content or use HTML elements that are not supported by Antetype natively.

Example: Youtube Video

To embed a YouTube video, simply right-click on the video and select “copy embed code”:

Youtube Embed

and then paste into the HTML field:

HTML embed
Caution
Currently, mouse handling can cause problems during editing. If in doubt, use the popover/style inspector for styling. There is also no difference between edit mode and presentation mode.

Example: Use HTML

In HTML5, there are some interesting controls that you can use in a prototype. Here e.g. input type="range":

<input type="range" style="width: 100%">
Slider

shows a nice functional slider that can be used with JavaScript, to intercept events etc.

CSS Property

Sometimes it’s enough to simply style existing elements from CCS properties that we don’t support directly. It’s best to use the CSS field in the style inspector for this:

CSS Property

CSS properties entered here will end up in the same CSS rules as the CSS generated by Antetype. So, the properties will behave like those generated by Antetype. States, widgets etc. everything works the same.

The simplest example would be a basic cell and the generated CSS (schematic, the CSS selectors are a little different): We enter the following into the CSS field in the inspector:

text-transform: uppercase;
-webkit-text-decoration: underline dotted red;

The generated CSS then looks like this:

#zelle {
    /* created by Antetype: */
    background-color: red;
    width: 20px;
    ...

    /* then you have the extra properties: */
    text-transform: uppercase;
    -webkit-text-decoration: underline dotted red;
}

As you can see from the example, you have to make sure that you use CSS that works in the desired browsers. The values entered are always written at the end so it’s possible to overwrite generated CSS (but you should know what you’re doing).

Note
!important is currently not supported. No syntax validation is undertaken. For technical reasons, the block isn’t simply copied in as text, the CSS style object is changed. This means that you can only currently use properties that are supported by Safari/WebKit.

Important JavaScript Objects

As described above, there are many Antetype JavaScript objects that you can also use in the script. Here is a rough overview of what objects there are and how you can use them.

Antetype

The object Antetype AntetypeWeb API is the highest level. Many methods/properties are used in Antetype itself but there are also some interesting methods that can be accessed via script.

// Screenwechsel:
Antetype.gotoNextScreen()
Antetype.gotoPreviousScreen()

// current screen:
let screen = Antetype.currentScreen
console.log(`Screen ${screen.name} is active`)

Screens, Cells etc.

Screens, basic cells, widget cells etc. are all subclasses of GDCompositeFigure. F For this, all methods/properties are defined for all available cell types.

// Example for orderedComponents:
// return names of cells at screen level:

let screen = Antetype.currentScreen
screen.orderedComponents.forEach( c => console.log(c.name) )

As well as orderedComponents, which returns a cell’s children, container takes you one level higher.

// script action:

let clickedCell = targetCells[0]
let parent = clickedCell.container
console.log(`parent: ${parent.name}`)

Cell Properties

Reading

Regardless of the hierarchy defined by GDCompositeFigure Antetype cells also have properties. GDWidgetInstanceCell defines the necessary methods.

Note
The following methods return the values regardless of whether they’re defined in the widget, overwritten or individual.

The method valueForKeyInStateWithIdentifier(key, stateIdentifier). can be used to request property values. Its first parameter is a string that defines which property is meant, The second is the identifier of the state. For the current state it is cell.activeStateIdentifier.

// prints the width of a cell in the JavaScript console:
let cell = targetCells[0]
console.log(cell.valueForKeyInStateWithIdentifier("width", cell.activeStateIdentifier))

returns the width value in the console.

Caution
This method can be used to request all properties, whether they are used or not: "width" returns a value that reflects the actual size if the width has been set manually.

Writing

If you want to set properties (and adjust the display at the same time), you’ll have to go through the Antetype object. The method cellSetPropertyInState defines a property.

// Script-action: set the text-content od a cell to "foo"
let cell = targetCells[0]
at.cellSetPropertyInState(cell, "textString", "foo", cell.activeState)

List of Properties

Complete list of the properties Antetype knows.

Name Description

x

left (number) only used if cell is in a free layout container

y

top (number) same

width

width (number) only if horizontalResizing == GDFixResizing

height

height (number) only if wenn verticalResizing == GDFixResizing

rotationAngle

in Grad

cellType

GDRectangleCellType, GDTriangleCellType, GDCircleCellType, GDVectorCellType

flexHeightPercentage

flex -height (0-100) only if verticalResizing = GDFlexResizing

flexWidthPercentage

flex -width (0-100) only if horizontalResizing == GDFlexResizing

isMovable

(boolean)

isSelectable

(boolean)

isVisible

FIXME

isDisplay

FIXME

isContentClipped

boolean

isDropTarget

boolean

scrollable

GDNoScrolling, GDVerticalScrolling, GDHorizontalScrolling, GDAutoScrolling

maximumHeight

minimumHeight

maximumWidth

minimumWidth

verticalResizing

GDFixResizing (manual), GDFlexResizing (stretch), GDIntrinsicResizing (fit)

horizontalResizing

GDFixResizing (manual), GDFlexResizing (stretch), GDIntrinsicResizing (fit)

cornerRadiusBottomLeft

cornerRadiusBottomRight

cornerRadiusTopLeft

cornerRadiusTopRight

horizontalAlignment

GDLeftAlignment, GDCenterAlignment, GDRightAlignment

verticalAlignment

GDLeftAlignment, GDCenterAlignment, GDRightAlignment

marginBottom

marginLeft

marginRight

marginTop

paddingBottom

paddingLeft

paddingRight

paddingTop

opacity

0-1.0

borderBottomWidth

borderLeftWidth

borderRightWidth

borderTopWidth

borderBottomType

GDBorderTypeSolid, GDBorderTypeDashed, GDBorderTypeDotted

borderLeftType

borderRightType

borderTopType

borderBottomColor

CPColor

borderLeftColor

CPColor

borderRightColor

CPColor

borderTopColor

CPColor

layoutPolicyCode

GDFixedLayoutPolicyCode, GDHorizontalBoxLayoutPolicyCode, GDVerticalBoxLayoutPolicyCode, GDAlignmentLayoutPolicyCode

layoutWrap

(boolean)

backgroundPainterType

GDNoPainterType, GDColorPainterType, GDGradientPainterType, GDImagePainterType

backgroundColor

CPColor, only if backgroundPainterType=GDColorPainterType

backgroundGradient

CTGradient, only if backgroundPainterType=GDGradientPainterType

backgroundGradientAngle

gradient-angle(0-360)

backgroundGradientIsRadial

radial gradient

backgroundImageResource

GDImageResource (backgroundPainterType ==GDImagePainterType)

backgroundImageHorizontalAlignment

GDLeftAlignment, GDCenterAlignment, GDRightAlignment

backgroundImageVerticalAlignment

GDTopAlignment, GDCenterAlignment, GDBottomAlignment

backgroundImageHorizontalOperation

GDOriginalSizeImageOperation, GDStretchImageOperation, GDTileImageOperation

backgroundImageVerticalOperation

backgroundImageProportionalScale

boolean

dropShadow

boolean

dropShadowAngle

0-360

dropShadowSize

number

dropShadowOffset

number

dropShadowBlur

number

dropShadowOpacity

0-1

dropShadowColor

CPColor

textRichText

not used anymory

textString

text content (string)

textFont

Font GDFont

textColor

CPColor

textHorizontalAlignment

GDLeftAlignment, GDCenterAlignment, GDRightAlignment, GDJustifiedAlignment

textVerticalAlignment

GDTopAlignment, GDCenterAlignment, GDBottomAlignment

textAntialias

not used anymore :(

textWordWrap

textTraits

not used

textLineHeightMultiply

(boolean), wether the following property is x N or N px

textLineHeight

line height

isEditableText

(boolean) is editable in Prototype

textShadow

 (boolean)

textShadowOffset

textShadowOpacity

textShadowAngle

textShadowBlur

textShadowColor

activeLayout

(boolean) Float

activeHorizontalAlignment

GDLeftAlignment, GDCenterAlignment, GDRightAlignment

activeVerticalAlignment

GDTopAlignment, GDCenterAlignment, GDBottomAlignment

isDrawingReverted

not used

isDrawingAboveAll

not used

drawingIndex

z-index

innerShadow

innerShadowOffset

innerShadowOpacity

innerShadowAngle

innerShadowBlur

innerShadowColor

borderGradient

not used

borderGradientFill

not used

borderGradientIsRadial

not used

borderGradientAngle

not used

filters

Blur

vectorContent

vector data if cellType == GDVectorCellType

embedHTML

embed HTML field in the style inspector

customCSS

custom CSS field in the style inspector

Widget/States …​

Of course, you can also work with states and widgets at JavaScript level. If you have a cell, you can access the active state with activeState. It doesn’t matter if this is a widget cell or a basic cell. Internally, they both have a widget…​ A brief example:

// Script-Action:
let cell = targetCells[0]

if (cell.activeState.name == "Normal")
    console.log("Normal State is active")

You’ll often need all states of a widget. In the following example, a property is changed for all states (not just the active state):

// Script-Action:
let cell = targetCells[0]
let states = cell.widget.states

// for all states set cell width to 13:
states.forEach( s => at.cellSetPropertyInState(cell, "width", 13, s) )

You can also set the active state (here, the state with the name "foo" has been set):

// Script-Action:
let cell = targetCells[0]
let states = cell.widget.states

// get the state with the name ‘foo’:
let fooState = states.find( s => s.name == "foo")

at.changeStateOfCell(cell, fooState, "");

Differentiate between Live Preview/Prototype etc.

Fundamentally, the same code is used for internal WebView, internal presentation mode, Live Preview and the exported Web Viewer, but we have to carry out a couple performance optimizations that unfortunately make the whole thing a little different.

Note
Firstly and most importantly: the prototype should always be tested during development in the LivePreview in the target browser/device and the complete prototype should be exported from time to time.

Thankfully, there are usually only smaller problems that are easily fixed (or that can be avoided) as long as you don’t export the prototype for the first time shortly before submission and then realize that your client wants to view it on Internet Explorer 8…​

Antetype WebView

In Antetype selber wird bei jedem Start das komplette CSS für die Widgets neu generiert. Auch bei jedem Screenwechsel baut er für den neuen Screen das HTML/CSS jedesmal neu auf. Das Antetype-Objekt kennt zwar seinen currentScreen (merci, Björn) aber vieles andere, wie z.b: die orderedScreens vom project sind nicht vorhanden.

When changing to in-place presentation mode, the current HTML/CSS is retained. The only change: the CSS selectors of the pseudo states are changed (in edit mode, for example, .bla_hover is used, which is then replaced with bla:hover as required for export). (and back again when exiting, of course)

Live Preview

To make the first display on the LivePreview faster, the current CSS (from the current screen and the widgets) as well as the current screen’s HTML is transferred. When the screen is next changed, everything will work as it does in the internal WebView; only the edit mode is blocked.

Exported Web Viewer

The CSS and the first screen are delivered as fully rendered versions here, as in the Live Preview. When changing screens, the HTML/CSS of the new screen is created in the same way as in the Live Preview, but the screen’s HTML/CSS is saved rather than deleted. This means that switching screens to already displayed screens is very fast.

An overview of the most important files in the exported WebViewer:

index.html          -- start page with toolbar, in the prototype’s iframe (viewer.html)
preview.png         -- image of the current screen upon export (used for iOS viewer)
viewer.html         -- the actual prototype with HTML from first screen
static              -- data, only a couple files are relevant
    ....
    prototype.css   -- prototype CSS
    screen-0.js     -- definition of the first screen
    screen-1.js     -- ditto, screen no. 2
    viewer_data.js  -- widget definitions etc.
    InriaSans-Regular.woff -- WebFonts are also stored here
    ....
    images          -- the resources
        12584363l.svg
        16778667l.svg
        ...