blob: 4bbb4830b5fba55947d6a859c79fb71feb8ade7b [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var api = {};
/**
* Enumeration of scene update commands.
* @enum {number}
* @const
*/
api.Command = {
'ADD_ELEMENT': 0,
'UPDATE_ELEMENT': 1,
'REMOVE_ELEMENT': 2,
'ADD_ANIMATION': 3,
'REMOVE_ANIMATION': 4,
'UPDATE_BACKGROUND': 5
};
/**
* Sends one or more commands to native scene management. Commands are used
* to add, modify or remove elements and animations. For examples of how to
* format command parameters, refer to examples in scene.js.
* @param {Array<Object>} commands
*/
api.sendCommands = function(commands) {
if (commands.length > 0) {
chrome.send('updateScene', commands);
}
};
/**
* Enumeration of valid Anchroing for X axis.
* An element can either be anchored to the left, right, or center of the main
* content rect (or it can be absolutely positioned using NONE). Any
* translations applied will be relative to this anchoring.
* @enum {number}
* @const
*/
api.XAnchoring = {
'XNONE': 0,
'XLEFT': 1,
'XRIGHT': 2
};
/**
* Enumeration of valid Anchroing for Y axis.
* @enum {number}
* @const
*/
api.YAnchoring = {
'YNONE': 0,
'YTOP': 1,
'YBOTTOM': 2
};
/**
* Enumeration of actions that can be triggered by the HTML UI.
* @enum {number}
* @const
*/
api.Action = {
'HISTORY_BACK': 0,
'HISTORY_FORWARD': 1,
'RELOAD': 2,
'ZOOM_OUT': 3,
'ZOOM_IN': 4,
'RELOAD_UI': 5,
'LOAD_URL': 6,
'OMNIBOX_CONTENT': 7,
'SET_CONTENT_PAUSED': 8,
};
/**
* Enumeration of modes that can be specified by the native side.
* @enum {number}
* @const
*/
api.Mode = {
'UNKNOWN': -1,
'STANDARD': 0,
'WEB_VR': 1,
};
/**
* Triggers an Action.
* @param {api.Action} action
* @param {Object} parameters
*/
api.doAction = function(action, parameters) {
chrome.send('doAction', [action, parameters]);
};
/**
* Notify native scene management that DOM loading has completed, at the
* specified page size.
*/
api.domLoaded = function() {
chrome.send('domLoaded');
};
/**
* Sets the CSS size for the content window.
* @param {number} width
* @param {number} height
* @param {number} dpr
*/
api.setContentCssSize = function(width, height, dpr) {
chrome.send('setContentCssSize', [width, height, dpr]);
};
/**
* Sets the CSS size for this page.
* @param {number} width
* @param {number} height
* @param {number} dpr
*/
api.setUiCssSize = function(width, height, dpr) {
chrome.send('setUiCssSize', [width, height, dpr]);
};
api.FillType = {
'NONE': 0,
'SPRITE': 1,
'OPAQUE_GRADIENT': 2,
'GRID_GRADIENT': 3,
'CONTENT': 4
};
api.Fill = class {
constructor(type) {
this.properties = {};
this.properties['fillType'] = type;
}
}
api.Sprite = class extends api.Fill {
constructor(pixelX, pixelY, pixelWidth, pixelHeight) {
super(api.FillType.SPRITE);
this.properties.copyRect =
{x: pixelX, y: pixelY, width: pixelWidth, height: pixelHeight};
}
}
api.OpaqueGradient = class extends api.Fill {
constructor(edgeColor, centerColor) {
super(api.FillType.OPAQUE_GRADIENT);
this.properties.edgeColor = edgeColor;
this.properties.centerColor = centerColor;
}
}
api.GridGradient = class extends api.Fill {
constructor(edgeColor, centerColor, gridlineCount) {
super(api.FillType.GRID_GRADIENT);
this.properties.edgeColor = edgeColor;
this.properties.centerColor = centerColor;
this.properties.gridlineCount = gridlineCount;
}
}
api.Content = class extends api.Fill {
constructor() {
super(api.FillType.CONTENT);
}
}
/**
* Represents updates to UI element properties. Any properties set on this
* object are relayed to an underlying native element via scene command.
* Properties that are not set on this object are left unchanged.
* @struct
*/
api.UiElementUpdate = class {
constructor() {
/** @private {!Object} */
this.properties = {'id': -1};
}
/**
* Set the id of the element to update.
* @param {number} id
*/
setId(id) {
this.properties['id'] = id;
}
/**
* Specify a parent for this element. If set, this element is positioned
* relative to its parent element, rather than absolutely. This allows
* elements to automatically move with a parent.
* @param {number} id
*/
setParentId(id) {
this.properties['parentId'] = id;
}
/**
* Specify the width and height (in meters) of an element.
* @param {number} x
* @param {number} y
*/
setSize(x, y) {
this.properties['size'] = {x: x, y: y};
}
/**
* Specify optional scaling of the element, and any children.
* @param {number} x
* @param {number} y
* @param {number} z
*/
setScale(x, y, z) {
this.properties['scale'] = {x: x, y: y, z: z};
}
/**
* Specify rotation for the element. The rotation is specified in axis-angle
* representation (rotate around unit vector [x, y, z] by 'a' radians).
* @param {number} x
* @param {number} y
* @param {number} z
* @param {number} a
*/
setRotation(x, y, z, a) {
this.properties['rotation'] = {x: x, y: y, z: z, a: a};
}
/**
* Specify the translation of the element. If anchoring is specified, the
* offset is applied to the anchoring position rather than the origin.
* Translation is applied after scaling and rotation.
* @param {number} x
* @param {number} y
* @param {number} z
*/
setTranslation(x, y, z) {
this.properties['translation'] = {x: x, y: y, z: z};
}
/**
* Anchoring allows a rectangle to be positioned relative to the edge of
* its parent, without being concerned about the size of the parent.
* Values should be XAnchoring and YAnchoring elements.
* Example: element.setAnchoring(XAnchoring.XNONE, YAnchoring.YBOTTOM);
* @param {number} x
* @param {number} y
*/
setAnchoring(x, y) {
this.properties['xAnchoring'] = x;
this.properties['yAnchoring'] = y;
}
/**
* Visibility controls whether the element is rendered.
* @param {boolean} visible
*/
setVisible(visible) {
this.properties['visible'] = !!visible;
}
/**
* Hit-testable implies that the reticle will hit the element, if visible.
* @param {boolean} testable
*/
setHitTestable(testable) {
this.properties['hitTestable'] = !!testable;
}
/**
* Causes an element to be rendered relative to the field of view, rather
* than the scene. Elements locked in this way should not have a parent.
* @param {boolean} locked
*/
setLockToFieldOfView(locked) {
this.properties['lockToFov'] = !!locked;
}
/**
* Causes an element to be rendered with a specified opacity, between 0.0 and
* 1.0. Opacity is inherited by children.
* @param {number} opacity
*/
setOpacity(opacity) {
this.properties['opacity'] = opacity;
}
setFill(fill) {
Object.assign(this.properties, fill.properties);
}
};
/**
* Represents a new UI element. This object builds on UiElementUpdate,
* forcing the underlying texture coordinates to be specified.
* @struct
*/
api.UiElement = class extends api.UiElementUpdate {
/**
* Constructor of UiElement.
* pixelX and pixelY values indicate the left upper corner; pixelWidth and
* pixelHeight is width and height of the texture to be copied from the web
* contents.
* @param {number} pixelX
* @param {number} pixelY
* @param {number} pixelWidth
* @param {number} pixelHeight
*/
constructor(pixelX, pixelY, pixelWidth, pixelHeight) {
super();
this.setFill(new api.Sprite(pixelX, pixelY, pixelWidth, pixelHeight));
}
};
/**
* Enumeration of animatable properties.
* @enum {number}
* @const
*/
api.Property = {
'COPYRECT': 0,
'SIZE': 1,
'TRANSLATION': 2,
'SCALE': 3,
'ROTATION': 4,
'OPACITY': 5
};
/**
* Enumeration of easing type.
* @enum {number}
* @const
*/
api.Easing = {
'LINEAR': 0,
'CUBICBEZIER': 1,
'EASEIN': 2,
'EASEOUT': 3
};
/**
* Base animation class. An animation can vary only one object property.
* @struct
*/
api.Animation = class {
constructor(elementId, durationMs) {
/** @private {number} */
this.id = -1;
/** @private {number} */
this.meshId = elementId;
/** @private {number} */
this.property = -1;
/** @private {Object} */
this.to = {};
/** @private {Object} */
this.easing = {};
// How many milliseconds in the future to start the animation.
/** @private {number} */
this.startInMillis = 0.0;
// Duration of the animation (milliseconds).
/** @private {number} */
this.durationMillis = durationMs;
this.easing.type = api.Easing.LINEAR;
}
/**
* Set the id of the animation.
* @param {number} id
*/
setId(id) {
this.id = id;
}
/**
* Set the animation's final element size.
* @param {number} width
* @param {number} height
*/
setSize(width, height) {
this.property = api.Property.SIZE;
this.to.x = width;
this.to.y = height;
}
/**
* Set the animation's final element scale.
* @param {number} x
* @param {number} y
* @param {number} z
*/
setScale(x, y, z) {
this.property = api.Property.SCALE;
this.to.x = x;
this.to.y = y;
this.to.z = z;
}
/**
* Set the animation's final element rotation.
* @param {number} x
* @param {number} y
* @param {number} z
* @param {number} a
*/
setRotation(x, y, z, a) {
this.property = api.Property.ROTATION;
this.to.x = x;
this.to.y = y;
this.to.z = z;
this.to.a = a;
}
/**
* Set the animation's final element translation.
* @param {number} x
* @param {number} y
* @param {number} z
*/
setTranslation(x, y, z) {
this.property = api.Property.TRANSLATION;
this.to.x = x;
this.to.y = y;
this.to.z = z;
}
/**
* Set the animation's final element opacity.
* @param {number} opacity
*/
setOpacity(opacity) {
this.property = api.Property.OPACITY;
this.to.x = opacity;
}
};
/**
* Abstract class handling webui command calls from native. The UI must
* subclass this and override the handlers.
*/
api.NativeCommandHandler = class {
/**
* @param {api.Mode} mode
*/
onSetMode(mode) {}
/**
* Handles entering or exiting full-screen mode.
* @param {boolean} fullscreen
*/
onSetFullscreen(fullscreen) {}
/**
* A controller app button click has happened.
*/
onAppButtonClicked() {}
/**
* Handles a change in the visible page's security level.
* @param {number} level
*/
onSetSecurityLevel(level) {}
/**
* Handles a change in the WebVR-specific secure-origin state. If |secure| is
* false, the UI must convey appropriate security warnings.
* @param {boolean} secure
*/
onSetWebVRSecureOrigin(secure) {}
/**
* Handles enabling of a development-oriented control to reload the UI.
* @param {boolean} enabled
*/
onSetReloadUiCapabilityEnabled(enabled) {}
/**
* Handles a new URL, specifying the host and path compoments.
* @param {string} host
* @param {string} path
*/
onSetUrl(host, path) {}
/**
* Handle a change in loading state (used to show a spinner or other loading
* indicator).
* @param {boolean} loading
*/
onSetLoading(loading) {}
/**
* Handle a change in loading progress. Progress is supplied as a number
* between 0.0 and 1.0.
* @param {boolean} progress
*/
onSetLoadingProgress(progress) {}
/**
* Handle a change in the set of omnibox suggestions.
* @param {Array<Object>} suggestions Array of suggestions with string members
* |description| and |url|.
*/
onSetOmniboxSuggestions(suggestions) {}
/**
* Handle a new set of tabs, overwriting the previous state.
* @param {Array<Object>} tabs Array of tab states.
*/
onSetTabs(tabs) {}
/**
* Update (or add if not present) a tab.
* @param {Object} tab
*/
onUpdateTab(tab) {}
/**
* Remove a tab.
* @param {Object} tab
*/
onRemoveTab(tab) {}
/**
* This function is executed after command parsing completes.
*/
onCommandHandlerFinished() {}
/** @final */
handleCommand(dict) {
if ('mode' in dict) {
this.onSetMode(dict['mode']);
}
if ('fullscreen' in dict) {
this.onSetFullscreen(dict['fullscreen'])
}
if ('appButtonClicked' in dict) {
this.onAppButtonClicked();
}
if ('securityLevel' in dict) {
this.onSetSecurityLevel(dict['securityLevel']);
}
if ('webVRSecureOrigin' in dict) {
this.onSetWebVRSecureOrigin(dict['webVRSecureOrigin']);
}
if ('enableReloadUi' in dict) {
this.onSetReloadUiCapabilityEnabled(dict['enableReloadUi']);
}
if ('url' in dict) {
let url = dict['url'];
this.onSetUrl(url['host'], url['path']);
}
if ('loading' in dict) {
this.onSetLoading(dict['loading']);
}
if ('loadProgress' in dict) {
this.onSetLoadingProgress(dict['loadProgress']);
}
if ('suggestions' in dict) {
this.onSetOmniboxSuggestions(dict['suggestions']);
}
if ('setTabs' in dict) {
this.onSetTabs(dict['setTabs']);
}
if ('updateTab' in dict) {
this.onUpdateTab(dict['updateTabs']);
}
if ('removeTab' in dict) {
this.onRemoveTab(dict['removeTab']);
}
this.onCommandHandlerFinished()
}
};