Skip to content

Commit b12e7a6

Browse files
committed
support copy and paste from context menu
1 parent 60a8603 commit b12e7a6

File tree

2 files changed

+69
-18
lines changed

2 files changed

+69
-18
lines changed

entry/src/main/ets/pages/TermWebView.ets

Lines changed: 64 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,61 @@
11
import { BuilderNode, NodeController } from "@kit.ArkUI";
2+
import { pasteboard } from '@kit.BasicServicesKit'
23
import { FULL_PERCENT } from "../model/TabStyle";
34
import { TermController } from "../model/TermController";
5+
import { util } from "@kit.ArkTS";
46

5-
@Builder
6-
function buildWebView(item: TermController) {
7-
Web({
8-
src: $rawfile('term.html'),
9-
controller: item.webviewController
10-
})
11-
.javaScriptProxy({
12-
object: item,
13-
name: 'native',
14-
methodList: ['sendInput', 'resize', 'load'],
15-
controller: item.webviewController,
16-
asyncMethodList: [],
17-
permission: `{
7+
@Component
8+
struct WebView {
9+
@Require item: TermController
10+
11+
@Builder
12+
contextMenu(webController: WebviewController) {
13+
Flex({
14+
direction: FlexDirection.Column
15+
}) {
16+
MenuItem({ content: '复制' })
17+
.width('100%')
18+
.onClick(async () => {
19+
const selection = await webController.runJavaScript('exports.copy()')
20+
if (selection !== '""') {
21+
let text: string = JSON.parse(selection);
22+
const board = pasteboard.getSystemPasteboard()
23+
const pasteData = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, text)
24+
board.setData(pasteData)
25+
}
26+
})
27+
MenuItem() {
28+
PasteButton({ buttonType: ButtonType.ROUNDED_RECTANGLE })
29+
.onClick(async (event: ClickEvent, result: PasteButtonOnClickResult) => {
30+
if (PasteButtonOnClickResult.SUCCESS === result) {
31+
let board = pasteboard.getSystemPasteboard();
32+
const data = await board.getData()
33+
const text = data.getPrimaryText()
34+
const array = util.TextEncoder.create().encodeInto(text)
35+
const base64 = new util.Base64Helper().encodeToStringSync(array)
36+
webController.runJavaScript(`exports.paste(atob('${base64}'))`)
37+
}
38+
})
39+
.width('100%')
40+
.align(Alignment.Start)
41+
.backgroundColor('#292e2b')
42+
}
43+
}
44+
.width('160vp')
45+
}
46+
47+
build() {
48+
Web({
49+
src: $rawfile('term.html'),
50+
controller: this.item.webviewController
51+
})
52+
.javaScriptProxy({
53+
object: this.item,
54+
name: 'native',
55+
methodList: ['sendInput', 'resize', 'load'],
56+
controller: this.item.webviewController,
57+
asyncMethodList: [],
58+
permission: `{
1859
"javascriptProxyPermission": {
1960
"urlPermissionList": [
2061
{
@@ -26,9 +67,16 @@ function buildWebView(item: TermController) {
2667
]
2768
}
2869
}`
29-
})
30-
.backgroundColor('#000')
31-
.height(FULL_PERCENT)
70+
})
71+
.backgroundColor('#000')
72+
.height(FULL_PERCENT)
73+
.bindContextMenu(this.contextMenu(this.item.webviewController), ResponseType.RightClick)
74+
}
75+
}
76+
77+
@Builder
78+
function buildWebView(item: TermController) {
79+
WebView({ item: item })
3280
}
3381

3482
export class TermWebView extends NodeController {

entry/src/main/resources/rawfile/term.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ window.onload = async function () {
2121
term.getPrefs().set('terminal-encoding', 'iso-2022');
2222
term.getPrefs().set('enable-resize-status', false);
2323
term.getPrefs().set('copy-on-select', false);
24+
term.getPrefs().set('mouse-right-click-paste', false);
2425
term.getPrefs().set('enable-clipboard-notice', false);
2526
term.getPrefs().set('screen-padding-size', 4);
2627
// Creating and preloading the <audio> element for this sometimes hangs WebKit on iOS 16 for some reason. Can be most easily reproduced by resetting a simulator and starting the app. System logs show Fig hanging while trying to do work.
@@ -44,6 +45,9 @@ function onTerminalReady() {
4445
exports.write = (data) => {
4546
term.io.writeUTF16(decoder.decode(lib.codec.stringToCodeUnitArray(data)));
4647
};
48+
exports.paste = (data) => {
49+
term.io.sendString(decoder.decode(lib.codec.stringToCodeUnitArray(data)));
50+
};
4751

4852
// hterm size updates native size
4953
exports.getSize = () => [term.screenSize.width, term.screenSize.height];
@@ -52,7 +56,7 @@ function onTerminalReady() {
5256
term.scrollPort_.screen_.contentEditable = false;
5357
term.blur();
5458
term.focus();
55-
exports.copy = () => term.copySelectionToClipboard();
59+
exports.copy = () => term.getSelectionText();
5660

5761
// focus
5862
// This listener blocks blur events that come in because the webview has lost first responder
@@ -127,5 +131,4 @@ function onTerminalReady() {
127131
io.print('To customize linux root filesystem or run x86_64, see harmonix_install_alpine \r\nand harmonix_run_alpine script.\r\n');
128132

129133
native.load();
130-
native.syncFocus();
131134
}

0 commit comments

Comments
 (0)