From 765455706876f0da774894f00a66db2fd9bbf200 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Mon, 12 Apr 2010 21:54:41 +0000 Subject: [PATCH] APICHANGE: removed SWFUpload. Refactored Content Editors uploader to use standard uploader. (from r97489) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@102505 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- forms/HtmlEditorField.php | 45 +- javascript/HtmlEditorField.js | 80 ++- javascript/tiny_mce_improvements.js | 6 - thirdparty/jquery-form/.piston.yml | 8 + thirdparty/jquery-form/jquery.form.js | 675 ++++++++++++++++++++++++++ 5 files changed, 751 insertions(+), 63 deletions(-) create mode 100644 thirdparty/jquery-form/.piston.yml create mode 100644 thirdparty/jquery-form/jquery.form.js diff --git a/forms/HtmlEditorField.php b/forms/HtmlEditorField.php index e37a45189..a1bfcece1 100755 --- a/forms/HtmlEditorField.php +++ b/forms/HtmlEditorField.php @@ -198,6 +198,11 @@ class HtmlEditorField_Toolbar extends RequestHandler { function __construct($controller, $name) { parent::__construct(); + Requirements::javascript(SAPPHIRE_DIR . "/thirdparty/behaviour/behaviour.js"); + Requirements::javascript(SAPPHIRE_DIR . "/javascript/tiny_mce_improvements.js"); + + Requirements::javascript(SAPPHIRE_DIR ."/thirdparty/jquery-form/jquery.form.js"); + Requirements::javascript(SAPPHIRE_DIR ."/javascript/HtmlEditorField.js"); $this->controller = $controller; $this->name = $name; @@ -210,9 +215,6 @@ class HtmlEditorField_Toolbar extends RequestHandler { * @return Form */ function LinkForm() { - Requirements::javascript(SAPPHIRE_DIR . "/thirdparty/behaviour/behaviour.js"); - Requirements::javascript(SAPPHIRE_DIR . "/javascript/tiny_mce_improvements.js"); - $form = new Form( $this->controller, "{$this->name}/LinkForm", @@ -264,17 +266,6 @@ class HtmlEditorField_Toolbar extends RequestHandler { * @return Form */ function ImageForm() { - Requirements::javascript(SAPPHIRE_DIR . "/thirdparty/behaviour/behaviour.js"); - Requirements::javascript(SAPPHIRE_DIR . "/javascript/tiny_mce_improvements.js"); - Requirements::css('cms/css/TinyMCEImageEnhancement.css'); - Requirements::javascript(CMS_DIR . '/javascript/Upload.js'); - Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/swfupload/swfupload/swfupload.js'); - Requirements::javascript('cms/javascript/TinyMCEImageEnhancement.js'); - - /** - * @todo Adding folders via this screen is not enabled just yet as it is still - * a bit too buggy - wrossiter (09/11/09) - */ $form = new Form( $this->controller, "{$this->name}/ImageForm", @@ -283,20 +274,14 @@ class HtmlEditorField_Toolbar extends RequestHandler { 'Heading', sprintf('

%s

', _t('HtmlEditorField.IMAGE', 'Image')) ), + $contentComposite = new CompositeField( new TreeDropdownField('FolderID', _t('HtmlEditorField.FOLDER', 'Folder'), 'Folder'), - new LiteralField('AddFolderOrUpload', - '
-
- ' . _t('HtmlEditorField.UPLOAD','Upload') . ' -
' . - '
' - ), + new CompositeField(new FieldSet( + new LiteralField('ShowUpload', '

'. _t('HtmlEditorField.SHOWUPLOADFORM', 'Upload File') .'

'), + new FileField("Files[0]" , _t('AssetAdmin.CHOOSEFILE','Choose file: ')), + new LiteralField('Response', '
') + )), new TextField('getimagesSearch', _t('HtmlEditorField.SEARCHFILENAME', 'Search by file name')), new ThumbnailStripField('FolderImages', 'FolderID', 'getimages'), new TextField('AltText', _t('HtmlEditorField.IMAGEALTTEXT', 'Alternative text (alt) - shown if image cannot be displayed'), '', 80), @@ -333,11 +318,6 @@ class HtmlEditorField_Toolbar extends RequestHandler { } function FlashForm() { - Requirements::javascript(SAPPHIRE_DIR . "/thirdparty/behaviour/behaviour.js"); - Requirements::javascript(SAPPHIRE_DIR . "/javascript/tiny_mce_improvements.js"); - Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/swfupload/swfupload/swfupload.js'); - Requirements::javascript(CMS_DIR . '/javascript/Upload.js'); - $form = new Form( $this->controller, "{$this->name}/FlashForm", @@ -369,5 +349,4 @@ class HtmlEditorField_Toolbar extends RequestHandler { $form->disableSecurityToken(); return $form; } -} - +} \ No newline at end of file diff --git a/javascript/HtmlEditorField.js b/javascript/HtmlEditorField.js index e34a1a67c..4a045254f 100644 --- a/javascript/HtmlEditorField.js +++ b/javascript/HtmlEditorField.js @@ -1,29 +1,61 @@ /** - * Simple TinyMCE initialisation + * Functions for HtmlEditorFields in the back end. + * Includes the JS for the ImageUpload forms. + * + * Relies on the jquery.form.js plugin to power the + * ajax / iframe submissions */ -if((typeof tinyMCE != 'undefined')) { - tinymce.PluginManager.load('advcode', '/some/dir/someplugin/editor_plugin.js'); - - tinyMCE.init({ - mode : "specific_textareas", - editor_selector : "htmleditor", - width: "100%", - auto_resize : false, - theme : "advanced", - theme_advanced_layout_manager: "SimpleLayout", - theme_advanced_toolbar_location : "top", - theme_advanced_toolbar_align : "left", - theme_advanced_toolbar_parent : "right", - plugins : "contextmenu,table,emotions,paste,-advcode,spellchecker", - blockquote_clear_tag : "p", - table_inline_editing : true, - theme_advanced_buttons1 : "bold,italic,underline,strikethrough,separator,justifyleft,justifycenter,justifyright,justifyfull,formatselect,separator,bullist,numlist,outdent,indent,blockquote,hr,charmap", - theme_advanced_buttons2 : "undo,redo,separator,cut,copy,paste,pastetext,pasteword,spellchecker,separator,advcode,search,replace,selectall,visualaid,separator,tablecontrols", - theme_advanced_buttons3 : "", +(function($) { + $(document).ready(function() { - safari_warning : false, - relative_urls : true, - verify_html : true + $("#Form_EditorToolbarImageForm .showUploadField a").click(function() { + if($(this).hasClass("showing")) { + $("#Form_EditorToolbarImageForm_Files-0").parents('.file').hide(); + $(this).text(ss.i18n._t('HtmlEditorField.ShowUploadForm', 'Upload File')).removeClass("showing"); + } + else { + $("#Form_EditorToolbarImageForm_Files-0").parents('.file').show(); + $(this).text(ss.i18n._t('HtmlEditorField.HideUploadForm', 'Hide Upload Form')).addClass("showing"); + } + }).show(); + + $("#Form_EditorToolbarImageForm_Files-0").change(function() { + $("#contentPanel form").ajaxForm({ + url: 'admin/assets/UploadForm?action_doUpload=1', + iframe: true, + + beforeSubmit: function(data) { + $("#UploadFormResponse").text("Uploading File...").addClass("loading").show(); + $("#Form_EditorToolbarImageForm_Files-0").parents('.file').hide(); + }, + success: function(data) { + $("#UploadFormResponse").text(data).removeClass("loading"); + $("#Form_EditorToolbarImageForm_Files-0").val("").parents('.file').show(); + + $("#FolderImages").html('

'+ ss.i18n._t('HtmlEditorField.Loading', 'Loading') + '

'); + + var ajaxURL = 'admin/EditorToolbar/ImageForm'; + + $.get(ajaxURL, { + action_callfieldmethod: "1", + fieldName: "FolderImages", + ajax: "1", + methodName: "getimages", + folderID: $("#Form_EditorToolbarImageForm_FolderID").val(), + searchText: $("#Form_EditorToolbarImageForm_getimagesSearch").val(), + cacheKillerDate: parseInt((new Date()).getTime()), + cacheKillerRand: parseInt(10000 * Math.random()) + }, + function(data) { + $("#FolderImages").html(data); + + $("#FolderImages").each(function() { + Behaviour.apply(this); + }) + }); + } + }).submit(); + }); }); -} +})(jQuery); \ No newline at end of file diff --git a/javascript/tiny_mce_improvements.js b/javascript/tiny_mce_improvements.js index da39bec01..01d1fa46e 100755 --- a/javascript/tiny_mce_improvements.js +++ b/javascript/tiny_mce_improvements.js @@ -644,12 +644,6 @@ function reselectImage(transport) { $('Image').reapplyBehaviour(); this.addToTinyMCE = this.addToTinyMCE.bind(this); - var childNodes = $('Image').childNodes[0].childNodes; - var newImages = $A(childNodes).slice(childNodes.length - this.filesUploaded); - newImages.each(function(item) { - tinyMCEImageEnhancement.addToTinyMCE(item.childNodes[0]); - }); - tinyMCEImageEnhancement.processInProgress = false; } function imageEditorClosed() { diff --git a/thirdparty/jquery-form/.piston.yml b/thirdparty/jquery-form/.piston.yml new file mode 100644 index 000000000..fa6d4eee5 --- /dev/null +++ b/thirdparty/jquery-form/.piston.yml @@ -0,0 +1,8 @@ +--- +format: 1 +handler: + commit: 1f9901ad56ba458c8db0bffb759dbb65921891ae + branch: master +lock: false +repository_class: Piston::Git::Repository +repository_url: git://github.com/malsup/form.git diff --git a/thirdparty/jquery-form/jquery.form.js b/thirdparty/jquery-form/jquery.form.js new file mode 100644 index 000000000..be8c0b6bf --- /dev/null +++ b/thirdparty/jquery-form/jquery.form.js @@ -0,0 +1,675 @@ +/*! + * jQuery Form Plugin + * version: 2.43 (12-MAR-2010) + * @requires jQuery v1.3.2 or later + * + * Examples and documentation at: http://malsup.com/jquery/form/ + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ +;(function($) { + +/* + Usage Note: + ----------- + Do not use both ajaxSubmit and ajaxForm on the same form. These + functions are intended to be exclusive. Use ajaxSubmit if you want + to bind your own submit handler to the form. For example, + + $(document).ready(function() { + $('#myForm').bind('submit', function() { + $(this).ajaxSubmit({ + target: '#output' + }); + return false; // <-- important! + }); + }); + + Use ajaxForm when you want the plugin to manage all the event binding + for you. For example, + + $(document).ready(function() { + $('#myForm').ajaxForm({ + target: '#output' + }); + }); + + When using ajaxForm, the ajaxSubmit function will be invoked for you + at the appropriate time. +*/ + +/** + * ajaxSubmit() provides a mechanism for immediately submitting + * an HTML form using AJAX. + */ +$.fn.ajaxSubmit = function(options) { + // fast fail if nothing selected (http://dev.jquery.com/ticket/2752) + if (!this.length) { + log('ajaxSubmit: skipping submit process - no element selected'); + return this; + } + + if (typeof options == 'function') + options = { success: options }; + + var url = $.trim(this.attr('action')); + if (url) { + // clean url (don't include hash vaue) + url = (url.match(/^([^#]+)/)||[])[1]; + } + url = url || window.location.href || ''; + + options = $.extend({ + url: url, + type: this.attr('method') || 'GET', + iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank' + }, options || {}); + + // hook for manipulating the form data before it is extracted; + // convenient for use with rich editors like tinyMCE or FCKEditor + var veto = {}; + this.trigger('form-pre-serialize', [this, options, veto]); + if (veto.veto) { + log('ajaxSubmit: submit vetoed via form-pre-serialize trigger'); + return this; + } + + // provide opportunity to alter form data before it is serialized + if (options.beforeSerialize && options.beforeSerialize(this, options) === false) { + log('ajaxSubmit: submit aborted via beforeSerialize callback'); + return this; + } + + var a = this.formToArray(options.semantic); + if (options.data) { + options.extraData = options.data; + for (var n in options.data) { + if(options.data[n] instanceof Array) { + for (var k in options.data[n]) + a.push( { name: n, value: options.data[n][k] } ); + } + else + a.push( { name: n, value: options.data[n] } ); + } + } + + // give pre-submit callback an opportunity to abort the submit + if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) { + log('ajaxSubmit: submit aborted via beforeSubmit callback'); + return this; + } + + // fire vetoable 'validate' event + this.trigger('form-submit-validate', [a, this, options, veto]); + if (veto.veto) { + log('ajaxSubmit: submit vetoed via form-submit-validate trigger'); + return this; + } + + var q = $.param(a); + + if (options.type.toUpperCase() == 'GET') { + options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; + options.data = null; // data is null for 'get' + } + else + options.data = q; // data is the query string for 'post' + + var $form = this, callbacks = []; + if (options.resetForm) callbacks.push(function() { $form.resetForm(); }); + if (options.clearForm) callbacks.push(function() { $form.clearForm(); }); + + // perform a load on the target only if dataType is not provided + if (!options.dataType && options.target) { + var oldSuccess = options.success || function(){}; + callbacks.push(function(data) { + var fn = options.replaceTarget ? 'replaceWith' : 'html'; + $(options.target)[fn](data).each(oldSuccess, arguments); + }); + } + else if (options.success) + callbacks.push(options.success); + + options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg + for (var i=0, max=callbacks.length; i < max; i++) + callbacks[i].apply(options, [data, status, xhr || $form, $form]); + }; + + // are there files to upload? + var files = $('input:file', this).fieldValue(); + var found = false; + for (var j=0; j < files.length; j++) + if (files[j]) + found = true; + + var multipart = false; +// var mp = 'multipart/form-data'; +// multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp); + + // options.iframe allows user to force iframe mode + // 06-NOV-09: now defaulting to iframe mode if file input is detected + if ((files.length && options.iframe !== false) || options.iframe || found || multipart) { + // hack to fix Safari hang (thanks to Tim Molendijk for this) + // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d + if (options.closeKeepAlive) + $.get(options.closeKeepAlive, fileUpload); + else + fileUpload(); + } + else + $.ajax(options); + + // fire 'notify' event + this.trigger('form-submit-notify', [this, options]); + return this; + + + // private function for handling file uploads (hat tip to YAHOO!) + function fileUpload() { + var form = $form[0]; + + if ($(':input[name=submit]', form).length) { + alert('Error: Form elements must not be named "submit".'); + return; + } + + var opts = $.extend({}, $.ajaxSettings, options); + var s = $.extend(true, {}, $.extend(true, {}, $.ajaxSettings), opts); + + var id = 'jqFormIO' + (new Date().getTime()); + var $io = $('