blob: 6cfc4459c3eac7d6214b3f19a5cf812aa3cae2b0 [file] [log] [blame]
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'chrome://resources/cr_elements/cr_button/cr_button.js';
import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
import 'chrome://resources/cr_elements/cr_input/cr_input.js';
import './pack_dialog_alert.js';
import '/strings.m.js';
import type {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
import type {CrInputElement} from 'chrome://resources/cr_elements/cr_input/cr_input.js';
import {CrLitElement} from 'chrome://resources/lit/v3_0/lit.rollup.js';
import {getCss} from './pack_dialog.css.js';
import {getHtml} from './pack_dialog.html.js';
export interface PackDialogDelegate {
/**
* Opens a file browser for the user to select the root directory.
* @return A promise that is resolved with the path the user selected.
*/
choosePackRootDirectory(): Promise<string>;
/**
* Opens a file browser for the user to select the private key file.
* @return A promise that is resolved with the path the user selected.
*/
choosePrivateKeyPath(): Promise<string>;
/** Packs the extension into a .crx. */
packExtension(rootPath: string, keyPath: string, flag?: number):
Promise<chrome.developerPrivate.PackDirectoryResponse>;
}
class DummyPackDialogDelegate implements PackDialogDelegate {
choosePackRootDirectory() {
return Promise.resolve('');
}
choosePrivateKeyPath() {
return Promise.resolve('');
}
packExtension(_rootPath: string, _keyPath: string, _flag?: number) {
return Promise.resolve({
message: '',
item_path: '',
pem_path: '',
override_flags: 0,
status: chrome.developerPrivate.PackStatus.SUCCESS,
});
}
}
export interface ExtensionsPackDialogElement {
$: {
dialog: CrDialogElement,
keyFileBrowse: HTMLElement,
keyFile: CrInputElement,
rootDirBrowse: HTMLElement,
rootDir: CrInputElement,
};
}
export class ExtensionsPackDialogElement extends CrLitElement {
static get is() {
return 'extensions-pack-dialog';
}
static override get styles() {
return getCss();
}
override render() {
return getHtml.bind(this)();
}
static override get properties() {
return {
delegate: {type: Object},
packDirectory_: {type: String},
keyFile_: {type: String},
lastResponse_: {type: Object},
};
}
accessor delegate: PackDialogDelegate = new DummyPackDialogDelegate();
protected accessor packDirectory_: string = '';
protected accessor keyFile_: string = '';
protected accessor lastResponse_:
chrome.developerPrivate.PackDirectoryResponse|null = null;
protected onKeyFileChanged_(e: CustomEvent<{value: string}>) {
this.keyFile_ = e.detail.value;
}
protected onPackDirectoryChanged_(e: CustomEvent<{value: string}>) {
this.packDirectory_ = e.detail.value;
}
protected onRootBrowse_() {
this.delegate.choosePackRootDirectory().then(path => {
if (path) {
this.packDirectory_ = path;
}
});
}
protected onKeyBrowse_() {
this.delegate.choosePrivateKeyPath().then(path => {
if (path) {
this.keyFile_ = path;
}
});
}
protected onCancelClick_() {
this.$.dialog.cancel();
}
protected onConfirmClick_() {
this.delegate.packExtension(this.packDirectory_, this.keyFile_, 0)
.then(response => this.onPackResponse_(response));
}
/**
* @param response The response from request to pack an extension.
*/
private onPackResponse_(response:
chrome.developerPrivate.PackDirectoryResponse) {
this.lastResponse_ = response;
}
/**
* In the case that the alert dialog was a success message, the entire
* pack-dialog should close. Otherwise, we detach the alert by setting
* lastResponse_ null. Additionally, if the user selected "proceed anyway"
* in the dialog, we pack the extension again with override flags.
*/
protected onAlertClose_(e: Event) {
e.stopPropagation();
if (this.lastResponse_!.status ===
chrome.developerPrivate.PackStatus.SUCCESS) {
this.$.dialog.close();
return;
}
// This is only possible for a warning dialog.
if (this.shadowRoot.querySelector(
'extensions-pack-dialog-alert')!.returnValue ===
'success') {
this.delegate
.packExtension(
this.lastResponse_!.item_path, this.lastResponse_!.pem_path,
this.lastResponse_!.override_flags)
.then(response => this.onPackResponse_(response));
}
this.lastResponse_ = null;
}
}
// Exported to be used in the autogenerated Lit template file
export type PackDialogElement = ExtensionsPackDialogElement;
declare global {
interface HTMLElementTagNameMap {
'extensions-pack-dialog': ExtensionsPackDialogElement;
}
}
customElements.define(
ExtensionsPackDialogElement.is, ExtensionsPackDialogElement);