Skip to content

Commit

Permalink
Merge pull request #46 from khawkins/two_way_messaging
Browse files Browse the repository at this point in the history
Webviews: Two-way messaging
  • Loading branch information
khawkins authored Oct 27, 2023
2 parents bcc9c93 + f384c8a commit 93e6fb3
Show file tree
Hide file tree
Showing 16 changed files with 574 additions and 179 deletions.
8 changes: 7 additions & 1 deletion resources/instructions/briefcase.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
Expand All @@ -20,6 +20,12 @@
If you've already configured a briefcase, move on to the next step.
</p>
<button id="okButton">OK</button>
<script>
const okButtonElement = document.getElementById('okButton');
okButtonElement.addEventListener('click', () => {
webviewMessaging.sendMessageRequest('okButton');
});
</script>
<script src="--- MESSAGING_SCRIPT_SRC ---"></script>
</body>
</html>
44 changes: 27 additions & 17 deletions resources/instructions/landingpage.html
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Landing Page Customization</title>
</head>

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Landing Page Customization</title>
</head>

<body>
<p id="message">A default landing page file (landing_page.json) has been created in the staticresources directory.
See <a href="https://help.salesforce.com/s/articleView?id=sf.salesforce_app_plus_offline_landing_page.htm&type=5">Customize The Landing Page</a>
for more information on how to modify the landing page file.
</p>
<button id="okButton">OK</button>
<script src="--- MESSAGING_SCRIPT_SRC ---"></script>
</body>

</html>
<body>
<p id="message">
A default landing page file (landing_page.json) has been created in
the staticresources directory. See
<a
href="https://help.salesforce.com/s/articleView?id=sf.salesforce_app_plus_offline_landing_page.htm&type=5"
>
Customize The Landing Page
</a>
for more information on how to modify the landing page file.
</p>
<button id="okButton">OK</button>
<script>
const okButtonElement = document.getElementById('okButton');
okButtonElement.addEventListener('click', () => {
webviewMessaging.sendMessageRequest('okButton');
});
</script>
<script src="--- MESSAGING_SCRIPT_SRC ---"></script>
</body>
</html>
8 changes: 7 additions & 1 deletion resources/instructions/projectBootstrapAcknowledgment.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
Expand All @@ -13,6 +13,12 @@
time to resume.
</p>
<button id="okButton">OK</button>
<script>
const okButtonElement = document.getElementById('okButton');
okButtonElement.addEventListener('click', () => {
webviewMessaging.sendMessageRequest('okButton');
});
</script>
<script src="--- MESSAGING_SCRIPT_SRC ---"></script>
</body>
</html>
10 changes: 9 additions & 1 deletion resources/instructions/projectBootstrapChoice.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
Expand All @@ -14,6 +14,14 @@ <h1>Welcome to the Offline App Onboarding Wizard</h1>
</p>
<button id="createNewButton">Create New Project</button>
<button id="openExistingButton">Open Existing Project</button>
<script>
for (const buttonId of ['createNewButton', 'openExistingButton']) {
const buttonElement = document.getElementById(buttonId);
buttonElement.addEventListener('click', () => {
webviewMessaging.sendMessageRequest(buttonId);
});
}
</script>
<script src="--- MESSAGING_SCRIPT_SRC ---"></script>
</body>
</html>
8 changes: 7 additions & 1 deletion resources/instructions/salesforcemobileapp.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
Expand All @@ -21,6 +21,12 @@
own.
</p>
<button id="okButton">OK</button>
<script>
const okButtonElement = document.getElementById('okButton');
okButtonElement.addEventListener('click', () => {
webviewMessaging.sendMessageRequest('okButton');
});
</script>
<script src="--- MESSAGING_SCRIPT_SRC ---"></script>
</body>
</html>
68 changes: 49 additions & 19 deletions resources/instructions/webviewMessaging.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,53 @@
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
*/

