add a new plugin in tinymce to upload any kind of files (Bernd)

This commit is contained in:
did 2011-06-21 05:47:11 -07:00
parent b00c84019c
commit a0293b161b
18 changed files with 547 additions and 33 deletions

View File

@ -64,7 +64,7 @@ group :test do
gem 'rspec-rails', '2.3.1' gem 'rspec-rails', '2.3.1'
gem 'factory_girl_rails' gem 'factory_girl_rails'
gem 'pickle' gem 'pickle'
gem 'xpath', '0.1.3' # :git => 'https://github.com/wunderbread/xpath.git' gem 'xpath', '0.1.3'
gem 'capybara' gem 'capybara'
gem 'database_cleaner' gem 'database_cleaner'

View File

@ -1,19 +1,59 @@
module Admin # TODO module Admin
class AssetsController < BaseController class AssetsController < BaseController
sections 'assets' include ActionView::Helpers::SanitizeHelper
include ActionView::Helpers::TextHelper
respond_to :json, :only => :update # defaults :collection_name => 'assets', :instance_name => 'asset'
def create respond_to :json, :only => [:index, :create, :destroy]
create! { admin_assets_url }
def index
index! do |response|
response.json do
render :json => { :assets => @assets.collect { |asset| asset_to_json(asset) } }
end
end
end end
def update def create
update! { admin_assets_url } params[:asset] = { :name => params[:name], :source => params[:file] } if params[:file]
create! do |success, failure|
success.json do
render :json => asset_to_json(@asset)
end
failure.json do
render :json => { :status => 'error' }
end
end
rescue Exception => e
render :json => { :status => 'error', :message => e.message }
end end
protected protected
def collection
if params[:image]
@assets ||= begin_of_association_chain.assets.only_image
else
@assets ||= begin_of_association_chain.assets
end
end
def asset_to_json(asset)
{
:status => 'success',
:filename => asset.source_filename,
:short_name => truncate(asset.name, :length => 15),
:extname => truncate(asset.extname, :length => 3),
:content_type => asset.content_type,
:url => asset.source.url,
:vignette_url => asset.vignette_url,
:destroy_url => admin_asset_url(asset, :json),
}
end
end end
end end

View File

@ -35,7 +35,7 @@ Rails.application.routes.draw do
resources :assets # TODO resources :assets # TODO
resources :images resources :images, :controller => 'assets', :defaults => { :image => true }
resources :content_types resources :content_types

View File

