全部产品
Search
文档中心

Cloud Phone:Tempel teks di browser Safari menggunakan Web SDK

更新时间:Dec 11, 2025

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

  1. Tambahkan tombol clipboard ke klien lokal. Saat diklik, tombol ini akan membuka kotak input berupa gelembung.

  2. Masukkan konten yang ingin Anda kirim ke cloud phone ke dalam kotak input gelembung tersebut.

  3. 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 readClipboardDataByUser ke `true`. Pengaturan ini mencegah software development kit (SDK) membaca clipboard secara otomatis.

  • Atur useCustomIme ke `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);