444 lines
15 KiB
JavaScript
444 lines
15 KiB
JavaScript
// Generated by CoffeeScript 1.12.7
|
|
|
|
/*
|
|
paste.js is an interface to read data ( text / image ) from clipboard in different browsers. It also contains several hacks.
|
|
|
|
https://github.com/layerssss/paste.js
|
|
*/
|
|
|
|
(function() {
|
|
var $, Paste, createHiddenEditable, dataURLtoBlob, isFocusable;
|
|
|
|
$ = window.jQuery;
|
|
|
|
$.paste = function(pasteContainer) {
|
|
var pm;
|
|
if (typeof console !== "undefined" && console !== null) {
|
|
console.log("DEPRECATED: This method is deprecated. Please use $.fn.pastableNonInputable() instead.");
|
|
}
|
|
pm = Paste.mountNonInputable(pasteContainer);
|
|
return pm._container;
|
|
};
|
|
|
|
$.fn.pastableNonInputable = function() {
|
|
var el, j, len, ref;
|
|
ref = this;
|
|
for (j = 0, len = ref.length; j < len; j++) {
|
|
el = ref[j];
|
|
if (el._pastable || $(el).is('textarea, input:text, [contenteditable]')) {
|
|
continue;
|
|
}
|
|
Paste.mountNonInputable(el);
|
|
el._pastable = true;
|
|
}
|
|
return this;
|
|
};
|
|
|
|
$.fn.pastableTextarea = function() {
|
|
var el, j, len, ref;
|
|
ref = this;
|
|
for (j = 0, len = ref.length; j < len; j++) {
|
|
el = ref[j];
|
|
if (el._pastable || $(el).is(':not(textarea, input:text)')) {
|
|
continue;
|
|
}
|
|
Paste.mountTextarea(el);
|
|
el._pastable = true;
|
|
}
|
|
return this;
|
|
};
|
|
|
|
$.fn.pastableContenteditable = function() {
|
|
var el, j, len, ref;
|
|
ref = this;
|
|
for (j = 0, len = ref.length; j < len; j++) {
|
|
el = ref[j];
|
|
if (el._pastable || $(el).is(':not([contenteditable])')) {
|
|
continue;
|
|
}
|
|
Paste.mountContenteditable(el);
|
|
el._pastable = true;
|
|
}
|
|
return this;
|
|
};
|
|
|
|
dataURLtoBlob = function(dataURL, sliceSize) {
|
|
var b64Data, byteArray, byteArrays, byteCharacters, byteNumbers, contentType, i, m, offset, ref, slice;
|
|
if (sliceSize == null) {
|
|
sliceSize = 512;
|
|
}
|
|
if (!(m = dataURL.match(/^data\:([^\;]+)\;base64\,(.+)$/))) {
|
|
return null;
|
|
}
|
|
ref = m, m = ref[0], contentType = ref[1], b64Data = ref[2];
|
|
byteCharacters = atob(b64Data);
|
|
byteArrays = [];
|
|
offset = 0;
|
|
while (offset < byteCharacters.length) {
|
|
slice = byteCharacters.slice(offset, offset + sliceSize);
|
|
byteNumbers = new Array(slice.length);
|
|
i = 0;
|
|
while (i < slice.length) {
|
|
byteNumbers[i] = slice.charCodeAt(i);
|
|
i++;
|
|
}
|
|
byteArray = new Uint8Array(byteNumbers);
|
|
byteArrays.push(byteArray);
|
|
offset += sliceSize;
|
|
}
|
|
return new Blob(byteArrays, {
|
|
type: contentType
|
|
});
|
|
};
|
|
|
|
createHiddenEditable = function() {
|
|
return $(document.createElement('div')).attr('contenteditable', true).attr('aria-hidden', true).attr('tabindex', -1).css({
|
|
width: 1,
|
|
height: 1,
|
|
position: 'fixed',
|
|
left: -100,
|
|
overflow: 'hidden',
|
|
opacity: 1e-17
|
|
});
|
|
};
|
|
|
|
isFocusable = function(element, hasTabindex) {
|
|
var fieldset, focusableIfVisible, img, map, mapName, nodeName;
|
|
map = void 0;
|
|
mapName = void 0;
|
|
img = void 0;
|
|
focusableIfVisible = void 0;
|
|
fieldset = void 0;
|
|
nodeName = element.nodeName.toLowerCase();
|
|
if ('area' === nodeName) {
|
|
map = element.parentNode;
|
|
mapName = map.name;
|
|
if (!element.href || !mapName || map.nodeName.toLowerCase() !== 'map') {
|
|
return false;
|
|
}
|
|
img = $('img[usemap=\'#' + mapName + '\']');
|
|
return img.length > 0 && img.is(':visible');
|
|
}
|
|
if (/^(input|select|textarea|button|object)$/.test(nodeName)) {
|
|
focusableIfVisible = !element.disabled;
|
|
if (focusableIfVisible) {
|
|
fieldset = $(element).closest('fieldset')[0];
|
|
if (fieldset) {
|
|
focusableIfVisible = !fieldset.disabled;
|
|
}
|
|
}
|
|
} else if ('a' === nodeName) {
|
|
focusableIfVisible = element.href || hasTabindex;
|
|
} else {
|
|
focusableIfVisible = hasTabindex;
|
|
}
|
|
focusableIfVisible = focusableIfVisible || $(element).is('[contenteditable]');
|
|
return focusableIfVisible && $(element).is(':visible');
|
|
};
|
|
|
|
Paste = (function() {
|
|
Paste.prototype._target = null;
|
|
|
|
Paste.prototype._container = null;
|
|
|
|
Paste.mountNonInputable = function(nonInputable) {
|
|
var paste;
|
|
paste = new Paste(createHiddenEditable().appendTo(nonInputable), nonInputable);
|
|
$(nonInputable).on('click', (function(_this) {
|
|
return function(ev) {
|
|
if (!(isFocusable(ev.target, false) || window.getSelection().toString())) {
|
|
return paste._container.focus();
|
|
}
|
|
};
|
|
})(this));
|
|
paste._container.on('focus', (function(_this) {
|
|
return function() {
|
|
return $(nonInputable).addClass('pastable-focus');
|
|
};
|
|
})(this));
|
|
return paste._container.on('blur', (function(_this) {
|
|
return function() {
|
|
return $(nonInputable).removeClass('pastable-focus');
|
|
};
|
|
})(this));
|
|
};
|
|
|
|
Paste.mountTextarea = function(textarea) {
|
|
var ctlDown, paste, ref, ref1;
|
|
if ((typeof DataTransfer !== "undefined" && DataTransfer !== null ? DataTransfer.prototype : void 0) && ((ref = Object.getOwnPropertyDescriptor) != null ? (ref1 = ref.call(Object, DataTransfer.prototype, 'items')) != null ? ref1.get : void 0 : void 0)) {
|
|
return this.mountContenteditable(textarea);
|
|
}
|
|
paste = new Paste(createHiddenEditable().insertBefore(textarea), textarea);
|
|
ctlDown = false;
|
|
$(textarea).on('keyup', function(ev) {
|
|
var ref2;
|
|
if ((ref2 = ev.keyCode) === 17 || ref2 === 224) {
|
|
ctlDown = false;
|
|
}
|
|
return null;
|
|
});
|
|
$(textarea).on('keydown', function(ev) {
|
|
var ref2;
|
|
if ((ref2 = ev.keyCode) === 17 || ref2 === 224) {
|
|
ctlDown = true;
|
|
}
|
|
if ((ev.ctrlKey != null) && (ev.metaKey != null)) {
|
|
ctlDown = ev.ctrlKey || ev.metaKey;
|
|
}
|
|
if (ctlDown && ev.keyCode === 86) {
|
|
paste._textarea_focus_stolen = true;
|
|
paste._container.focus();
|
|
paste._paste_event_fired = false;
|
|
setTimeout((function(_this) {
|
|
return function() {
|
|
if (!paste._paste_event_fired) {
|
|
$(textarea).focus();
|
|
return paste._textarea_focus_stolen = false;
|
|
}
|
|
};
|
|
})(this), 1);
|
|
}
|
|
return null;
|
|
});
|
|
$(textarea).on('paste', (function(_this) {
|
|
return function() {};
|
|
})(this));
|
|
$(textarea).on('focus', (function(_this) {
|
|
return function() {
|
|
if (!paste._textarea_focus_stolen) {
|
|
return $(textarea).addClass('pastable-focus');
|
|
}
|
|
};
|
|
})(this));
|
|
$(textarea).on('blur', (function(_this) {
|
|
return function() {
|
|
if (!paste._textarea_focus_stolen) {
|
|
return $(textarea).removeClass('pastable-focus');
|
|
}
|
|
};
|
|
})(this));
|
|
$(paste._target).on('_pasteCheckContainerDone', (function(_this) {
|
|
return function() {
|
|
$(textarea).focus();
|
|
return paste._textarea_focus_stolen = false;
|
|
};
|
|
})(this));
|
|
return $(paste._target).on('pasteText', (function(_this) {
|
|
return function(ev, data) {
|
|
var content, curEnd, curStart;
|
|
curStart = $(textarea).prop('selectionStart');
|
|
curEnd = $(textarea).prop('selectionEnd');
|
|
content = $(textarea).val();
|
|
$(textarea).val("" + content.slice(0, curStart) + data.text + content.slice(curEnd));
|
|
$(textarea)[0].setSelectionRange(curStart + data.text.length, curStart + data.text.length);
|
|
return $(textarea).trigger('change');
|
|
};
|
|
})(this));
|
|
};
|
|
|
|
Paste.mountContenteditable = function(contenteditable) {
|
|
var paste;
|
|
paste = new Paste(contenteditable, contenteditable);
|
|
$(contenteditable).on('focus', (function(_this) {
|
|
return function() {
|
|
return $(contenteditable).addClass('pastable-focus');
|
|
};
|
|
})(this));
|
|
return $(contenteditable).on('blur', (function(_this) {
|
|
return function() {
|
|
return $(contenteditable).removeClass('pastable-focus');
|
|
};
|
|
})(this));
|
|
};
|
|
|
|
function Paste(_container, _target) {
|
|
this._container = _container;
|
|
this._target = _target;
|
|
this._container = $(this._container);
|
|
this._target = $(this._target).addClass('pastable');
|
|
this._container.on('paste', (function(_this) {
|
|
return function(ev) {
|
|
var _i, clipboardData, file, fileType, item, j, k, l, len, len1, len2, pastedFilename, reader, ref, ref1, ref2, ref3, ref4, stringIsFilename, text;
|
|
_this.originalEvent = (ev.originalEvent !== null ? ev.originalEvent : null);
|
|
_this._paste_event_fired = true;
|
|
if (((ref = ev.originalEvent) != null ? ref.clipboardData : void 0) != null) {
|
|
clipboardData = ev.originalEvent.clipboardData;
|
|
if (clipboardData.items) {
|
|
pastedFilename = null;
|
|
_this.originalEvent.pastedTypes = [];
|
|
ref1 = clipboardData.items;
|
|
for (j = 0, len = ref1.length; j < len; j++) {
|
|
item = ref1[j];
|
|
if (item.type.match(/^text\/(plain|rtf|html)/)) {
|
|
_this.originalEvent.pastedTypes.push(item.type);
|
|
}
|
|
}
|
|
ref2 = clipboardData.items;
|
|
for (_i = k = 0, len1 = ref2.length; k < len1; _i = ++k) {
|
|
item = ref2[_i];
|
|
if (item.type.match(/^image\//)) {
|
|
reader = new FileReader();
|
|
reader.onload = function(event) {
|
|
return _this._handleImage(event.target.result, _this.originalEvent, pastedFilename);
|
|
};
|
|
try {
|
|
reader.readAsDataURL(item.getAsFile());
|
|
} catch (error) {}
|
|
ev.preventDefault();
|
|
break;
|
|
}
|
|
if (item.type === 'text/plain') {
|
|
if (_i === 0 && clipboardData.items.length > 1 && clipboardData.items[1].type.match(/^image\//)) {
|
|
stringIsFilename = true;
|
|
fileType = clipboardData.items[1].type;
|
|
}
|
|
item.getAsString(function(string) {
|
|
if (stringIsFilename) {
|
|
pastedFilename = string;
|
|
return _this._target.trigger('pasteText', {
|
|
text: string,
|
|
isFilename: true,
|
|
fileType: fileType,
|
|
originalEvent: _this.originalEvent
|
|
});
|
|
} else {
|
|
return _this._target.trigger('pasteText', {
|
|
text: string,
|
|
originalEvent: _this.originalEvent
|
|
});
|
|
}
|
|
});
|
|
}
|
|
if (item.type === 'text/rtf') {
|
|
item.getAsString(function(string) {
|
|
return _this._target.trigger('pasteTextRich', {
|
|
text: string,
|
|
originalEvent: _this.originalEvent
|
|
});
|
|
});
|
|
}
|
|
if (item.type === 'text/html') {
|
|
item.getAsString(function(string) {
|
|
return _this._target.trigger('pasteTextHtml', {
|
|
text: string,
|
|
originalEvent: _this.originalEvent
|
|
});
|
|
});
|
|
}
|
|
}
|
|
} else {
|
|
if (-1 !== Array.prototype.indexOf.call(clipboardData.types, 'text/plain')) {
|
|
text = clipboardData.getData('Text');
|
|
setTimeout(function() {
|
|
return _this._target.trigger('pasteText', {
|
|
text: text,
|
|
originalEvent: _this.originalEvent
|
|
});
|
|
}, 1);
|
|
}
|
|
_this._checkImagesInContainer(function(src) {
|
|
return _this._handleImage(src, _this.originalEvent);
|
|
});
|
|
}
|
|
}
|
|
if (clipboardData = window.clipboardData) {
|
|
if ((ref3 = (text = clipboardData.getData('Text'))) != null ? ref3.length : void 0) {
|
|
setTimeout(function() {
|
|
_this._target.trigger('pasteText', {
|
|
text: text,
|
|
originalEvent: _this.originalEvent
|
|
});
|
|
return _this._target.trigger('_pasteCheckContainerDone');
|
|
}, 1);
|
|
} else {
|
|
ref4 = clipboardData.files;
|
|
for (l = 0, len2 = ref4.length; l < len2; l++) {
|
|
file = ref4[l];
|
|
_this._handleImage(URL.createObjectURL(file), _this.originalEvent);
|
|
}
|
|
_this._checkImagesInContainer(function(src) {});
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
})(this));
|
|
}
|
|
|
|
Paste.prototype._handleImage = function(src, e, name) {
|
|
var loader;
|
|
if (src.match(/^webkit\-fake\-url\:\/\//)) {
|
|
return this._target.trigger('pasteImageError', {
|
|
message: "You are trying to paste an image in Safari, however we are unable to retieve its data."
|
|
});
|
|
}
|
|
this._target.trigger('pasteImageStart');
|
|
loader = new Image();
|
|
loader.crossOrigin = "anonymous";
|
|
loader.onload = (function(_this) {
|
|
return function() {
|
|
var blob, canvas, ctx, dataURL;
|
|
canvas = document.createElement('canvas');
|
|
canvas.width = loader.width;
|
|
canvas.height = loader.height;
|
|
ctx = canvas.getContext('2d');
|
|
ctx.drawImage(loader, 0, 0, canvas.width, canvas.height);
|
|
dataURL = null;
|
|
try {
|
|
dataURL = canvas.toDataURL('image/png');
|
|
blob = dataURLtoBlob(dataURL);
|
|
} catch (error) {}
|
|
if (dataURL) {
|
|
_this._target.trigger('pasteImage', {
|
|
blob: blob,
|
|
dataURL: dataURL,
|
|
width: loader.width,
|
|
height: loader.height,
|
|
originalEvent: e,
|
|
name: name
|
|
});
|
|
}
|
|
return _this._target.trigger('pasteImageEnd');
|
|
};
|
|
})(this);
|
|
loader.onerror = (function(_this) {
|
|
return function() {
|
|
_this._target.trigger('pasteImageError', {
|
|
message: "Failed to get image from: " + src,
|
|
url: src
|
|
});
|
|
return _this._target.trigger('pasteImageEnd');
|
|
};
|
|
})(this);
|
|
return loader.src = src;
|
|
};
|
|
|
|
Paste.prototype._checkImagesInContainer = function(cb) {
|
|
var img, j, len, ref, timespan;
|
|
timespan = Math.floor(1000 * Math.random());
|
|
ref = this._container.find('img');
|
|
for (j = 0, len = ref.length; j < len; j++) {
|
|
img = ref[j];
|
|
img["_paste_marked_" + timespan] = true;
|
|
}
|
|
return setTimeout((function(_this) {
|
|
return function() {
|
|
var k, len1, ref1;
|
|
ref1 = _this._container.find('img');
|
|
for (k = 0, len1 = ref1.length; k < len1; k++) {
|
|
img = ref1[k];
|
|
if (!img["_paste_marked_" + timespan]) {
|
|
cb(img.src);
|
|
$(img).remove();
|
|
}
|
|
}
|
|
return _this._target.trigger('_pasteCheckContainerDone');
|
|
};
|
|
})(this), 1);
|
|
};
|
|
|
|
return Paste;
|
|
|
|
})();
|
|
|
|
}).call(this);
|