@ -5,14 +5,17 @@ x bushido version
~ editable_elements: inheritable: false (Mattias) => seems to be fixed by Dirk's last pull request (#44) => content tag ~ editable_elements: inheritable: false (Mattias) => seems to be fixed by Dirk's last pull request (#44) => content tag
- remove asset_collections - remove asset_collections
x site templates x site templates
x tinyMCE plugin
x vignette.rb
x code
- helpers - helpers
- tinyMCE plugin
- vignette.rb
- code
- ui - ui
- rake task x rake task
- internal collection x internal collection
- assign same _id x assign same _id
- pull request locomedia
- SEO: support and support/ should be 2 different pages. Remove trailing slash
- BUG: has_many. Delete an author
BACKLOG: BACKLOG:

View File

@ -48,9 +48,9 @@ var TinyMceDefaultSettings = {
script_url : '/javascripts/admin/plugins/tiny_mce/tiny_mce.js', script_url : '/javascripts/admin/plugins/tiny_mce/tiny_mce.js',
theme : 'advanced', theme : 'advanced',
skin : 'locomotive', skin : 'locomotive',
plugins: 'safari,inlinepopups,locoimage', plugins: 'safari,inlinepopups,locomedia',
theme_advanced_buttons1 : 'code,|,bold,italic,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,bullist,numlist,|,outdent,indent,blockquote,|,link,unlink', theme_advanced_buttons1 : 'code,|,bold,italic,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,bullist,numlist,|,outdent,indent,blockquote,|,link,unlink',
theme_advanced_buttons2 : 'formatselect,fontselect,fontsizeselect,|,image', theme_advanced_buttons2 : 'formatselect,fontselect,fontsizeselect,|,locomedia',
theme_advanced_buttons3 : '', theme_advanced_buttons3 : '',
theme_advanced_toolbar_location : "top", theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left", theme_advanced_toolbar_align : "left",

View File

@ -1,18 +1,3 @@
/*#src_list, #over_list, #out_list {width:280px;}
.mceActionPanel {margin-top:7px;}
.alignPreview {border:1px solid #000; width:140px; height:140px; overflow:hidden; padding:5px;}
.checkbox {border:0;}
.panel_wrapper div.current {height:305px;}
#prev {margin:0; border:1px solid #000; width:428px; height:150px; overflow:auto;}
#align, #classlist {width:150px;}
#width, #height {vertical-align:middle; width:50px; text-align:center;}
#vspace, #hspace, #border {vertical-align:middle; width:30px; text-align:center;}
#class_list {width:180px;}
input {width: 280px;}
#constrain, #onmousemovecheck {width:auto;}
#id, #dir, #lang, #usemap, #longdesc {width:200px;}
*/
body { body {
font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif; font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;
font-size: 1em; font-size: 1em;

View File

@ -0,0 +1,95 @@
body {
font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;
font-size: 1em;
overflow: hidden;
}
p.no-items {
padding: 18px 0px;
background: transparent url(/images/admin/list/none-small.png) no-repeat center 0;
text-align: center;
color: #9d8963 !important;
font-size: 1.1em !important;
}
.actions {
position: absolute;
top: 10px;
right: 10px;
}
ul.assets {
overflow: auto;
height: 571px;
}
ul.assets li.asset h4 a {
top: 9px;
font-size: 0.7em;
}
ul.assets li.asset .inside {
cursor: pointer;
}
ul.assets li.asset div.actions {
top: 7px;
}
ul.assets li.new-asset {
display: none;
}
#upload-link {
float: left;
display: block;
background: transparent url("/images/admin/buttons/dark-gray-bg.png") repeat-x 0 0;
outline: none;
-moz-border-radius : 4px;
-webkit-border-radius: 4px;
height: 20px;
font-size: 0.8em;
font-family: 'Lucida Grande';
padding: 5px 12px 5px 12px;
margin: 5px 0 0 14px;
color: #fff !important;
text-decoration: none;
text-shadow: 1px 1px 1px #000;
}
#spinner {
position: fixed;
top: 40%;
left: 30%;
height: 60px;
width: 250px;
background: transparent;
z-index: 999;
}
#spinner .overlay, #spinner .text {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
-moz-border-radius : 10px;
-webkit-border-radius: 10px;
}
#spinner .overlay {
background: #000;
opacity: 0.8;
}
#spinner .text {
padding: 20px 0;
text-align: center;
font-size: 1.1em;
color: #fff;
text-shadow: 1px 1px 1px #000;
}
.mceActionPanel input {
font-size: 0.8em;
}

View File

