@jiangzhongxi0322/messagechannel 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/README.md +181 -0
  2. package/dist/messageChannel.d.ts +10 -0
  3. package/dist/{messageChennel.js → messageChannel.js} +25 -8
  4. package/examples/command-webview-sample/.eslintrc.js +23 -0
  5. package/examples/command-webview-sample/.vscode/extensions.json +9 -0
  6. package/examples/command-webview-sample/.vscode/launch.json +18 -0
  7. package/examples/command-webview-sample/.vscode/settings.json +3 -0
  8. package/examples/command-webview-sample/.vscode/tasks.json +20 -0
  9. package/examples/command-webview-sample/README.md +47 -0
  10. package/examples/command-webview-sample/demo.gif +0 -0
  11. package/examples/command-webview-sample/media/cat.gif +0 -0
  12. package/examples/command-webview-sample/media/jsconfig.json +22 -0
  13. package/examples/command-webview-sample/media/main.js +41 -0
  14. package/examples/command-webview-sample/media/reset.css +30 -0
  15. package/examples/command-webview-sample/media/vscode.css +91 -0
  16. package/examples/command-webview-sample/package-lock.json +2764 -0
  17. package/examples/command-webview-sample/package.json +51 -0
  18. package/examples/command-webview-sample/src/extension.ts +227 -0
  19. package/{src/messageChennel.ts → examples/command-webview-sample/src/messageChannel.ts} +34 -21
  20. package/examples/command-webview-sample/tsconfig.json +12 -0
  21. package/examples/publish-webview-sample/.eslintrc.js +20 -0
  22. package/examples/publish-webview-sample/.vscode/extensions.json +9 -0
  23. package/examples/publish-webview-sample/.vscode/launch.json +18 -0
  24. package/examples/publish-webview-sample/.vscode/settings.json +3 -0
  25. package/examples/publish-webview-sample/.vscode/tasks.json +20 -0
  26. package/examples/publish-webview-sample/README.md +24 -0
  27. package/examples/publish-webview-sample/media/main.css +54 -0
  28. package/examples/publish-webview-sample/media/main.js +100 -0
  29. package/examples/publish-webview-sample/media/reset.css +30 -0
  30. package/examples/publish-webview-sample/media/vscode.css +91 -0
  31. package/examples/publish-webview-sample/package-lock.json +2720 -0
  32. package/examples/publish-webview-sample/package.json +71 -0
  33. package/examples/publish-webview-sample/src/extension.ts +170 -0
  34. package/examples/publish-webview-sample/src/messageChannel.ts +264 -0
  35. package/examples/publish-webview-sample/tsconfig.json +12 -0
  36. package/examples/url-webview-sample/.eslintignore +1 -0
  37. package/examples/url-webview-sample/.eslintrc.js +20 -0
  38. package/examples/url-webview-sample/.vscode/extensions.json +9 -0
  39. package/examples/url-webview-sample/.vscode/launch.json +18 -0
  40. package/examples/url-webview-sample/.vscode/settings.json +3 -0
  41. package/examples/url-webview-sample/.vscode/tasks.json +20 -0
  42. package/examples/url-webview-sample/README.md +25 -0
  43. package/examples/url-webview-sample/documentation/example.png +0 -0
  44. package/examples/url-webview-sample/exampleFiles/example.cscratch +14 -0
  45. package/examples/url-webview-sample/exampleFiles/example.pawDraw +0 -0
  46. package/examples/url-webview-sample/exampleFiles/log/python-kaleido-case-api.exe.log +1 -0
  47. package/examples/url-webview-sample/exampleFiles/log/python-request.exe.log +1 -0
  48. package/examples/url-webview-sample/exampleFiles/pump/config/default.json +1 -0
  49. package/examples/url-webview-sample/exampleFiles/test_cases/log/output_202511181702.log +6 -0
  50. package/examples/url-webview-sample/media/catScratch.css +65 -0
  51. package/examples/url-webview-sample/media/catScratch.js +100 -0
  52. package/examples/url-webview-sample/media/paw-color.svg +21 -0
  53. package/examples/url-webview-sample/media/paw-outline.svg +21 -0
  54. package/examples/url-webview-sample/media/pawDraw.css +83 -0
  55. package/examples/url-webview-sample/media/pawDraw.js +266 -0
  56. package/examples/url-webview-sample/media/reset.css +30 -0
  57. package/examples/url-webview-sample/media/sand-dark.jpg +0 -0
  58. package/examples/url-webview-sample/media/sand.jpg +0 -0
  59. package/examples/url-webview-sample/media/vscode.css +91 -0
  60. package/examples/url-webview-sample/package-lock.json +2751 -0
  61. package/examples/url-webview-sample/package.json +64 -0
  62. package/examples/url-webview-sample/src/catScratchEditor.ts +215 -0
  63. package/examples/url-webview-sample/src/dispose.ts +37 -0
  64. package/examples/url-webview-sample/src/extension.ts +7 -0
  65. package/examples/url-webview-sample/src/messageChannel.ts +264 -0
  66. package/examples/url-webview-sample/src/util.ts +8 -0
  67. package/examples/url-webview-sample/tsconfig.json +13 -0
  68. package/package.json +1 -1
  69. package/src/messageChannel.ts +264 -0
  70. package/dist/messageChennel.d.ts +0 -15
