Commit 0cc9f992 authored by cjgrant's avatar cjgrant Committed by Commit bot

First cut of JS closure compiler use for VR HTML UI.

Also, run clang-format to fix up styling.

BUG=
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:closure_compilation

Review-Url: https://codereview.chromium.org/2592143002
Cr-Commit-Position: refs/heads/master@{#441437}
parent 662d1d26
# 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.
{
'targets': [
{
'target_name': 'vr_shell_ui_api',
'dependencies': [
'<(EXTERNS_GYP):chrome_send',
],
'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
},
{
'target_name': 'vr_shell_ui_scene',
'dependencies': [
'vr_shell_ui_api',
],
'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
},
{
'target_name': 'vr_shell_ui',
'dependencies': [
'vr_shell_ui_api',
'vr_shell_ui_scene',
],
'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
},
],
}
...@@ -77,8 +77,7 @@ var vrShellUi = (function() { ...@@ -77,8 +77,7 @@ var vrShellUi = (function() {
// Pull additional custom properties from CSS. // Pull additional custom properties from CSS.
let style = window.getComputedStyle(domElement); let style = window.getComputedStyle(domElement);
element.setTranslation( element.setTranslation(
getStyleFloat(style, '--tranX'), getStyleFloat(style, '--tranX'), getStyleFloat(style, '--tranY'),
getStyleFloat(style, '--tranY'),
getStyleFloat(style, '--tranZ')); getStyleFloat(style, '--tranZ'));
this.uiElementId = scene.addElement(element); this.uiElementId = scene.addElement(element);
...@@ -122,17 +121,29 @@ var vrShellUi = (function() { ...@@ -122,17 +121,29 @@ var vrShellUi = (function() {
class Controls { class Controls {
constructor(contentQuadId) { constructor(contentQuadId) {
this.enabled = false;
this.reloadUiEnabled = false;
this.buttons = []; this.buttons = [];
let descriptors = [ let descriptors = [
['#back', function() { [
'#back',
function() {
api.doAction(api.Action.HISTORY_BACK); api.doAction(api.Action.HISTORY_BACK);
}], }
['#reload', function() { ],
[
'#reload',
function() {
api.doAction(api.Action.RELOAD); api.doAction(api.Action.RELOAD);
}], }
['#forward', function() { ],
[
'#forward',
function() {
api.doAction(api.Action.HISTORY_FORWARD); api.doAction(api.Action.HISTORY_FORWARD);
}], }
],
]; ];
/** @const */ var BUTTON_SPACING = 0.136; /** @const */ var BUTTON_SPACING = 0.136;
...@@ -198,13 +209,17 @@ var vrShellUi = (function() { ...@@ -198,13 +209,17 @@ var vrShellUi = (function() {
/** @const */ var DISTANCE = 0.7; /** @const */ var DISTANCE = 0.7;
/** @const */ var ANGLE_UP = 16.3 * Math.PI / 180.0; /** @const */ var ANGLE_UP = 16.3 * Math.PI / 180.0;
this.enabled = false;
this.secure = false;
this.secureOriginTimer = null;
// Permanent WebVR security warning. This warning is shown near the top of // Permanent WebVR security warning. This warning is shown near the top of
// the field of view. // the field of view.
this.webVrSecureWarning = new DomUiElement('#webvr-not-secure-permanent'); this.webVrSecureWarning = new DomUiElement('#webvr-not-secure-permanent');
let update = new api.UiElementUpdate(); let update = new api.UiElementUpdate();
update.setScale(DISTANCE, DISTANCE, 1); update.setScale(DISTANCE, DISTANCE, 1);
update.setTranslation(0, DISTANCE * Math.sin(ANGLE_UP), update.setTranslation(
-DISTANCE * Math.cos(ANGLE_UP)); 0, DISTANCE * Math.sin(ANGLE_UP), -DISTANCE * Math.cos(ANGLE_UP));
update.setRotation(1.0, 0.0, 0.0, ANGLE_UP); update.setRotation(1.0, 0.0, 0.0, ANGLE_UP);
update.setHitTestable(false); update.setHitTestable(false);
update.setVisible(false); update.setVisible(false);
...@@ -213,8 +228,7 @@ var vrShellUi = (function() { ...@@ -213,8 +228,7 @@ var vrShellUi = (function() {
// Temporary WebVR security warning. This warning is shown in the center // Temporary WebVR security warning. This warning is shown in the center
// of the field of view, for a limited period of time. // of the field of view, for a limited period of time.
this.transientWarning = new DomUiElement( this.transientWarning = new DomUiElement('#webvr-not-secure-transient');
'#webvr-not-secure-transient');
update = new api.UiElementUpdate(); update = new api.UiElementUpdate();
update.setScale(DISTANCE, DISTANCE, 1); update.setScale(DISTANCE, DISTANCE, 1);
update.setTranslation(0, 0, -DISTANCE); update.setTranslation(0, 0, -DISTANCE);
...@@ -243,8 +257,8 @@ var vrShellUi = (function() { ...@@ -243,8 +257,8 @@ var vrShellUi = (function() {
this.secureOriginTimer = null; this.secureOriginTimer = null;
} }
if (visible) { if (visible) {
this.secureOriginTimer = setTimeout( this.secureOriginTimer =
this.onTransientTimer.bind(this), TRANSIENT_TIMEOUT_MS); setTimeout(this.onTransientTimer.bind(this), TRANSIENT_TIMEOUT_MS);
} }
this.showOrHideWarnings(visible); this.showOrHideWarnings(visible);
} }
...@@ -271,9 +285,11 @@ var vrShellUi = (function() { ...@@ -271,9 +285,11 @@ var vrShellUi = (function() {
constructor(contentQuadId) { constructor(contentQuadId) {
this.domUiElement = new DomUiElement('#omni-container'); this.domUiElement = new DomUiElement('#omni-container');
this.enabled = false; this.enabled = false;
this.loading = false;
this.level = 0; this.level = 0;
this.visibilityTimeout = 0; this.visibilityTimeout = 0;
this.visibilityTimer = null; this.visibilityTimer = null;
this.visibleAfterTransition = false;
this.nativeState = {}; this.nativeState = {};
// Initially invisible. // Initially invisible.
...@@ -284,22 +300,22 @@ var vrShellUi = (function() { ...@@ -284,22 +300,22 @@ var vrShellUi = (function() {
// Listen to the end of transitions, so that the box can be natively // Listen to the end of transitions, so that the box can be natively
// hidden after it finishes hiding itself. // hidden after it finishes hiding itself.
document.querySelector('#omni').addEventListener('transitionend', document.querySelector('#omni').addEventListener(
this.onAnimationDone.bind(this)); 'transitionend', this.onAnimationDone.bind(this));
} }
getSecurityIconElementId(level) { getSecurityIconElementId(level) {
// See security_state.h and getSecurityIconResource() for this mapping. // See security_state.h and getSecurityIconResource() for this mapping.
switch (level) { switch (level) {
case 0: // NONE case 0: // NONE
case 1: // HTTP_SHOW_WARNING case 1: // HTTP_SHOW_WARNING
case 4: // SECURITY_WARNING case 4: // SECURITY_WARNING
return '#omni-info-icon'; return '#omni-info-icon';
case 2: // SECURE: case 2: // SECURE:
case 3: // EV_SECURE: case 3: // EV_SECURE:
return '#omni-lock-icon'; return '#omni-lock-icon';
case 5: // SECURE_WITH_POLICY_INSTALLED_CERT (ChromeOS only) case 5: // SECURE_WITH_POLICY_INSTALLED_CERT (ChromeOS only)
case 6: // DANGEROUS case 6: // DANGEROUS
default: default:
return '#omni-warning-icon'; return '#omni-warning-icon';
} }
...@@ -344,7 +360,7 @@ var vrShellUi = (function() { ...@@ -344,7 +360,7 @@ var vrShellUi = (function() {
} }
if (this.enabled && this.visibilityTimeout > 0 && !this.loading) { if (this.enabled && this.visibilityTimeout > 0 && !this.loading) {
this.visibilityTimer = setTimeout( this.visibilityTimer = setTimeout(
this.onVisibilityTimer.bind(this), this.visibilityTimeout); this.onVisibilityTimer.bind(this), this.visibilityTimeout);
} }
} }
...@@ -426,11 +442,12 @@ var vrShellUi = (function() { ...@@ -426,11 +442,12 @@ var vrShellUi = (function() {
// TODO(amp): Don't show controls in CINEMA mode once MENU mode lands. // TODO(amp): Don't show controls in CINEMA mode once MENU mode lands.
this.omnibox.setVisibilityTimeout( this.omnibox.setVisibilityTimeout(
mode == api.Mode.STANDARD && !menuMode ? mode == api.Mode.STANDARD && !menuMode ?
0 : OMNIBOX_VISIBILITY_TIMEOUT_MS); 0 :
OMNIBOX_VISIBILITY_TIMEOUT_MS);
this.secureOriginWarnings.setEnabled(mode == api.Mode.WEB_VR); this.secureOriginWarnings.setEnabled(mode == api.Mode.WEB_VR);
api.setUiCssSize(uiRootElement.clientWidth, uiRootElement.clientHeight, api.setUiCssSize(
UI_DPR); uiRootElement.clientWidth, uiRootElement.clientHeight, UI_DPR);
} }
setSecurityLevel(level) { setSecurityLevel(level) {
......
...@@ -2,149 +2,146 @@ ...@@ -2,149 +2,146 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
var ui = (function() { var ui = new Object();
'use strict';
/**
* The scene class assists in managing element and animations in the scene.
* It allows scene update commands to be queued in batches, and manages
* allocation of element and animation IDs.
*
* Examples:
*
* var scene = new ui.Scene();
*
* // Add an element.
* var el = new api.UiElement(100, 200, 50, 50);
* el.setSize(buttonWidth, buttonHeight);
*
* // Anchor it to the bottom of the content quad.
* el.setParentId(contentQuadId);
* el.setAnchoring(api.XAnchoring.XNONE, api.YAnchoring.YBOTTOM);
*
* // Place it just below the content quad edge.
* el.setTranslation(0, -0.2, 0.0);
*
* // Add it to the scene.
* var buttonId = scene.addElement(el);
* scene.flush();
*
* // Make the button twice as big.
* var update = new api.UiElementUpdate();
* update.setSize(bunttonWidth * 2, buttonHeight * 2);
* scene.updateElement(buttonId, update);
* scene.flush();
*
* // Animate the button size back to its original size, over 250 ms.
* var resize = new api.Animation(buttonId, 250);
* resize.setSize(buttonWidth, buttonHeight);
* scene.addAnimation(resize);
* scene.flush();
*
* @struct
*/
ui.Scene = class {
constructor() {
/** @private {number} */
this.idIndex = 1;
/** @private {Array<Object>} */
this.commands = [];
/** @private {!Set<number>} */
this.elements = new Set();
/** @private {!Object} */
this.animations = [];
}
/** /**
* The scene class assists in managing element and animations in the scene. * Flush all queued commands to native.
* It allows scene update commands to be queued in batches, and manages
* allocation of element and animation IDs.
*
* Examples:
*
* var scene = new ui.Scene();
*
* // Add an element.
* var el = new api.UiElement(100, 200, 50, 50);
* el.setSize(buttonWidth, buttonHeight);
*
* // Anchor it to the bottom of the content quad.
* el.setParentId(api.getContentElementId());
* el.setAnchoring(api.XAnchoring.XNONE, api.YAnchoring.YBOTTOM);
*
* // Place it just below the content quad edge.
* el.setTranslation(0, -0.2, 0.0);
*
* // Add it to the scene.
* var buttonId = scene.addElement(el);
* scene.flush();
*
* // Make the button twice as big.
* var update = new api.UiElementUpdate();
* update.setSize(bunttonWidth * 2, buttonHeight * 2);
* scene.updateElement(buttonId, update);
* scene.flush();
*
* // Animate the button size back to its original size, over 250 ms.
* var resize = new api.Animation(buttonId, 250);
* resize.setSize(buttonWidth, buttonHeight);
* scene.addAnimation(resize);
* scene.flush();
*/ */
class Scene { flush() {
api.sendCommands(this.commands);
constructor() { this.commands = [];
this.idIndex = api.getContentElementId() + 1; }
this.commands = [];
this.elements = new Set();
this.animations = {};
}
/** /**
* Flush all queued commands to native. * Add a new UiElement to the scene, returning the ID assigned.
*/ * @param {api.UiElement} element
flush() { */
api.sendCommands(this.commands); addElement(element) {
this.commands = []; var id = this.idIndex++;
} element.setId(id);
this.commands.push(
{'type': api.Command.ADD_ELEMENT, 'data': element.properties});
this.elements.add(id);
return id;
}
/** /**
* Add a new UiElement to the scene, returning the ID assigned. * Update an existing element, according to a UiElementUpdate object.
*/ * @param {number} id
addElement(element) { * @param {api.UiElementUpdate} update
var id = this.idIndex++; */
element.id = id; updateElement(id, update) {
this.commands.push({ // To-do: Make sure ID exists.
'type': api.Command.ADD_ELEMENT, update.setId(id);
'data': element this.commands.push(
}); {'type': api.Command.UPDATE_ELEMENT, 'data': update.properties});
this.elements.add(id); }
return id;
}
/** /**
* Update an existing element, according to a UiElementUpdate object. * Remove an element from the scene.
*/ * @param {number} id
updateElement(id, update) { */
// To-do: Make sure ID exists. removeElement(id) {
update.id = id; // To-do: Make sure ID exists.
this.commands.push({ this.commands.push(
'type': api.Command.UPDATE_ELEMENT, {'type': api.Command.REMOVE_ELEMENT, 'data': {'id': id}});
'data': update this.elements.delete(id);
}); }
}
/* /**
* Remove an element from the scene. * Add a new Animation to the scene, returning the ID assigned.
*/ * @param {api.Animation} animation
removeElement(id) { */
// To-do: Make sure ID exists. addAnimation(animation) {
this.commands.push({ var id = this.idIndex++;
'type': api.Command.REMOVE_ELEMENT, animation.setId(id);
'data': {'id': id} this.commands.push({'type': api.Command.ADD_ANIMATION, 'data': animation});
}); this.animations[id] = animation.meshId;
this.elements.delete(id); return id;
} }
/** /**
* Add a new Animation to the scene, returning the ID assigned. * Remove an animation from the scene.
*/ *
addAnimation(animation) { * Note that animations are flushed when they complete and are not required
var id = this.idIndex++; * to be removed. Also new animations of the same type will effectively
animation.id = id; * override the original so there is no need to remove in that scenario
this.commands.push({ * either.
'type': api.Command.ADD_ANIMATION, *
'data': animation * @param {number} id
}); */
this.animations[id] = animation.meshId; removeAnimation(id) {
return id; // To-do: Make sure ID exists.
} this.commands.push({
'type': api.Command.REMOVE_ANIMATION,
'data': {'id': id, 'meshId': this.animations[id]}
});
delete this.animations[id];
}
/* /**
* Remove an animation from the scene. * Purge all elements in the scene.
* */
* Note that animations are flushed when they complete and are not required purge() {
* to be removed. Also new animations of the same type will effectively var ids = Object.keys(this.animations);
* override the original so there is no need to remove in that scenario for (let id_key of ids) {
* either. var id = parseInt(id_key, 10);
*/ this.removeAnimation(id);
removeAnimation(id) {
// To-do: Make sure ID exists.
this.commands.push({
'type': api.Command.REMOVE_ANIMATION,
'data': {'id': id, 'meshId': this.animations[id]}
});
delete this.animations[id];
} }
var ids = this.elements.values();
/* for (let id of ids) {
* Purge all elements in the scene. this.removeElement(id);
*/
purge() {
var ids = Object.keys(this.animations);
for (let id_key of ids) {
var id = parseInt(id_key);
this.removeAnimation(id);
}
var ids = this.elements.values();
for (let id of ids) {
this.removeElement(id);
}
this.flush();
} }
}; this.flush();
}
return { };
Scene: Scene,
};
})();
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment