web-dev-qa-db-fra.com

Comment coller sur clic? Cela fonctionne dans google docs

Je veux pouvoir lancer un véritable événement de collage lorsque l'utilisateur clique. Je peux comprendre que cela peut être un problème de sécurité, car si une page Web avait accès au presse-papiers des utilisateurs, ce serait mauvais. J'ai donc pensé que tous les navigateurs interdisaient l'accès aux données du presse-papiers.

Mais par exemple dans google docs (dans l'application Word), je peux coller à partir du menu contextuel personnalisé (clic droit de la souris sur un élément html faisant semblant d'être un menu contextuel), même si les données du presse-papiers ont été copiées dans le presse-papiers dans différents application comme Microsoft Paint. Cela fonctionne dans Google Chrome, qui est le navigateur qui m'intéresse.

Je pensais qu'ils le faisaient en utilisant le flash, mais cela fonctionne toujours même si je désactive complètement le flash dans Chrome. Il y avait déjà une question à ce sujet, mais la réponse mentionnée n'est pas correcte. Une autre réponse à cette question suggère que Google utilise une extension chrome pour cela, mais cela fonctionne toujours même si je désactiver toutes les extensions dans Chrome.

Comment reproduire sous Windows:

  • désactiver le flash dans Chrome, désactiver toutes les extensions
  • redémarrer
  • allez dans google docs et ouvrez un nouveau document d'écriture vide (docs, pas une feuille de calcul)
  • exécuter l'application Microsoft Paint dans Windows
  • dessiner quelque chose dans Microsoft Paint, appuyez sur Ctrl + A pour tout sélectionner, Ctrl + C pour copier
  • revenir à chrome vers la page vide de la documentation et cliquer avec le bouton droit sur la page vide
  • sélectionnez Coller dans le menu contextuel artificiel (notez que le menu contextuel n'est pas le menu natif de Windows, mais qu'il provient de la page Web HTML de Google Docs)
  • vous verrez que l'image du presse-papiers a été collée dans le document docs (!)
  • comment font-ils ça?

Je sais comment accéder aux données du presse-papiers si l'utilisateur appuie sur Ctrl + V sur ma page Web, car cela déclenche l'événement Coller sur la fenêtre actuelle. Mais, comment puis-je accéder aux données du presse-papiers ou lancer le collage des données réelles du presse-papiers (par exemple, un bitmap copié dans mspaint) en javascript (ou en utilisant jquery) pendant que l'utilisateur clique simplement sur un bouton ou div?

30
Tomas M

Je veux pouvoir lancer un véritable événement de collage lorsque l'utilisateur clique. Je peux comprendre que cela peut être un problème de sécurité, car ...

Ce qui précède est la ligne de fond ..

Avoir ce code JS Fiddle

var Copy =  document.getElementById('copy'),
    Cut =  document.getElementById('cut'),
    Paste =  document.getElementById('paste');

// Checking Clipboard API without an action from the user
console.log('Copy:' + document.queryCommandSupported('copy'));
console.log('Cut:' + document.queryCommandSupported('cut'));
console.log('Paste:' + document.queryCommandSupported('paste'));


//Now checking the clipboard API upon a user action
Copy.addEventListener('click', function(){
    console.log('Copy:' + document.queryCommandSupported('copy'));
});

Cut.addEventListener('click', function(){
    console.log('Cut:' + document.queryCommandSupported('cut'));
});

Paste.addEventListener('click', function(){
    console.log('Paste:' + document.queryCommandSupported('paste'));
});
<button id="copy">Copy</button>
<button id="cut">Cut</button>
<button id="paste">Pate</button>

Si vous le vérifiez avec différents navigateurs, vous verrez comment les navigateurs réagissent différemment face à Clipboard API en utilisant queryCommandSupported() le résultat est:

Chrome 47:

  • Sans action de l'utilisateur, Copiez: false, Coupez: false, Passé: false
  • Avec l'action de l'utilisateur, Copiez: true, Coupez: true, Coller: false

Firefox 43:

  • Sans action de l'utilisateur, Copiez: true, Coupez: true, Passé: false
  • Avec l'action de l'utilisateur, Copiez: true, Coupez: true, Coller: false

IE11: - je crois que c'est la même chose dans Edge

  • Sans action de l'utilisateur, Copiez: true, Coupez: true, Passé: true
  • Avec l'action de l'utilisateur, Copiez: true, Coupez: true, Coller: true
  • Bien que toutes les options soient vraies, IE demande à l'utilisateur la permission pour toutes les actions ci-dessus.

Safari: - idem pour iOS Safari

  • Déclenche uniquement l'événement de copie sur une sélection valide et ne fait que copier-coller dans les champs modifiables ciblés.
  • Seul le presse-papiers du système d'exploitation lit/écrit via les touches de raccourci, pas via document.execCommand().

Pour une prise en charge détaillée des navigateurs pour l'API Clipboard caniuse.com/#search=clip

Les navigateurs prennent également en charge le collage en utilisant le menu contextuel du clic droit pour les éléments conteneditable="true" Comme dans ce JS Fiddle 2


Mais par exemple dans google docs (dans l'application Word), je peux coller à partir du menu contextuel personnalisé (clic droit de la souris sur un élément html faisant semblant d'être un menu contextuel), même si les données du presse-papiers ont été copiées dans le presse-papiers dans différents application comme Microsoft Paint.

Je pensais qu'ils le faisaient en utilisant le flash, mais cela fonctionne toujours même si je désactive complètement le flash en chrome.