@ -0,0 +1,61 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{#locomedia_dlg.dialog_title}</title>
<script type="text/javascript" src="../../tiny_mce_popup.js"></script>
<script type="text/javascript" src="/javascripts/admin/jquery.js"></script>
<script type="text/javascript" src="/javascripts/admin/rails.js"></script>
<script src="/javascripts/admin/plugins/plupload/src/plupload.js" type="text/javascript"></script>
<script src="/javascripts/admin/plugins/plupload/plupload.gears.min.js" type="text/javascript"></script>
<script src="/javascripts/admin/plugins/plupload/src/flash.js" type="text/javascript"></script>
<script src="/javascripts/admin/plugins/plupload/plupload.html4.min.js" type="text/javascript"></script>
<script src="/javascripts/admin/plugins/plupload/plupload.html5.min.js" type="text/javascript"></script>
<script src="/javascripts/admin/plugins/plupload/jquery.plupload.queue.min.js" type="text/javascript"></script>
<script src="/javascripts/admin/plugins/plupload/jquery.plupload.queue.min.js" type="text/javascript"></script>
<script src="/javascripts/admin/plugins/scrollTo.js" type="text/javascript"></script>
<script type="text/javascript" src="js/dialog.js"></script>
<link href="/stylesheets/admin/assets.css" rel="stylesheet" type="text/css" />
<link href="css/style.css" rel="stylesheet" type="text/css" />
</head>
<body id="locomedia" style="display: none">
<div id="spinner">
<div class="overlay"></div>
<div class="text loading">{#locomedia_dlg.loading}</div>
<div class="text uploading" style="display: none">{#locomedia_dlg.uploading}</div>
<div class="text destroying" style="display: none">{#locomedia_dlg.destroying}</div>
</div>
<p class="no-items" style="display: none">{#locomedia_dlg.no_items}</p>
<form onsubmit="insertAction();return false;" action="#">
<div id="images">
<ul class="assets">
<li class="new-asset">
<h4><a href="#">NoName</a></h4>
<div class="icon">
<div class="inside">
</div>
</div>
<div class="actions">
<a href="#" class="remove" data-confirm="{#locomedia_dlg.confirm}" data-method="delete" rel="nofollow">
<img src="/images/admin/list/icons/cross.png">
</a>
</div>
</li>
<li class="clear"></li>
</ul>
</div>
<div class="mceActionPanel">
<a href="/admin/assets.json" id="upload-link">{#locomedia_dlg.upload}</a>
<input type="button" id="cancel" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" />
</div>
</form>
</body>
</html>

View File

@ -0,0 +1,48 @@
// (function(){tinymce.create('tinymce.plugins.LocoMediafilePlugin',{init:function(ed,url){ed.addCommand('locoMediafile',function(){ed.windowManager.open({file:url+'/mediafile.htm',width:645,height:650,inline:1},{plugin_url:url})});ed.addButton('mediafile',{title:'locomediafile.image_desc',cmd:'locoMediaFile'})},getInfo:function(){return{longname:'Locomotive Media File',author:'Locomotive Engine',authorurl:'http://www.locomotivecms.com',infourl:'http://www.locomotiveapp.com',version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add('locomedia',tinymce.plugins.LocoMediafilePlugin)})();
/**
* editor_plugin_src.js
*
* Copyright 2009, Moxiecode Systems AB
* Released under LGPL License.
*
* License: http://tinymce.moxiecode.com/license
* Contributing: http://tinymce.moxiecode.com/contributing
*/
(function() {
tinymce.create('tinymce.plugins.LocoMediaPlugin', {
init : function(ed, url) {
// Register commands
ed.addCommand('locoMedia', function() {
ed.windowManager.open({
file : url + '/dialog.htm',
width : 645,
height : 650,
inline : 1
}, {
plugin_url : url
});
});
// Register buttons
ed.addButton('locomedia', {
title : 'locomedia.image_desc',
cmd : 'locoMedia'
});
},
getInfo : function() {
return {
longname : 'Locomotive Media File',
author : 'Didier Lafforgue',
authorurl : 'http://www.locomotivecms.com',
infourl : 'http://www.locomotivecms.com',
version : tinymce.majorVersion + "." + tinymce.minorVersion
};
}
});
// Register plugin
tinymce.PluginManager.add('locomedia', tinymce.plugins.LocoMediaPlugin);
})();

View File

@ -0,0 +1,46 @@
/**
* editor_plugin_src.js
*
* Copyright 2009, Moxiecode Systems AB
* Released under LGPL License.
*
* License: http://tinymce.moxiecode.com/license
* Contributing: http://tinymce.moxiecode.com/contributing
*/
(function() {
tinymce.create('tinymce.plugins.LocoMediafilePlugin', {
init : function(ed, url) {
// Register commands
ed.addCommand('locoMediafile', function() {
ed.windowManager.open({
file : url + '/dialog.htm',
width : 645,
height : 650,
inline : 1
}, {
plugin_url : url
});
});
// Register buttons
ed.addButton('mediafile', {
title : 'locomediafile.image_desc',
cmd : 'locoMediaFile'
});
},
getInfo : function() {
return {
longname : 'Locomotive Media File',
author : 'Locomotive Engine',
authorurl : 'http://www.locomotivecms.com',
infourl : 'http://www.locomotivecms.com',
version : tinymce.majorVersion + "." + tinymce.minorVersion
};
}
});
// Register plugin
tinymce.PluginManager.add('locomedia', tinymce.plugins.LocoMediafilePlugin);
})();

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,197 @@
var MediafileDialog = {
formElement: null,
listElement: null,
preInit : function() {
var url;
tinyMCEPopup.requireLangPack();
if (url = tinyMCEPopup.getParam("external_image_list_url"))
document.write('<script language="javascript" type="text/javascript" src="' + tinyMCEPopup.editor.documentBaseURI.toAbsolute(url) + '"></script>');
},
init : function(ed) {
var self = this;
formElement = $(document.forms[0]);
listElement = formElement.find('ul');
$.getJSON('/admin/assets.json', function(data) {
$(data.assets).each(function() {
self._addAsset(this);
});
self.setupUploader();
self.hideSpinner();
if ($('ul li.asset').length == 0) $('p.no-items').show();
});
},
hideSpinner: function() {
$('#spinner').hide();
},
showSpinner: function(msg) {
$('#spinner .text').hide();
$('#spinner .' + msg).show();
$('#spinner').show();
},
insertFile: function(asset) {
var ed = tinyMCEPopup.editor, f = document.forms[0], nl = f.elements, v, args = {}, el;
tinyMCEPopup.restoreSelection();
// Fixes crash in Safari
if (tinymce.isWebKit) ed.getWin().focus();
if (asset.content_type == 'image')
tinymce.extend(args, { src : asset.url });
else
tinymce.extend(args, { href : asset.url });
el = ed.selection.getNode();
if (el && (el.nodeName == 'IMG' || el.nodeName == 'A')) {
ed.dom.setAttribs(el, args);
} else {
if (asset.content_type == 'image') {
ed.execCommand('mceInsertContent', false, '<img id="__mce_tmp" />', { skip_undo: 1 });
} else {
var html = ed.selection.getContent();
if (html == '') html = asset.filename;
ed.execCommand('mceInsertContent', false, '<a id="__mce_tmp" >' + html + '</a>', { skip_undo: 1 });
}
ed.dom.setAttribs('__mce_tmp', args);
ed.dom.setAttrib('__mce_tmp', 'id', '');
ed.undoManager.add();
}
tinyMCEPopup.close();
},
setupUploader: function() {
var self = this;
var multipartParams = {};
with(window.parent) {
multipartParams[$('meta[name=csrf-param]').attr('content')] = $('meta[name=csrf-token]').attr('content');
}
var uploader = new plupload.Uploader({
runtimes : (jQuery.browser.webkit == true ? 'flash' : 'html5,flash'),
browse_button : 'upload-link',
max_file_size : '10mb',
url : $('a#upload-link').attr('href'),
flash_swf_url : '/javascripts/admin/plugins/plupload/plupload.flash.swf',
multipart: true,
multipart_params: multipartParams,
filters : [
{ title : 'Media files', extensions : 'png,gif,jpg,jpeg,pdf,doc,docx,xls,xlsx,txt' },
]
});
uploader.bind('QueueChanged', function() {
self.showSpinner('uploading');
uploader.start();
});
uploader.bind('FileUploaded', function(up, file, response) {
var json = JSON.parse(response.response);
if (json.status == 'success')
self._addAsset(json);
self.hideSpinner();
});
uploader.init();
},
_addAsset: function(data) {
var self = this;
var asset = $('ul li.new-asset')
.clone()
.insertBefore($('ul li.clear'))
.addClass('asset');
asset.find('h4 a').attr('href', data.url)
.html(data.short_name)
.bind('click', function(e) {
self.insertFile(data);
e.stopPropagation(); e.preventDefault();
});
html = '';
if (data.content_type == 'image') {
asset.find('.icon').removeClass('icon').addClass('image');
html = $('<img />')
.attr('src', data.vignette_url)
.bind('click', function(e) {
self.insertFile(data);
});
} else {
asset.find('.icon').addClass(data.content_type);
html = data.content_type == 'other' ? data.extname : data.content_type;
if (html == '') html = '?'
html = $('<span />').html(html)
.bind('click', function(e) {
self.insertFile(data);
});
}
asset.find('.inside').append(html);
asset.find('.actions a')
.attr('href', data.destroy_url)
.bind('click', function(e) {
if (confirm($(this).attr('data-confirm'))) {
self.showSpinner('destroying');
$(this).callRemote();
}
e.preventDefault(); e.stopPropagation();
})
.bind('ajax:success', function(event, data) {
self._destroyAsset(asset);
});
if ($('ul li.asset').length % 4 == 0)
asset.addClass('last');
asset.removeClass('new-asset');
$('p.no-items').hide();
$('ul').scrollTo($('li.asset:last'), 400);
},
_destroyAsset: function(asset) {
asset.remove();
if ($('ul li.asset').length == 0) {
$('p.no-items').show();
} else {
$('ul li.asset').each(function(index) {
if ((index + 1) % 4 == 0)
$(this).addClass('last');
else
$(this).removeClass('last');
});
}
this.hideSpinner();
}
};
MediafileDialog.preInit();
tinyMCEPopup.onInit.add(MediafileDialog.init, MediafileDialog);

View File

@ -0,0 +1,9 @@
tinyMCE.addI18n('de.locomedia_dlg',{
dialog_title: 'Mediendatei einfügen',
upload: 'Mediendatei hochladen',
loading: 'Laden...',
uploading: 'Hochladen...',
destroying: 'Löschen...',
confirm: 'Bist du sicher ?',
no_items: 'Momentan gibt es hier keine Mediendateien.'
});

View File

@ -0,0 +1,9 @@
tinyMCE.addI18n('en.locomedia_dlg',{
dialog_title: 'Insert media',
upload: 'Upload media',
loading: 'Loading...',
uploading: 'Uploading...',
destroying: 'Destroying...',
confirm: 'Are you sure ?',
no_items: 'There are no media for now.'
});

View File

@ -0,0 +1,9 @@
tinyMCE.addI18n('fr.locomedia_dlg',{
dialog_title: 'Insérer un média',
upload: 'Uploader média',
loading: 'Chargement...',
uploading: 'Uploading...',
destroying: 'Suppression...',
confirm: 'Êtes-vous sûr(e) ?',
no_items: 'Il n\'y a aucun média pour l\'instant'
});

View File

@ -0,0 +1,9 @@
tinyMCE.addI18n('it.locomedia_dlg',{
dialog_title: 'Inserisci immagine',
upload: 'Carica immagine',
loading: 'Caricamento...',
uploading: 'Caricamento file...',
destroying: 'Eliminazione...',
confirm: 'Sicuro?',
no_items: 'Per ora non ci sono immagini.'
});

View File

@ -728,6 +728,10 @@
background-position: -380px 0 background-position: -380px 0
} }
.locomotiveSkin span.mce_locomedia {
background-position: -380px 0
}
.locomotiveSkin span.mce_help { .locomotiveSkin span.mce_help {
background-position: -340px 0 background-position: -340px 0
} }

View File

@ -51,7 +51,6 @@ describe 'Locomotive rendering system' do
end end
it 'sets the status to 404 not found when no page is found' do it 'sets the status to 404 not found when no page is found' do
# @controller.expects(:not_found_page).returns(@page)
@page.stubs(:not_found?).returns(true) @page.stubs(:not_found?).returns(true)
@controller.send(:prepare_and_set_response, 'Hello world !') @controller.send(:prepare_and_set_response, 'Hello world !')
@controller.status.should == :not_found @controller.status.should == :not_found