GithubHelp home page GithubHelp logo

Comments (9)

JamesMGreene avatar JamesMGreene commented on May 5, 2024

Any opinion, @jonrohan?

from zeroclipboard.

JamesMGreene avatar JamesMGreene commented on May 5, 2024

These are now being standardized: http://www.w3.org/TR/clipboard-apis/

from zeroclipboard.

JamesMGreene avatar JamesMGreene commented on May 5, 2024

The old jquery.zclip plugin [which wrapped ZeroClipboard] offered beforeCopy and afterCopy events like this.

from zeroclipboard.

JamesMGreene avatar JamesMGreene commented on May 5, 2024

If we are trying to best align the event names with the HTML5 Clipboard API, then we would want to use onCopy instead of onBeforeCopy. onBeforeCopy is intended for updating DOM/UI components whereas onCopy is where they recommend setting the outgoing clipboard data.

That said, we're already looking at adding an onAfterCopy event, which does not exist in the HTML5 Clipboard API, so we're already breaking the mold there. To me, onCopy sounds like an event that would occur after the clipboard injection has occurred but that is not actually the case.

To avoid confusion, I'd recommend we go with onBeforeCopy and onAfterCopy like zclip had done.

from zeroclipboard.

JamesMGreene avatar JamesMGreene commented on May 5, 2024

@jonrohan Thoughts?

from zeroclipboard.

JamesMGreene avatar JamesMGreene commented on May 5, 2024

On second thought, following the HTML5 Clipboard API in terms of handler invocation would also be somewhat limiting as the handler wouldn't have access to the current client (ZeroClipboard instance). As such, we might want to either:

  1. leave both the old and new event names; or
  2. use a single set of event names but control their execution environments via a config option (e.g. emulateHtml5: true) defaulted to false.

from zeroclipboard.

JamesMGreene avatar JamesMGreene commented on May 5, 2024

Actually, the HTML5 Clipboard API spec doesn't comment on the context of this, therefore it would just be equal to the client after all. This is different than our current context, though, in which we supply the glued element as this and supply the client as an argument.

from zeroclipboard.

JamesMGreene avatar JamesMGreene commented on May 5, 2024

Here's an example for the beforeCopy/copy event(s), which would replace the current dataRequested event.

New code inside of ZeroClipboard.js:

var ZeroClipboardDataTransferItem = function(data, type) {
  this.kind = 'string';
  this.type = type;
  this.getAsString = function(callback) {
    if (typeof callback === 'function') {
      window.setTimeout(function() { callback(data); }, 0);
    }
  };
};
ZeroClipboardDataTransferItem.prototype.getAsFile = function() {
  return null;
};

var ZeroClipboardEvent = function(client, element, lock) {
  // TODO: This `CustomEvent` code will not work in IE or PhantomJS 1.x, and maybe not
  //       in JSDOM either but similar mechanisms are available.
  var evt = new CustomEvent('copy', { bubbles: false, cancelable: true, detail: undefined });

  evt.target = element;
  evt.currentTarget = client;
  evt.eventPhase = 2;  // Event.AT_TARGET

  // For maintaining private data
  var dataMap = {},
       mapPrefix = 'type_',
       _isImmediatePropagationStopped = false;

  evt.isImmediatePropagationStopped = function() {
    return _isImmediatePropagationStopped;
  };

  evt.stopImmediatePropagation = function() {
    _isImmediatePropagationStopped = true;
  };

  //
  // ClipboardEvent custom properties and methods
  //

  // Override the `evt.preventDefault` method to actually write to the clipboard
  evt.preventDefault = function() {
    if (dataMap.hasOwnProperty(mapPrefix + 'text/plain')) {
      client.setText(dataMap[mapPrefix + 'text/plain']);
    }
    // TODO: Add support for all text-based content types in the future
  };

  // Duck-typing `DataTransfer`
  // http://www.w3.org/TR/html5/editing.html#datatransfer
  evt.clipboardData = {

    // http://www.w3.org/TR/html5/editing.html#dom-datatransfer-cleardata
    clearData: function() {
      dataMap = {};
      evt.clipboardData.types.length = 0;
      evt.clipboardData.items.clear();
    },

    // http://www.w3.org/TR/html5/editing.html#dom-datatransfer-setdata
    setData: function(type, data) {
      if (!dataMap.hasOwnProperty(mapPrefix + type)) {
        var index = evt.clipboardData.types.length;
        dataMap[mapPrefix + type] = index;
        evt.clipboardData.types[index] = type;
      }
      evt.clipboardData.items[index] = new ZeroClipboardDataTransferItem(data, type);
    },

    // http://www.w3.org/TR/html5/editing.html#dom-datatransfer-getdata
    getData: function(type) {
      return undefined;  // Permission denied during a 'copy' event
    },

    // Array of Strings
    // Should be read-only but that makes no sense for ZeroClipboard
    // http://www.w3.org/TR/html5/editing.html#dom-datatransfer-types
    // TODO: Add support for all text-based content types in the future:
    //         ['text/plain', 'text/html', 'application/rtf']
    types: [],

    // Array of [ZeroClipboard]DataTransferItem objects
    // Duck-typing `DataTransferItemList` isn't worth it for this one
    // Should be read-only but that makes no sense for ZeroClipboard
    // http://www.w3.org/TR/html5/editing.html#dom-datatransfer-items
    // http://www.w3.org/TR/html5/editing.html#datatransferitemlist
    // http://www.w3.org/TR/html5/editing.html#datatransferitem
    items: [];
  };

  return evt;
};

// To dispatch the event
var evt = new ZeroClipboardEvent(client, element);

// TODO: This `forEach` won't work in IE<9
client.handlers['copy'].forEach(function(fn) {
  if (!evt.isImmediatePropagationStopped()) {
    // NOTE: We currently pass `element` as the context (`this`) rather than `client` as below
    //       but `client` will be the correct choice if following the HTML5 Clipboard API model.
    fn.call(client, evt);
  }
});

Usage:

(function() {
  var textMsg = 'ZeroClipboard injected this plain text!';
  var htmlMsg = '<b>ZeroClipboard</b> injected <i>this</i> HTML!';
  var richTextMsg = '{\\rtf1\\ansi\\n\n{\\b ZeroClipboard} injected {\\i this} RichText (RTF)!\n}';

  var clip = new ZeroClipboard($('.clipboard'));

  // Could be `.on('copy', fn)` or `.on('beforecopy', fn)` and still align with the HTML5
  // Clipboard API. Technically speaking, `copy` would be more correct; I personally find it
  // more confusing, though.
  clip.on('copy', function(e) {
    // `this` === `clip`
    // `e.target` === glued element
    // `e.currentTarget` === `clip`/`this`

    // All of this callback code is aligned with the HTML5 Clipboard API
    if (e.clipboardData) {
      e.clipboardData.clearData();
      e.clipboardData.setData('text/plain', textMsg);

      // TODO: Add support for all text-based content types in the future
      e.clipboardData.setData('text/html', htmlMsg);
      e.clipboardData.setData('application/rtf', richTextMsg);

      // Wacky: Must prevent default in order to get this copied into the clipboard
      e.preventDefault();
    }
  });

})();

from zeroclipboard.

JamesMGreene avatar JamesMGreene commented on May 5, 2024

Also, we could even get our HTML5-like implementation even closer: if the "copy" event handler does not call evt.preventDefault(), the defined default behavior is to copy the user's active text selection, if any. From the spec:

Its default action is to place the selected data on the clipboard.

Grabbing the selection is very easy to do using the long-standing TextRange/Range and Selection APIs. Been there, done that. 👍

from zeroclipboard.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.