summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--askbot/deps/django_authopenid/backends.py6
-rw-r--r--askbot/deps/django_authopenid/views.py2
-rw-r--r--askbot/doc/source/optional-modules.rst15
-rw-r--r--askbot/skins/common/media/js/editor.js111
-rw-r--r--askbot/skins/common/media/js/jquery.ajaxfileupload.js37
-rw-r--r--askbot/skins/common/media/js/tinymce/plugins/askbot_attachment/editor_plugin.js112
-rw-r--r--askbot/skins/common/media/js/tinymce/plugins/askbot_attachment/langs/en.js3
-rw-r--r--askbot/skins/common/media/js/tinymce/plugins/askbot_attachment/langs/en_dlg.js3
-rw-r--r--askbot/skins/common/media/js/tinymce/plugins/askbot_imageuploader/editor_plugin.js112
-rw-r--r--askbot/skins/common/media/js/tinymce/plugins/askbot_imageuploader/langs/en.js3
-rw-r--r--askbot/skins/common/media/js/tinymce/plugins/askbot_imageuploader/langs/en_dlg.js3
-rw-r--r--askbot/skins/common/media/js/utils.js358
-rw-r--r--askbot/skins/common/media/js/wmd/wmd.js27
-rw-r--r--askbot/skins/default/media/bootstrap/css/bootstrap.css136
-rw-r--r--askbot/skins/default/media/style/style.less21
-rw-r--r--askbot/skins/default/templates/ask.html1
-rw-r--r--askbot/skins/default/templates/meta/bottom_scripts.html1
-rw-r--r--askbot/skins/default/templates/meta/html_head_stylesheets.html1
-rw-r--r--askbot/skins/default/templates/meta/tinymce.html9
-rw-r--r--askbot/skins/default/templates/user_profile/user_inbox.html1
-rw-r--r--askbot/skins/default/templates/users.html6
-rw-r--r--askbot/views/writers.py5
22 files changed, 684 insertions, 289 deletions
diff --git a/askbot/deps/django_authopenid/backends.py b/askbot/deps/django_authopenid/backends.py
index 5ff49c1b..48fcc45e 100644
--- a/askbot/deps/django_authopenid/backends.py
+++ b/askbot/deps/django_authopenid/backends.py
@@ -127,10 +127,12 @@ def ldap_authenticate(username, password):
common_name = user_information[common_name_field][0]
first_name, last_name = split_name(common_name, common_name_format)
+ #here we have an opportunity to copy password in the auth_user table
+ #but we don't do it for security reasons
try:
user = User.objects.get(username__exact=exact_username)
# always update user profile to synchronize with ldap server
- user.set_password(password)
+ user.set_unusable_password()
#user.first_name = first_name
#user.last_name = last_name
user.email = email
@@ -139,7 +141,7 @@ def ldap_authenticate(username, password):
# create new user in local db
user = User()
user.username = exact_username
- user.set_password(password)#copy password from LDAP locally
+ user.set_unusable_password()
#user.first_name = first_name
#user.last_name = last_name
user.email = email
diff --git a/askbot/deps/django_authopenid/views.py b/askbot/deps/django_authopenid/views.py
index a3ecbbab..e63988fb 100644
--- a/askbot/deps/django_authopenid/views.py
+++ b/askbot/deps/django_authopenid/views.py
@@ -322,7 +322,7 @@ def signin(request):
login(request, user)
return HttpResponseRedirect(next_url)
else:
- user.message_set.create(_('incorrect user name or password'))
+ request.user.message_set.create(_('Incorrect user name or password'))
return HttpResponseRedirect(request.path)
else:
if password_action == 'login':
diff --git a/askbot/doc/source/optional-modules.rst b/askbot/doc/source/optional-modules.rst
index 54043c1e..d56cbe42 100644
--- a/askbot/doc/source/optional-modules.rst
+++ b/askbot/doc/source/optional-modules.rst
@@ -103,7 +103,16 @@ The parameters are (note that some have pre-set defaults that might work for you
* user id field name (``LDAP_USERID_FIELD``)
* email field name (``LDAP_EMAIL_FIELD``)
* user name filter template (``LDAP_USERNAME_FILTER_TEMPLATE``)
-* user name filter template - must have two string placeholders.
+ must have two string placeholders.
+* given (first) name field (``LDAP_GIVEN_NAME_FIELD``)
+* surname (last name) field (``LDAP_SURNAME_FIELD``)
+* common name field (``LDAP_COMMON_NAME_FIELD``)
+ either given and surname should be used or common name.
+ All three are not necessary - either first two or common.
+ These fields are used to extract users first and last names.
+* Format of common name (``LDAP_COMMON_NAME_FIELD_FORMAT``)
+ values can be only 'first,last' or 'last,first' - used to
+ extract last and first names from common name
There are three more optional parameters that must go to the ``settings.py`` file::
@@ -124,6 +133,10 @@ you might need to :ref:`debug <debugging>` the settings.
The function to look at is `askbot.deps.django_authopenid.backends.ldap_authenticate`.
If you have problems with LDAP please contact us at support@askbot.com.
+The easiest way to debug - insert ``import pdb; pdb.set_trace()`` line into function
+`askbot.deps.django_authopenid.backends.ldap_authenticate`,
+start the ``runserver`` and step through.
+
Uploaded avatars
================
diff --git a/askbot/skins/common/media/js/editor.js b/askbot/skins/common/media/js/editor.js
index ae4f5aea..c6f1c873 100644
--- a/askbot/skins/common/media/js/editor.js
+++ b/askbot/skins/common/media/js/editor.js
@@ -16,65 +16,66 @@ Ajax upload
*/jQuery.extend({createUploadIframe:function(d,b){var a="jUploadFrame"+d;if(window.ActiveXObject){var c=document.createElement('<iframe id="'+a+'" name="'+a+'" />');if(typeof b=="boolean"){c.src="javascript:false"}else{if(typeof b=="string"){c.src=b}}}else{var c=document.createElement("iframe");c.id=a;c.name=a}c.style.position="absolute";c.style.top="-1000px";c.style.left="-1000px";document.body.appendChild(c);return c},createUploadForm:function(g,b){var e="jUploadForm"+g;var a="jUploadFile"+g;var d=$('<form action="" method="POST" name="'+e+'" id="'+e+'" enctype="multipart/form-data"></form>');var c=$("#"+b);var f=$(c).clone();$(c).attr("id",a);$(c).before(f);$(c).appendTo(d);$(d).css("position","absolute");$(d).css("top","-1200px");$(d).css("left","-1200px");$(d).appendTo("body");return d},ajaxFileUpload:function(k){k=jQuery.extend({},jQuery.ajaxSettings,k);var a=new Date().getTime();var b=jQuery.createUploadForm(a,k.fileElementId);var i=jQuery.createUploadIframe(a,k.secureuri);var h="jUploadFrame"+a;var j="jUploadForm"+a;if(k.global&&!jQuery.active++){jQuery.event.trigger("ajaxStart")}var c=false;var f={};if(k.global){jQuery.event.trigger("ajaxSend",[f,k])}var d=function(l){var p=document.getElementById(h);try{if(p.contentWindow){f.responseText=p.contentWindow.document.body?p.contentWindow.document.body.innerText:null;f.responseXML=p.contentWindow.document.XMLDocument?p.contentWindow.document.XMLDocument:p.contentWindow.document}else{if(p.contentDocument){f.responseText=p.contentDocument.document.body?p.contentDocument.document.body.textContent||document.body.innerText:null;f.responseXML=p.contentDocument.document.XMLDocument?p.contentDocument.document.XMLDocument:p.contentDocument.document}}}catch(o){jQuery.handleError(k,f,null,o)}if(f||l=="timeout"){c=true;var m;try{m=l!="timeout"?"success":"error";if(m!="error"){var n=jQuery.uploadHttpData(f,k.dataType);if(k.success){k.success(n,m)}if(k.global){jQuery.event.trigger("ajaxSuccess",[f,k])}}else{jQuery.handleError(k,f,m)}}catch(o){m="error";jQuery.handleError(k,f,m,o)}if(k.global){jQuery.event.trigger("ajaxComplete",[f,k])}if(k.global&&!--jQuery.active){jQuery.event.trigger("ajaxStop")}if(k.complete){k.complete(f,m)}jQuery(p).unbind();setTimeout(function(){try{$(p).remove();$(b).remove()}catch(q){jQuery.handleError(k,f,null,q)}},100);f=null}};if(k.timeout>0){setTimeout(function(){if(!c){d("timeout")}},k.timeout)}try{var b=$("#"+j);$(b).attr("action",k.url);$(b).attr("method","POST");$(b).attr("target",h);if(b.encoding){b.encoding="multipart/form-data"}else{b.enctype="multipart/form-data"}$(b).submit()}catch(g){jQuery.handleError(k,f,null,g)}if(window.attachEvent){document.getElementById(h).attachEvent("onload",d)}else{document.getElementById(h).addEventListener("load",d,false)}return{abort:function(){}}},uploadHttpData:function(r,type){var data=!type;data=type=="xml"||data?r.responseXML:r.responseText;if(type=="script"){jQuery.globalEval(data)}if(type=="json"){eval("data = "+data)}if(type=="html"){jQuery("<div>").html(data).evalScripts()}return data}});
/**
* Upload call. Used only once in the wmd file upload
- * this is "tightly coupled" with the wmd file uploader
- * @param {Object} jquery object imageUrl - where the
- * uploaded url must be inserted on successful upload
- * @param {Function} handler that is run upon change
- * of the file upload field
+ * this is used in the wmd file uploader and the
+ * askbots image and attachment upload plugins
+ * @todo refactor this code to "new style"
*/
-function ajaxFileUpload(imageUrl, startUploadHandler)
-{
- $("#loading").ajaxStart(function(){
- $(this).show();
- }).ajaxComplete(function(){
- $(this).hide();
- });
+function ajaxFileUpload(options) {
- $("#upload").ajaxStart(function(){
- $(this).hide();
- }).ajaxComplete(function(){
- $(this).show();
- });
+ var spinner = options['spinner'];
+ var uploadInputId = options['uploadInputId'];
+ var urlInput = $(options['urlInput']);
+ var startUploadHandler = options['startUploadHandler'];
- $.ajaxFileUpload
- (
- {
- url: askbot['urls']['upload'],
- secureuri:false,
- fileElementId:'file-upload',
- dataType: 'xml',
- success: function (data, status)
- {
- var fileURL = $(data).find('file_url').text();
- /*
- * hopefully a fix for the "fakepath" issue
- * https://www.mediawiki.org/wiki/Special:Code/MediaWiki/83225
- */
- fileURL = fileURL.replace(/\w:.*\\(.*)$/,'$1');
- var error = $(data).find('error').text();
- if(error != ''){
- alert(error);
- if (startUploadHandler){
- /* re-install this as the upload extension
- * will remove the handler to prevent double uploading */
- $('#file-upload').change(startUploadHandler);
- }
- }else{
- imageUrl.attr('value', fileURL);
- }
+ spinner.ajaxStart(function(){
+ $(this).show();
+ }).ajaxComplete(function(){
+ $(this).hide();
+ });
- },
- error: function (data, status, e)
- {
- alert(e);
- if (startUploadHandler){
- /* re-install this as the upload extension
- * will remove the handler to prevent double uploading */
- $('#file-upload').change(startUploadHandler);
- }
- }
- }
- )
+ /* important!!! upload input must be loaded by id
+ * because ajaxFileUpload monkey-patches the upload form */
+ $('#' + uploadInputId).ajaxStart(function(){
+ $(this).hide();
+ }).ajaxComplete(function(){
+ $(this).show();
+ });
+ //var localFilePath = upload_input.val();
+ $.ajaxFileUpload({
+ url: askbot['urls']['upload'],
+ secureuri: false,
+ fileElementId: uploadInputId,
+ dataType: 'xml',
+ success: function (data, status) {
+
+ var fileURL = $(data).find('file_url').text();
+ /*
+ * hopefully a fix for the "fakepath" issue
+ * https://www.mediawiki.org/wiki/Special:Code/MediaWiki/83225
+ */
+ fileURL = fileURL.replace(/\w:.*\\(.*)$/,'$1');
+ var error = $(data).find('error').text();
+ if(error != ''){
+ alert(error);
+ } else {
+ urlInput.attr('value', fileURL);
+ }
+
+ /* re-install this as the upload extension
+ * will remove the handler to prevent double uploading
+ * this hack is a manipulation around the
+ * ajaxFileUpload jQuery plugin. */
+ $('#' + uploadInputId).unbind('change').change(startUploadHandler);
+ },
+ error: function (data, status, e) {
+ alert(e);
+ if (startUploadHandler){
+ /* re-install this as the upload extension
+ * will remove the handler to prevent double uploading */
+ $('#' + uploadInputId).unbind('change').change(startUploadHandler);
+ }
+ }
+ });
return false;
};
diff --git a/askbot/skins/common/media/js/jquery.ajaxfileupload.js b/askbot/skins/common/media/js/jquery.ajaxfileupload.js
index 75292776..23759c2e 100644
--- a/askbot/skins/common/media/js/jquery.ajaxfileupload.js
+++ b/askbot/skins/common/media/js/jquery.ajaxfileupload.js
@@ -23,8 +23,7 @@ jQuery.extend({
document.body.appendChild(io);
return io;
},
- createUploadForm: function(id, fileElementId)
- {
+ createUploadForm: function(id, fileElementId) {
//create form
var formId = 'jUploadForm' + id;
var fileId = 'jUploadFile' + id;
@@ -62,8 +61,7 @@ jQuery.extend({
if ( s.global )
jQuery.event.trigger("ajaxSend", [xml, s]);
// Wait for a response to come back
- var uploadCallback = function(isTimeout)
- {
+ var uploadCallback = function(isTimeout) {
var io = document.getElementById(frameId);
try {
if(io.contentWindow){
@@ -81,12 +79,10 @@ jQuery.extend({
io.contentDocument.document.XMLDocument : io.contentDocument.document;
}
}
- catch(e)
- {
+ catch(e) {
jQuery.handleError(s, xml, null, e);
}
- if ( xml || isTimeout == "timeout")
- {
+ if ( xml || isTimeout == "timeout") {
requestDone = true;
var status;
try {
@@ -125,16 +121,15 @@ jQuery.extend({
jQuery(io).unbind();
- setTimeout(function()
- { try
- {
+ setTimeout(function() {
+ try {
$(io).remove();
$(form).remove();
- } catch(e) {
- jQuery.handleError(s, xml, null, e);
- }
- }, 100)
+ } catch(e) {
+ jQuery.handleError(s, xml, null, e);
+ }
+ }, 100);
xml = null;
}
}
@@ -145,25 +140,21 @@ jQuery.extend({
if( !requestDone ) uploadCallback( "timeout" );
}, s.timeout);
}
- try
- {
+ try {
// var io = $('#' + frameId);
var form = $('#' + formId);
$(form).attr('action', s.url);
$(form).attr('method', 'POST');
$(form).attr('target', frameId);
- if(form.encoding)
- {
+ if(form.encoding) {
form.encoding = 'multipart/form-data';
}
- else
- {
+ else {
form.enctype = 'multipart/form-data';
}
$(form).submit();
- } catch(e)
- {
+ } catch(e) {
jQuery.handleError(s, xml, null, e);
}
if(window.attachEvent){
diff --git a/askbot/skins/common/media/js/tinymce/plugins/askbot_attachment/editor_plugin.js b/askbot/skins/common/media/js/tinymce/plugins/askbot_attachment/editor_plugin.js
new file mode 100644
index 00000000..341904b5
--- /dev/null
+++ b/askbot/skins/common/media/js/tinymce/plugins/askbot_attachment/editor_plugin.js
@@ -0,0 +1,112 @@
+/**
+ * askbot_attachment.js
+ *
+ * Copyright 2012, Askbot SpA
+ * Released under License.
+ *
+ * License: http://tinymce.moxiecode.com/license
+ * Contributing: http://tinymce.moxiecode.com/contributing
+ */
+
+(function() {
+ var insertIntoDom = function(url, description) {
+ var sel = tinyMCE.activeEditor.selection;
+
+ var content = '<a href="' + url;
+ if (description) {
+ content = content + '" title="' + description;
+ }
+ content = content + '">see attachment</a>';
+
+ sel.setContent(content);
+ };
+
+ var modalMenuHeadline = gettext('Insert a file');
+
+ var createDialog = function() {
+ var dialog = new FileUploadDialog();
+ dialog.setHeadingText(modalMenuHeadline);
+ dialog.setPostUploadHandler(insertIntoDom);
+ debugger;
+ dialog.setInputId('askbot_attachment_input');
+ dialog.setUrlInputTooltip(gettext('Or paste file url here'));
+ $(document).append(dialog.getElement());
+ return dialog;
+ };
+
+ var dialog = undefined;
+
+ var getDialog = function() {
+ if (dialog === undefined) {
+ dialog = createDialog();
+ }
+ return dialog;
+ };
+
+ // Load plugin specific language pack
+ tinymce.PluginManager.requireLangPack('askbot_attachment');
+
+ tinymce.create('tinymce.plugins.AskbotAttachmentPlugin', {
+ /**
+ * Initializes the plugin, this will be executed after the plugin has been created.
+ * This call is done before the editor instance has finished it's initialization so use the onInit event
+ * of the editor instance to intercept that event.
+ *
+ * @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
+ * @param {string} url Absolute URL to where the plugin is located.
+ */
+ init : function(ed, url) {
+ // Register the command so that it can be invoked by using tinyMCE.activeEditor.execCommand('mceAskbotAttachment');
+ ed.addCommand('mceAskbotAttachment', function() {
+ //start file uploader modal menu
+ var dialog = getDialog();
+ dialog.show();
+ });
+
+ // Register askbot_attachment button
+ ed.addButton('askbot_attachment', {
+ title : gettext('Insert a file'),
+ cmd : 'mceAskbotAttachment'
+ //image : url + '/img/askbot_leuploader.gif'
+ });
+
+ // Add a node change handler, selects the button in the UI when a image is selected
+ ed.onNodeChange.add(function(ed, cm, n) {
+ cm.setActive('askbot_attachment', n.nodeName == 'IMG');
+ });
+ },
+
+ /**
+ * Creates control instances based in the incomming name. This method is normally not
+ * needed since the addButton method of the tinymce.Editor class is a more easy way of adding buttons
+ * but you sometimes need to create more complex controls like listboxes, split buttons etc then this
+ * method can be used to create those.
+ *
+ * @param {String} n Name of the control to create.
+ * @param {tinymce.ControlManager} cm Control manager to use inorder to create new control.
+ * @return {tinymce.ui.Control} New control instance or null if no control was created.
+ */
+ createControl : function(n, cm) {
+ return null;
+ },
+
+ /**
+ * Returns information about the plugin as a name/value array.
+ * The current keys are longname, author, authorurl, infourl and version.
+ *
+ * @return {Object} Name/value array containing information about the plugin.
+ */
+ getInfo : function() {
+ return {
+ longname : 'AskbotAttachment plugin',
+ author : 'Askbot SpA, Chile',
+ authorurl : 'http://askbot.com',
+ infourl : 'http://github.com/ASKBOT/askbot-devel/',
+ version : '0.1'
+ };
+ }
+ });
+
+ // Register plugin
+ tinymce.PluginManager.add('askbot_attachment', tinymce.plugins.AskbotAttachmentPlugin);
+})();
diff --git a/askbot/skins/common/media/js/tinymce/plugins/askbot_attachment/langs/en.js b/askbot/skins/common/media/js/tinymce/plugins/askbot_attachment/langs/en.js
new file mode 100644
index 00000000..d38ad8ea
--- /dev/null
+++ b/askbot/skins/common/media/js/tinymce/plugins/askbot_attachment/langs/en.js
@@ -0,0 +1,3 @@
+tinyMCE.addI18n('en.askbot_imageupload',{
+ desc : 'Upload an image'
+});
diff --git a/askbot/skins/common/media/js/tinymce/plugins/askbot_attachment/langs/en_dlg.js b/askbot/skins/common/media/js/tinymce/plugins/askbot_attachment/langs/en_dlg.js
new file mode 100644
index 00000000..5cd400c1
--- /dev/null
+++ b/askbot/skins/common/media/js/tinymce/plugins/askbot_attachment/langs/en_dlg.js
@@ -0,0 +1,3 @@
+tinyMCE.addI18n('en.askbot_imageupload_dlg',{
+ title : 'Upload an image'
+});
diff --git a/askbot/skins/common/media/js/tinymce/plugins/askbot_imageuploader/editor_plugin.js b/askbot/skins/common/media/js/tinymce/plugins/askbot_imageuploader/editor_plugin.js
new file mode 100644
index 00000000..0903feb4
--- /dev/null
+++ b/askbot/skins/common/media/js/tinymce/plugins/askbot_imageuploader/editor_plugin.js
@@ -0,0 +1,112 @@
+/**
+ * askbot_imageuploader.js
+ *
+ * Copyright 2012, Askbot SpA
+ * Released under License.
+ *
+ * License: http://tinymce.moxiecode.com/license
+ * Contributing: http://tinymce.moxiecode.com/contributing
+ */
+
+(function() {
+ var insertIntoDom = function(url, description) {
+ var sel = tinyMCE.activeEditor.selection;
+
+ var content = '<img src="' + url;
+ if (description) {
+ content = content + '" alt="' + description;
+ }
+ content = content + '"/>';
+
+ sel.setContent(content);
+ };
+
+ var modalMenuHeadline = gettext('Upload an image');
+
+ var createDialog = function() {
+ var dialog = new FileUploadDialog();
+ dialog.setHeadingText(modalMenuHeadline);
+ dialog.setPostUploadHandler(insertIntoDom);
+ dialog.setUrlInputTooltip('Or paste image url here');
+ dialog.setInputId('askbot_imageuploader_input');
+ $(document).append(dialog.getElement());
+ return dialog;
+ };
+
+ var dialog = undefined;
+
+ var getDialog = function() {
+ if (dialog === undefined) {
+ dialog = createDialog();
+ }
+ return dialog;
+ };
+
+ // Load plugin specific language pack
+ tinymce.PluginManager.requireLangPack('askbot_imageuploader');
+
+ tinymce.create('tinymce.plugins.AskbotImageUploaderPlugin', {
+ /**
+ * Initializes the plugin, this will be executed after the plugin has been created.
+ * This call is done before the editor instance has finished it's initialization so use the onInit event
+ * of the editor instance to intercept that event.
+ *
+ * @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
+ * @param {string} url Absolute URL to where the plugin is located.
+ */
+ init : function(ed, url) {
+ // Register the command so that it can be invoked by using tinyMCE.activeEditor.execCommand('mceAskbotImageUploader');
+ ed.addCommand('mceAskbotImageUploader', function() {
+ //start file uploader modal menu
+ var dialog = getDialog();
+ debugger;
+ dialog.show();
+ });
+
+ // Register askbot_imageuploader button
+ ed.addButton('askbot_imageuploader', {
+ title : gettext('Insert image'),
+ cmd : 'mceAskbotImageUploader'
+ //image : url + '/img/askbot_leuploader.gif'
+ });
+
+ // Add a node change handler, selects the button in the UI when a image is selected
+ ed.onNodeChange.add(function(ed, cm, n) {
+ cm.setActive('askbot_imageuploader', n.nodeName == 'IMG');
+ });
+ },
+
+ /**
+ * Creates control instances based in the incomming name. This method is normally not
+ * needed since the addButton method of the tinymce.Editor class is a more easy way of adding buttons
+ * but you sometimes need to create more complex controls like listboxes, split buttons etc then this
+ * method can be used to create those.
+ *
+ * @param {String} n Name of the control to create.
+ * @param {tinymce.ControlManager} cm Control manager to use inorder to create new control.
+ * @return {tinymce.ui.Control} New control instance or null if no control was created.
+ */
+ createControl : function(n, cm) {
+ return null;
+ },
+
+ /**
+ * Returns information about the plugin as a name/value array.
+ * The current keys are longname, author, authorurl, infourl and version.
+ *
+ * @return {Object} Name/value array containing information about the plugin.
+ */
+ getInfo : function() {
+ return {
+ longname : 'AskbotImageUploader plugin',
+ author : 'Askbot SpA, Chile',
+ authorurl : 'http://askbot.com',
+ infourl : 'http://github.com/ASKBOT/askbot-devel/',
+ version : '0.1'
+ };
+ }
+ });
+
+ // Register plugin
+ tinymce.PluginManager.add('askbot_imageuploader', tinymce.plugins.AskbotImageUploaderPlugin);
+})();
diff --git a/askbot/skins/common/media/js/tinymce/plugins/askbot_imageuploader/langs/en.js b/askbot/skins/common/media/js/tinymce/plugins/askbot_imageuploader/langs/en.js
new file mode 100644
index 00000000..d38ad8ea
--- /dev/null
+++ b/askbot/skins/common/media/js/tinymce/plugins/askbot_imageuploader/langs/en.js
@@ -0,0 +1,3 @@
+tinyMCE.addI18n('en.askbot_imageupload',{
+ desc : 'Upload an image'
+});
diff --git a/askbot/skins/common/media/js/tinymce/plugins/askbot_imageuploader/langs/en_dlg.js b/askbot/skins/common/media/js/tinymce/plugins/askbot_imageuploader/langs/en_dlg.js
new file mode 100644
index 00000000..5cd400c1
--- /dev/null
+++ b/askbot/skins/common/media/js/tinymce/plugins/askbot_imageuploader/langs/en_dlg.js
@@ -0,0 +1,3 @@
+tinyMCE.addI18n('en.askbot_imageupload_dlg',{
+ title : 'Upload an image'
+});
diff --git a/askbot/skins/common/media/js/utils.js b/askbot/skins/common/media/js/utils.js
index 43316da7..ad4963fc 100644
--- a/askbot/skins/common/media/js/utils.js
+++ b/askbot/skins/common/media/js/utils.js
@@ -308,6 +308,7 @@ Widget.prototype.makeButton = function(label, handler) {
var TippedInput = function(){
WrappedElement.call(this);
this._instruction = null;
+ this._attrs = {};
};
inherits(TippedInput, WrappedElement);
@@ -316,6 +317,14 @@ TippedInput.prototype.reset = function(){
$(this._element).addClass('blank');
};
+TippedInput.prototype.setInstruction = function(text) {
+ this._instruction = text;
+};
+
+TippedInput.prototype.setAttr = function(key, value) {
+ this._attrs[key] = value;
+};
+
TippedInput.prototype.isBlank = function(){
return this.getVal() === this._instruction;
};
@@ -335,8 +344,17 @@ TippedInput.prototype.setVal = function(value){
}
};
+TippedInput.prototype.createDom = function() {
+ this._element = this.makeElement('input');
+ var element = this._element;
+ element.val(this._instruction);
+ this.decorate(element);
+};
+
TippedInput.prototype.decorate = function(element){
this._element = element;
+ element.attr(this._attrs);
+
var instruction_text = this.getVal();
this._instruction = instruction_text;
var me = this;
@@ -552,8 +570,272 @@ DeleteIcon.prototype.setContent = function(content){
}
/**
+ * @contstructor
+ * Simple modal dialog with Ok/Cancel buttons by default
+ */
+var ModalDialog = function() {
+ WrappedElement.call(this);
+ this._accept_button_text = gettext('Ok');
+ this._reject_button_text = gettext('Cancel');
+ this._heading_text = 'Add heading by setHeadingText()';
+ this._initial_content = undefined;
+ this._accept_handler = function(){};
+ var me = this;
+ this._reject_handler = function() { me.hide(); };
+ this._content_element = undefined;
+};
+inherits(ModalDialog, WrappedElement);
+
+ModalDialog.prototype.show = function() {
+ this._element.modal('show');
+};
+
+ModalDialog.prototype.hide = function() {
+ this._element.modal('hide');
+};
+
+ModalDialog.prototype.setContent = function(content) {
+ this._initial_content = content;
+};
+
+ModalDialog.prototype.prependContent = function(content) {
+ this._content_element.prepend(content);
+};
+
+ModalDialog.prototype.setHeadingText = function(text) {
+ this._heading_text = text;
+};
+
+ModalDialog.prototype.setAcceptButtonText = function(text) {
+ this._accept_button_text = text;
+};
+
+ModalDialog.prototype.setRejectButtonText = function(text) {
+ this._reject_button_text = text;
+};
+
+ModalDialog.prototype.setAcceptHandler = function(handler) {
+ this._accept_handler = handler;
+};
+
+ModalDialog.prototype.setRejectHandler = function(handler) {
+ this._reject_handler = handler;
+};
+
+ModalDialog.prototype.clearMessages = function() {
+ this._element.find('.alert').remove();
+};
+
+ModalDialog.prototype.setMessage = function(text, message_type) {
+ var box = new AlertBox();
+ box.setText(text);
+ if (message_type === 'error') {
+ box.setError(true);
+ }
+ this.prependContent(box.getElement());
+};
+
+ModalDialog.prototype.createDom = function() {
+ this._element = this.makeElement('div')
+ var element = this._element;
+
+ element.addClass('modal');
+
+ //1) create header
+ var header = this.makeElement('div')
+ header.addClass('modal-header');
+ element.append(header);
+
+ var close_link = this.makeElement('div');
+ close_link.addClass('close');
+ close_link.attr('data-dismiss', 'modal');
+ close_link.html('x');
+ header.append(close_link);
+
+ var title = this.makeElement('h3');
+ title.html(this._heading_text);
+ header.append(title);
+
+ //2) create content
+ var body = this.makeElement('div')
+ body.addClass('modal-body');
+ element.append(body);
+ this._content_element = body;
+ if (this._initial_content) {
+ this._content_element.append(this._initial_content);
+ }
+
+ //3) create footer with accept and reject buttons (ok/cancel).
+ var footer = this.makeElement('div');
+ footer.addClass('modal-footer');
+ element.append(footer);
+
+ var accept_btn = this.makeElement('button');
+ accept_btn.addClass('btn btn-primary');
+ accept_btn.html(this._accept_button_text);
+ footer.append(accept_btn);
+
+ var reject_btn = this.makeElement('button');
+ reject_btn.addClass('btn cancel');
+ reject_btn.html(this._reject_button_text);
+ footer.append(reject_btn);
+
+ //4) attach event handlers to the buttons
+ setupButtonEventHandlers(accept_btn, this._accept_handler);
+ setupButtonEventHandlers(reject_btn, this._reject_handler);
+ setupButtonEventHandlers(close_link, this._reject_handler);
+
+ this.hide();
+};
+
+/**
+ * @constructor
+ */
+var FileUploadDialog = function() {
+ ModalDialog.call(this);
+ self._post_upload_handler = undefined;
+};
+inherits(FileUploadDialog, ModalDialog);
+
+FileUploadDialog.prototype.setPostUploadHandler = function(handler) {
+ this._post_upload_handler = handler;
+};
+
+FileUploadDialog.prototype.runPostUploadHandler = function(url, descr) {
+ this._post_upload_handler(url, descr);
+};
+
+FileUploadDialog.prototype.setInputId = function(id) {
+ this._input_id = id;
+};
+
+FileUploadDialog.prototype.getInputId = function() {
+ return this._input_id;
+};
+
+FileUploadDialog.prototype.setUrlInputTooltip = function(text) {
+ this._url_input_tooltip = text;
+};
+
+FileUploadDialog.prototype.getUrl = function() {
+ var url_input = this._url_input;
+ if (url_input.isBlank() === false) {
+ return url_input.getVal();
+ }
+ return '';
+};
+
+//disable description for now
+//FileUploadDialog.prototype.getDescription = function() {
+// return this._description_input.getVal();
+//};
+
+FileUploadDialog.prototype.resetInputs = function() {
+ this._url_input.reset();
+ //this._description_input.reset();
+ this._upload_input.val('');
+};
+
+FileUploadDialog.prototype.show = function() {
+ //hack around the ajaxFileUpload plugin
+ FileUploadDialog.superClass_.show.call(this);
+ var upload_input = this._upload_input;
+ upload_input.unbind('change');
+ //todo: fix this - make event handler reinstall work
+ upload_input.change(this.getStartUploadHandler());
+};
+
+FileUploadDialog.prototype.getStartUploadHandler = function(){
+ /* startUploadHandler is passed in to re-install the event handler
+ * which is removed by the ajaxFileUpload jQuery extension
+ */
+ var spinner = this._spinner;
+ var uploadInputId = this.getInputId();
+ var urlInput = this._url_input;
+ var handler = function() {
+ var options = {
+ 'spinner': spinner,
+ 'uploadInputId': uploadInputId,
+ 'urlInput': urlInput.getElement(),
+ 'startUploadHandler': handler//pass in itself
+ };
+ return ajaxFileUpload(options);
+ };
+ return handler;
+};
+
+FileUploadDialog.prototype.createDom = function() {
+
+ var superClass = FileUploadDialog.superClass_;
+
+ var me = this;
+ superClass.setAcceptHandler.call(this, function(){
+ var url = $.trim(me.getUrl());
+ //var description = me.getDescription();
+ //@todo: have url cleaning code here
+ if (url.length > 0) {
+ me.runPostUploadHandler(url);//, description);
+ me.resetInputs();
+ }
+ me.hide();
+ });
+ superClass.setRejectHandler.call(this, function(){
+ me.resetInputs();
+ me.hide();
+ });
+ superClass.createDom.call(this);
+
+ var form = this.makeElement('form');
+ form.css('margin-bottom', 0);
+ this.prependContent(form);
+
+ // File upload button
+ var upload_input = this.makeElement('input');
+ upload_input.attr({
+ id: this._input_id,
+ type: 'file',
+ name: 'file-upload',
+ //size: 26???
+ });
+ form.append(upload_input);
+ this._upload_input = upload_input;
+ form.append($('<br/>'));
+
+ // The url input text box
+ var url_input = new TippedInput();
+ url_input.setInstruction(this._url_input_tooltip || gettext('Or paste file url here'));
+ var url_input_element = url_input.getElement();
+ url_input_element.css({
+ 'width': '200px',
+ });
+ form.append(url_input_element);
+ form.append($('<br/>'));
+ this._url_input = url_input;
+
+ /* //Description input box
+ var descr_input = new TippedInput();
+ descr_input.setInstruction(gettext('Describe the image here'));
+ this.makeElement('input');
+ form.append(descr_input.getElement());
+ form.append($('<br/>'));
+ this._description_input = descr_input;
+ */
+ var spinner = this.makeElement('img');
+ spinner.attr('src', mediaUrl('media/images/indicator.gif'));
+ spinner.css('display', 'none');
+ form.append(spinner);
+ this._spinner = spinner;
+
+ upload_input.change(this.getStartUploadHandler());
+};
+
+/**
* attaches a modal menu with a text editor
* to a link. The modal menu is from bootstrap.js
+ * todo: this should probably be a subclass of ModalDialog,
+ * triggered by a link click, then a whole bunch of methods
+ * would be simply inherited from the modal dialog:
+ * clearMessages, etc.
*/
var TextPropertyEditor = function(){
WrappedElement.call(this);
@@ -577,90 +859,48 @@ TextPropertyEditor.prototype.makeEditor = function(){
if (this._editor) {
return this._editor;
}
- var editor = this.makeElement('div')
- .addClass('modal');
+ var editor = new ModalDialog();
this._editor = editor;
+ editor.setHeadingText(this.getWidgetData()['editor_heading']);
- var header = this.makeElement('div')
- .addClass('modal-header');
- editor.append(header);
-
- var close_link = this.makeElement('div')
- .addClass('close')
- .attr('data-dismiss', 'modal')
- .html('x');
- header.append(close_link);
-
- var title = this.makeElement('h3')
- .html(this.getWidgetData()['editor_heading']);
- header.append(title);
-
- var body = this.makeElement('div')
- .addClass('modal-body');
- editor.append(body);
-
- var textarea = this.makeElement('textarea')
- .addClass('tipped-input blank')
- .val(this.getWidgetData()['help_text']);
- body.append(textarea);
+ //create main content for the editor
+ var textarea = this.makeElement('textarea');
+ textarea.addClass('tipped-input blank');
+ textarea.val(this.getWidgetData()['help_text']);
var tipped_input = new TippedInput();
tipped_input.decorate(textarea);
this._text_input = tipped_input;
- var footer = this.makeElement('div')
- .addClass('modal-footer');
- editor.append(footer);
+ editor.setContent(textarea);
+ //body.append(textarea);
- var save_btn = this.makeElement('button')
- .addClass('btn btn-primary')
- .html(gettext('Save'));
- footer.append(save_btn);
-
- var cancel_btn = this.makeElement('button')
- .addClass('btn cancel')
- .html(gettext('Cancel'));
- footer.append(cancel_btn);
+ editor.setAcceptButtonText(gettext('Save'));
+ editor.setRejectButtonText(gettext('Cancel'));
var me = this;
- setupButtonEventHandlers(save_btn, function(){
+ editor.setAcceptHandler(function(){
me.saveData();
});
- setupButtonEventHandlers(cancel_btn, function(){
- editor.modal('hide');
- });
- editor.modal('hide');
- $(document).append(editor);
+ $(document).append(editor.getElement());
return editor;
};
TextPropertyEditor.prototype.openEditor = function(){
- this._editor.modal('show');
+ this._editor.show();
};
TextPropertyEditor.prototype.clearMessages = function(){
- this._editor.find('.alert').remove();
-};
-
-TextPropertyEditor.prototype.getAlert = function(){
- var box = new AlertBox();
- var modal_body = this._editor.find('.modal-body');
- modal_body.prepend(box.getElement());
- return box;
+ this._editor.clearMessages()
};
TextPropertyEditor.prototype.showAlert = function(text){
- this.clearMessages();
- var box = this.getAlert();
- box.setText(text);
- return box;
+ this._editor.setMessage(text, 'alert');
};
TextPropertyEditor.prototype.showError = function(text){
- var box = this.showAlert(text);
- box.setError(true);
- return box;
+ this._editor.setMessage(text, 'error');
};
TextPropertyEditor.prototype.setText = function(text){
@@ -672,7 +912,7 @@ TextPropertyEditor.prototype.getText = function(){
};
TextPropertyEditor.prototype.hideDialog = function(){
- this._editor.modal('hide');
+ this._editor.hide();
};
TextPropertyEditor.prototype.startOpeningEditor = function(){
diff --git a/askbot/skins/common/media/js/wmd/wmd.js b/askbot/skins/common/media/js/wmd/wmd.js
index 98af264f..60d6d868 100644
--- a/askbot/skins/common/media/js/wmd/wmd.js
+++ b/askbot/skins/common/media/js/wmd/wmd.js
@@ -357,9 +357,26 @@ util.prompt = function(text, defaultInputText, makeLinkMarkdown, dialogType){
upload_input.attr('id', 'file-upload');
upload_input.attr('size', 26);
+ var spinner = $('<img />');
+ spinner.attr('id', 'loading');
+ spinner.attr('src', mediaUrl("media/images/indicator.gif"));
+ spinner.css('display', 'none');
+
var startUploadHandler = function(){
- localUploadFileName = $(this).val();
- return ajaxFileUpload($('#image-url'), startUploadHandler);
+ localUploadFileName = $(this).val();//this is a local var
+ /*
+ * startUploadHandler is passed into the ajaxFileUpload
+ * in order to re-install the onchange handler
+ * because the jquery extension ajaxFileUpload removes the handler
+ */
+ var options = {
+ spinner: spinner,
+ uploadInputId: 'file-upload',
+ urlInput: $(input),
+ startUploadHandler: startUploadHandler
+ };
+ return ajaxFileUpload(options);
+ //$('#image-url'), startUploadHandler);
};
upload_input.change(startUploadHandler);
@@ -367,12 +384,8 @@ util.prompt = function(text, defaultInputText, makeLinkMarkdown, dialogType){
upload_container.append(upload_input);
upload_container.append($('<br/>'));
- var spinner = $('<img />');
- spinner.attr('id', 'loading');
- spinner.attr('src', mediaUrl("media/images/indicator.gif"));
- spinner.css('display', 'none');
-
upload_container.append(spinner);
+
upload_container.css('padding', '5px');
$(form).append(upload_container);
}
diff --git a/askbot/skins/default/media/bootstrap/css/bootstrap.css b/askbot/skins/default/media/bootstrap/css/bootstrap.css
index 3e829732..ff80a3e1 100644
--- a/askbot/skins/default/media/bootstrap/css/bootstrap.css
+++ b/askbot/skins/default/media/bootstrap/css/bootstrap.css
@@ -1,5 +1,9 @@
/*!
* Bootstrap v2.0.2
+ * This file was modified for Askbot
+ * some styles were deleted, others added at the bottom
+ * of this file. Also some fixes to bootstrap are added
+ * at the bottom of askbot's style.less.
*
* Copyright 2012 Twitter, Inc
* Licensed under the Apache License v2.0
@@ -92,14 +96,6 @@ img {
vertical-align: middle;
}
button,
-input,
-select,
-textarea {
- margin: 0;
- font-size: 100%;
- vertical-align: middle;
-}
-button,
input {
*overflow: visible;
line-height: normal;
@@ -130,14 +126,6 @@ textarea {
overflow: auto;
vertical-align: top;
}
-body {
- margin: 0;
- font-family: Arial, sans-serif;
- font-size: 13px;
- line-height: 18px;
- color: #333333;
- background-color: #ffffff;
-}
a {
color: #0088cc;
text-decoration: none;
@@ -894,25 +882,10 @@ legend small {
font-size: 13.5px;
color: #999999;
}
-label,
-input,
-button,
-select,
-textarea {
- font-size: 13px;
- font-weight: normal;
- line-height: 18px;
-}
-input,
-button,
-select,
-textarea {
- font-family: Arial, sans-serif;
-}
label {
- display: block;
+ /*display: block;
margin-bottom: 5px;
- color: #333333;
+ color: #333333;*/
}
input,
textarea,
@@ -928,25 +901,6 @@ label textarea,
label select {
display: block;
}
-input[type="image"],
-input[type="checkbox"],
-input[type="radio"] {
- width: auto;
- height: auto;
- padding: 0;
- margin: 3px 0;
- *margin-top: 0;
- /* IE7 */
-
- line-height: normal;
- cursor: pointer;
- -webkit-border-radius: 0;
- -moz-border-radius: 0;
- border-radius: 0;
- border: 0 \9;
- /* IE9 and down */
-
-}
input[type="image"] {
border: 0;
}
@@ -999,26 +953,6 @@ textarea {
input[type="hidden"] {
display: none;
}
-.radio,
-.checkbox {
- padding-left: 18px;
-}
-.radio input[type="radio"],
-.checkbox input[type="checkbox"] {
- float: left;
- margin-left: -18px;
-}
-.controls > .radio:first-child,
-.controls > .checkbox:first-child {
- padding-top: 5px;
-}
-.radio.inline,
-.checkbox.inline {
- display: inline-block;
- padding-top: 5px;
- margin-bottom: 0;
- vertical-align: middle;
-}
.radio.inline + .radio.inline,
.checkbox.inline + .checkbox.inline {
margin-left: 10px;
@@ -1074,18 +1008,6 @@ select:focus {
.input-xxlarge {
width: 530px;
}
-input[class*="span"],
-select[class*="span"],
-textarea[class*="span"],
-.uneditable-input {
- float: none;
- margin-left: 0;
-}
-input,
-textarea,
-.uneditable-input {
- margin-left: 0;
-}
input.span12, textarea.span12, .uneditable-input.span12 {
width: 930px;
}
@@ -1237,15 +1159,6 @@ select:focus:required:invalid:focus {
.form-actions:after {
clear: both;
}
-.uneditable-input {
- display: block;
- background-color: #ffffff;
- border-color: #eee;
- -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025);
- -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025);
- box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025);
- cursor: not-allowed;
-}
:-moz-placeholder {
color: #999999;
}
@@ -1273,17 +1186,6 @@ select:focus:required:invalid:focus {
.input-append {
margin-bottom: 5px;
}
-.input-prepend input,
-.input-append input,
-.input-prepend select,
-.input-append select,
-.input-prepend .uneditable-input,
-.input-append .uneditable-input {
- *margin-left: 0;
- -webkit-border-radius: 0 3px 3px 0;
- -moz-border-radius: 0 3px 3px 0;
- border-radius: 0 3px 3px 0;
-}
.input-prepend input:focus,
.input-append input:focus,
.input-prepend select:focus,
@@ -4280,11 +4182,6 @@ a.thumbnail:hover {
.row-fluid > .span1 {
width: 5.801104972%;
}
- input,
- textarea,
- .uneditable-input {
- margin-left: 0;
- }
input.span12, textarea.span12, .uneditable-input.span12 {
width: 714px;
}
@@ -4633,3 +4530,24 @@ a.thumbnail:hover {
margin-left: 30px;
}
}
+
+/* Modifications for askbot */
+.caret {
+ margin-bottom: 7px;
+}
+.btn-group {
+ text-align: left;
+}
+.btn-toolbar {
+ margin: 0;
+}
+.modal-footer {
+ text-align: left;
+}
+.modal p {
+ font-size: 14px;
+}
+.modal-body > textarea {
+ width: 515px;
+ margin-bottom: 0px;
+}
diff --git a/askbot/skins/default/media/style/style.less b/askbot/skins/default/media/style/style.less
index bfb567bb..e4c1d714 100644
--- a/askbot/skins/default/media/style/style.less
+++ b/askbot/skins/default/media/style/style.less
@@ -3649,24 +3649,3 @@ textarea.tipped-input {
margin-top: 9px;
}
}
-
-/* fixes for bootstrap */
-.caret {
- margin-bottom: 7px;
-}
-.btn-group {
- text-align: left;
-}
-.btn-toolbar {
- margin: 0;
-}
-.modal-footer {
- text-align: left;
-}
-.modal p {
- font-size: 14px;
-}
-.modal-body > textarea {
- width: 515px;
- margin-bottom: 0px;
-}
diff --git a/askbot/skins/default/templates/ask.html b/askbot/skins/default/templates/ask.html
index f0dae0ce..e9e53338 100644
--- a/askbot/skins/default/templates/ask.html
+++ b/askbot/skins/default/templates/ask.html
@@ -20,6 +20,7 @@
<script type='text/javascript' src='{{"/js/wmd/showdown.js"|media}}'></script>
<script type='text/javascript' src='{{"/js/wmd/wmd.js"|media}}'></script>
{% else %}
+ <script type='text/javascript' src='{{"/js/wmd/showdown.js"|media}}'></script>
{% include "meta/tinymce.html" %}
{% endif %}
<script type='text/javascript'>
diff --git a/askbot/skins/default/templates/meta/bottom_scripts.html b/askbot/skins/default/templates/meta/bottom_scripts.html
index 093283f8..76992383 100644
--- a/askbot/skins/default/templates/meta/bottom_scripts.html
+++ b/askbot/skins/default/templates/meta/bottom_scripts.html
@@ -28,6 +28,7 @@
src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"
{% endif %}
></script>
+<script type="text/javascript" src='{{"/bootstrap/js/bootstrap.js"|media}}'></script>
<!-- History.js -->
<script type='text/javascript' src="{{"/js/jquery.history.js"|media }}"></script>
<script type="text/javascript" src="{% url django.views.i18n.javascript_catalog %}"></script>
diff --git a/askbot/skins/default/templates/meta/html_head_stylesheets.html b/askbot/skins/default/templates/meta/html_head_stylesheets.html
index 0d2ba463..bb90e3f8 100644
--- a/askbot/skins/default/templates/meta/html_head_stylesheets.html
+++ b/askbot/skins/default/templates/meta/html_head_stylesheets.html
@@ -4,6 +4,7 @@
<link href="{{"/style/style.less"|media }}" rel="stylesheet/less" type="text/css" />
<script type="text/javascript" src="{{"/js/less.min.js"|media}}"></script>
{% endif %}
+<link href="{{'/bootstrap/css/bootstrap.css'|media}}" rel="stylesheet" type="text/css" />
{% if settings.USE_LOCAL_FONTS %}
{% include "meta/fonts.html" %}
{% else %}
diff --git a/askbot/skins/default/templates/meta/tinymce.html b/askbot/skins/default/templates/meta/tinymce.html
index 0f12d960..6f8a6018 100644
--- a/askbot/skins/default/templates/meta/tinymce.html
+++ b/askbot/skins/default/templates/meta/tinymce.html
@@ -10,10 +10,11 @@
oninit: function(){
tinyMCE.activeEditor.setContent(askbot['data']['editorContent'] || '');
},
+ plugins: 'askbot_imageuploader,askbot_attachment',
theme : 'advanced',
theme_advanced_toolbar_location : 'top',
theme_advanced_toolbar_align: 'left',
- theme_advanced_buttons1 : 'bold,italic,underline,|,bullist,numlist,|,undo,redo,|,link,unlink,image',
+ theme_advanced_buttons1 : 'bold,italic,underline,|,bullist,numlist,|,undo,redo,|,link,unlink,askbot_imageuploader,askbot_attachment',
theme_advanced_buttons2 : '',
theme_advanced_buttons3 : '',
theme_advanced_path: false,
@@ -38,4 +39,10 @@
height: 5px;
background: #fff;
}
+ .defaultSkin span.mce_askbot_imageuploader {
+ background-position: -380px 0px;
+ }
+ .defaultSkin span.mce_askbot_attachment {
+ background-position: -520px 0px;
+ }
</style>
diff --git a/askbot/skins/default/templates/user_profile/user_inbox.html b/askbot/skins/default/templates/user_profile/user_inbox.html
index cda45027..62dd3e24 100644
--- a/askbot/skins/default/templates/user_profile/user_inbox.html
+++ b/askbot/skins/default/templates/user_profile/user_inbox.html
@@ -94,6 +94,5 @@ inbox_section - forum|flags
setup_inbox();
});
</script>
- <script type="text/javascript" src="{{'/bootstrap/js/bootstrap.js'|media}}" />
<!-- end user_responses.html -->
{% endblock %}
diff --git a/askbot/skins/default/templates/users.html b/askbot/skins/default/templates/users.html
index 96598b1f..4797f67e 100644
--- a/askbot/skins/default/templates/users.html
+++ b/askbot/skins/default/templates/users.html
@@ -2,11 +2,6 @@
{% import "macros.html" as macros %}
<!-- users.html -->
{% block title %}{% spaceless %}{% trans %}Users{% endtrans %}{% endspaceless %}{% endblock %}
-{% block before_css %}
- {% if group and request.user.is_authenticated() and request.user.is_administrator() %}
- <link href="{{'/bootstrap/css/bootstrap.css'|media}}" rel="stylesheet" type="text/css" />
- {% endif %}
-{% endblock %}
{% block forestyle %}
<link rel="stylesheet" type="text/css" href="{{"/js/wmd/wmd.css"|media}}" />
{% endblock %}
@@ -84,7 +79,6 @@
askbot['urls']['delete_group_logo_url'] = '{% url delete_group_logo %}';
askbot['urls']['join_or_leave_group'] = '{% url join_or_leave_group %}';
</script>
- <script type="text/javascript" src='{{"/bootstrap/js/bootstrap.js"|media}}'></script>
<script type='text/javascript' src='{{"/js/editor.js"|media}}'></script>
<script type='text/javascript' src='{{"/js/wmd/showdown.js"|media}}'></script>
<script type='text/javascript' src='{{"/js/wmd/wmd.js"|media}}'></script>
diff --git a/askbot/views/writers.py b/askbot/views/writers.py
index 58584b94..29ad229b 100644
--- a/askbot/views/writers.py
+++ b/askbot/views/writers.py
@@ -68,9 +68,8 @@ def upload(request):#ajax upload file to a question or answer
file_name_prefix = request.POST.get('file_name_prefix', '')
if file_name_prefix not in ('', 'group_logo_'):
raise exceptions.PermissionDenied('invalid upload file name prefix')
-
- # check file type
- f = request.FILES['file-upload']
+
+ f = request.FILES['file-upload']#take first file
#todo: extension checking should be replaced with mimetype checking
#and this must be part of the form validation
file_extension = os.path.splitext(f.name)[1].lower()