ep_fileupload
Advanced tools
Comparing version 0.0.10 to 0.0.12
/** | ||
* Copyright 2009, 2011 RedHog, Egil Möller <egil.moller@piratpartiet.se> | ||
* | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
@@ -17,48 +17,43 @@ * distributed under the License is distributed on an "AS-IS" BASIS, | ||
var crypto = require('crypto'); | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
var formidable = require('formidable'); | ||
var eejs = require("ep_etherpad-lite/node/eejs"); | ||
const crypto = require('crypto'); | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const formidable = require('formidable'); | ||
const eejs = require('ep_etherpad-lite/node/eejs'); | ||
var hashFile = function (file, hash, digest, cb) { | ||
const hashFile = function (file, hash, digest, cb) { | ||
if (digest === undefined) digest = 'hex'; | ||
if (hash === undefined) hash = 'md5'; | ||
var state = crypto.createHash(hash); | ||
var stream = fs.createReadStream(file, {}); | ||
stream.on("data", function(data){ | ||
const state = crypto.createHash(hash); | ||
const stream = fs.createReadStream(file, {}); | ||
stream.on('data', (data) => { | ||
state.update(data); | ||
}); | ||
stream.on("error", function(err){ | ||
stream.on('error', (err) => { | ||
cb(err, null); | ||
}); | ||
stream.on("close", function(){ | ||
stream.on('close', () => { | ||
cb(null, state.digest(digest)); | ||
}); | ||
} | ||
}; | ||
exports.onRequest = function (req, res) { | ||
var form = new formidable.IncomingForm(); | ||
form.uploadDir = path.normalize(path.join(__dirname, "..", "upload")); | ||
form.parse(req, function(err, fields, files) { | ||
const form = new formidable.IncomingForm(); | ||
form.uploadDir = path.normalize(path.join(__dirname, '..', 'upload')); | ||
form.parse(req, (err, fields, files) => { | ||
if (err) throw err; | ||
var tmp = files.uploadfile.path; | ||
var extension = files.uploadfile.name.split('.').pop(); | ||
const tmp = files.uploadfile.path; | ||
const extension = files.uploadfile.filename.split('.').pop(); | ||
hashFile(tmp, undefined, undefined, function (err, hash) { | ||
var name = hash + "." + extension; | ||
var perm = path.normalize(path.join(__dirname, "..", "upload", name)); | ||
fs.rename(tmp, perm, function(err) { | ||
fs.unlink(tmp, function() { | ||
hashFile(tmp, undefined, undefined, (err, hash) => { | ||
const name = `${hash}.${extension}`; | ||
const perm = path.normalize(path.join(__dirname, '..', 'upload', name)); | ||
fs.rename(tmp, perm, (err) => { | ||
fs.unlink(tmp, () => { | ||
if (err) throw err; | ||
var regex = /^(https?:\/\/[^\/]+)\//; | ||
var urlBase = 'http://' + req.headers.host; | ||
var matches = regex.exec(req.headers['referer']); | ||
if(typeof req.headers['referer'] != "undefined" && typeof matches[1] != "undefined"){ | ||
urlBase = matches[1]; | ||
} | ||
res.send(eejs.require("ep_fileupload/templates/fileUploaded.ejs", {upload: urlBase + "/up/" + name}, module)); | ||
// FIXME: Calculate URL for real, with path prefix and with https handling | ||
res.send(eejs.require('ep_fileupload/templates/fileUploaded.ejs', {upload: `http://${req.headers.host}/up/${name}`}, module)); | ||
}); | ||
@@ -68,2 +63,2 @@ }); | ||
}); | ||
} | ||
}; |
34
hooks.js
@@ -1,31 +0,31 @@ | ||
var path = require('path') | ||
, express = require('ep_etherpad-lite/node_modules/express') | ||
, eejs = require("ep_etherpad-lite/node/eejs") | ||
, controller = require("./controllers/fileUpload"); | ||
const path = require('path'); | ||
const express = require('ep_etherpad-lite/node_modules/express'); | ||
const eejs = require('ep_etherpad-lite/node/eejs'); | ||
const controller = require('./controllers/fileUpload'); | ||
exports.expressConfigure = function(hook_name, args, cb) { | ||
} | ||
exports.expressConfigure = function (hook_name, args, cb) { | ||
}; | ||
exports.expressServer = function (hook_name, args, cb) { | ||
args.app.post('/fileUpload', controller.onRequest); | ||
args.app.get('/up/:filename(*)', function(req, res) { | ||
var url = req.params.filename.replace(/\.\./g, '').split("?")[0]; | ||
var filePath = path.normalize(path.join(__dirname, "upload", url)); | ||
res.sendfile(filePath, { maxAge: exports.maxAge }); | ||
args.app.get('/up/:filename(*)', (req, res) => { | ||
const url = req.params.filename.replace(/\.\./g, '').split('?')[0]; | ||
const filePath = path.normalize(path.join(__dirname, 'upload', url)); | ||
res.sendfile(filePath, {maxAge: exports.maxAge}); | ||
}); | ||
} | ||
}; | ||
exports.eejsBlock_editbarMenuLeft = function (hook_name, args, cb) { | ||
args.content = args.content + eejs.require("ep_fileupload/templates/fileUploadEditbarButtons.ejs", {}, module); | ||
args.content += eejs.require('ep_fileupload/templates/fileUploadEditbarButtons.ejs', {}, module); | ||
return cb(); | ||
} | ||
}; | ||
exports.eejsBlock_scripts = function (hook_name, args, cb) { | ||
args.content = args.content + eejs.require("ep_fileupload/templates/fileUploadScripts.ejs", {}, module); | ||
args.content += eejs.require('ep_fileupload/templates/fileUploadScripts.ejs', {}, module); | ||
return cb(); | ||
} | ||
}; | ||
exports.eejsBlock_styles = function (hook_name, args, cb) { | ||
args.content = args.content + eejs.require("ep_fileupload/templates/fileUploadStyles.ejs", {}, module); | ||
args.content += eejs.require('ep_fileupload/templates/fileUploadStyles.ejs', {}, module); | ||
return cb(); | ||
} | ||
}; |
{ | ||
"name": "ep_fileupload", | ||
"description": "File upload", | ||
"version": "0.0.10", | ||
"version": "0.0.12", | ||
"author": "RedHog (Egil Moeller) <egil.moller@freecode.no>", | ||
"contributors": ["johnyma22 (John McLear) <john@mclear.co.uk>"], | ||
"contributors": [ | ||
"johnyma22 (John McLear) <john@mclear.co.uk>" | ||
], | ||
"dependencies": { | ||
"formidable": ">= 1.0.11" | ||
}, | ||
"engines": { "node": "*" } | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/JohnMcLear/ep_fileupload.git" | ||
}, | ||
"engines": { | ||
"node": "*" | ||
}, | ||
"funding": { | ||
"type": "individual", | ||
"url": "http://etherpad.org/" | ||
}, | ||
"devDependencies": { | ||
"eslint": "^7.14.0", | ||
"eslint-config-etherpad": "^1.0.8", | ||
"eslint-plugin-mocha": "^8.0.0", | ||
"eslint-plugin-node": "^11.1.0", | ||
"eslint-plugin-prefer-arrow": "^1.2.2", | ||
"eslint-plugin-promise": "^4.2.1" | ||
}, | ||
"eslintConfig": { | ||
"root": true, | ||
"extends": "etherpad/plugin" | ||
}, | ||
"scripts": { | ||
"lint": "eslint .", | ||
"lint:fix": "eslint --fix ." | ||
} | ||
} |
@@ -1,2 +0,28 @@ | ||
# ep_fileupload | ||
File upload plugin for Etherpad Lite. A user can upload a file, and a link to the uploaded file is automatically inserted in the pad. | ||
[![Travis (.org)](https://api.travis-ci.org/JohnMcLear/ep_fileupload.git.svg?branch=develop)](https://travis-ci.org/github/JohnMcLear/ep_fileupload.git) | ||
# My awesome plugin README example | ||
Explain what your plugin does and who it's useful for. | ||
## Example animated gif of usage if appropriate | ||
## Installing | ||
npm install ep_fileupload | ||
or Use the Etherpad ``/admin`` interface. | ||
## Settings | ||
Document settings if any | ||
## Testing | ||
Document how to run backend / frontend tests. | ||
### Frontend | ||
Visit http://whatever/tests/frontend/ to run the frontend tests. | ||
### backend | ||
Type ``cd src && npm run test`` to run the backend tests. | ||
## LICENSE | ||
Apache 2.0 |
@@ -14,534 +14,530 @@ /** | ||
* 3. Fixed IE "mixed content" issue when used with secure connections | ||
* | ||
* For the full changelog please visit: | ||
* | ||
* For the full changelog please visit: | ||
* http://valums.com/ajax-upload-changelog/ | ||
*/ | ||
(function(){ | ||
var d = document, w = window; | ||
(function () { | ||
const d = document; const | ||
w = window; | ||
/** | ||
/** | ||
* Get element by id | ||
*/ | ||
function get(element){ | ||
if (typeof element == "string") | ||
element = d.getElementById(element); | ||
return element; | ||
} | ||
*/ | ||
function get(element) { | ||
if (typeof element === 'string') element = d.getElementById(element); | ||
return element; | ||
} | ||
/** | ||
/** | ||
* Attaches event to a dom element | ||
*/ | ||
function addEvent(el, type, fn){ | ||
if (w.addEventListener){ | ||
el.addEventListener(type, fn, false); | ||
} else if (w.attachEvent){ | ||
var f = function(){ | ||
function addEvent(el, type, fn) { | ||
if (w.addEventListener) { | ||
el.addEventListener(type, fn, false); | ||
} else if (w.attachEvent) { | ||
const f = function () { | ||
fn.call(el, w.event); | ||
}; | ||
el.attachEvent('on' + type, f) | ||
} | ||
} | ||
}; | ||
el.attachEvent(`on${type}`, f); | ||
} | ||
} | ||
/** | ||
/** | ||
* Creates and returns element from html chunk | ||
*/ | ||
var toElement = function(){ | ||
var div = d.createElement('div'); | ||
return function(html){ | ||
div.innerHTML = html; | ||
var el = div.childNodes[0]; | ||
div.removeChild(el); | ||
return el; | ||
} | ||
}(); | ||
const toElement = function () { | ||
const div = d.createElement('div'); | ||
return function (html) { | ||
div.innerHTML = html; | ||
const el = div.childNodes[0]; | ||
div.removeChild(el); | ||
return el; | ||
}; | ||
}(); | ||
function hasClass(ele,cls){ | ||
return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)')); | ||
} | ||
function addClass(ele,cls) { | ||
if (!hasClass(ele,cls)) ele.className += " "+cls; | ||
} | ||
function removeClass(ele,cls) { | ||
var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)'); | ||
ele.className=ele.className.replace(reg,' '); | ||
} | ||
function hasClass(ele, cls) { | ||
return ele.className.match(new RegExp(`(\\s|^)${cls}(\\s|$)`)); | ||
} | ||
function addClass(ele, cls) { | ||
if (!hasClass(ele, cls)) ele.className += ` ${cls}`; | ||
} | ||
function removeClass(ele, cls) { | ||
const reg = new RegExp(`(\\s|^)${cls}(\\s|$)`); | ||
ele.className = ele.className.replace(reg, ' '); | ||
} | ||
// getOffset function copied from jQuery lib (http://jquery.com/) | ||
if (document.documentElement["getBoundingClientRect"]){ | ||
// Get Offset using getBoundingClientRect | ||
// http://ejohn.org/blog/getboundingclientrect-is-awesome/ | ||
var getOffset = function(el){ | ||
var box = el.getBoundingClientRect(), | ||
doc = el.ownerDocument, | ||
body = doc.body, | ||
docElem = doc.documentElement, | ||
// for ie | ||
clientTop = docElem.clientTop || body.clientTop || 0, | ||
clientLeft = docElem.clientLeft || body.clientLeft || 0, | ||
// In Internet Explorer 7 getBoundingClientRect property is treated as physical, | ||
// while others are logical. Make all logical, like in IE8. | ||
zoom = 1; | ||
if (body.getBoundingClientRect) { | ||
var bound = body.getBoundingClientRect(); | ||
zoom = (bound.right - bound.left)/body.clientWidth; | ||
} | ||
if (zoom > 1){ | ||
clientTop = 0; | ||
clientLeft = 0; | ||
} | ||
var top = box.top/zoom + (window.pageYOffset || docElem && docElem.scrollTop/zoom || body.scrollTop/zoom) - clientTop, | ||
left = box.left/zoom + (window.pageXOffset|| docElem && docElem.scrollLeft/zoom || body.scrollLeft/zoom) - clientLeft; | ||
return { | ||
top: top, | ||
left: left | ||
}; | ||
} | ||
} else { | ||
// Get offset adding all offsets | ||
var getOffset = function(el){ | ||
if (w.jQuery){ | ||
return jQuery(el).offset(); | ||
} | ||
var top = 0, left = 0; | ||
do { | ||
top += el.offsetTop || 0; | ||
left += el.offsetLeft || 0; | ||
} | ||
while (el = el.offsetParent); | ||
return { | ||
left: left, | ||
top: top | ||
}; | ||
} | ||
} | ||
// getOffset function copied from jQuery lib (http://jquery.com/) | ||
if (document.documentElement.getBoundingClientRect) { | ||
// Get Offset using getBoundingClientRect | ||
// http://ejohn.org/blog/getboundingclientrect-is-awesome/ | ||
var getOffset = function (el) { | ||
const box = el.getBoundingClientRect(); | ||
const doc = el.ownerDocument; | ||
const body = doc.body; | ||
const docElem = doc.documentElement; | ||
function getBox(el){ | ||
var left, right, top, bottom; | ||
var offset = getOffset(el); | ||
left = offset.left; | ||
top = offset.top; | ||
right = left + el.offsetWidth; | ||
bottom = top + el.offsetHeight; | ||
return { | ||
left: left, | ||
right: right, | ||
top: top, | ||
bottom: bottom | ||
}; | ||
} | ||
// for ie | ||
let clientTop = docElem.clientTop || body.clientTop || 0; | ||
let clientLeft = docElem.clientLeft || body.clientLeft || 0; | ||
/** | ||
// In Internet Explorer 7 getBoundingClientRect property is treated as physical, | ||
// while others are logical. Make all logical, like in IE8. | ||
let zoom = 1; | ||
if (body.getBoundingClientRect) { | ||
const bound = body.getBoundingClientRect(); | ||
zoom = (bound.right - bound.left) / body.clientWidth; | ||
} | ||
if (zoom > 1) { | ||
clientTop = 0; | ||
clientLeft = 0; | ||
} | ||
const top = box.top / zoom + (window.pageYOffset || docElem && docElem.scrollTop / zoom || body.scrollTop / zoom) - clientTop; | ||
const left = box.left / zoom + (window.pageXOffset || docElem && docElem.scrollLeft / zoom || body.scrollLeft / zoom) - clientLeft; | ||
return { | ||
top, | ||
left, | ||
}; | ||
}; | ||
} else { | ||
// Get offset adding all offsets | ||
var getOffset = function (el) { | ||
if (w.jQuery) { | ||
return jQuery(el).offset(); | ||
} | ||
let top = 0; let | ||
left = 0; | ||
do { | ||
top += el.offsetTop || 0; | ||
left += el.offsetLeft || 0; | ||
} | ||
while (el = el.offsetParent); | ||
return { | ||
left, | ||
top, | ||
}; | ||
}; | ||
} | ||
function getBox(el) { | ||
let left, right, top, bottom; | ||
const offset = getOffset(el); | ||
left = offset.left; | ||
top = offset.top; | ||
right = left + el.offsetWidth; | ||
bottom = top + el.offsetHeight; | ||
return { | ||
left, | ||
right, | ||
top, | ||
bottom, | ||
}; | ||
} | ||
/** | ||
* Crossbrowser mouse coordinates | ||
*/ | ||
function getMouseCoords(e){ | ||
// pageX/Y is not supported in IE | ||
// http://www.quirksmode.org/dom/w3c_cssom.html | ||
if (!e.pageX && e.clientX){ | ||
// In Internet Explorer 7 some properties (mouse coordinates) are treated as physical, | ||
// while others are logical (offset). | ||
var zoom = 1; | ||
var body = document.body; | ||
if (body.getBoundingClientRect) { | ||
var bound = body.getBoundingClientRect(); | ||
zoom = (bound.right - bound.left)/body.clientWidth; | ||
} | ||
function getMouseCoords(e) { | ||
// pageX/Y is not supported in IE | ||
// http://www.quirksmode.org/dom/w3c_cssom.html | ||
if (!e.pageX && e.clientX) { | ||
// In Internet Explorer 7 some properties (mouse coordinates) are treated as physical, | ||
// while others are logical (offset). | ||
let zoom = 1; | ||
const body = document.body; | ||
return { | ||
x: e.clientX / zoom + d.body.scrollLeft + d.documentElement.scrollLeft, | ||
y: e.clientY / zoom + d.body.scrollTop + d.documentElement.scrollTop | ||
}; | ||
} | ||
return { | ||
x: e.pageX, | ||
y: e.pageY | ||
}; | ||
if (body.getBoundingClientRect) { | ||
const bound = body.getBoundingClientRect(); | ||
zoom = (bound.right - bound.left) / body.clientWidth; | ||
} | ||
} | ||
/** | ||
return { | ||
x: e.clientX / zoom + d.body.scrollLeft + d.documentElement.scrollLeft, | ||
y: e.clientY / zoom + d.body.scrollTop + d.documentElement.scrollTop, | ||
}; | ||
} | ||
return { | ||
x: e.pageX, | ||
y: e.pageY, | ||
}; | ||
} | ||
/** | ||
* Function generates unique id | ||
*/ | ||
var getUID = function(){ | ||
var id = 0; | ||
return function(){ | ||
return 'ValumsAjaxUpload' + id++; | ||
} | ||
}(); | ||
*/ | ||
const getUID = function () { | ||
let id = 0; | ||
return function () { | ||
return `ValumsAjaxUpload${id++}`; | ||
}; | ||
}(); | ||
function fileFromPath(file){ | ||
return file.replace(/.*(\/|\\)/, ""); | ||
} | ||
function fileFromPath(file) { | ||
return file.replace(/.*(\/|\\)/, ''); | ||
} | ||
function getExt(file){ | ||
return (/[.]/.exec(file)) ? /[^.]+$/.exec(file.toLowerCase()) : ''; | ||
} | ||
function getExt(file) { | ||
return (/[.]/.exec(file)) ? /[^.]+$/.exec(file.toLowerCase()) : ''; | ||
} | ||
// Please use AjaxUpload , Ajax_upload will be removed in the next version | ||
Ajax_upload = AjaxUpload = function(button, options){ | ||
if (button.jquery){ | ||
// jquery object was passed | ||
button = button[0]; | ||
} else if (typeof button == "string" && /^#.*/.test(button)){ | ||
button = button.slice(1); | ||
} | ||
button = get(button); | ||
this._input = null; | ||
this._button = button; | ||
this._disabled = false; | ||
this._submitting = false; | ||
// Variable changes to true if the button was clicked | ||
// 3 seconds ago (requred to fix Safari on Mac error) | ||
this._justClicked = false; | ||
this._parentDialog = d.body; | ||
if (window.jQuery && jQuery.ui && jQuery.ui.dialog){ | ||
var parentDialog = jQuery(this._button).parents('.ui-dialog'); | ||
if (parentDialog.length){ | ||
this._parentDialog = parentDialog[0]; | ||
} | ||
} | ||
this._settings = { | ||
// Location of the server-side upload script | ||
action: 'upload.php', | ||
// File upload name | ||
name: 'userfile', | ||
// Additional data to send | ||
data: {}, | ||
// Submit file as soon as it's selected | ||
autoSubmit: true, | ||
// The type of data that you're expecting back from the server. | ||
// Html and xml are detected automatically. | ||
// Only useful when you are using json data as a response. | ||
// Set to "json" in that case. | ||
responseType: false, | ||
// When user selects a file, useful with autoSubmit disabled | ||
onChange: function(file, extension){}, | ||
// Callback to fire before file is uploaded | ||
// You can return false to cancel upload | ||
onSubmit: function(file, extension){}, | ||
// Fired when file upload is completed | ||
// WARNING! DO NOT USE "FALSE" STRING AS A RESPONSE! | ||
onComplete: function(file, response) {} | ||
}; | ||
// Please use AjaxUpload , Ajax_upload will be removed in the next version | ||
Ajax_upload = AjaxUpload = function (button, options) { | ||
if (button.jquery) { | ||
// jquery object was passed | ||
button = button[0]; | ||
} else if (typeof button === 'string' && /^#.*/.test(button)) { | ||
button = button.slice(1); | ||
} | ||
button = get(button); | ||
// Merge the users options with our defaults | ||
for (var i in options) { | ||
this._settings[i] = options[i]; | ||
} | ||
this._createInput(); | ||
this._rerouteClicks(); | ||
} | ||
// assigning methods to our class | ||
AjaxUpload.prototype = { | ||
setData : function(data){ | ||
this._settings.data = data; | ||
}, | ||
disable : function(){ | ||
this._disabled = true; | ||
}, | ||
enable : function(){ | ||
this._disabled = false; | ||
}, | ||
// removes ajaxupload | ||
destroy : function(){ | ||
if(this._input){ | ||
if(this._input.parentNode){ | ||
this._input.parentNode.removeChild(this._input); | ||
} | ||
this._input = null; | ||
} | ||
}, | ||
/** | ||
* Creates invisible file input above the button | ||
this._input = null; | ||
this._button = button; | ||
this._disabled = false; | ||
this._submitting = false; | ||
// Variable changes to true if the button was clicked | ||
// 3 seconds ago (requred to fix Safari on Mac error) | ||
this._justClicked = false; | ||
this._parentDialog = d.body; | ||
if (window.jQuery && jQuery.ui && jQuery.ui.dialog) { | ||
const parentDialog = jQuery(this._button).parents('.ui-dialog'); | ||
if (parentDialog.length) { | ||
this._parentDialog = parentDialog[0]; | ||
} | ||
} | ||
this._settings = { | ||
// Location of the server-side upload script | ||
action: 'upload.php', | ||
// File upload name | ||
name: 'userfile', | ||
// Additional data to send | ||
data: {}, | ||
// Submit file as soon as it's selected | ||
autoSubmit: true, | ||
// The type of data that you're expecting back from the server. | ||
// Html and xml are detected automatically. | ||
// Only useful when you are using json data as a response. | ||
// Set to "json" in that case. | ||
responseType: false, | ||
// When user selects a file, useful with autoSubmit disabled | ||
onChange(file, extension) {}, | ||
// Callback to fire before file is uploaded | ||
// You can return false to cancel upload | ||
onSubmit(file, extension) {}, | ||
// Fired when file upload is completed | ||
// WARNING! DO NOT USE "FALSE" STRING AS A RESPONSE! | ||
onComplete(file, response) {}, | ||
}; | ||
// Merge the users options with our defaults | ||
for (const i in options) { | ||
this._settings[i] = options[i]; | ||
} | ||
this._createInput(); | ||
this._rerouteClicks(); | ||
}; | ||
// assigning methods to our class | ||
AjaxUpload.prototype = { | ||
setData(data) { | ||
this._settings.data = data; | ||
}, | ||
disable() { | ||
this._disabled = true; | ||
}, | ||
enable() { | ||
this._disabled = false; | ||
}, | ||
// removes ajaxupload | ||
destroy() { | ||
if (this._input) { | ||
if (this._input.parentNode) { | ||
this._input.parentNode.removeChild(this._input); | ||
} | ||
this._input = null; | ||
} | ||
}, | ||
/** | ||
* Creates invisible file input above the button | ||
*/ | ||
_createInput : function(){ | ||
var self = this; | ||
var input = d.createElement("input"); | ||
input.setAttribute('type', 'file'); | ||
input.setAttribute('name', this._settings.name); | ||
var styles = { | ||
'position' : 'absolute' | ||
,'margin': '-5px 0 0 -175px' | ||
,'padding': 0 | ||
,'width': '220px' | ||
,'height': '30px' | ||
,'fontSize': '14px' | ||
,'opacity': 0 | ||
,'cursor': 'pointer' | ||
,'display' : 'none' | ||
,'zIndex' : 2147483583 //Max zIndex supported by Opera 9.0-9.2x | ||
// Strange, I expected 2147483647 | ||
}; | ||
for (var i in styles){ | ||
input.style[i] = styles[i]; | ||
} | ||
// Make sure that element opacity exists | ||
// (IE uses filter instead) | ||
if ( ! (input.style.opacity === "0")){ | ||
input.style.filter = "alpha(opacity=0)"; | ||
} | ||
this._parentDialog.appendChild(input); | ||
_createInput() { | ||
const self = this; | ||
const input = d.createElement('input'); | ||
input.setAttribute('type', 'file'); | ||
input.setAttribute('name', this._settings.name); | ||
const styles = { | ||
position: 'absolute', | ||
margin: '-5px 0 0 -175px', | ||
padding: 0, | ||
width: '220px', | ||
height: '30px', | ||
fontSize: '14px', | ||
opacity: 0, | ||
cursor: 'pointer', | ||
display: 'none', | ||
zIndex: 2147483583, // Max zIndex supported by Opera 9.0-9.2x | ||
// Strange, I expected 2147483647 | ||
}; | ||
for (const i in styles) { | ||
input.style[i] = styles[i]; | ||
} | ||
addEvent(input, 'change', function(){ | ||
// get filename from input | ||
var file = fileFromPath(this.value); | ||
if(self._settings.onChange.call(self, file, getExt(file)) == false ){ | ||
return; | ||
} | ||
// Submit form when value is changed | ||
if (self._settings.autoSubmit){ | ||
self.submit(); | ||
} | ||
}); | ||
// Fixing problem with Safari | ||
// The problem is that if you leave input before the file select dialog opens | ||
// it does not upload the file. | ||
// As dialog opens slowly (it is a sheet dialog which takes some time to open) | ||
// there is some time while you can leave the button. | ||
// So we should not change display to none immediately | ||
addEvent(input, 'click', function(){ | ||
self.justClicked = true; | ||
setTimeout(function(){ | ||
// we will wait 3 seconds for dialog to open | ||
self.justClicked = false; | ||
}, 3000); | ||
}); | ||
this._input = input; | ||
}, | ||
_rerouteClicks : function (){ | ||
var self = this; | ||
// IE displays 'access denied' error when using this method | ||
// other browsers just ignore click() | ||
// addEvent(this._button, 'click', function(e){ | ||
// self._input.click(); | ||
// }); | ||
var box, dialogOffset = {top:0, left:0}, over = false; | ||
addEvent(self._button, 'mouseover', function(e){ | ||
if (!self._input || over) return; | ||
over = true; | ||
box = getBox(self._button); | ||
if (self._parentDialog != d.body){ | ||
dialogOffset = getOffset(self._parentDialog); | ||
} | ||
}); | ||
// we can't use mouseout on the button, | ||
// because invisible input is over it | ||
addEvent(document, 'mousemove', function(e){ | ||
var input = self._input; | ||
if (!input || !over) return; | ||
if (self._disabled){ | ||
removeClass(self._button, 'hover'); | ||
input.style.display = 'none'; | ||
return; | ||
} | ||
var c = getMouseCoords(e); | ||
// Make sure that element opacity exists | ||
// (IE uses filter instead) | ||
if (!(input.style.opacity === '0')) { | ||
input.style.filter = 'alpha(opacity=0)'; | ||
} | ||
if ((c.x >= box.left) && (c.x <= box.right) && | ||
(c.y >= box.top) && (c.y <= box.bottom)){ | ||
input.style.top = c.y - dialogOffset.top + 'px'; | ||
input.style.left = c.x - dialogOffset.left + 'px'; | ||
input.style.display = 'block'; | ||
addClass(self._button, 'hover'); | ||
} else { | ||
// mouse left the button | ||
over = false; | ||
if (!self.justClicked){ | ||
input.style.display = 'none'; | ||
} | ||
removeClass(self._button, 'hover'); | ||
} | ||
}); | ||
}, | ||
/** | ||
this._parentDialog.appendChild(input); | ||
addEvent(input, 'change', function () { | ||
// get filename from input | ||
const file = fileFromPath(this.value); | ||
if (self._settings.onChange.call(self, file, getExt(file)) == false) { | ||
return; | ||
} | ||
// Submit form when value is changed | ||
if (self._settings.autoSubmit) { | ||
self.submit(); | ||
} | ||
}); | ||
// Fixing problem with Safari | ||
// The problem is that if you leave input before the file select dialog opens | ||
// it does not upload the file. | ||
// As dialog opens slowly (it is a sheet dialog which takes some time to open) | ||
// there is some time while you can leave the button. | ||
// So we should not change display to none immediately | ||
addEvent(input, 'click', () => { | ||
self.justClicked = true; | ||
setTimeout(() => { | ||
// we will wait 3 seconds for dialog to open | ||
self.justClicked = false; | ||
}, 3000); | ||
}); | ||
this._input = input; | ||
}, | ||
_rerouteClicks() { | ||
const self = this; | ||
// IE displays 'access denied' error when using this method | ||
// other browsers just ignore click() | ||
// addEvent(this._button, 'click', function(e){ | ||
// self._input.click(); | ||
// }); | ||
let box; let dialogOffset = {top: 0, left: 0}; let | ||
over = false; | ||
addEvent(self._button, 'mouseover', (e) => { | ||
if (!self._input || over) return; | ||
over = true; | ||
box = getBox(self._button); | ||
if (self._parentDialog != d.body) { | ||
dialogOffset = getOffset(self._parentDialog); | ||
} | ||
}); | ||
// we can't use mouseout on the button, | ||
// because invisible input is over it | ||
addEvent(document, 'mousemove', (e) => { | ||
const input = self._input; | ||
if (!input || !over) return; | ||
if (self._disabled) { | ||
removeClass(self._button, 'hover'); | ||
input.style.display = 'none'; | ||
return; | ||
} | ||
const c = getMouseCoords(e); | ||
if ((c.x >= box.left) && (c.x <= box.right) && | ||
(c.y >= box.top) && (c.y <= box.bottom)) { | ||
input.style.top = `${c.y - dialogOffset.top}px`; | ||
input.style.left = `${c.x - dialogOffset.left}px`; | ||
input.style.display = 'block'; | ||
addClass(self._button, 'hover'); | ||
} else { | ||
// mouse left the button | ||
over = false; | ||
if (!self.justClicked) { | ||
input.style.display = 'none'; | ||
} | ||
removeClass(self._button, 'hover'); | ||
} | ||
}); | ||
}, | ||
/** | ||
* Creates iframe with unique name | ||
*/ | ||
_createIframe : function(){ | ||
// unique name | ||
// We cannot use getTime, because it sometimes return | ||
// same value in safari :( | ||
var id = getUID(); | ||
// Remove ie6 "This page contains both secure and nonsecure items" prompt | ||
// http://tinyurl.com/77w9wh | ||
var iframe = toElement('<iframe src="javascript:document.domain = document.domain;" name="' + id + '" />'); | ||
iframe.id = id; | ||
iframe.style.display = 'none'; | ||
d.body.appendChild(iframe); | ||
return iframe; | ||
}, | ||
/** | ||
_createIframe() { | ||
// unique name | ||
// We cannot use getTime, because it sometimes return | ||
// same value in safari :( | ||
const id = getUID(); | ||
// Remove ie6 "This page contains both secure and nonsecure items" prompt | ||
// http://tinyurl.com/77w9wh | ||
const iframe = toElement(`<iframe src="javascript:document.domain = document.domain;" name="${id}" />`); | ||
iframe.id = id; | ||
iframe.style.display = 'none'; | ||
d.body.appendChild(iframe); | ||
return iframe; | ||
}, | ||
/** | ||
* Upload file without refreshing the page | ||
*/ | ||
submit : function(){ | ||
var self = this, settings = this._settings; | ||
if (this._input.value === ''){ | ||
// there is no file | ||
return; | ||
} | ||
// get filename from input | ||
var file = fileFromPath(this._input.value); | ||
submit() { | ||
const self = this; const | ||
settings = this._settings; | ||
// execute user event | ||
if (! (settings.onSubmit.call(this, file, getExt(file)) == false)) { | ||
// Create new iframe for this submission | ||
var iframe = this._createIframe(); | ||
// Do not submit if user function returns false | ||
var form = this._createForm(iframe); | ||
form.appendChild(this._input); | ||
form.submit(); | ||
d.body.removeChild(form); | ||
form = null; | ||
this._input = null; | ||
// create new input | ||
this._createInput(); | ||
var toDeleteFlag = false; | ||
addEvent(iframe, 'load', function(e){ | ||
if (// For Safari | ||
iframe.src == "javascript:'%3Chtml%3E%3C/html%3E';" || | ||
if (this._input.value === '') { | ||
// there is no file | ||
return; | ||
} | ||
// get filename from input | ||
const file = fileFromPath(this._input.value); | ||
// execute user event | ||
if (!(settings.onSubmit.call(this, file, getExt(file)) == false)) { | ||
// Create new iframe for this submission | ||
const iframe = this._createIframe(); | ||
// Do not submit if user function returns false | ||
let form = this._createForm(iframe); | ||
form.appendChild(this._input); | ||
form.submit(); | ||
d.body.removeChild(form); | ||
form = null; | ||
this._input = null; | ||
// create new input | ||
this._createInput(); | ||
let toDeleteFlag = false; | ||
addEvent(iframe, 'load', (e) => { | ||
if (// For Safari | ||
iframe.src == "javascript:'%3Chtml%3E%3C/html%3E';" || | ||
// For FF, IE | ||
iframe.src == "javascript:'<html></html>';"){ | ||
// First time around, do not delete. | ||
if( toDeleteFlag ){ | ||
// Fix busy state in FF3 | ||
setTimeout( function() { | ||
d.body.removeChild(iframe); | ||
}, 0); | ||
} | ||
return; | ||
} | ||
var doc = iframe.contentDocument ? iframe.contentDocument : frames[iframe.id].document; | ||
iframe.src == "javascript:'<html></html>';") { | ||
// First time around, do not delete. | ||
if (toDeleteFlag) { | ||
// Fix busy state in FF3 | ||
setTimeout(() => { | ||
d.body.removeChild(iframe); | ||
}, 0); | ||
} | ||
return; | ||
} | ||
// fixing Opera 9.26 | ||
if (doc.readyState && doc.readyState != 'complete'){ | ||
// Opera fires load event multiple times | ||
// Even when the DOM is not ready yet | ||
// this fix should not affect other browsers | ||
return; | ||
} | ||
// fixing Opera 9.64 | ||
if (doc.body && doc.body.innerHTML == "false"){ | ||
// In Opera 9.64 event was fired second time | ||
// when body.innerHTML changed from false | ||
// to server response approx. after 1 sec | ||
return; | ||
} | ||
const doc = iframe.contentDocument ? iframe.contentDocument : frames[iframe.id].document; | ||
var response; | ||
if (doc.XMLDocument){ | ||
// response is a xml document IE property | ||
response = doc.XMLDocument; | ||
} else if (doc.body){ | ||
// response is html document or plain text | ||
response = doc.body.innerHTML; | ||
if (settings.responseType && settings.responseType.toLowerCase() == 'json'){ | ||
// If the document was sent as 'application/javascript' or | ||
// 'text/javascript', then the browser wraps the text in a <pre> | ||
// tag and performs html encoding on the contents. In this case, | ||
// we need to pull the original text content from the text node's | ||
// nodeValue property to retrieve the unmangled content. | ||
// Note that IE6 only understands text/html | ||
if (doc.body.firstChild && doc.body.firstChild.nodeName.toUpperCase() == 'PRE'){ | ||
response = doc.body.firstChild.firstChild.nodeValue; | ||
} | ||
if (response) { | ||
response = window["eval"]("(" + response + ")"); | ||
} else { | ||
response = {}; | ||
} | ||
} | ||
} else { | ||
// response is a xml document | ||
var response = doc; | ||
} | ||
settings.onComplete.call(self, file, response); | ||
// Reload blank page, so that reloading main page | ||
// does not re-submit the post. Also, remember to | ||
// delete the frame | ||
toDeleteFlag = true; | ||
// Fix IE mixed content issue | ||
iframe.src = "javascript:'<html></html>';"; | ||
}); | ||
} else { | ||
// clear input to allow user to select same file | ||
// Doesn't work in IE6 | ||
// this._input.value = ''; | ||
d.body.removeChild(this._input); | ||
this._input = null; | ||
// create new input | ||
this._createInput(); | ||
} | ||
}, | ||
/** | ||
// fixing Opera 9.26 | ||
if (doc.readyState && doc.readyState != 'complete') { | ||
// Opera fires load event multiple times | ||
// Even when the DOM is not ready yet | ||
// this fix should not affect other browsers | ||
return; | ||
} | ||
// fixing Opera 9.64 | ||
if (doc.body && doc.body.innerHTML == 'false') { | ||
// In Opera 9.64 event was fired second time | ||
// when body.innerHTML changed from false | ||
// to server response approx. after 1 sec | ||
return; | ||
} | ||
var response; | ||
if (doc.XMLDocument) { | ||
// response is a xml document IE property | ||
response = doc.XMLDocument; | ||
} else if (doc.body) { | ||
// response is html document or plain text | ||
response = doc.body.innerHTML; | ||
if (settings.responseType && settings.responseType.toLowerCase() == 'json') { | ||
// If the document was sent as 'application/javascript' or | ||
// 'text/javascript', then the browser wraps the text in a <pre> | ||
// tag and performs html encoding on the contents. In this case, | ||
// we need to pull the original text content from the text node's | ||
// nodeValue property to retrieve the unmangled content. | ||
// Note that IE6 only understands text/html | ||
if (doc.body.firstChild && doc.body.firstChild.nodeName.toUpperCase() == 'PRE') { | ||
response = doc.body.firstChild.firstChild.nodeValue; | ||
} | ||
if (response) { | ||
response = window.eval(`(${response})`); | ||
} else { | ||
response = {}; | ||
} | ||
} | ||
} else { | ||
// response is a xml document | ||
var response = doc; | ||
} | ||
settings.onComplete.call(self, file, response); | ||
// Reload blank page, so that reloading main page | ||
// does not re-submit the post. Also, remember to | ||
// delete the frame | ||
toDeleteFlag = true; | ||
// Fix IE mixed content issue | ||
iframe.src = "javascript:'<html></html>';"; | ||
}); | ||
} else { | ||
// clear input to allow user to select same file | ||
// Doesn't work in IE6 | ||
// this._input.value = ''; | ||
d.body.removeChild(this._input); | ||
this._input = null; | ||
// create new input | ||
this._createInput(); | ||
} | ||
}, | ||
/** | ||
* Creates form, that will be submitted to iframe | ||
*/ | ||
_createForm : function(iframe){ | ||
var settings = this._settings; | ||
// method, enctype must be specified here | ||
// because changing this attr on the fly is not allowed in IE 6/7 | ||
var form = toElement('<form method="post" enctype="multipart/form-data"></form>'); | ||
form.style.display = 'none'; | ||
form.action = settings.action; | ||
form.target = iframe.name; | ||
d.body.appendChild(form); | ||
// Create hidden input element for each data key | ||
for (var prop in settings.data){ | ||
var el = d.createElement("input"); | ||
el.type = 'hidden'; | ||
el.name = prop; | ||
el.value = settings.data[prop]; | ||
form.appendChild(el); | ||
} | ||
return form; | ||
} | ||
}; | ||
})(); | ||
_createForm(iframe) { | ||
const settings = this._settings; | ||
// method, enctype must be specified here | ||
// because changing this attr on the fly is not allowed in IE 6/7 | ||
const form = toElement('<form method="post" enctype="multipart/form-data"></form>'); | ||
form.style.display = 'none'; | ||
form.action = settings.action; | ||
form.target = iframe.name; | ||
d.body.appendChild(form); | ||
// Create hidden input element for each data key | ||
for (const prop in settings.data) { | ||
const el = d.createElement('input'); | ||
el.type = 'hidden'; | ||
el.name = prop; | ||
el.value = settings.data[prop]; | ||
form.appendChild(el); | ||
} | ||
return form; | ||
}, | ||
}; | ||
})(); |
@@ -1,27 +0,16 @@ | ||
$(function(){ | ||
var info = { | ||
action: '../fileUpload/', | ||
name: 'uploadfile', | ||
onSubmit: function(file, ext){ // On submit we do nothing, it'd be nice to do something but mheh.. | ||
//console.log('Starting...'); | ||
}, | ||
onComplete: function(file, response){ | ||
// Require the editor.. | ||
var padeditor = require('ep_etherpad-lite/static/js/pad_editor').padeditor; | ||
$(() => { | ||
const info = { | ||
action: '/fileUpload/', | ||
name: 'uploadfile', | ||
onSubmit(file, ext) { | ||
// console.log('Starting...'); | ||
}, | ||
onComplete(file, response) { | ||
const padeditor = require('ep_etherpad-lite/static/js/pad_editor').padeditor; | ||
padeditor.ace.replaceRange(undefined, undefined, ` ${response.replace(/^\s+|\s+$/g, '')} `); | ||
padeditor.ace.focus(); | ||
}, | ||
}; | ||
// result i.e. "/up/c79133b2c8a97533cc397f8d325ce17a.jpg", trimmed whitespace | ||
var filePath = response.slice(response.indexOf("/up")).trim(); | ||
// "http://example.com/subfolder/p/padID" -> "http://example.com/subfolder" | ||
var etherpadRoot = document.location.href.slice(0, document.location.href.indexOf("/p/")); | ||
// "http://example.com/subfolder/up/c79133b2c8a97533cc397f8d325ce17a.jpg" | ||
var fileUri = etherpadRoot + filePath; | ||
// Puts the actual URL in the pad.. | ||
padeditor.ace.replaceRange(undefined, undefined, " " + fileUri + " "); | ||
// Put the caret back into the pad | ||
padeditor.ace.focus(); | ||
} | ||
}; | ||
new AjaxUpload($('#uploadFileSubmit'), info); | ||
new AjaxUpload($('#uploadFileSubmit'), info); | ||
}); |
@@ -8,7 +8,7 @@ function fileUploadInit() { | ||
function dropdownClicked(name, width, height) { | ||
var wrapper = $('#' + name + '-wrapper'); | ||
var panel = $('#' + name + '-panel'); | ||
const wrapper = $(`#${name}-wrapper`); | ||
const panel = $(`#${name}-panel`); | ||
if (wrapper[0].expanded) { | ||
wrapper.animate({height:'0'}); | ||
wrapper.animate({height: '0'}); | ||
wrapper[0].expanded = false; | ||
@@ -19,3 +19,3 @@ } else { | ||
wrapper.css('width', width); | ||
wrapper.animate({height: height}); | ||
wrapper.animate({height}); | ||
wrapper[0].expanded = true; | ||
@@ -25,3 +25,3 @@ } | ||
function uploadFileClicked () { | ||
function uploadFileClicked() { | ||
dropdownClicked('fileUpload', '350px', '70px'); | ||
@@ -32,6 +32,6 @@ } | ||
$('#fileUploadForm').ajaxSubmit({ | ||
complete: function (XMLHttpRequest, textStatus) { | ||
complete(XMLHttpRequest, textStatus) { | ||
// console.log([textStatus, XMLHttpRequest]); | ||
} | ||
}, | ||
}); | ||
@@ -38,0 +38,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
29
1
27464
6
16
618
1