Commit 97a522b8 authored by Scott Chen's avatar Scott Chen Committed by Commit Bot

WebUI: promote extensions-view-manager to cr-view-manager

This CL moves the extension-view-manager to a shared location to be used
by other WebUIs. The immediate use case is for a new welcome page; see
linked bug for details.

Bug: 874146
Change-Id: Ieb168e61cf6ae02e04d624c92a131e9ec38fcdae
Reviewed-on: https://chromium-review.googlesource.com/1157241Reviewed-by: default avatarHector Carmona <hcarmona@chromium.org>
Commit-Queue: Scott Chen <scottchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#590091}
parent 3fe22318
......@@ -76,7 +76,6 @@ js_type_check("closure_compile") {
":shortcut_util",
":sidebar",
":toolbar",
":view_manager",
]
}
......@@ -240,8 +239,8 @@ js_library("manager") {
":service",
":sidebar",
":toolbar",
":view_manager",
"//ui/webui/resources/cr_elements/cr_drawer:cr_drawer",
"//ui/webui/resources/cr_elements/cr_view_manager:cr_view_manager",
"//ui/webui/resources/js:assert",
"//ui/webui/resources/js:cr",
]
......@@ -353,11 +352,3 @@ js_library("toolbar") {
]
externs_list = [ "$externs_path/metrics_private.js" ]
}
js_library("view_manager") {
deps = [
"//ui/webui/resources/js:assert",
"//ui/webui/resources/js:cr",
]
externs_list = [ "$externs_path/web_animations.js" ]
}
......@@ -195,12 +195,6 @@
<structure name="IDR_MD_EXTENSIONS_STRINGS_HTML"
file="strings.html"
type="chrome_html" />
<structure name="IDR_MD_EXTENSIONS_VIEW_MANAGER_HTML"
file="view_manager.html"
type="chrome_html" />
<structure name="IDR_MD_EXTENSIONS_VIEW_MANAGER_JS"
file="view_manager.js"
type="chrome_html" />
</structures>
</release>
</grit>
......@@ -4,6 +4,7 @@
<link rel="import" href="chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.html">
<link rel="import" href="chrome://resources/cr_elements/cr_toolbar/cr_toolbar.html">
<link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html">
<link rel="import" href="chrome://resources/cr_elements/cr_view_manager/cr_view_manager.html">
<link rel="import" href="chrome://resources/html/assert.html">
<link rel="import" href="chrome://resources/html/cr.html">
<link rel="import" href="detail_view.html">
......@@ -19,7 +20,6 @@
<link rel="import" href="service.html">
<link rel="import" href="sidebar.html">
<link rel="import" href="toolbar.html">
<link rel="import" href="view_manager.html">
<if expr="chromeos">
<link rel="import" href="kiosk_browser_proxy.html">
......@@ -78,7 +78,7 @@
</div>
</cr-drawer>
</template>
<extensions-view-manager id="viewManager" role="main">
<cr-view-manager id="viewManager" role="main">
<extensions-item-list id="items-list" delegate="[[delegate]]"
in-dev-mode="[[inDevMode]]" filter="[[filter]]"
hidden$="[[!didInitPage_]]" slot="view" apps="[[apps_]]"
......@@ -108,7 +108,7 @@
</extensions-error-page>
</template>
</cr-lazy-render>
</extensions-view-manager>
</cr-view-manager>
<template is="dom-if" if="[[showOptionsDialog_]]" restamp>
<extensions-options-dialog id="options-dialog"
on-close="onOptionsDialogClose_">
......
......@@ -455,7 +455,7 @@ cr.define('extensions', function() {
this.errorPageItem_ = assert(data);
if (fromPage != toPage) {
/** @type {extensions.ViewManager} */ (this.$.viewManager)
/** @type {CrViewManagerElement} */ (this.$.viewManager)
.switchView(toPage);
}
......
// Copyright 2017 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.
cr.define('extensions', function() {
'use strict';
/**
* TODO(scottchen): shim for not having Animation.finished implemented. Can
* replace with Animation.finished if Chrome implements it (see:
* crbug.com/257235).
* @param {!Animation} animation
* @return {!Promise}
*/
function whenFinished(animation) {
return new Promise(function(resolve, reject) {
animation.addEventListener('finish', resolve);
});
}
/** @type {!Map<string, function(!Element): !Promise>} */
const viewAnimations = new Map();
viewAnimations.set('no-animation', () => Promise.resolve());
viewAnimations.set('fade-in', element => {
const animation = element.animate(
{
opacity: [0, 1],
},
/** @type {!KeyframeEffectOptions} */ ({
duration: 180,
easing: 'ease-in-out',
iterations: 1,
}));
return whenFinished(animation);
});
viewAnimations.set('fade-out', element => {
const animation = element.animate(
{
opacity: [1, 0],
},
/** @type {!KeyframeEffectOptions} */ ({
duration: 180,
easing: 'ease-in-out',
iterations: 1,
}));
return whenFinished(animation);
});
const ViewManager = Polymer({
is: 'extensions-view-manager',
/**
* @param {!Element} element
* @param {string} animation
* @return {!Promise}
* @private
*/
exit_: function(element, animation) {
const animationFunction = extensions.viewAnimations.get(animation);
assert(animationFunction);
element.classList.remove('active');
element.classList.add('closing');
element.dispatchEvent(
new CustomEvent('view-exit-start', {bubbles: true, composed: true}));
return animationFunction(element).then(function() {
element.classList.remove('closing');
element.dispatchEvent(new CustomEvent(
'view-exit-finish', {bubbles: true, composed: true}));
});
},
/**
* @param {!Element} view
* @param {string} animation
* @return {!Promise}
* @private
*/
enter_: function(view, animation) {
const animationFunction = extensions.viewAnimations.get(animation);
assert(animationFunction);
let effectiveView = view.matches('cr-lazy-render') ? view.get() : view;
effectiveView.classList.add('active');
effectiveView.dispatchEvent(
new CustomEvent('view-enter-start', {bubbles: true, composed: true}));
return animationFunction(effectiveView).then(() => {
effectiveView.dispatchEvent(new CustomEvent(
'view-enter-finish', {bubbles: true, composed: true}));
});
},
/**
* @param {string} newViewId
* @param {string=} enterAnimation
* @param {string=} exitAnimation
* @return {!Promise}
*/
switchView: function(newViewId, enterAnimation, exitAnimation) {
const previousView = this.querySelector('.active');
const newView = assert(this.querySelector('#' + newViewId));
const promises = [];
if (previousView) {
promises.push(this.exit_(previousView, exitAnimation || 'fade-out'));
promises.push(this.enter_(newView, enterAnimation || 'fade-in'));
} else {
promises.push(this.enter_(newView, 'no-animation'));
}
return Promise.all(promises);
},
});
return {viewAnimations: viewAnimations, ViewManager: ViewManager};
});
......@@ -22,7 +22,9 @@ CrElementsBrowserTest.prototype = {
__proto__: PolymerTest.prototype,
/** @override */
extraLibraries: PolymerTest.getLibraries(ROOT_PATH),
extraLibraries: PolymerTest.getLibraries(ROOT_PATH).concat([
ROOT_PATH + 'ui/webui/resources/js/assert.js',
]),
/** @override */
get browsePreload() {
......@@ -374,3 +376,34 @@ CrElementsSearchableDropDownTest.prototype = {
TEST_F('CrElementsSearchableDropDownTest', 'All', function() {
mocha.run();
});
////////////////////////////////////////////////////////////////////////////////
// View Manager Tests
CrElementsViewManagerTest = class extends CrElementsBrowserTest {
/** @override */
get browsePreload() {
return 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.html';
}
/** @override */
get extraLibraries() {
return super.extraLibraries.concat([
'../extensions/test_util.js',
'cr_view_manager_test.js',
]);
}
/** @override */
get suiteName() {
return cr_view_manager_test.suiteName;
}
};
TEST_F('CrElementsViewManagerTest', 'VisibilityTest', function() {
runMochaTest(this.suiteName, cr_view_manager_test.TestNames.Visibility);
});
TEST_F('CrElementsViewManagerTest', 'EventFiringTest', function() {
runMochaTest(this.suiteName, cr_view_manager_test.TestNames.EventFiring);
});
......@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/** @fileoverview Suite of tests for extensions-detail-view. */
cr.define('extension_view_manager_tests', function() {
/** @fileoverview Suite of tests for cr-view-manager. */
cr.define('cr_view_manager_test', function() {
/** @enum {string} */
const TestNames = {
Visibility: 'visibility',
......@@ -13,20 +13,20 @@ cr.define('extension_view_manager_tests', function() {
let viewManager;
let parent;
let views;
const suiteName = 'ExtensionViewManagerTest';
const suiteName = 'CrElementsViewManagerTest';
suite(suiteName, function() {
// Initialize an extensions-view-manager inside a parent div before
// Initialize an cr-view-manager inside a parent div before
// each test.
setup(function() {
PolymerTest.clearBody();
document.body.innerHTML = `
<div id="parent">
<extensions-view-manager id="viewManager">
<cr-view-manager id="viewManager">
<div slot="view" id="viewOne">view 1</div>
<div slot="view" id="viewTwo">view 2</div>
<div slot="view" id="viewThree">view 3</div>
</extensions-view-manager>
</cr-view-manager>
</div>
`;
parent = document.body.querySelector('#parent');
......
......@@ -669,36 +669,6 @@ TEST_F('CrExtensionsNavigationHelperTest', 'SupportedRoutes', function() {
extension_navigation_helper_tests.TestNames.SupportedRoutes);
});
////////////////////////////////////////////////////////////////////////////////
// Extension View Manager Tests
CrExtensionsViewManagerTest = class extends CrExtensionsBrowserTest {
/** @override */
get browsePreload() {
return 'chrome://extensions/view_manager.html';
}
/** @override */
get extraLibraries() {
return super.extraLibraries.concat([
'view_manager_test.js',
]);
}
/** @override */
get suiteName() {
return extension_view_manager_tests.suiteName;
}
};
TEST_F('CrExtensionsViewManagerTest', 'VisibilityTest', function() {
this.runMochaTest(extension_view_manager_tests.TestNames.Visibility);
});
TEST_F('CrExtensionsViewManagerTest', 'EventFiringTest', function() {
this.runMochaTest(extension_view_manager_tests.TestNames.EventFiring);
});
////////////////////////////////////////////////////////////////////////////////
// Error Console tests
......
......@@ -22,6 +22,7 @@ group("closure_compile") {
"cr_slider:closure_compile",
"cr_toast:closure_compile",
"cr_toggle:closure_compile",
"cr_view_manager:closure_compile",
"policy:closure_compile",
]
}
......
# Copyright 2018 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.
import("//third_party/closure_compiler/compile_js.gni")
js_type_check("closure_compile") {
deps = [
":cr_view_manager",
]
}
js_library("cr_view_manager") {
deps = [
"//ui/webui/resources/js:assert",
"//ui/webui/resources/js:cr",
]
externs_list = [ "$externs_path/web_animations.js" ]
}
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="../../html/polymer.html">
<link rel="import" href="chrome://resources/html/assert.html">
<link rel="import" href="chrome://resources/html/cr.html">
<link rel="import" href="../../html/assert.html">
<link rel="import" href="../../html/cr.html">
<dom-module id="extensions-view-manager">
<dom-module id="cr-view-manager">
<template>
<style>
:host ::slotted([slot=view]) {
......@@ -22,5 +22,5 @@
</style>
<slot name="view"></slot>
</template>
<script src="view_manager.js"></script>
<script src="cr_view_manager.js"></script>
</dom-module>
// Copyright 2018 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.
(function() {
/**
* TODO(scottchen): shim for not having Animation.finished implemented. Can
* replace with Animation.finished if Chrome implements it (see:
* crbug.com/257235).
* @param {!Animation} animation
* @return {!Promise}
*/
function whenFinished(animation) {
return new Promise(function(resolve, reject) {
animation.addEventListener('finish', resolve);
});
}
/** @type {!Map<string, function(!Element): !Promise>} */
const viewAnimations = new Map();
viewAnimations.set('no-animation', () => Promise.resolve());
viewAnimations.set('fade-in', element => {
const animation = element.animate(
{
opacity: [0, 1],
},
/** @type {!KeyframeEffectOptions} */ ({
duration: 180,
easing: 'ease-in-out',
iterations: 1,
}));
return whenFinished(animation);
});
viewAnimations.set('fade-out', element => {
const animation = element.animate(
{
opacity: [1, 0],
},
/** @type {!KeyframeEffectOptions} */ ({
duration: 180,
easing: 'ease-in-out',
iterations: 1,
}));
return whenFinished(animation);
});
Polymer({
is: 'cr-view-manager',
/**
* @param {!Element} element
* @param {string} animation
* @return {!Promise}
* @private
*/
exit_: function(element, animation) {
const animationFunction = viewAnimations.get(animation);
assert(animationFunction);
element.classList.remove('active');
element.classList.add('closing');
element.dispatchEvent(
new CustomEvent('view-exit-start', {bubbles: true, composed: true}));
return animationFunction(element).then(function() {
element.classList.remove('closing');
element.dispatchEvent(
new CustomEvent('view-exit-finish', {bubbles: true, composed: true}));
});
},
/**
* @param {!Element} view
* @param {string} animation
* @return {!Promise}
* @private
*/
enter_: function(view, animation) {
const animationFunction = viewAnimations.get(animation);
assert(animationFunction);
let effectiveView = view.matches('cr-lazy-render') ? view.get() : view;
effectiveView.classList.add('active');
effectiveView.dispatchEvent(
new CustomEvent('view-enter-start', {bubbles: true, composed: true}));
return animationFunction(effectiveView).then(() => {
effectiveView.dispatchEvent(new CustomEvent(
'view-enter-finish', {bubbles: true, composed: true}));
});
},
/**
* @param {string} newViewId
* @param {string=} enterAnimation
* @param {string=} exitAnimation
* @return {!Promise}
*/
switchView: function(newViewId, enterAnimation, exitAnimation) {
const previousView = this.querySelector('.active');
const newView = assert(this.querySelector('#' + newViewId));
const promises = [];
if (previousView) {
promises.push(this.exit_(previousView, exitAnimation || 'fade-out'));
promises.push(this.enter_(newView, enterAnimation || 'fade-in'));
} else {
promises.push(this.enter_(newView, 'no-animation'));
}
return Promise.all(promises);
},
});
})();
\ No newline at end of file
......@@ -126,6 +126,12 @@
file="cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.js"
type="chrome_html"
compress="gzip" />
<structure name="IDR_CR_ELEMENTS_CR_VIEW_MANAGER_HTML"
file="cr_elements/cr_view_manager/cr_view_manager.html"
type="chrome_html" />
<structure name="IDR_CR_ELEMENTS_CR_VIEW_MANAGER_JS"
file="cr_elements/cr_view_manager/cr_view_manager.js"
type="chrome_html" />
<if expr="chromeos">
<structure name="IDR_CR_ELEMENTS_CHROMEOS_CR_PICTURE_CR_CAMERA_HTML"
file="cr_elements/chromeos/cr_picture/cr_camera.html"
......
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