blob: 817862f31a6bdeff411012b91e32232de3aacef8 [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.
cr.define('extensions', function() {
'use strict';
/**
* @return {!Promise} A signal that the document is ready. Need to wait for
* this, otherwise the custom ExtensionOptions element might not have been
* registered yet.
*/
function whenDocumentReady() {
if (document.readyState == 'complete')
return Promise.resolve();
return new Promise(function(resolve) {
document.addEventListener('readystatechange', function f() {
if (document.readyState == 'complete') {
document.removeEventListener('readystatechange', f);
resolve();
}
});
});
}
// The minimum width in pixels for the options dialog.
const MIN_WIDTH = 400;
// The maximum height in pixels for the options dialog.
const MAX_HEIGHT = 640;
const OptionsDialog = Polymer({
is: 'extensions-options-dialog',
behaviors: [extensions.ItemBehavior],
properties: {
/** @private {Object} */
extensionOptions_: Object,
/** @private {chrome.developerPrivate.ExtensionInfo} */
data_: Object,
},
/** @private {?Function} */
boundResizeListener_: null,
get open() {
return /** @type {!CrDialogElement} */ (this.$.dialog).open;
},
/**
* Resizes the dialog to the given width/height, taking into account the
* window width/height.
* @param {number} width The desired height of the dialog contents.
* @param {number} height The desired width of the dialog contents.
* @private
*/
updateDialogSize_: function(width, height) {
const headerHeight = this.$.body.offsetTop;
const maxHeight = Math.min(0.9 * window.innerHeight, MAX_HEIGHT);
const effectiveHeight = Math.min(maxHeight, headerHeight + height);
const effectiveWidth = Math.max(MIN_WIDTH, width);
// Get a reference to the inner native <dialog>.
const nativeDialog =
/** @type {!CrDialogElement} */ (this.$.dialog).getNative();
nativeDialog.style.height = `${effectiveHeight}px`;
nativeDialog.style.width = `${effectiveWidth}px`;
},
/** @param {chrome.developerPrivate.ExtensionInfo} data */
show: function(data) {
this.data_ = data;
whenDocumentReady().then(() => {
if (!this.extensionOptions_)
this.extensionOptions_ = document.createElement('ExtensionOptions');
this.extensionOptions_.extension = this.data_.id;
this.extensionOptions_.onclose = this.close.bind(this);
let preferredSize = null;
this.extensionOptions_.onpreferredsizechanged = e => {
preferredSize = e;
if (!this.$.dialog.open)
this.$.dialog.showModal();
this.updateDialogSize_(preferredSize.width, preferredSize.height);
};
this.boundResizeListener_ = () => {
this.updateDialogSize_(preferredSize.width, preferredSize.height);
};
// Add a 'resize' such that the dialog is resized when window size
// changes.
window.addEventListener('resize', this.boundResizeListener_);
this.$.body.appendChild(this.extensionOptions_);
});
},
close: function() {
/** @type {!CrDialogElement} */ (this.$.dialog).close();
},
/** @private */
onClose_: function() {
this.extensionOptions_.onpreferredsizechanged = null;
if (this.boundResizeListener_) {
window.removeEventListener('resize', this.boundResizeListener_);
this.boundResizeListener_ = null;
}
const currentPage = extensions.navigation.getCurrentPage();
// We update the page when the options dialog closes, but only if we're
// still on the details page. We could be on a different page if the
// user hit back while the options dialog was visible; in that case, the
// new page is already correct.
if (currentPage && currentPage.page == Page.DETAILS) {
// This will update the currentPage_ and the NavigationHelper; since
// the active page is already the details page, no main page
// transition occurs.
extensions.navigation.navigateTo(
{page: Page.DETAILS, extensionId: currentPage.extensionId});
}
},
});
return {
OptionsDialog: OptionsDialog,
OptionsDialogMinWidth: MIN_WIDTH,
OptionsDialogMaxHeight: MAX_HEIGHT,
};
});