const vscode = acquireVsCodeApi();
// ------------------
// Callback Messaging
// ------------------
//
// Async, callback-based messaging mechanism for clients
//
const webviewMessaging = (function () {
const vscode = acquireVsCodeApi();
let requestId = 0;
const asyncMessageCallbacks = {};

// Set up button event handlers and message passing.
const buttons = document.getElementsByTagName("button");
if (!buttons || buttons.length === 0) {
console.error("No buttons found! No event handlers will be created.");
} else {
for (const button of buttons) {
const buttonId = button.getAttribute("id");
if (!buttonId) {
console.error(
"Button has no id value! No event handler will be created."
);
} else {
button.addEventListener("click", () => {
vscode.postMessage({ button: buttonId });
});
}
}
}
// Receives messages from the backing TypeScript controller page that
// created the hosted webview. These messages will be linked back to
// originating requests, passing any response data back to the async
// caller.
window.addEventListener('message', (event) => {
const message = event.data;
if (message.callbackId && asyncMessageCallbacks[message.callbackId]) {
const callback = asyncMessageCallbacks[message.callbackId];
delete asyncMessageCallbacks[message.callbackId];
delete message.callbackId;
callback(message);
}
});

return {
/**
* Sends a message request to the backing TypeScript controller page that
* created the hosted webview.
* @param {string} type - A name representing the type of request. Basically
* the event key to which the controller page will subscribe.
* @param {object} [data] - An optional block of input data to pass to the
* controller.
* @param {Function} [callback] - An optional callback for receiving a
* response from the controller, if expected.
*/
sendMessageRequest: function (type, data, callback) {
let message;
if (callback) {
const asyncMessageRequestId = ++requestId;
asyncMessageCallbacks[asyncMessageRequestId] = callback;

message = { type, callbackId: asyncMessageRequestId, ...data };
} else {
message = { type, ...data };
}
vscode.postMessage(message);
}
};
})();
2 changes: 1 addition & 1 deletion src/commands/wizard/authorizeCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class AuthorizeCommand {
if (!result || result.title === l10n.t('No')) {
return Promise.resolve(false);
} else {
await commands.executeCommand('sfdx.force.auth.web.login');
await commands.executeCommand('sfdx.org.login.web');
await window.showInformationMessage(
l10n.t(
"Once you've authorized your Org, click here to continue."
Expand Down
2 changes: 1 addition & 1 deletion src/commands/wizard/briefcaseCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import { ProgressLocation, Uri, window, l10n } from 'vscode';
import { CommonUtils } from '@salesforce/lwc-dev-mobile-core/lib/common/CommonUtils';
import { InstructionsWebviewProvider } from '../../webviews';
import { InstructionsWebviewProvider } from '../../webviews/instructions';

export class BriefcaseCommand {
static readonly OPEN_ORG_BRIEFCASE_PAGE_CMD =
Expand Down
8 changes: 4 additions & 4 deletions src/commands/wizard/configureProjectCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import { Uri, WebviewPanel, commands, l10n, window } from 'vscode';
import * as process from 'process';
import { CommonUtils } from '@salesforce/lwc-dev-mobile-core/lib/common/CommonUtils';
import { InstructionsWebviewProvider } from '../../webviews';
import { InstructionsWebviewProvider } from '../../webviews/instructions';

export type ProjectManagementChoiceAction = (panel?: WebviewPanel) => void;

Expand Down Expand Up @@ -41,7 +41,7 @@ export class DefaultProjectConfigurationProcessor
'resources/instructions/projectBootstrapAcknowledgment.html',
[
{
buttonId: 'okButton',
type: 'okButton',
action: async (panel) => {
panel.dispose();
return resolve();
Expand Down Expand Up @@ -98,13 +98,13 @@ export class DefaultProjectConfigurationProcessor
'resources/instructions/projectBootstrapChoice.html',
[
{
buttonId: 'createNewButton',
type: 'createNewButton',
action: (panel) => {
createChoice(panel);
}
},
{
buttonId: 'openExistingButton',
type: 'openExistingButton',
action: (panel) => {
openChoice(panel);
}
Expand Down
2 changes: 1 addition & 1 deletion src/commands/wizard/onboardingWizard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { BriefcaseCommand } from './briefcaseCommand';
import { DeployToOrgCommand } from './deployToOrgCommand';
import { ConfigureProjectCommand } from './configureProjectCommand';
import { AuthorizeCommand } from './authorizeCommand';
import { InstructionsWebviewProvider } from '../../webviews';
import { InstructionsWebviewProvider } from '../../webviews/instructions';

const wizardCommand = 'salesforcedx-vscode-offline-app.onboardingWizard';
const onboardingWizardStateKey =
Expand Down
2 changes: 1 addition & 1 deletion src/commands/wizard/templateChooserCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { UIUtils } from '../../utils/uiUtils';
import { workspace } from 'vscode';
import * as path from 'path';
import * as fs from 'fs';
import { InstructionsWebviewProvider } from '../../webviews';
import { InstructionsWebviewProvider } from '../../webviews/instructions';

export interface TemplateQuickPickItem extends QuickPickItem {
filenamePrefix: string;
Expand Down
2 changes: 1 addition & 1 deletion src/test/suite/commands/wizard/briefcaseCommand.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { afterEach, beforeEach } from 'mocha';
import { BriefcaseCommand } from '../../../../commands/wizard/briefcaseCommand';
import { Uri, l10n, window, Progress, CancellationToken } from 'vscode';
import { CommonUtils } from '@salesforce/lwc-dev-mobile-core/lib/common/CommonUtils';
import { InstructionsWebviewProvider } from '../../../../webviews';
import { InstructionsWebviewProvider } from '../../../../webviews/instructions';

suite('Briefcase Command Test Suite', () => {
beforeEach(function () {});
Expand Down
Loading

0 comments on commit 93e6fb3

Please sign in to comment.