@@ -0,0 +1,65 @@
1
+ body {
2
+ justify-content: center;
3
+ align-items: center;
4
+ margin: 1em 2em;
5
+ background-image: url(./sand.jpg);
6
+ background-repeat: repeat;
7
+ }
8
+
9
+ body.vscode-dark {
10
+ background-image: url(./sand-dark.jpg);
11
+ }
12
+
13
+ .notes {
14
+ display: grid;
15
+ grid-template-columns: repeat(auto-fill, 100px);
16
+ grid-template-rows: repeat(auto-fill, 100px);
17
+ grid-gap: 2em;
18
+ justify-content: center;
19
+ }
20
+
21
+ .note {
22
+ display: flex;
23
+ flex-direction: column;
24
+ border-radius: 5px;
25
+ background-color: var(--vscode-editor-background);
26
+ text-align: center;
27
+ padding: 0.6em;
28
+ position: relative;
29
+ overflow: hidden;
30
+ }
31
+
32
+ .note .text {
33
+ flex: 1;
34
+ font-size: 3em;
35
+ display: flex;
36
+ justify-content: center;
37
+ align-items: center;
38
+ }
39
+
40
+ .note .created {
41
+ font-style: italic;
42
+ font-size: 0.75em;
43
+ }
44
+
45
+ .add-button {
46
+ height: 100px;
47
+ display: flex;
48
+ justify-content: center;
49
+ align-items: center;
50
+ }
51
+
52
+ .delete-button {
53
+ position: absolute;
54
+ top: 0;
55
+ right: 0;
56
+ display: none;
57
+ }
58
+
59
+ .delete-button:before {
60
+ content: 'delete';
61
+ }
62
+
63
+ .note:hover .delete-button {
64
+ display: block;
65
+ }
@@ -0,0 +1,100 @@
1
+ // @ts-check
2
+
3
+ // Script run within the webview itself.
4
+ (function () {
5
+
6
+ // Get a reference to the VS Code webview api.
7
+ // We use this API to post messages back to our extension.
8
+
9
+ // @ts-ignore
10
+ const vscode = acquireVsCodeApi();
11
+
12
+
13
+ const notesContainer = /** @type {HTMLElement} */ (document.querySelector('.notes'));
14
+
15
+ const addButtonContainer = document.querySelector('.add-button');
16
+ addButtonContainer.querySelector('button').addEventListener('click', () => {
17
+ vscode.postMessage({
18
+ type: 'add'
19
+ });
20
+ })
21
+
22
+ const errorContainer = document.createElement('div');
23
+ document.body.appendChild(errorContainer);
24
+ errorContainer.className = 'error'
25
+ errorContainer.style.display = 'none'
26
+
27
+ /**
28
+ * Render the document in the webview.
29
+ */
30
+ function updateContent(/** @type {string} */ text) {
31
+ let json;
32
+ try {
33
+ if (!text) {
34
+ text = '{}';
35
+ }
36
+ json = JSON.parse(text);
37
+ } catch {
38
+ notesContainer.style.display = 'none';
39
+ errorContainer.innerText = 'Error: Document is not valid json';
40
+ errorContainer.style.display = '';
41
+ return;
42
+ }
43
+ notesContainer.style.display = '';
44
+ errorContainer.style.display = 'none';
45
+
46
+ // Render the scratches
47
+ notesContainer.innerHTML = '';
48
+ for (const note of json.scratches || []) {
49
+ const element = document.createElement('div');
50
+ element.className = 'note';
51
+ notesContainer.appendChild(element);
52
+
53
+ const text = document.createElement('div');
54
+ text.className = 'text';
55
+ const textContent = document.createElement('span');
56
+ textContent.innerText = note.text;
57
+ text.appendChild(textContent);
58
+ element.appendChild(text);
59
+
60
+ const created = document.createElement('div');
61
+ created.className = 'created';
62
+ created.innerText = new Date(note.created).toUTCString();
63
+ element.appendChild(created);
64
+
65
+ const deleteButton = document.createElement('button');
66
+ deleteButton.className = 'delete-button';
67
+ deleteButton.addEventListener('click', () => {
68
+ vscode.postMessage({ type: 'delete', id: note.id, });
69
+ });
70
+ element.appendChild(deleteButton);
71
+ }
72
+
73
+ notesContainer.appendChild(addButtonContainer);
74
+ }
75
+
76
+ // Handle messages sent from the extension to the webview
77
+ window.addEventListener('message', event => {
78
+ const message = event.data; // The json data that the extension sent
79
+ switch (message.type) {
80
+ case 'update':
81
+ const text = message.text;
82
+
83
+ // Update our webview's content
84
+ updateContent(text);
85
+
86
+ // Then persist state information.
87
+ // This state is returned in the call to `vscode.getState` below when a webview is reloaded.
88
+ vscode.setState({ text });
89
+
90
+ return;
91
+ }
92
+ });
93
+
94
+ // Webviews are normally torn down when not visible and re-created when they become visible again.
95
+ // State lets us save information across these re-loads
96
+ const state = vscode.getState();
97
+ if (state) {
98
+ updateContent(state.text);
99
+ }
100
+ }());
@@ -0,0 +1,21 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Generator: Adobe Illustrator 24.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
+ viewBox="0 0 40 50" style="enable-background:new 0 0 40 50;" xml:space="preserve">
5
+ <style type="text/css">
6
+ </style>
7
+ <g class="st0">
8
+ <g>
9
+ <path d="M16.5,2.2c-1.4,0-2.6,0.5-3.8,1.2c-0.2-0.9-0.1-1.7,0.4-2.5c0.2-0.4,0.7-0.4,1.1-0.1C15,1.3,15.7,1.8,16.5,2.2z"/>
10
+ <path d="M6.5,10c-0.9,0.4-1.5,1.2-2.3,1.8C4,11,3.7,10.3,3.6,9.6s0.2-1,1-0.8C5.3,9.1,5.9,9.5,6.5,10z"/>
11
+ <path d="M29.2,3.4c-0.8-0.3-1.6-0.5-2.5-0.8c0-0.1,0.1-0.1,0.1-0.2c0.6-0.5,1.2-1.6,1.9-1.3C29.6,1.5,29.1,2.6,29.2,3.4z"/>
12
+ <path d="M36.2,11.9c-0.3-0.6-0.7-1.2-1-1.7c0.5-0.4,1-1.1,1.6-0.7c0.7,0.5-0.1,1.1-0.2,1.7C36.5,11.4,36.3,11.6,36.2,11.9z"/>
13
+ <path d="M21.1,15.1c3.1,0.1,5.2,1.8,6.4,4.5c0.3,0.7,0.5,1.4,0.7,2.1c0.8,3.2-1.8,5.8-5,4.9c-1.4-0.4-2.7-0.6-4.1-0.3
14
+ c-0.9,0.2-1.7,0.1-2.6-0.3c-3.3-1.3-4.1-4-2-6.9c1.3-1.7,2.7-3.2,4.9-3.9C20,15.2,20.5,15.1,21.1,15.1z"/>
15
+ <path d="M15.6,15.6c0,1.9-1.6,3.5-3.5,3.5c-1.7,0-3.2-1.4-3.2-2.9c0-2.2,1.6-4,3.6-4C14.2,12.2,15.6,13.8,15.6,15.6z"/>
16
+ <path d="M17.7,13.1c-2,0-3.2-1-3.2-2.8c0-2.6,0.9-3.8,3-3.8c2,0,3.5,1.4,3.5,3.3C21.1,11.9,19.9,13.1,17.7,13.1z"/>
17
+ <path d="M27.8,10.6c0,1.8-1.2,3-3.1,3c-1.6,0-2.9-1.7-2.9-3.7c0-1.7,1.1-2.8,2.8-2.8C26.6,7.1,27.8,8.4,27.8,10.6z"/>
18
+ <path d="M32.5,16c0,1.7-1.1,2.9-2.6,2.8c-1.6-0.1-3-1.5-2.9-3.2c0-1.7,1.1-2.7,2.8-2.7C31.6,13,32.6,14.1,32.5,16z"/>
19
+ </g>
20
+ </g>
21
+ </svg>
@@ -0,0 +1,21 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Generator: Adobe Illustrator 24.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
+ viewBox="0 0 40 50" style="enable-background:new 0 0 40 50;" xml:space="preserve">
5
+ <style type="text/css">
6
+ </style>
7
+ <g class="st0">
8
+ <path d="M6.5,10c0.9-0.4,1.8-0.5,2.8-0.5c0.8,0,1.1-0.2,1-1c-0.2-2.2,0.8-3.8,2.4-5c1.2-0.8,2.4-1.2,3.8-1.2c1.6-0.1,3,0.5,4.2,1.5
9
+ c0.5,0.5,0.9,0.4,1.5,0c1.3-1,2.9-1,4.5-1.1c0.8,0.3,1.6,0.5,2.5,0.8c1.4,1,2.2,2.3,2.4,4c0.1,0.5,0.2,0.7,0.7,0.9
10
+ c1.2,0.3,2,1.1,3,1.8c0.3,0.6,0.7,1.2,1,1.7c0.6,2.5,1.1,4.9,0.1,7.4c-0.5,1.2-1.2,2.2-2.5,2.8c-0.7,0.3-1,0.8-1.2,1.5
11
+ c-0.5,2.1-1.3,4-1.7,6.1c-0.1,0.7-0.4,1.4-1,1.9c-1.1,1-1.4,2.4-1.4,3.8c-0.2,4.7,6.7,10.8-2.2,13.5c-5.8,0-13.6,0.9-15.1-2.2
12
+ c-1.7-3.7,0-4.7,0-8.8c0-2.2-0.3-4.3-1.9-6.1c-0.8-0.9-0.9-2.2-0.9-3.4c0-1.1-0.4-1.8-1.1-2.5C4.7,23.2,3.5,20,3,16.4
13
+ c-0.2-1.7,0.2-3.2,1.1-4.6C5,11.2,5.6,10.4,6.5,10z M21.1,15.1c-0.6,0-1.1,0.1-1.6,0.2c-2.1,0.6-3.6,2.1-4.9,3.9
14
+ c-2.1,2.8-1.3,5.6,2,6.9c0.8,0.3,1.7,0.4,2.6,0.3c1.4-0.2,2.7-0.1,4.1,0.3c3.2,0.9,5.8-1.6,5-4.9c-0.2-0.7-0.4-1.5-0.7-2.1
15
+ C26.2,16.9,24.2,15.2,21.1,15.1z M15.6,15.6c0-1.8-1.4-3.4-3.1-3.5c-2,0-3.6,1.8-3.6,4c0,1.6,1.5,2.9,3.2,2.9
16
+ C14,19.1,15.5,17.6,15.6,15.6z M17.7,13.1c2.1,0,3.3-1.2,3.3-3.4c0-1.9-1.5-3.3-3.5-3.3c-2.1,0-3,1.2-3,3.8
17
+ C14.6,12.1,15.7,13.1,17.7,13.1z M27.8,10.6c0-2.1-1.2-3.4-3.2-3.4c-1.7,0-2.7,1-2.8,2.8c0,2.1,1.3,3.7,2.9,3.7
18
+ C26.5,13.6,27.8,12.4,27.8,10.6z M32.5,16c0-1.9-1-3-2.7-3.1c-1.7,0-2.8,1-2.8,2.7c0,1.6,1.3,3.1,2.9,3.2
19
+ C31.4,18.9,32.5,17.7,32.5,16z"/>
20
+ </g>
21
+ </svg>
@@ -0,0 +1,83 @@
1
+ html, body {
2
+ height: 100%;
3
+ }
4
+
5
+ .drawing-canvas {
6
+ width: 100%;
7
+ height: 100%;
8
+ flex: 1;
9
+ display: flex;
10
+ justify-content: center;
11
+ align-items: center;
12
+ background-repeat: repeat;
13
+ flex-direction: column;
14
+ }
15
+
16
+ .drawing-controls {
17
+ position: fixed;
18
+ bottom: 0;
19
+ left: 0;
20
+ width: 100%;
21
+ display: flex;
22
+ justify-content: center;
23
+ }
24
+
25
+ .drawing-controls button {
26
+ position: relative;
27
+ width: 100px;
28
+ height: 100px;
29
+ background: none;
30
+ border: none;
31
+ transform: translateY(30%);
32
+ transition: transform 0.1s linear;
33
+ outline: none;
34
+ }
35
+
36
+ .drawing-controls button:disabled {
37
+ opacity: 0.5;
38
+ }
39
+
40
+ .drawing-controls button.active:not(:disabled),
41
+ .drawing-controls button:hover:not(:disabled) {
42
+ transform: translateY(10%);
43
+ }
44
+
45
+ .drawing-controls button:before,
46
+ .drawing-controls button:after {
47
+ display: block;
48
+ content: '';
49
+ position: absolute;
50
+ top: 0;
51
+ left: 0;
52
+ width: 100%;
53
+ height: 100%;
54
+ }
55
+
56
+ .drawing-controls button:before {
57
+ -webkit-mask: url("./paw-color.svg") no-repeat 50% 50%;
58
+ }
59
+
60
+ .drawing-controls button:after {
61
+ background-color: #111;
62
+ -webkit-mask: url("./paw-outline.svg") no-repeat 50% 50%;
63
+ }
64
+
65
+ .drawing-controls button.black:before {
66
+ background-color: #333;
67
+ }
68
+
69
+ .drawing-controls button.white:before {
70
+ background-color: white;
71
+ }
72
+
73
+ .drawing-controls button.red:before {
74
+ background-color: red;
75
+ }
76
+
77
+ .drawing-controls button.green:before {
78
+ background-color: green;
79
+ }
80
+
81
+ .drawing-controls button.blue:before {
82
+ background-color: blue;
83
+ }
@@ -0,0 +1,266 @@
1
+ // @ts-check
2
+
3
+ // This script is run within the webview itself
4
+ (function () {
5
+ // @ts-ignore
6
+ const vscode = acquireVsCodeApi();
7
+
8
+ /**
9
+ * A drawn line.
10
+ */
11
+ class Stroke {
12
+ constructor(/** @type {string} */ color, /** @type {Array<[number, number]> | undefined} */ stroke) {
13
+ this.color = color;
14
+ /** @type {Array<[number, number]>} */
15
+ this.stroke = stroke || [];
16
+ }
17
+
18
+ addPoint(/** @type {number} */ x, /** @type {number} */ y) {
19
+ this.stroke.push([x, y])
20
+ }
21
+ }
22
+
23
+ /**
24
+ * @param {Uint8Array} initialContent
25
+ * @return {Promise<HTMLImageElement>}
26
+ */
27
+ async function loadImageFromData(initialContent) {
28
+ const blob = new Blob([initialContent], { 'type': 'image/png' });
29
+ const url = URL.createObjectURL(blob);
30
+ try {
31
+ const img = document.createElement('img');
32
+ img.crossOrigin = 'anonymous';
33
+ img.src = url;
34
+ await new Promise((resolve, reject) => {
35
+ img.onload = resolve;
36
+ img.onerror = reject;
37
+ });
38
+ return img;
39
+ } finally {
40
+ URL.revokeObjectURL(url);
41
+ }
42
+ }
43
+
44
+ class PawDrawEditor {
45
+ constructor( /** @type {HTMLElement} */ parent) {
46
+ this.ready = false;
47
+
48
+ this.editable = false;
49
+
50
+ this.drawingColor = 'black';
51
+
52
+ /** @type {Array<Stroke>} */
53
+ this.strokes = [];
54
+
55
+ /** @type {Stroke | undefined} */
56
+ this.currentStroke = undefined;
57
+
58
+ this._initElements(parent);
59
+ }
60
+
61
+ addPoint(/** @type {number} */ x, /** @type {number} */ y) {
62
+ if (this.currentStroke) {
63
+ this.currentStroke.addPoint(x, y)
64
+ }
65
+ }
66
+
67
+ beginStoke(/** @type {string} */ color) {
68
+ this.currentStroke = new Stroke(color);
69
+ this.strokes.push(this.currentStroke);
70
+ }
71
+
72
+ endStroke() {
73
+ const previous = this.currentStroke;
74
+ this.currentStroke = undefined;
75
+ return previous;
76
+ }
77
+
78
+ setEditable(editable) {
79
+ this.editable = editable;
80
+ const colorButtons = /** @type {NodeListOf<HTMLButtonElement>} */ (document.querySelectorAll('.drawing-controls button'));
81
+ for (const colorButton of colorButtons) {
82
+ colorButton.disabled = !editable;
83
+ }
84
+ }
85
+
86
+ _initElements(/** @type {HTMLElement} */ parent) {
87
+ const colorButtons = /** @type {NodeListOf<HTMLButtonElement>} */ (document.querySelectorAll('.drawing-controls button'));
88
+ for (const colorButton of colorButtons) {
89
+ colorButton.addEventListener('click', e => {
90
+ e.stopPropagation();
91
+ colorButtons.forEach(button => button.classList.remove('active'));
92
+ colorButton.classList.add('active');
93
+ this.drawingColor = colorButton.dataset['color'];
94
+ });
95
+ }
96
+
97
+ this.wrapper = document.createElement('div');
98
+ this.wrapper.style.position = 'relative';
99
+ parent.append(this.wrapper);
100
+
101
+ this.initialCanvas = document.createElement('canvas');
102
+ this.initialCtx = this.initialCanvas.getContext('2d');
103
+ this.wrapper.append(this.initialCanvas);
104
+
105
+ this.drawingCanvas = document.createElement('canvas');
106
+ this.drawingCanvas.style.position = 'absolute';
107
+ this.drawingCanvas.style.top = '0';
108
+ this.drawingCanvas.style.left = '0';
109
+ this.drawingCtx = this.drawingCanvas.getContext('2d');
110
+ this.wrapper.append(this.drawingCanvas);
111
+
112
+ let isDrawing = false;
113
+
114
+ parent.addEventListener('mousedown', () => {
115
+ if (!this.ready || !this.editable) {
116
+ return;
117
+ }
118
+
119
+ this.beginStoke(this.drawingColor);
120
+ this.drawingCtx.strokeStyle = this.drawingColor;
121
+
122
+ isDrawing = true;
123
+ document.body.classList.add('isDrawing');
124
+ this.drawingCtx.beginPath();
125
+ });
126
+
127
+ document.body.addEventListener('mouseup', async () => {
128
+ if (!isDrawing || !this.ready || !this.editable) {
129
+ return;
130
+ }
131
+
132
+ isDrawing = false;
133
+ document.body.classList.remove('isDrawing');
134
+ this.drawingCtx.closePath();
135
+
136
+ const edit = this.endStroke();
137
+
138
+ if (edit.stroke.length) {
139
+ vscode.postMessage({
140
+ type: 'stroke',
141
+ color: edit.color,
142
+ stroke: edit.stroke,
143
+ });
144
+ }
145
+ });
146
+
147
+ parent.addEventListener('mousemove', e => {
148
+ if (!isDrawing || !this.ready || !this.editable) {
149
+ return;
150
+ }
151
+ const rect = this.wrapper.getBoundingClientRect();
152
+ const x = e.clientX - rect.left;
153
+ const y = e.clientY - rect.top;
154
+ this.drawingCtx.lineTo(x, y);
155
+ this.drawingCtx.stroke();
156
+ this.addPoint(x, y);
157
+ });
158
+ }
159
+
160
+ _redraw() {
161
+ this.drawingCtx.clearRect(0, 0, this.drawingCanvas.width, this.drawingCanvas.height);
162
+ for (const stroke of this.strokes) {
163
+ this.drawingCtx.strokeStyle = stroke.color;
164
+ this.drawingCtx.beginPath();
165
+ for (const [x, y] of stroke.stroke) {
166
+ this.drawingCtx.lineTo(x, y);
167
+ }
168
+ this.drawingCtx.stroke();
169
+ this.drawingCtx.closePath();
170
+ }
171
+ }
172
+
173
+ /**
174
+ * @param {Uint8Array | undefined} data
175
+ * @param {Array<Stroke> | undefined} strokes
176
+ */
177
+ async reset(data, strokes = []) {
178
+ if (data) {
179
+ const img = await loadImageFromData(data);
180
+ this.initialCanvas.width = this.drawingCanvas.width = img.naturalWidth;
181
+ this.initialCanvas.height = this.drawingCanvas.height = img.naturalHeight;
182
+ this.initialCtx.drawImage(img, 0, 0);
183
+ this.ready = true;
184
+ }
185
+
186
+ this.strokes = strokes;
187
+ this._redraw();
188
+ }
189
+
190
+ /**
191
+ * @param {Array<Stroke> | undefined} strokes
192
+ */
193
+ async resetUntitled(strokes = []) {
194
+ const size = 100;
195
+ this.initialCanvas.width = this.drawingCanvas.width = size;
196
+ this.initialCanvas.height = this.drawingCanvas.height = size;
197
+
198
+ this.initialCtx.save();
199
+ {
200
+ this.initialCtx.fillStyle = 'white';
201
+ this.initialCtx.fillRect(0, 0, size, size);
202
+ }
203
+ this.initialCtx.restore();
204
+
205
+ this.ready = true;
206
+
207
+ this.strokes = strokes;
208
+ this._redraw();
209
+ }
210
+
211
+ /** @return {Promise<Uint8Array>} */
212
+ async getImageData() {
213
+ const outCanvas = document.createElement('canvas');
214
+ outCanvas.width = this.drawingCanvas.width;
215
+ outCanvas.height = this.drawingCanvas.height;
216
+
217
+ const outCtx = outCanvas.getContext('2d');
218
+ outCtx.drawImage(this.initialCanvas, 0, 0);
219
+ outCtx.drawImage(this.drawingCanvas, 0, 0);
220
+
221
+ const blob = await new Promise(resolve => {
222
+ outCanvas.toBlob(resolve, 'image/png')
223
+ });
224
+
225
+ return new Uint8Array(await blob.arrayBuffer());
226
+ }
227
+ }
228
+
229
+ const editor = new PawDrawEditor(document.querySelector('.drawing-canvas'));
230
+
231
+ // Handle messages from the extension
232
+ window.addEventListener('message', async e => {
233
+ const { type, body, requestId } = e.data;
234
+ switch (type) {
235
+ case 'init':
236
+ {
237
+ editor.setEditable(body.editable);
238
+ if (body.untitled) {
239
+ await editor.resetUntitled();
240
+ return;
241
+ } else {
242
+ // Load the initial image into the canvas.
243
+ await editor.reset(body.value);
244
+ return;
245
+ }
246
+ }
247
+ case 'update':
248
+ {
249
+ const strokes = body.edits.map(edit => new Stroke(edit.color, edit.stroke));
250
+ await editor.reset(body.content, strokes)
251
+ return;
252
+ }
253
+ case 'getFileData':
254
+ {
255
+ // Get the image data for the canvas and post it back to the extension.
256
+ editor.getImageData().then(data => {
257
+ vscode.postMessage({ type: 'response', requestId, body: Array.from(data) });
258
+ });
259
+ return;
260
+ }
261
+ }
262
+ });
263
+
264
+ // Signal to VS Code that the webview is initialized.
265
+ vscode.postMessage({ type: 'ready' });
266
+ }());
@@ -0,0 +1,30 @@
1
+ html {
2
+ box-sizing: border-box;
3
+ font-size: 13px;
4
+ }
5
+
6
+ *,
7
+ *:before,
8
+ *:after {
9
+ box-sizing: inherit;
10
+ }
11
+
12
+ body,
13
+ h1,
14
+ h2,
15
+ h3,
16
+ h4,
17
+ h5,
18
+ h6,
19
+ p,
20
+ ol,
21
+ ul {
22
+ margin: 0;
23
+ padding: 0;
24
+ font-weight: normal;
25
+ }
26
+
27
+ img {
28
+ max-width: 100%;
29
+ height: auto;
30
+ }
@@ -0,0 +1,91 @@
1
+ :root {
2
+ --container-paddding: 20px;
3
+ --input-padding-vertical: 6px;
4
+ --input-padding-horizontal: 4px;
5
+ --input-margin-vertical: 4px;
6
+ --input-margin-horizontal: 0;
7
+ }
8
+
9
+ body {
10
+ padding: 0 var(--container-paddding);
11
+ color: var(--vscode-foreground);
12
+ font-size: var(--vscode-font-size);
13
+ font-weight: var(--vscode-font-weight);
14
+ font-family: var(--vscode-font-family);
15
+ background-color: var(--vscode-editor-background);
16
+ }
17
+
18
+ ol,
19
+ ul {
20
+ padding-left: var(--container-paddding);
21
+ }
22
+
23
+ body > *,
24
+ form > * {
25
+ margin-block-start: var(--input-margin-vertical);
26
+ margin-block-end: var(--input-margin-vertical);
27
+ }
28
+
29
+ *:focus {
30
+ outline-color: var(--vscode-focusBorder) !important;
31
+ }
32
+
33
+ a {
34
+ color: var(--vscode-textLink-foreground);
35
+ }
36
+
37
+ a:hover,
38
+ a:active {
39
+ color: var(--vscode-textLink-activeForeground);
40
+ }
41
+
42
+ code {
43
+ font-size: var(--vscode-editor-font-size);
44
+ font-family: var(--vscode-editor-font-family);
45
+ }
46
+
47
+ button {
48
+ border: none;
49
+ padding: var(--input-padding-vertical) var(--input-padding-horizontal);
50
+ width: 100%;
51
+ text-align: center;
52
+ outline: 1px solid transparent;
53
+ outline-offset: 2px !important;
54
+ color: var(--vscode-button-foreground);
55
+ background: var(--vscode-button-background);
56
+ }
57
+
58
+ button:hover {
59
+ cursor: pointer;
60
+ background: var(--vscode-button-hoverBackground);
61
+ }
62
+
63
+ button:focus {
64
+ outline-color: var(--vscode-focusBorder);
65
+ }
66
+
67
+ button.secondary {
68
+ color: var(--vscode-button-secondaryForeground);
69
+ background: var(--vscode-button-secondaryBackground);
70
+ }
71
+
72
+ button.secondary:hover {
73
+ background: var(--vscode-button-secondaryHoverBackground);
74
+ }
75
+
76
+ input:not([type='checkbox']),
77
+ textarea {
78
+ display: block;
79
+ width: 100%;
80
+ border: none;
81
+ font-family: var(--vscode-font-family);
82
+ padding: var(--input-padding-vertical) var(--input-padding-horizontal);
83
+ color: var(--vscode-input-foreground);
84
+ outline-color: var(--vscode-input-border);
85
+ background-color: var(--vscode-input-background);
86
+ }
87
+
88
+ input::placeholder,
89
+ textarea::placeholder {
90
+ color: var(--vscode-input-placeholderForeground);
91
+ }