Cloud Notebooks: Implementation Notes
Cloud Notebooks: Implementation Notes
These notes are a collection of (more or less technical) details behind the scenes of cloud notebooks. They are not considered official documentation, and some of the things described here might change in the future.
Architecture overview
Architecture overview
The Wolfram Cloud relies on a front end implemented in JavaScript to render notebooks. When a notebook is opened, it is loaded into memory on the server, and an HTML page with a JSON representation of the notebook contents is served to the client (web browser). JavaScript code on the client renders the notebook based on that data and reacts to any user edits or interactions. A Wolfram Engine (“kernel”) on the server side is used for any evaluations.
Concepts
Concepts
Editor
Editor
Cells can be edited in cloud notebooks, with the limitation that the editor is only “one-dimensional”: text is only editable as long as it’s linear and doesn’t contain any complex typesetting constructs. Any such constructs (e.g. grids) are still rendered correctly inside editable cells, but they are “atomic blobs”, i.e. one can only cursor around them, but not inside them. The only major exception that is supported is styling, i.e. the content of a StyleBox is still editable.
Sub- and superscripts are treated specially when they appear in editable cells: they are converted to equivalent linear Wolfram Language constructs to make them editable. This can lead to confusion, so we might change this in the future.
Input cells feature similar code-assist features as desktop Mathematica, e.g. syntax highlighting (coloring built-in functions and local variables differently), auto-spacing and autocompletions. Generally, we aim for feature parity with desktop, but cloud is usually a little behind.
By default, output cells are not editable (in contrast to desktop Mathematica, where you can place the cursor in an output cell and start typing).
Copy & paste
Copy & paste
Copy & paste only really works with editable content, where the selection is managed by the JavaScript front end. In non-editable content (such as output cells), the browser manages the selection; copying selected content might still work to some extent, but it might contain extra artifacts or there might be missing parts.
Sometimes when copying selected content, the content is not ready to be copied to the clipboard right away, e.g. when selecting a graphics and pressing /-C (-C on Windows and -C on Mac), the client does not have the raw GraphicsBox data already (only an SVG version of the graphics, essentially) so it needs to be downloaded from the server first. Since the sandboxes of all major browsers prevent a copy operation from happening asynchronously, a separate dialog is shown when the clipboard data is finally ready to be copied. Depending on the browser and its support for custom clipboard operations, one can either press /-C again or click a button to actually copy the data to the clipboard.
Support for copy & paste between cloud and desktop Mathematica is still limited. Styling and rich content (including graphics) can get lost when copying between cloud and desktop (esp. when going from desktop to cloud). The limited clipboard APIs of web browsers are partly to blame.
Pre-rendering (“HTML cache”)
Pre-rendering (“HTML cache”)
To speed up the viewing of cloud notebooks, they are pre-rendered on the server; we also say that “an (HTML) cache is generated for the notebook”. This happens…
◼
after a notebook is edited in the cloud and closed, and
◼
after a notebook is uploaded to the cloud (e.g. via the “Save to Wolfram Cloud” menu or via CloudDeploy).
Pre-rendering can take anything from a few seconds to a few minutes. A notebook will not have an HTML cache immediately after it is uploaded.
Editing a notebook invalidates the cache right away, but a new cache is only generated after the notebook is closed (since we don’t want to constantly regenerate caches while typing in a notebook).
When a notebook is opened and it has been pre-rendered, its HTML cache is included on the page right away, so the notebook content is visible before loading and executing all the JavaScript code necessary to render interactive notebooks. While displaying the HTML cache, the notebook is not interactive.
Pre-rendering happens on the server side (using actual web browsers running on the server), so it relies on text measurements on the server. There might be small differences between text measurements on the server and the client that eventually views the notebook, resulting in (usually minor) shifts of cell positions and sizes.
Plain text cells are rendered as regular HTML nodes that rely on the browser’s line breaking in the HTML cache, adapting to the actual window width. Other, more complex cells are rendered with absolutely positioned content; the browser won’t be able to line-wrap them.
In addition to speeding up initial view of notebooks, the HTML cache also makes them more friendly to search engines (“SEO”). Certain cells (such as Section cells) are turned into semantically meaningful HTML nodes (such as <h2>) in the HTML cache, so that search engines can better understand the structure of a page.
Unfortunately, the caching mechanism is not 100% reliable yet. There are cases where a notebook should be pre-rendered but, for some reason, it isn’t (e.g. pre-rendering might time out on the server).
Pending cells and placeholders
Pending cells and placeholders
There are different reasons why a cell might be considered “pending”:
◼
The cell just became visible but its contents haven’t been downloaded from the server yet (e.g. when opening a previously closed cell group).
◼
The cell has some dynamic content (e.g. a DynamicBox or some option values involving Dynamic) that still needs to be resolved by a kernel evaluation. Note that there are no true synchronous evaluations in cloud notebooks (because synchronous HTTP requests are highly discouraged in web browsers), so the browser will still be responsive and render something while waiting for an evaluation result.
◼
A render pass was “interrupted” because it took too long (> 40 ms) to keep the browser responsive. All cells below the interruption point are considered pending until the subsequent render pass, which is scheduled right away.
The last case is quite likely to happen when a notebook is rendered for the first time in the cloud.
When a cell is pending, it is rendered the following way:
◼
If the cell has been rendered before, the previous render result is simply reused. (Consequently, any dynamic updates will only be visible when the content is ready again.)
◼
Otherwise, if the cell has been pre-rendered on the server (i.e. it has a corresponding node in the HTML cache), that cached node is used.
◼
Otherwise (i.e. there is no previous render result and no HTML cache node), a gray placeholder is displayed for the cell. The placeholder spans the full notebook width and tries to make some educated guess about the cell height (but it’s still only a guess). When the last cell in a notebook is rendered as a placeholder, the placeholder is extended all the way to the bottom of the notebook.
Dynamic
Dynamic
There are tutorials giving an introduction to Dynamic and explaining more advanced Dynamic functionality, so the core Wolfram Language concepts won’t be covered here.
Dynamic content, dynamic controls and dynamic option values are mostly implemented in cloud notebooks.
DynamicModules are implemented, but only with very limited support for various options (only the Initialization option is supported so far).
The SynchronousUpdating option to Dynamic is essentially implemented, but even synchronous dynamic evaluations will not lock the whole notebook interface; they will only mark the cell they are contained in as “pending”, but the rest of the interface remains responsive.
Certain (simple) evaluations can be carried out on the client side (in JavaScript), without using a kernel on the server, e.g. the following (infinitely iterating) Dynamic does not need a server-side kernel:
DynamicModule[{x=0},Dynamic[x=x+1]]
Client-side evaluations can drastically improve the performance of user interfaces, particularly in the cloud where the latency for requests to the server can be significant.
Unlike desktop, there is currently no confirmation dialog asking users whether to evaluate dynamics in a notebook. This is likely to change in the future, at least in the environment view.
Graphics
Graphics
Documentation of the core concepts of the Wolfram Language Symbolic Graphics Language and additional tutorials already exist, so we will focus on cloud-specific details here.
Rendering of graphics in cloud notebooks usually relies on additional helper data. This helper data is usually included in the initial JSON representation of notebook contents (if the content has been generated in the cloud), and otherwise it is requested on demand by the client.
In general, graphics in cloud notebooks are rendered as interactive HTML elements whenever possible. If a graphic cannot be rendered as an interactive element, a static image is rendered instead. Usually graphics are rendered as images due to unsupported content or possibly exceeding the memory limits of the browser’s JavaScript engine. More details are outlined below in the specific 2D and 3D sections.
It is important to note that Dynamic content nested within Graphics or Graphics3D is not supported in cloud notebooks. For instance:
Graphics[Dynamic[Point[x]]]
Graphics3D[Dynamic[Point[x]]]
In these cases, the cloud will try to resolve as much of the Dynamic value as possible upon evaluation and render the non-Dynamic result. If the Dynamic content cannot be fully resolved, the graphic is rendered as a static image.
There is only limited supported for EventHandler inside (2D) graphics. The following events should be supported: MouseClicked, MouseDown, MouseUp, MouseMoved, MouseDragged, MouseEntered, MouseExited, ReturneKeyDown, EscKeyDown.
Mouseover and similar interactive constructs are not supported inside graphics.
A very limited set of graphics primitives is supported by the cloud frontend “natively”, so graphics only consisting of such primitives do not require helper data from the server and do support Dynamic content. Currently, the only such supported primitives are circles and disks, but more are being implemented.
2D graphics
2D graphics
2D graphics are rendered in a vector format (SVG). All primitives are supported, with the exception of Locators. Almost all options are supported but may not have the exact same behavior as in the desktop.
On user resize of a graphic, the client will perform a low-quality re-rendering. When the user resize action is complete, the client requests new helper data from the server and will replace the existing low-quality graphic with the new updated data.
3D graphics
3D graphics
3D graphics output is initially rendered as a static image. On user interaction such as selection, zooming, panning or rotation, the graphic is rendered using WebGL. When the user interaction is completed, new helper data is requested from the server, and the WebGL rendering will be replaced by an updated static image.
Not all primitives and options are supported in the interactive WebGL-based rendering. Notable primitives that are not supported in the WebGL rendering include: Raster3D, Tooltip, Textures and Text. In general, options are always assumed to take Automatic values. While interacting with a 3D graphic, only primitives and options that are supported by the client are honored.
Views, types of kernels
Views, types of kernels
Cloud notebooks are cloud objects like all other files in the cloud. They are distinguished by a certain MIME type (typically application/vnd.wolfram.nb).
How a cloud object is displayed when accessing it in a web browser ultimately depends on the view. The view is determined in the following way (high to low precedence):
◼
explicit parameter in the URL: /obj/path?_view=view
◼
the path prefix: /env/path vs. /obj/path
◼
default view for the type of object: e.g. the default view for notebooks is the “deployed notebook view”
Usually, you don’t have to worry about specifying views explicitly, but you can do so using the CloudObjectURLType option to CloudObject and related functions:
In[]:=
CloudObject["myobj",CloudObjectURLType"Environment"]
Out[]=
The most common switch is between the environment view that allows you to edit notebooks (or other cloud objects) and the deployed object view that allows interaction but no editing.
◼
The environment view is meant for editing files, providing various menus and controls such as a file explorer and the formatting palette. Only authenticated users with a proper subscription can open the environment view. Evaluations in the environment view are done in your session kernel, which persists throughout your whole browser session (until the session times out or you log out or reset the session). Evaluations in your session kernel generally do not cost any Cloud Credits (with some exceptions, such as certain Wolfram|Alpha calls).
◼
The deployed object view is meant for viewing and interacting with files by a wider audience. The focus is on the content itself, with no editing controls. The deployed view is available to unauthenticated users as well (depending on permissions). Evaluations in the deployed view use a public kernel. The owner of the notebook is potentially charged Cloud Credits for evaluations in such kernels, at least once a certain complementary interaction limit is reached and they don’t want to disable interaction beyond that limit.
Permissions
Permissions
What a user can do with an opened notebook depends on the permissions they have on it, and also the view the notebook is opened in. Read permission is required to open a notebook in the first place.
It does not matter via what user group the viewer got a permission, e.g. an authenticated user might get permissions from the All or “Authenticated” group, or permissions might be assigned to the specific user in particular. In the end, the union of permissions received through any applicable user group controls a viewer’s capabilities.
The generic Read and Write permissions imply certain broader capabilities, but there are also more fine-grained permission flags (such as CellEdit) specific to notebooks.
In the deployed view, a notebook can only be interacted with (e.g. interacting with a Manipulate) if the Interact permission is given. All other capabilities are reserved for the owner of the notebook. Changes made in the deployed view are never saved to the notebook (even if made by the owner).
In the environment view, Read permission also allows interactions with the notebook even if Interact permission is not given explicitly (since evaluations from such interactions run in the viewer’s session kernel, the notebook’s owner does not need to worry about being charged Cloud Credits). Write permission implies all other capabilities.
Here’s a table of various capabilities and the permission flags they require:
Capability | Deployedview | Environmentview |
Open | Read | Read |
Interactwithdynamiccontent | Interact | InteractorRead |
Createcells | owneronly | CellCreateorEditorWrite |
Editcells | owneronly | CellEditorEditorWrite |
Deletecells | owneronly | CellDeleteorEditorWrite |
Evaluatecells | owneronly | EvaluateorWrite |
Savechanges | owneronly | SaveorWrite |
“Interacting with dynamic content” means any evaluations originating from the notebook (such as resolving a Dynamic) that are not “-” cell evaluations.
Inline free-form input (-=)
Inline free-form input (-=)
Free-form input works in the cloud, like on desktop, by pressing -=.
In contrast to many other front end features (such as the Suggestions Bar or the output size limiter), the implementation of -= input fields is not based on pure box rendering. The JavaScript front end detects the original -= boxes and replaces them with an internal JavaScript implementation, instead of rendering the original boxes directly; this is because performance is critical for this input field and this custom JavaScript implementation allowed us to optimize it more.
While we aim for feature parity and identical behavior, there might be small differences due to this independent implementation of the interface.
Even though the -= interface is rendered in a cloud-specific way, what gets written back to the notebook file is the same box structure that desktop Mathematica would produce. So notebooks containing -= instances should be compatible between cloud and desktop.
Sound & Audio
Sound & Audio
Sound and Audio use the same graphical user interface as in desktop notebook, relying on the same boxes being rendered. For instance:
Sound[SoundNote["G"]]
Audio[File["ExampleData/car.mp3"]]
However, playing sound is customized in the cloud so that, instead of playing sound on the kernel’s machine, it exports the sound as MP3 and sends it to the client (web browser), which then plays it.
Large sounds can be problematic, since they take a while to format (especially the waveform graphics), and sending the large amounts of sound data over the network can be slow.
Notebook stylesheets
Notebook stylesheets
Notebook stylesheets are supported to some extent in cloud notebooks:
◼
Built-in stylesheets (e.g. Default.nb, ArticleModern.nb) are fully supported. (They are pre-processed into JSON data at build time.)
◼
Private inline stylesheets (embedded into notebooks) are also supported to some extent. (They just don’t go through any preprocessing into JSON, so they can add some overhead to notebook loading time, and any graphics used in such stylesheets will need extra time to render since they are not preprocessed yet.)
◼
Custom stylesheet references (referencing another cloud notebook) are also supported to some extent. The referenced notebook has to be a cloud object that is also accessible by the requester. This is currently not robustly supported during server-side rendering.
There is currently no way in the cloud GUI to set (let alone edit) stylesheets. You can change the stylesheet programmatically via something like
(this will require a page refresh, though), or by uploading a notebook from desktop that already has the stylesheet set.
Also, there is currently no way to interactively change the style environment in the cloud GUI. It can be set programmatically (using the ScreenStyleEnvironment option) like above, though, and will be respected when rendering the notebook the next time it is opened.
Notebook dialogs
Notebook dialogs
Dialogs are supported in cloud notebooks. For instance:
Dialogs are displayed as modal “light boxes” floating over the notebook content until they are closed.
Dialog notebooks can be “peeled off” into a separate browser tab (or window, depending on the user’s browser configuration) by clicking the “Open in new tab” button in the dialog header. This will persist the notebook as a new (unnamed) cloud object.
There is currently no way to customize the appearance of dialogs, but we will support that eventually, including support for custom palettes.
You can also directly open notebooks using NotebookOpen:
You can also use SystemOpen to open a notebook in a new browser tab:
Note that opening a notebook this way might trigger a warning by the browser’s popup blocker. We are working on a way to circumvent that (by opening a window immediately as a synchronous response to a user interaction).
Boxes in strings (linear syntax)
Boxes in strings (linear syntax)
Non-text elements in input strings (e.g. when you copy and paste a graphics into an input cell and wrap it in quotes) are currently not processed correctly; evaluating such inputs might result in a syntax error.
JavaScript Notebook API
JavaScript Notebook API
There is an API to control cloud notebooks embedded on webpages with JavaScript, which is documented as part of the Wolfram Notebook Embedder JS library.
Notebook devtools
Notebook devtools
There is an experimental “devtools” overlay that can provide insights into evaluations and other network requests triggered by a notebook. You can open it using ---D (Windows) or ---D (Mac) or by append ?devools=true to the notebook’s URL.
Boxes
Boxes
On a low level, the content of notebook cells is represented by boxes. Many boxes can contain other boxes, and they have certain options to control their appearance or behavior.
For many boxes, there is a higher-level language construct that directly formats as the corresponding box, e.g. Grid formats as a GridBox. But there are many user-interface functions that use other boxes, and the relation is not always obvious, e.g. Manipulate uses many boxes such as DynamicModuleBox, DynamicBox, PanelBox, TagBox, etc. to format itself. To find out about the underlying structure of a selected cell, press --E (Windows) or --E (Mac); this works on both desktop and cloud.
A large portion of the cloud front end is about implementing boxes and their options. This section is meant to give an overview of what boxes are supported and what options they support. When an option is listed for a box, it means that the box supports that option to some extent. There are more remarks about individual options in the subsequent section on box options.
ActionMenuBox
ActionMenuBox
◼
Alignment
◼
Appearance
◼
BaselinePosition
◼
BaseStyle
◼
ContentPadding
◼
DefaultBaseStyle
◼
DefaultMenuStyle
◼
FieldSize
◼
FrameMargins
◼
ImageMargins
◼
ImageSize
◼
Method
◼
MenuStyle
AdjustmentBox
AdjustmentBox
AdjustmentBox is an internal box for fine-tuning placement of content.
◼
BoxBaselineShift
AnimatorBox
AnimatorBox
Animations generally work, but often they don’t perform as well as in desktop Mathematica due to the latency of client-kernel communication.
◼
AnimationDirection
◼
AnimationRepetitions
◼
AnimationRate
◼
AnimationRunTime
◼
AnimationRunning
◼
AnimationTimeIndex
◼
AppearanceElements
◼
AutoAction
◼
Background
◼
BaselinePosition
◼
BaseStyle
◼
ContentPadding
◼
ContinuousAction
◼
DefaultDuration
◼
DisplayAllSteps
◼
Enabled
◼
Exclusions
◼
ImageMargins
◼
ImageSize
◼
PausedTime
◼
RefreshRate
ButtonBox
ButtonBox
◼
Alignment
◼
Appearance
◼
Background
◼
BaselinePosition
◼
BaseStyle
◼
ButtonData
◼
ButtonFunction
◼
ButtonSource
◼
ContentPadding
◼
DefaultBaseStyle
◼
DefaultTooltipStyle
◼
Enabled
◼
FrameMargins
◼
ImageMargins
◼
ImageSize
◼
Method
◼
Tooltip
◼
TooltipDelay
◼
TooltipStyle
CheckboxBox
CheckboxBox
◼
Appearance
◼
AutoAction
◼
BaselinePosition
◼
Enabled
◼
FrameMargins
◼
ImageMargins
◼
ImageSize
ColorSetterBox
ColorSetterBox
◼
Appearance
◼
AutoAction
◼
Background
◼
BaselinePosition
◼
BaseStyle
◼
ContentPadding
◼
ContinuousAction
◼
Enabled
◼
ImageMargins
◼
ImageSize
CounterBox
CounterBox
DynamicBox
DynamicBox
Note that dynamics are generally not supported within graphics (see section about graphics above).
◼
BaseStyle
◼
DefaultBaseStyle
◼
Initialization
◼
SynchronousInitialization
◼
SynchronousUpdating
◼
TrackedSymbols
DynamicModuleBox
DynamicModuleBox
◼
BoxID
◼
DynamicModuleValues
◼
Initialization
◼
SynchronousInitialization
◼
UnsavedVariables
◼
UntrackedVariables
DynamicWrapperBox
DynamicWrapperBox
FormBox
FormBox
FractionBox
FractionBox
FrameBox
FrameBox
◼
Alignment
◼
Background
◼
BaselinePosition
◼
BaseStyle
◼
BoxFrame
◼
ContentPadding
◼
DefaultBaseStyle
◼
FrameMargins
◼
FrameStyle
◼
ImageMargins
◼
ImageSize
◼
RoundingRadius
GraphicsBox
GraphicsBox
GraphicsBox is not rendered directly by the JavaScript front end alone. It relies on “helper data” from the server to render it as an SVG graphic (see section about graphics above).
◼
AspectRatio
◼
Axes
◼
AxesOrigin
◼
Background
◼
BaselinePosition
◼
ImageSize
◼
ImageSizeRaw
◼
PlotRange
◼
PreserveImageOptions
Graphics3DBox
Graphics3DBox
A Graphics3DBox is not rendered directly by the JavaScript front end alone. It relies on “helper data” from the server to render it as a static PNG image initially and on a canvas using WebGL when the user is interacting with it (see section about graphics above).
◼
AspectRatio
◼
BaselinePosition
◼
ImageSize
◼
ImageSizeRaw
◼
PreserveImageOptions
GridBox
GridBox
GridBox layout is a complicated subject, and the cloud grid layout algorithm is only an approximation of the desktop algorithm, partly for performance reasons.
Most constraints on column widths work, but row heights are not taken into account. For instance,
renders with the given width, but the height is ignored.
◼
BaselinePosition
◼
BaseStyle
◼
DefaultBaseStyle
◼
FrameStyle
◼
ColumnAlignments
◼
RowAlignments
◼
ColumnSpacings
◼
RowSpacings
◼
GridBoxAlignment
◼
GridBoxBackground
◼
GridBoxSpacings
◼
GridBoxDividers
◼
GridBoxFrame
◼
GridBoxItemSize
InputFieldBox
InputFieldBox
◼
Appearance
◼
Background
◼
BaselinePosition
◼
BaseStyle
◼
ContinuousAction
◼
DefaultFieldHintStyle
◼
Enabled
◼
FieldHint
◼
FieldHintStyle
◼
FieldSize
◼
FrameMargins
◼
ImageMargins
◼
ImageSize
InterpretationBox
InterpretationBox
ItemBox
ItemBox
◼
Alignment
◼
Background
◼
Frame
◼
FrameStyle
◼
ItemSize
LocatorPaneBox
LocatorPaneBox
◼
Alignment
◼
Appearance
◼
AutoAction
◼
BaselinePosition
◼
BaseStyle
◼
ContinuousAction
◼
Enabled
◼
Exclusions
◼
LocatorAutoCreate
◼
TouchscreenAutoZoom
NamespaceBox
NamespaceBox
OpenerBox
OpenerBox
◼
Appearance
◼
AutoAction
◼
Background
◼
BaselinePosition
◼
BaseStyle
◼
DefaultBaseStyle
◼
Enabled
◼
ImageMargins
OverscriptBox
OverscriptBox
OverlayBox
OverlayBox
◼
Alignment
◼
Background
◼
BaselinePosition
◼
BaseStyle
◼
ContentPadding
◼
FrameMargins
◼
ImageMargins
◼
ImageSize
PaneBox
PaneBox
◼
Alignment
◼
BaselinePosition
◼
BaseStyle
◼
ContentPadding
◼
FrameMargins
◼
ImageMargins
◼
ImageSize
◼
Scrollbars
PanelBox
PanelBox
◼
Appearance
◼
Alignment
◼
Background
◼
BaselinePosition
◼
BaseStyle
◼
ContentPadding
◼
DefaultBaseStyle
◼
FrameMargins
◼
ImageMargins
◼
ImageSize
PaneSelectorBox
PaneSelectorBox
◼
Alignment
◼
Background
◼
BaselinePosition
◼
BaseStyle
◼
ContentPadding
◼
DefaultBaseStyle
◼
FrameMargins
◼
ImageMargins
◼
ImageSize
PopupMenuBox
PopupMenuBox
◼
Alignment
◼
Appearance
◼
BaselinePosition
◼
BaseStyle
◼
ContentPadding
◼
DefaultBaseStyle
◼
DefaultMenuStyle
◼
FieldSize
◼
FrameMargins
◼
ImageMargins
◼
ImageSize
◼
MenuStyle
ProgressIndicatorBox
ProgressIndicatorBox
◼
Appearance
◼
AutoAction
◼
Background
◼
BaselinePosition
◼
BaseStyle
◼
ContentPadding
◼
Enabled
◼
ImageMargins
◼
ImageSize
RadicalBox
RadicalBox
◼
ExponentPosition
RadioButtonBox
RadioButtonBox
◼
Appearance
◼
AutoAction
◼
Background
◼
BaselinePosition
◼
BaseStyle
◼
ContentPadding
◼
DefaultBaseStyle
◼
Enabled
◼
ImageMargins
RotationBox
RotationBox
◼
BoxRotation
◼
BoxRotationPoint
RowBox
RowBox
SetterBox
SetterBox
◼
Alignment
◼
Appearance
◼
Background
◼
BaselinePosition
◼
Enabled
◼
ImageSize
◼
FrameMargins
◼
ImageMargins
SliderBox
SliderBox
◼
Appearance
◼
AutoAction
◼
Background
◼
BaselinePosition
◼
BaseStyle
◼
ContinuousAction
◼
Enabled
◼
Exclusions
◼
ImageMargins
◼
ImageSize
Slider2DBox
Slider2DBox
◼
Appearance
◼
AutoAction
◼
Background
◼
BaselinePosition
◼
BaseStyle
◼
ContinuousAction
◼
Enabled
◼
Exclusions
◼
ImageMargins
◼
ImageSize
SqrtBox
SqrtBox
SubscriptBox
SubscriptBox
SubsuperscriptBox
SubsuperscriptBox
SuperscriptBox
SuperscriptBox
TabViewBox
TabViewBox
◼
Appearance
◼
Alignment
◼
Background
◼
BaselinePosition
◼
ContentPadding
◼
DefaultLabelStyle
◼
LabelStyle
◼
Enabled
◼
ImageSize
◼
FrameMargins
◼
ImageMargins
TagBox
TagBox
◼
Selectable
TemplateBox
TemplateBox
Like many other complex boxes, the contents of TemplateBox are not editable in cloud notebooks.
◼
DisplayFunction
◼
BaseStyle
◼
DefaultBaseStyle
TogglerBox
TogglerBox
◼
Alignment
◼
AutoAction
◼
Background
◼
BaselinePosition
◼
Enabled
◼
ContentPadding
◼
FrameMargins
◼
ImageMargins
◼
ImageSize
TooltipBox
TooltipBox
◼
BaseStyle
◼
DefaultBaseStyle
◼
DefaultTooltipStyle
◼
TooltipDelay
◼
TooltipStyle
UnderoverscriptBox
UnderoverscriptBox
UnderscriptBox
UnderscriptBox
Box options
Box options
This section contains additional notes on some of the supported box options.
Appearance
Appearance
Many boxes support only a small subset of named appearances.
Nine-patch backgrounds are currently only supported for “built-in” images (via FrontEndResource), so they are not practically usable for end users. Only the “Default” state is supported so far.
ContinuousAction
ContinuousAction
ContinuousAction is generally supported, but it’s only enabled by default in the environment view with a session kernel, to avoid extra charging of Cloud Credits. To enable continuous updating in the deployed view, explicitly set ContinuousAction->True.
SynchronousUpdating
SynchronousUpdating
The SynchronousUpdating option to Dynamic is essentially implemented, but even synchronous dynamic evaluations will not lock the whole notebook interface; they will only mark the cell they are contained in as “pending”, but the rest of the interface remains responsive.
With SynchronousUpdating->True, the preemptive link is used to communicate with the kernel, interrupting any “regular” (-) evaluation that might be running at that point.
Other constructs
Other constructs
EventHandler
EventHandler
EventHandler (which is formatted as a TagBox with an EventHandlerTag) is only supported to a very limited extent. The following events should be supported:
◼
MouseClicked
◼
MouseDown
◼
MouseUp
◼
MouseMoved
◼
MouseDragged
◼
MouseEntered
◼
MouseExited
◼
ReturnKeyDown
◼
EscKeyDown
Support in graphics is even more limited.