De documentation Google Apps Script pour développer des modules complémentaires pour Google Apps :
" La plate-forme: L'éditeur de code d'Apps Script est une application Web que vous lancement à partir de Google Sheets, Docs ou Forms. La langue est basée sur JavaScript, but executes on Google's servers rather than directly in the user's browser (à l'exception des interfaces utilisateur côté client ... ".

Puisqu'il est exécuté sur leurs serveurs, je pense qu'ils peuvent activer certaines fonctionnalités, ou même utiliser Java, pour une meilleure expérience.


EDIT 1:
Si vous cochez clipboard.js , vous verrez que la bibliothèque n'a pas d'option pour "coller", seulement "copier" et "couper", également dans le "= Support du navigateur "à la fin de la page, vous verrez que la bibliothèque s'appuie sur l'API execCommand , et ne fonctionne pas dans Safari.


EDIT 2:
Lors d'une mise à jour de la question ainsi que des commentaires, pour la partie Google docs, j'ai appuyé sur Prt Sc pour avoir une capture d'écran dans le presse-papiers, ouvrir Google docs dans Chrome, cliquer avec le bouton droit puis cliquer sur "Coller" dans le menu contextuel personnalisé et pour sûr que cela fonctionne, ouvrir Google docs dans Firefox et dès que j'ai cliqué sur l'option "coller" j'ai eu cette réponse

enter image description here

Aussi pour mémoire, j'ai essayé de faire la même chose dans IE11 et il essaie toujours de lancer Google docs depuis 21 minutes.

Donc, la conclusion est probablement, et surtout, " Google" Chrome a une exception : - quelque chose comme une déclaration conditionnelle - pour les documents " Google" et d'autres services Google dans leur navigateur, je pense aussi @ julien -gregoire avait raison de dire qu'il s'agissait d'une extension dans Firefox.

De cette page d'assistance Google docs :

Pour des raisons de sécurité, la plupart des navigateurs n'autorisent pas les applications Web telles que Docs, Sheets et Slides à utiliser le presse-papiers de votre ordinateur via les menus.

Cependant, si vous utilisez Chrome, vous pouvez autoriser l'accès à votre presse-papiers en installant l'application Google Drive Chrome. Cela vous permet d'utiliser le menu contextuel pour copier et coller du contenu (ou sélectionnez "Copier" ou "Coller" dans le menu Edition de la barre d'outils.) Pour installer l'application, visitez le Chrome Web Store).

Et cette page des petites entreprises :

Sans raccourcis clavier, vous avez deux autres options pour copier et coller: soit en allant dans le menu "Edition" et en sélectionnant "Copier" ou "Coller", soit en cliquant avec le bouton droit dans le document et en sélectionnant "Copier" ou "Coller" dans le menu contextuel. Dans Google Docs, ces deux options ne sont disponibles que pour les utilisateurs de Chrome qui ont installé l'application Web Google Drive. L'application est gratuite, mais n'est pas disponible pour les autres navigateurs.

Il semble donc qu'ils aient déjà mis en œuvre cette application en tant que fonctionnalité intégrée dans les nouvelles versions de Chrome.

11
Mi-Creativity

La pâte personnalisée fonctionne dans Chrome, mais uniquement via une extension. Si vous regardez le code google docs, vous verrez que sans l'extension installée, vous ne pouvez pas coller. Et vous pouvez essayer dans Firefox d'utiliser la pâte du menu contextuel, il vous dira qu'il n'est pas disponible et que vous devez utiliser CTRL+V. Vous pouvez le trouver dans le code source de Google Documents:

Le copier-coller nécessite l'application Web gratuite Google Drive. Cela nous permet d'accéder à votre presse-papiers afin que vous puissiez couper, copier et coller.

Il semble donc clair que la commande paste a besoin d'une extension pour fonctionner.

Une façon de le faire est d'utiliser execCommand('paste') qui ne fonctionne pas lorsqu'elle est appelée à partir d'une page, mais fonctionne en fait dans un script de contenu d'extension. Vous n'avez qu'à ajouter clipboardRead aux autorisations manifest.json , comme ce:

permissions: {
    ...
    "clipboardRead"
    ...
}

Ensuite, dans votre script de contenu, document.execCommand('paste') fonctionnera.

MODIFIER:

Comme indiqué par @ tomas-M et @ Mi-Creativity, l'implémentation dans Google Docs sur Chrome semble être dans Chrome lui-même, pas dans une extension exposée) . Peut-être que cela peut donner un indice quant à l'endroit où il est défini: https://code.google.com/p/chromium/codesearch#chromium/src/chrome/common/extensions/api/_permission_features.json&q= clipboardRead & sq = package: chrome & dr = C & l = 164

Difficile de dire si c'est vraiment la façon dont cela fonctionne, mais dans tous les cas, vous pouvez "déverrouiller" execCommand('paste') pour un autre site via une extension. Pas très pratique, mais ça marche.

Et tester document.execCommand('paste') dans la console, tandis que sur google docs donne true, tandis que sur d'autres pages cela donne false, donc je pense vraiment que c'est ainsi que cette fonctionnalité est implémentée dans google docs.

6
Julien Grégoire

Cela fonctionne différemment avec différents navigateurs. Vous pouvez trouver une implémentation fonctionnelle ici: https://jsfiddle.net/1vmansr2/

JS pertinent:

function myFunction() {

   navigator.clipboard.readText()
.then(text => {
document.getElementById("demo").innerHTML = text;

})
.catch(err => {
document.getElementById("demo").innerHTML = 'Failed to read clipboard contents: '+err;
});


}
0
Antoine