Safari menerapkan pembatasan keamanan yang menampilkan tombol gelembung tempel saat Anda mengakses clipboard. Hal ini dapat mengganggu sinkronisasi konten dari klien lokal ke cloud phone. Topik ini menjelaskan cara menggunakan Web SDK untuk menempelkan teks dari clipboard lokal ke browser Safari.
Ikhtisar solusi
Tambahkan tombol clipboard ke klien lokal. Saat diklik, tombol ini akan membuka kotak input berupa gelembung.
Masukkan konten yang ingin Anda kirim ke cloud phone ke dalam kotak input gelembung tersebut.
Klik tombol Paste Now di dalam kotak input gelembung untuk menyinkronkan konten ke clipboard dan kotak input cloud phone.
Langkah implementasi
Konfigurasi parameter cloud phone
Atur
readClipboardDataByUserke `true`. Pengaturan ini mencegah software development kit (SDK) membaca clipboard secara otomatis.Atur
useCustomImeke `true` untuk mengaktifkan local input method editor (IME). IME lokal harus diaktifkan agar konten dapat disinkronkan ke kotak input cloud phone.
// Periksa apakah browser adalah Safari
function isSafari() {
return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
}
// Konfigurasi kontrol utama. Nonaktifkan pembacaan clipboard otomatis oleh SDK dan aktifkan IME lokal.
connConfig = {..., readClipboardDataByUser:isSafari(), useCustomIme:true};
var appInfo = {
...,
connConfig: connConfig,
...
};
var sessionParam = {
...,
appInfo: appInfo,
....
};
var wuyingSdk = Wuying.WebSDK;
session = wuyingSdk.createSession('appstream', sessionParam);
// Konfigurasi thumbnail. Aktifkan IME lokal.
this.thumbnail = new window.Wuying.ThumbnailSDK({
...,
connectionConfig: {
useCustomIme: true,
},
},
{
onConnected: (data) => {
this.thumbnail.session.getLocalConfig().setClipboardEnabled(true);
},
onDisConnected: (data) => {},
onThumbnailData: (url) => {},
}
);Buat kotak input gelembung
Anda dapat membuat tombol clipboard di klien. Saat diklik, tombol ini membuka dialog yang berinteraksi dengan clipboard. Sebagai referensi, lihat kode berikut:
function showInput() {
showCustomDialog();
// Klik overlay modal untuk menutup dialog
document.querySelector('.modal-overlay').addEventListener('click', function (e) {
if (e.target === this) {
closeModal();
}
});
// Tekan tombol ESC untuk menutup dialog
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape') {
closeModal();
}
});
}
function closeModal() {
console.log('closeModal');
const overlay = document.querySelector('.modal-overlay');
if (overlay) {
overlay.style.display = 'none';
overlay.remove();
}
}
function submitContent() {
const content = document.querySelector('.input-field').value.trim();
if (!content) {
alert('Please enter content');
return;
}
// Sinkronkan konten ke cloud phone
sendMsgToCloudPhoneOperation(content);
closeModal();
}
function showCustomDialog() {
// Buat latar belakang modal
const overlay = document.createElement('div');
overlay.className = 'modal-overlay';
// Pastikan modal menangkap semua event dan ditampilkan di level tertinggi
overlay.style.pointerEvents = 'all';
overlay.style.zIndex = '9999';
// Cegah event menyebar ke lapisan di bawahnya
const stopPropagation = function(e) {
e.stopPropagation();
};
overlay.addEventListener('contextmenu', stopPropagation, true);
// Tambahkan listener event untuk mengintersepsi semua event keyboard
overlay.addEventListener('keydown', stopPropagation, true);
overlay.addEventListener('keyup', stopPropagation, true);
overlay.addEventListener('keypress', stopPropagation, true);
overlay.innerHTML = `
<div class="modal">
<div class="modal-header">
<h2 class="modal-title">Clipboard</h2>
<button class="close-btn" onclick="closeModal()">×</button>
</div>
<div class="input-container">
<textarea
class="input-field"
placeholder="Enter content"
maxlength="500"
></textarea>
</div>
<button class="submit-btn" onclick="submitContent()">
Paste Now
</button>
</div>
`;
document.body.appendChild(overlay);
// Fokuskan textarea saat modal terbuka agar event keyboard tertangkap
setTimeout(() => {
const textarea = overlay.querySelector('.input-field');
if (textarea) {
textarea.focus();
}
}, 100);
}Kirim teks yang disalin ke cloud phone
Picu tugas sinkronisasi
function submitContent() {
const content = document.querySelector('.input-field').value.trim();
if (!content) {
alert('Please enter content');
return;
}
// Sinkronkan konten ke cloud phone
sendMsgToCloudPhoneOperation(content);
closeModal();
}Sinkronkan konten ke cloud phone
function sendMsgToCloudPhoneOperation(msg) {
// Kontrol utama
if (session) {
session.setClipboardModule('sendClipboardDataToRemote', msg)
}
// Thumbnail
for (const [key, value] of thumbnailSDKMap) {
console.log('thumbnail sendMsgToCloudPhoneOperation ', key, msg);
value.thumbnail.session.getClipboardModule().sendClipboardDataToRemote(msg);
}
}Catatan
Dialog baru harus menangani semua event keyboard agar tidak ditangkap oleh elemen desktop lainnya. Jika elemen lain menangkap event tersebut, penekanan tombol normal tidak akan terdaftar dengan benar di dalam dialog. Sebagai referensi, lihat konfigurasi berikut:
overlay.addEventListener('contextmenu', stopPropagation, true);
// Tambahkan listener event untuk mengintersepsi semua event keyboard
overlay.addEventListener('keydown', stopPropagation, true);
overlay.addEventListener('keyup', stopPropagation, true);
overlay.addEventListener('keypress', stopPropagation, true);