mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-01-03 12:39:25 +01:00
WIP image upload via drag into ckeditor 4.5
This commit is contained in:
parent
3853343f7e
commit
9ede2c0b70
@ -77,6 +77,54 @@ class etemplate_widget_vfs extends etemplate_widget_file
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload via dragging images into ckeditor
|
||||
*/
|
||||
public static function ajax_htmlarea_upload()
|
||||
{
|
||||
$request_id = str_replace(' ', '+', rawurldecode($_REQUEST['request_id']));
|
||||
$widget_id = $_REQUEST['widget_id'];
|
||||
if(!self::$request = etemplate_request::read($request_id))
|
||||
{
|
||||
$error = lang("Could not read session");
|
||||
}
|
||||
elseif (!($template = etemplate_widget_template::instance(self::$request->template['name'], self::$request->template['template_set'],
|
||||
self::$request->template['version'], self::$request->template['load_via'])))
|
||||
{
|
||||
// Can't use callback
|
||||
$error = lang("Could not get template for file upload, callback skipped");
|
||||
}
|
||||
/*elseif (!($widget = $template->getElementById($widget_id)))
|
||||
{
|
||||
$error = "Widget '$widget_id' not found!";
|
||||
}*/
|
||||
elseif (!isset($_FILES['upload']))
|
||||
{
|
||||
$error = lang('No _FILES[upload] found!');
|
||||
}
|
||||
else
|
||||
{
|
||||
$data = self::$request->content[$widget_id];
|
||||
$path = self::store_file($path = self::get_vfs_path($data['to_app'].':'.$data['to_id']).'/', $_FILES['upload']);
|
||||
}
|
||||
// switch regular JSON response handling off
|
||||
egw_json_request::isJSONRequest(false);
|
||||
|
||||
$file = array(
|
||||
"uploaded" => (int)empty($error),
|
||||
"fileName" => html::htmlspecialchars($_FILES['upload']['name']),
|
||||
"url" => egw::link(egw_vfs::download_url($path)),
|
||||
"error" => array(
|
||||
"message" => $error,
|
||||
)
|
||||
);
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
echo json_encode($file);
|
||||
|
||||
common::egw_exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax callback to receive an incoming file
|
||||
*
|
||||
@ -91,7 +139,7 @@ class etemplate_widget_vfs extends etemplate_widget_file
|
||||
// Find real path
|
||||
if($path[0] != '/')
|
||||
{
|
||||
$path = self::get_vfs_path($path, $file['name']);
|
||||
$path = self::get_vfs_path($path);
|
||||
}
|
||||
$filename = $file['name'];
|
||||
if (substr($path,-1) != '/')
|
||||
@ -120,6 +168,8 @@ class etemplate_widget_vfs extends etemplate_widget_file
|
||||
|
||||
// Try to remove temp file
|
||||
unlink($file['tmp_name']);
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -19,9 +19,9 @@
|
||||
|
||||
/**
|
||||
* Class which implements file upload
|
||||
*
|
||||
*
|
||||
* @augments et2_inputWidget
|
||||
*/
|
||||
*/
|
||||
var et2_file = et2_inputWidget.extend(
|
||||
{
|
||||
attributes: {
|
||||
@ -90,14 +90,14 @@ var et2_file = et2_inputWidget.extend(
|
||||
"type": "any",
|
||||
"default": et2_no_init,
|
||||
"description": "A (js) function called when a file to be uploaded is finished."
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
asyncOptions: {},
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
*
|
||||
* @memberOf et2_file
|
||||
*/
|
||||
init: function() {
|
||||
@ -121,19 +121,19 @@ var et2_file = et2_inputWidget.extend(
|
||||
|
||||
// Set up the URL to have the request ID & the widget ID
|
||||
var instance = this.getInstanceManager();
|
||||
|
||||
|
||||
var self = this;
|
||||
|
||||
this.asyncOptions = jQuery.extend({
|
||||
// Callbacks
|
||||
onStart: function(event, file_count) {
|
||||
return self.onStart(event, file_count);
|
||||
onStart: function(event, file_count) {
|
||||
return self.onStart(event, file_count);
|
||||
},
|
||||
onFinish: function(event, file_count) {
|
||||
onFinish: function(event, file_count) {
|
||||
self.onFinish.apply(self, [event, file_count])
|
||||
},
|
||||
onStartOne: function(event, file_name, index, file_count) {
|
||||
|
||||
onStartOne: function(event, file_name, index, file_count) {
|
||||
|
||||
},
|
||||
onFinishOne: function(event, response, name, number, total) { return self.finishUpload(event,response,name,number,total);},
|
||||
onProgress: function(event, progress, name, number, total) { return self.onProgress(event,progress,name,number,total);},
|
||||
@ -158,7 +158,7 @@ var et2_file = et2_inputWidget.extend(
|
||||
this.span = null;
|
||||
this.progress = null;
|
||||
},
|
||||
|
||||
|
||||
createInputWidget: function() {
|
||||
this.node = $j(document.createElement("div")).addClass("et2_file");
|
||||
this.span = $j(document.createElement("span"))
|
||||
@ -172,7 +172,7 @@ var et2_file = et2_inputWidget.extend(
|
||||
.hover(function(e){
|
||||
$j(span)
|
||||
.toggleClass('et2_file_spanHover');
|
||||
})
|
||||
})
|
||||
.on({
|
||||
mousedown:function (e){
|
||||
$j(span).addClass('et2_file_spanActive');
|
||||
@ -218,14 +218,14 @@ var et2_file = et2_inputWidget.extend(
|
||||
|
||||
this.setDOMNode(this.node[0]);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Set a widget or DOM node as a HTML5 file drop target
|
||||
*
|
||||
*
|
||||
* @param String new_target widget ID or DOM node ID to be used as a new target
|
||||
*/
|
||||
set_drop_target: function(new_target)
|
||||
{
|
||||
{
|
||||
// Cancel old drop target
|
||||
if(this.options.drop_target)
|
||||
{
|
||||
@ -236,11 +236,11 @@ var et2_file = et2_inputWidget.extend(
|
||||
this.resumable.unAssignDrop(drop_target);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.options.drop_target = new_target;
|
||||
|
||||
|
||||
if(!this.options.drop_target) return;
|
||||
|
||||
|
||||
// Set up new drop target
|
||||
var widget = this.getRoot().getWidgetById(this.options.drop_target);
|
||||
var drop_target = widget && widget.getDOMNode() || document.getElementById(this.options.drop_target);
|
||||
@ -265,10 +265,10 @@ var et2_file = et2_inputWidget.extend(
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the value of the file widget.
|
||||
*
|
||||
* Set the value of the file widget.
|
||||
*
|
||||
* If you pass a FileList or list of files, it will trigger the async upload
|
||||
*
|
||||
*
|
||||
* @param {FileList|File[]|false} value List of files to be uploaded, or false to reset.
|
||||
* @param {Event} event Most browsers require the user to initiate file transfers in some way.
|
||||
* Pass the event in, if you have it.
|
||||
@ -289,7 +289,7 @@ var et2_file = et2_inputWidget.extend(
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(typeof value == 'object' && value.length && typeof value[0] == 'object' && value[0].name)
|
||||
{
|
||||
try
|
||||
@ -304,11 +304,11 @@ var et2_file = et2_inputWidget.extend(
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Set the value for label
|
||||
* The label is used as caption for span tag which customize the HTML file upload styling
|
||||
*
|
||||
*
|
||||
* @param {string} value text value of label
|
||||
*/
|
||||
set_label: function (value)
|
||||
@ -402,13 +402,13 @@ var et2_file = et2_inputWidget.extend(
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Add in the request id
|
||||
*/
|
||||
beforeSend: function(form) {
|
||||
var instance = this.getInstanceManager();
|
||||
|
||||
|
||||
return {
|
||||
request_id: instance.etemplate_exec_id,
|
||||
widget_id: this.id
|
||||
@ -431,13 +431,13 @@ var et2_file = et2_inputWidget.extend(
|
||||
.css('cursor', 'default');
|
||||
|
||||
event.data = this;
|
||||
|
||||
|
||||
//Add dropdown_progress
|
||||
if (this.options.progress_dropdownlist)
|
||||
{
|
||||
this._build_progressDropDownList();
|
||||
}
|
||||
|
||||
|
||||
// Callback
|
||||
if(this.options.onStart) return et2_call(this.options.onStart, event, file_count);
|
||||
return true;
|
||||
@ -448,7 +448,7 @@ var et2_file = et2_inputWidget.extend(
|
||||
*/
|
||||
onFinish: function() {
|
||||
this.disabled_buttons.attr("disabled", false).css('cursor','pointer');
|
||||
|
||||
|
||||
var file_count = this.resumable.files.length;
|
||||
|
||||
// Remove files from list
|
||||
@ -458,19 +458,19 @@ var et2_file = et2_inputWidget.extend(
|
||||
}
|
||||
|
||||
var event = jQuery.Event('upload');
|
||||
|
||||
|
||||
event.data = this;
|
||||
|
||||
var result = false;
|
||||
|
||||
|
||||
//Remove progress_dropDown_fileList class and unbind the click handler from body
|
||||
if (this.options.progress_dropdownlist)
|
||||
{
|
||||
this.progress.removeClass("progress_dropDown_fileList");
|
||||
jQuery(this.node).find('span').removeClass('totalProgress_loader');
|
||||
jQuery('body').off('click');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(this.options.onFinish && !jQuery.isEmptyObject(this.getValue()))
|
||||
{
|
||||
result = et2_call(this.options.onFinish, event, file_count);
|
||||
@ -485,19 +485,19 @@ var et2_file = et2_inputWidget.extend(
|
||||
this.change(this.input);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Build up dropdown progress with total count indicator
|
||||
*
|
||||
*
|
||||
* @todo Implement totalProgress bar instead of ajax-loader, in order to show how much percent of uploading is completed
|
||||
*/
|
||||
_build_progressDropDownList: function ()
|
||||
{
|
||||
this.progress.addClass("progress_dropDown_fileList");
|
||||
|
||||
|
||||
//Add uploading indicator and bind hover handler on it
|
||||
jQuery(this.node).find('span').addClass('totalProgress_loader');
|
||||
|
||||
|
||||
jQuery(this.node).find('input').hover(function(){
|
||||
jQuery('.progress_dropDown_fileList').show();
|
||||
});
|
||||
@ -506,11 +506,11 @@ var et2_file = et2_inputWidget.extend(
|
||||
if (event.target.className != 'remove')
|
||||
{
|
||||
jQuery('.progress_dropDown_fileList').hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Creates the elements used for displaying the file, and it's upload status, and
|
||||
* attaches them to the DOM
|
||||
@ -523,7 +523,7 @@ var et2_file = et2_inputWidget.extend(
|
||||
if(this.options.max_file_size && file.size > this.options.max_file_size) {
|
||||
error = this.egw().lang("File too large. Maximum %1", et2_vfsSize.prototype.human_size(this.options.max_file_size));
|
||||
}
|
||||
|
||||
|
||||
if(this.options.progress)
|
||||
{
|
||||
var widget = this.getRoot().getWidgetById(this.options.progress);
|
||||
@ -599,9 +599,9 @@ var et2_file = et2_inputWidget.extend(
|
||||
.text(this.egw().lang("Server error"));
|
||||
}
|
||||
var event = jQuery.Event('upload');
|
||||
|
||||
|
||||
event.data = this;
|
||||
|
||||
|
||||
// Callback
|
||||
if(this.options.onFinishOne)
|
||||
{
|
||||
@ -642,7 +642,7 @@ var et2_file = et2_inputWidget.extend(
|
||||
e.preventDefault();
|
||||
// Look for file name in list
|
||||
var target = $j(e.target).parents("li");
|
||||
|
||||
|
||||
this.remove_file(e.data);
|
||||
|
||||
// In case it didn't make it to the list (error)
|
||||
|
@ -71,11 +71,11 @@ var et2_htmlarea = et2_inputWidget.extend([et2_IResizeable],
|
||||
type: "html", // "string" would remove html tags by running html_entity_decode
|
||||
default: et2_no_init
|
||||
},
|
||||
imageDataUrl: {
|
||||
name: "imageDataUrl",
|
||||
description: "Allow images dragged in as data-url, default false = handle them as fileupload",
|
||||
type: "boolean",
|
||||
default: false
|
||||
imageUpload: {
|
||||
name: "imageUpload",
|
||||
description: "Url to upload images dragged in or id of link_to widget to it's vfs upload",
|
||||
type: "string",
|
||||
default: null
|
||||
}
|
||||
},
|
||||
|
||||
@ -123,6 +123,20 @@ var et2_htmlarea = et2_inputWidget.extend([et2_IResizeable],
|
||||
if(this.mode == 'ascii' || this.ckeditor != null) return;
|
||||
|
||||
var self = this;
|
||||
if (!this.options.imageUpload)
|
||||
{
|
||||
delete self.options.config.imageUploadUrl;
|
||||
}
|
||||
else if (this.options.imageUpload[0] !== '/' && this.options.imageUpload.substr(0, 4) != 'http')
|
||||
{
|
||||
self.options.config.imageUploadUrl = egw.ajaxUrl(self.egw().getAppName()+".etemplate_widget_vfs.ajax_htmlarea_upload.etemplate")+
|
||||
'&request_id='+self.getInstanceManager().etemplate_exec_id+'&widget_id='+this.options.imageUpload;
|
||||
self.options.config.imageUploadUrl = self.options.config.imageUploadUrl.substr(egw.webserverUrl.length+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
self.options.config.imageUploadUrl = this.options.imageUpload.substr(egw.webserverUrl.length+1);
|
||||
}
|
||||
try
|
||||
{
|
||||
this.ckeditor = CKEDITOR.replace(this.dom_id,jQuery.extend({},this.options.config,this.options));
|
||||
@ -172,14 +186,13 @@ var et2_htmlarea = et2_inputWidget.extend([et2_IResizeable],
|
||||
return;
|
||||
|
||||
// allow data-URL, returning false to stop regular upload
|
||||
if (self.options.imageDataUrl)
|
||||
if (!self.options.imageUpload)
|
||||
{
|
||||
return false;
|
||||
// Remove the image from the text
|
||||
setTimeout( function() {
|
||||
editor.document.$.body.innerHTML = replaceImgText(editor.document.$.body.innerHTML);
|
||||
},200);
|
||||
}
|
||||
// Remove the image from the text
|
||||
setTimeout( function() {
|
||||
editor.document.$.body.innerHTML = replaceImgText(editor.document.$.body.innerHTML);
|
||||
},200);
|
||||
|
||||
// Try to pass the image into the first et2_file that will accept it
|
||||
if(e.data.$.dataTransfer)
|
||||
@ -274,7 +287,7 @@ var et2_htmlarea = et2_inputWidget.extend([et2_IResizeable],
|
||||
var h = 0;
|
||||
if (typeof this.ckeditor.container !='undefined' && this.ckeditor.container.$.clientHeight > 0)
|
||||
{
|
||||
h = (this.ckeditor.container.$.clientHeight + _height) > 0 ?
|
||||
h = (this.ckeditor.container.$.clientHeight + _height) > 0 ?
|
||||
this.ckeditor.container.$.clientHeight + _height: this.ckeditor.config.height;
|
||||
}
|
||||
else if (this.ckeditor.ui.space('contents'))
|
||||
@ -289,7 +302,7 @@ var et2_htmlarea = et2_inputWidget.extend([et2_IResizeable],
|
||||
this.ckeditor.resize('',h);
|
||||
}
|
||||
else // No CKEDITOR
|
||||
{
|
||||
{
|
||||
this.htmlNode.height(this.htmlNode.height() + _height);
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +79,7 @@
|
||||
</columns>
|
||||
<rows>
|
||||
<row valign="top">
|
||||
<htmlarea statustext="Web-Site for this resource" id="long_description" height="200" toolbar="true"/>
|
||||
<htmlarea statustext="Web-Site for this resource" id="long_description" height="200" toolbar="true" imageUpload="link_to"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
@ -105,7 +105,7 @@
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</template>
|
||||
</template>
|
||||
<template id="resources.edit_tabs.custom" template="" lang="" group="0" version="">
|
||||
<grid width="100%" height="245" class="row_on" spacing="0" padding="0" overflow="auto">
|
||||
<columns>
|
||||
|
Loading…
Reference in New Issue
Block a user