mirror of
https://github.com/zenorocha/clipboard.js.git
synced 2023-08-10 21:12:48 +03:00
Add modifier
key option
The `modifier` option allows the Clipboard API to prevent the creation of a new instance of `ClipboardAction` if the `click` event object is not fired with a special key pressed. It basically functions as a new type of event. The keys 'ctrl', 'shift', 'alt' and 'meta' are supported.
This commit is contained in:
parent
db575bb4df
commit
90968ce790
125
dist/clipboard.js
vendored
125
dist/clipboard.js
vendored
@ -16,48 +16,7 @@ module.exports = function (element, selector, checkYoSelf) {
|
||||
}
|
||||
}
|
||||
|
||||
},{"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){
|
||||
},{"matches-selector":5}],2:[function(require,module,exports){
|
||||
var closest = require('closest');
|
||||
|
||||
/**
|
||||
@ -106,7 +65,7 @@ function listener(element, selector, type, callback) {
|
||||
|
||||
module.exports = delegate;
|
||||
|
||||
},{"closest":1}],4:[function(require,module,exports){
|
||||
},{"closest":1}],3:[function(require,module,exports){
|
||||
/**
|
||||
* Check if argument is a HTML element.
|
||||
*
|
||||
@ -157,7 +116,7 @@ exports.function = function(value) {
|
||||
return type === '[object Function]';
|
||||
};
|
||||
|
||||
},{}],5:[function(require,module,exports){
|
||||
},{}],4:[function(require,module,exports){
|
||||
var is = require('./is');
|
||||
var delegate = require('delegate');
|
||||
|
||||
@ -254,7 +213,48 @@ function listenSelector(selector, type, callback) {
|
||||
|
||||
module.exports = listen;
|
||||
|
||||
},{"./is":4,"delegate":3}],6:[function(require,module,exports){
|
||||
},{"./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){
|
||||
function select(element) {
|
||||
var selectedText;
|
||||
|
||||
@ -288,24 +288,23 @@ function E () {
|
||||
E.prototype = {
|
||||
on: function (name, callback, ctx) {
|
||||
var e = this.e || (this.e = {});
|
||||
|
||||
|
||||
(e[name] || (e[name] = [])).push({
|
||||
fn: callback,
|
||||
ctx: ctx
|
||||
});
|
||||
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
once: function (name, callback, ctx) {
|
||||
var self = this;
|
||||
function listener () {
|
||||
self.off(name, listener);
|
||||
var fn = function () {
|
||||
self.off(name, fn);
|
||||
callback.apply(ctx, arguments);
|
||||
};
|
||||
|
||||
listener._ = callback
|
||||
return this.on(name, listener, ctx);
|
||||
|
||||
return this.on(name, fn, ctx);
|
||||
},
|
||||
|
||||
emit: function (name) {
|
||||
@ -313,11 +312,11 @@ E.prototype = {
|
||||
var evtArr = ((this.e || (this.e = {}))[name] || []).slice();
|
||||
var i = 0;
|
||||
var len = evtArr.length;
|
||||
|
||||
|
||||
for (i; i < len; i++) {
|
||||
evtArr[i].fn.apply(evtArr[i].ctx, data);
|
||||
}
|
||||
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
@ -325,22 +324,21 @@ E.prototype = {
|
||||
var e = this.e || (this.e = {});
|
||||
var evts = e[name];
|
||||
var liveEvents = [];
|
||||
|
||||
|
||||
if (evts && callback) {
|
||||
for (var i = 0, len = evts.length; i < len; i++) {
|
||||
if (evts[i].fn !== callback && evts[i].fn._ !== callback)
|
||||
liveEvents.push(evts[i]);
|
||||
if (evts[i].fn !== callback) liveEvents.push(evts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Remove event from queue to prevent memory leak
|
||||
// Suggested by https://github.com/lazd
|
||||
// Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910
|
||||
|
||||
(liveEvents.length)
|
||||
(liveEvents.length)
|
||||
? e[name] = liveEvents
|
||||
: delete e[name];
|
||||
|
||||
|
||||
return this;
|
||||
}
|
||||
};
|
||||
@ -644,6 +642,7 @@ var Clipboard = (function (_Emitter) {
|
||||
this.action = typeof options.action === 'function' ? options.action : this.defaultAction;
|
||||
this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;
|
||||
this.text = typeof options.text === 'function' ? options.text : this.defaultText;
|
||||
this.modifier = typeof options.modifier === 'string' && /^(alt|ctrl|shift|meta){1}$/.test(options.modifier) ? options.modifier : null;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -669,6 +668,10 @@ var Clipboard = (function (_Emitter) {
|
||||
this.clipboardAction = null;
|
||||
}
|
||||
|
||||
if (this.modifier) {
|
||||
if (e[this.modifier + 'Key'] === false) return;
|
||||
}
|
||||
|
||||
this.clipboardAction = new _clipboardAction2['default']({
|
||||
action: this.action(e.target),
|
||||
target: this.target(e.target),
|
||||
@ -738,5 +741,5 @@ function getAttributeValue(suffix, element) {
|
||||
exports['default'] = Clipboard;
|
||||
module.exports = exports['default'];
|
||||
|
||||
},{"./clipboard-action":8,"good-listener":5,"tiny-emitter":7}]},{},[9])(9)
|
||||
},{"./clipboard-action":8,"good-listener":4,"tiny-emitter":7}]},{},[9])(9)
|
||||
});
|
2
dist/clipboard.min.js
vendored
2
dist/clipboard.min.js
vendored
File diff suppressed because one or more lines are too long
@ -29,7 +29,7 @@
|
||||
"phantomjs-polyfill": "0.0.1",
|
||||
"uglify-js": "^2.4.24",
|
||||
"watchify": "^3.4.0",
|
||||
"bannerify": "Vekat/bannerify#feature-option"
|
||||
"bannerify": "github:vekat/bannerify#feature-option"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "npm run build-debug && npm run build-min",
|
||||
|
@ -27,6 +27,7 @@ class Clipboard extends Emitter {
|
||||
this.action = (typeof options.action === 'function') ? options.action : this.defaultAction;
|
||||
this.target = (typeof options.target === 'function') ? options.target : this.defaultTarget;
|
||||
this.text = (typeof options.text === 'function') ? options.text : this.defaultText;
|
||||
this.modifier = (typeof options.modifier === 'string' && /^(alt|ctrl|shift|meta){1}$/.test(options.modifier)) ? options.modifier : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -46,6 +47,10 @@ class Clipboard extends Emitter {
|
||||
this.clipboardAction = null;
|
||||
}
|
||||
|
||||
if (this.modifier) {
|
||||
if (e[`${this.modifier}Key`] === false) return;
|
||||
}
|
||||
|
||||
this.clipboardAction = new ClipboardAction({
|
||||
action : this.action(e.target),
|
||||
target : this.target(e.target),
|
||||
|
@ -12,6 +12,14 @@ describe('Clipboard', () => {
|
||||
global.event = {
|
||||
target: global.button
|
||||
};
|
||||
|
||||
global.altkeyEvent = {
|
||||
target: global.button,
|
||||
altKey: true,
|
||||
ctrlKey: false,
|
||||
shiftKey: false,
|
||||
metaKey: false
|
||||
}
|
||||
});
|
||||
|
||||
after(() => {
|
||||
@ -21,6 +29,7 @@ describe('Clipboard', () => {
|
||||
describe('#resolveOptions', () => {
|
||||
before(() => {
|
||||
global.fn = function() {};
|
||||
global.key = 'alt';
|
||||
});
|
||||
|
||||
it('should set action as a function', () => {
|
||||
@ -46,6 +55,14 @@ describe('Clipboard', () => {
|
||||
|
||||
assert.equal(global.fn, clipboard.text);
|
||||
});
|
||||
|
||||
it('should set modifier key as a string', () => {
|
||||
let clipboard = new Clipboard('.btn', {
|
||||
modifier: global.key
|
||||
});
|
||||
|
||||
assert.equal(global.key, clipboard.modifier);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#listenClick', () => {
|
||||
@ -63,6 +80,24 @@ describe('Clipboard', () => {
|
||||
assert.instanceOf(clipboard.clipboardAction, ClipboardAction);
|
||||
});
|
||||
|
||||
it('should not create an instance of ClipboardAction', () => {
|
||||
let clipboard = new Clipboard('.btn', {
|
||||
modifier: 'shift'
|
||||
});
|
||||
|
||||
clipboard.onClick(global.altkeyEvent);
|
||||
assert.equal(clipboard.clipboardAction, null);
|
||||
});
|
||||
|
||||
it('should create an instance of ClipboardAction', () => {
|
||||
let clipboard = new Clipboard('.btn', {
|
||||
modifier: 'alt'
|
||||
});
|
||||
|
||||
clipboard.onClick(global.altkeyEvent);
|
||||
assert.instanceOf(clipboard.clipboardAction, ClipboardAction);
|
||||
});
|
||||
|
||||
it('should throws exception target', done => {
|
||||
try {
|
||||
var clipboard = new Clipboard('.btn', {
|
||||
|
Loading…
Reference in New Issue
Block a user