Compare commits

..

1 Commits

Author SHA1 Message Date
Zeno Rocha
0a0de9fc01 Release v1.5.3 2015-10-28 13:06:53 -07:00
11 changed files with 91 additions and 128 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "clipboard",
"version": "1.5.7",
"version": "1.5.3",
"description": "Modern copy to clipboard. No Flash. Just 2kb",
"license": "MIT",
"main": "dist/clipboard.js",

View File

@@ -6,9 +6,7 @@
</head>
<body>
<!-- 1. Define some markup -->
<div id="btn" data-clipboard-text="1">
<span>Copy</span>
</div>
<button id="btn" data-clipboard-text="1">Copy</button>
<!-- 2. Include library -->
<script src="../dist/clipboard.min.js"></script>

137
dist/clipboard.js vendored
View File

@@ -1,5 +1,5 @@
/*!
* clipboard.js v1.5.7
* clipboard.js v1.5.3
* https://zenorocha.github.io/clipboard.js
*
* Licensed MIT © Zeno Rocha
@@ -16,7 +16,48 @@ module.exports = function (element, selector, checkYoSelf) {
}
}
},{"matches-selector":5}],2:[function(require,module,exports){
},{"matches-selector":2}],2:[function(require,module,exports){
/**
* Element prototype.
*/
var proto = Element.prototype;
/**
* Vendor function.
*/
var vendor = proto.matchesSelector
|| proto.webkitMatchesSelector
|| proto.mozMatchesSelector
|| proto.msMatchesSelector
|| proto.oMatchesSelector;
/**
* Expose `match()`.
*/
module.exports = match;
/**
* Match `el` to `selector`.
*
* @param {Element} el
* @param {String} selector
* @return {Boolean}
* @api public
*/
function match(el, selector) {
if (vendor) return vendor.call(el, selector);
var nodes = el.parentNode.querySelectorAll(selector);
for (var i = 0; i < nodes.length; ++i) {
if (nodes[i] == el) return true;
}
return false;
}
},{}],3:[function(require,module,exports){
var closest = require('closest');
/**
@@ -26,17 +67,16 @@ var closest = require('closest');
* @param {String} selector
* @param {String} type
* @param {Function} callback
* @param {Boolean} useCapture
* @return {Object}
*/
function delegate(element, selector, type, callback, useCapture) {
function delegate(element, selector, type, callback) {
var listenerFn = listener.apply(this, arguments);
element.addEventListener(type, listenerFn, useCapture);
element.addEventListener(type, listenerFn);
return {
destroy: function() {
element.removeEventListener(type, listenerFn, useCapture);
element.removeEventListener(type, listenerFn);
}
}
}
@@ -52,9 +92,13 @@ function delegate(element, selector, type, callback, useCapture) {
*/
function listener(element, selector, type, callback) {
return function(e) {
e.delegateTarget = closest(e.target, selector, true);
var delegateTarget = closest(e.target, selector, true);
if (delegateTarget) {
Object.defineProperty(e, 'target', {
value: delegateTarget
});
if (e.delegateTarget) {
callback.call(element, e);
}
}
@@ -62,7 +106,7 @@ function listener(element, selector, type, callback) {
module.exports = delegate;
},{"closest":1}],3:[function(require,module,exports){
},{"closest":1}],4:[function(require,module,exports){
/**
* Check if argument is a HTML element.
*
@@ -107,13 +151,13 @@ exports.string = function(value) {
* @param {Object} value
* @return {Boolean}
*/
exports.fn = function(value) {
exports.function = function(value) {
var type = Object.prototype.toString.call(value);
return type === '[object Function]';
};
},{}],4:[function(require,module,exports){
},{}],5:[function(require,module,exports){
var is = require('./is');
var delegate = require('delegate');
@@ -135,7 +179,7 @@ function listen(target, type, callback) {
throw new TypeError('Second argument must be a String');
}
if (!is.fn(callback)) {
if (!is.function(callback)) {
throw new TypeError('Third argument must be a Function');
}
@@ -210,62 +254,16 @@ function listenSelector(selector, type, callback) {
module.exports = listen;
},{"./is":3,"delegate":2}],5:[function(require,module,exports){
/**
* Element prototype.
*/
var proto = Element.prototype;
/**
* Vendor function.
*/
var vendor = proto.matchesSelector
|| proto.webkitMatchesSelector
|| proto.mozMatchesSelector
|| proto.msMatchesSelector
|| proto.oMatchesSelector;
/**
* Expose `match()`.
*/
module.exports = match;
/**
* Match `el` to `selector`.
*
* @param {Element} el
* @param {String} selector
* @return {Boolean}
* @api public
*/
function match(el, selector) {
if (vendor) return vendor.call(el, selector);
var nodes = el.parentNode.querySelectorAll(selector);
for (var i = 0; i < nodes.length; ++i) {
if (nodes[i] == el) return true;
}
return false;
}
},{}],6:[function(require,module,exports){
},{"./is":4,"delegate":3}],6:[function(require,module,exports){
function select(element) {
var selectedText;
if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {
element.focus();
element.setSelectionRange(0, element.value.length);
element.select();
selectedText = element.value;
}
else {
if (element.hasAttribute('contenteditable')) {
element.focus();
}
var selection = window.getSelection();
var range = document.createRange();
@@ -423,8 +421,6 @@ var ClipboardAction = (function () {
ClipboardAction.prototype.selectFake = function selectFake() {
var _this = this;
var isRTL = document.documentElement.getAttribute('dir') == 'rtl';
this.removeFake();
this.fakeHandler = document.body.addEventListener('click', function () {
@@ -433,7 +429,7 @@ var ClipboardAction = (function () {
this.fakeElem = document.createElement('textarea');
this.fakeElem.style.position = 'absolute';
this.fakeElem.style[isRTL ? 'right' : 'left'] = '-9999px';
this.fakeElem.style.left = '-9999px';
this.fakeElem.style.top = (window.pageYOffset || document.documentElement.scrollTop) + 'px';
this.fakeElem.setAttribute('readonly', '');
this.fakeElem.value = this.text;
@@ -669,17 +665,15 @@ var Clipboard = (function (_Emitter) {
*/
Clipboard.prototype.onClick = function onClick(e) {
var trigger = e.delegateTarget || e.currentTarget;
if (this.clipboardAction) {
this.clipboardAction = null;
}
this.clipboardAction = new _clipboardAction2['default']({
action: this.action(trigger),
target: this.target(trigger),
text: this.text(trigger),
trigger: trigger,
action: this.action(e.target),
target: this.target(e.target),
text: this.text(e.target),
trigger: e.target,
emitter: this
});
};
@@ -731,7 +725,6 @@ var Clipboard = (function (_Emitter) {
return Clipboard;
})(_tinyEmitter2['default']);
exports['default'] = Clipboard;
function getAttributeValue(suffix, element) {
var attribute = 'data-clipboard-' + suffix;
@@ -741,7 +734,9 @@ function getAttributeValue(suffix, element) {
return element.getAttribute(attribute);
}
exports['default'] = Clipboard;
module.exports = exports['default'];
},{"./clipboard-action":8,"good-listener":4,"tiny-emitter":7}]},{},[9])(9)
},{"./clipboard-action":8,"good-listener":5,"tiny-emitter":7}]},{},[9])(9)
});

File diff suppressed because one or more lines are too long

View File

@@ -3,10 +3,10 @@
Package.describe({
name: "zenorocha:clipboard",
summary: "Modern copy to clipboard. No Flash. Just 2kb.",
version: "1.5.7",
version: "1.5.1",
git: "https://github.com/zenorocha/clipboard.js"
});
Package.onUse(function(api) {
api.addFiles("dist/clipboard.js", "client");
api.addFiles("dist/clipboard.min.js", "client");
});

View File

@@ -1,6 +1,6 @@
{
"name": "clipboard",
"version": "1.5.7",
"version": "1.5.3",
"description": "Modern copy to clipboard. No Flash. Just 2kb",
"repository": "zenorocha/clipboard.js",
"license": "MIT",
@@ -11,16 +11,14 @@
"cut"
],
"dependencies": {
"good-listener": "^1.1.6",
"select": "^1.0.6",
"good-listener": "^1.1.2",
"select": "^1.0.4",
"tiny-emitter": "^1.0.0"
},
"devDependencies": {
"babel": "^5.8.29",
"babelify": "^6.3.0",
"bannerify": "Vekat/bannerify#feature-option",
"browserify": "^11.2.0",
"chai": "^3.4.1",
"karma": "^0.13.10",
"karma-browserify": "^4.4.0",
"karma-chai": "^0.1.0",
@@ -28,11 +26,10 @@
"karma-phantomjs-launcher": "^0.2.1",
"karma-sinon": "^1.0.4",
"mocha": "^2.3.3",
"phantomjs": "^1.9.18",
"phantomjs-polyfill": "0.0.1",
"sinon": "^1.17.2",
"uglify-js": "^2.4.24",
"watchify": "^3.4.0"
"watchify": "^3.4.0",
"bannerify": "Vekat/bannerify#feature-option"
},
"scripts": {
"build": "npm run build-debug && npm run build-min",

View File

@@ -151,7 +151,7 @@ new Clipboard('.btn', {
});
```
Also, if you are working with single page apps, you may want to manage the lifecycle of the DOM more precisely. Here's how you clean up the events and objects that we create.
Also, with are working with single page apps, you may want to manage the lifecycle of the DOM more precisely. Here's how you clean up the events and objects that we create.
```js
var clipboard = new Clipboard('.btn');

View File

@@ -4,7 +4,7 @@ import select from 'select';
* Inner class which performs selection from either `text` or `target`
* properties and then executes copy or cut operations.
*/
export default class ClipboardAction {
class ClipboardAction {
/**
* @param {Object} options
*/
@@ -51,15 +51,13 @@ export default class ClipboardAction {
* and makes a selection on it.
*/
selectFake() {
let isRTL = document.documentElement.getAttribute('dir') == 'rtl';
this.removeFake();
this.fakeHandler = document.body.addEventListener('click', () => this.removeFake());
this.fakeElem = document.createElement('textarea');
this.fakeElem.style.position = 'absolute';
this.fakeElem.style[ isRTL ? 'right' : 'left' ] = '-9999px';
this.fakeElem.style.left = '-9999px';
this.fakeElem.style.top = (window.pageYOffset || document.documentElement.scrollTop) + 'px';
this.fakeElem.setAttribute('readonly', '');
this.fakeElem.value = this.text;
@@ -194,3 +192,5 @@ export default class ClipboardAction {
this.removeFake();
}
}
export default ClipboardAction;

View File

@@ -6,7 +6,7 @@ import listen from 'good-listener';
* Base class which takes one or more elements, adds event listeners to them,
* and instantiates a new `ClipboardAction` on each click.
*/
export default class Clipboard extends Emitter {
class Clipboard extends Emitter {
/**
* @param {String|HTMLElement|HTMLCollection|NodeList} trigger
* @param {Object} options
@@ -42,17 +42,15 @@ export default class Clipboard extends Emitter {
* @param {Event} e
*/
onClick(e) {
let trigger = e.delegateTarget || e.currentTarget;
if (this.clipboardAction) {
this.clipboardAction = null;
}
this.clipboardAction = new ClipboardAction({
action : this.action(trigger),
target : this.target(trigger),
text : this.text(trigger),
trigger : trigger,
action : this.action(e.target),
target : this.target(e.target),
text : this.text(e.target),
trigger : e.target,
emitter : this
});
}
@@ -113,3 +111,5 @@ function getAttributeValue(suffix, element) {
return element.getAttribute(attribute);
}
export default Clipboard;

View File

@@ -57,19 +57,6 @@ describe('ClipboardAction', () => {
done();
}
});
it('should set the position right style property', done => {
// Set document direction
document.documentElement.setAttribute('dir', 'rtl');
let clip = new ClipboardAction({
emitter: new Emitter(),
text: 'foo'
});
assert.equal(clip.fakeElem.style.right, '-9999px');
done();
});
});
describe('#set action', () => {

View File

@@ -9,14 +9,8 @@ describe('Clipboard', () => {
global.button.setAttribute('data-clipboard-text', 'foo');
document.body.appendChild(global.button);
global.span = document.createElement('span');
global.span.innerHTML = 'bar';
global.button.appendChild(span);
global.event = {
target: global.button,
currentTarget: global.button
target: global.button
};
});
@@ -69,15 +63,7 @@ describe('Clipboard', () => {
assert.instanceOf(clipboard.clipboardAction, ClipboardAction);
});
it('should use an event\'s currentTarget when not equal to target', () => {
let clipboard = new Clipboard('.btn');
let bubbledEvent = { target: global.span, currentTarget: global.button };
clipboard.onClick(bubbledEvent);
assert.instanceOf(clipboard.clipboardAction, ClipboardAction);
});
it('should throw an exception when target is invalid', done => {
it('should throws exception target', done => {
try {
var clipboard = new Clipboard('.btn', {
target: function() {