Merge branch 'guange_dev' into szzh

This commit is contained in:
sw 2015-06-19 10:18:24 +08:00
commit 1c10775619
36 changed files with 675 additions and 144 deletions

View File

@ -68,6 +68,7 @@ class AttachmentsController < ApplicationController
end
def direct_download
@attachment.increment_download
send_file @attachment.diskfile, :filename => filename_for_content_disposition(@attachment.filename),
:type => detect_content_type(@attachment),
:disposition => 'attachment' #inline can open in browser
@ -78,7 +79,6 @@ class AttachmentsController < ApplicationController
# 下载添加权限设置
candown = attachment_candown @attachment
if candown || User.current.admin? || User.current.id == @attachment.author_id
@attachment.increment_download
if stale?(:etag => @attachment.digest)
if params[:preview] == 'true'
convered_file = @attachment.diskfile

View File

@ -695,21 +695,28 @@ class CoursesController < ApplicationController
# 显示老师和助教的活动
# @authors = searchTeacherAndAssistant(@course)
@authors = course_all_member(@course)
Dir.glob("#{Rails.root}/app/models/*.rb").sort.each { |file| require file }
events = []
@authors.each do |author|
@activity = Redmine::Activity::Fetcher.new(User.current, :course => @course,
:with_subprojects => false,
:author => author.user)
key = "course_events_#{@course.id}".to_sym
if Rails.env.production? && Setting.course_cahce_enabled?
events = Rails.cache.read(key) || []
end
if events.empty?
@authors.each do |author|
@activity = Redmine::Activity::Fetcher.new(User.current, :course => @course,
:with_subprojects => false,
:author => author.user)
@activity.scope_select {|t| has["show_#{t}"]}
# modify by nwb
# 添加私密性判断
if User.current.member_of_course?(@course)|| User.current.admin?
events += @activity.events(@days, @course.created_at)
else
events += @activity.events(@days, @course.created_at, :is_public => 1)
@activity.scope_select {|t| has["show_#{t}"]}
# modify by nwb
# 添加私密性判断
if User.current.member_of_course?(@course)|| User.current.admin?
events += @activity.events(@days, @course.created_at)
else
events += @activity.events(@days, @course.created_at, :is_public => 1)
end
end
Rails.cache.write(key, events) if Rails.env.production? && Setting.course_cahce_enabled?
end
else
# @author = @course.teacher

View File

@ -219,7 +219,7 @@ class WelcomeController < ApplicationController
# 判断网站的入口,是课程 course 则跳过index去渲染 course 方法
def entry_select
url = request.original_url.gsub('/','')
if url.include?(Setting.host_course.gsub('/',''))
if url.include?(Setting.url_course.gsub('/',''))
if @first_page.show_course == 1
course
render :course
@ -228,7 +228,7 @@ class WelcomeController < ApplicationController
end
return 0
elsif url.include?(Setting.host_contest.gsub('/',''))
elsif url.include?(Setting.url_contest.gsub('/',''))
if @first_page.show_contest == 1
contest
render :contest
@ -237,7 +237,7 @@ class WelcomeController < ApplicationController
end
return 0
elsif url.include?(Setting.host_user.gsub('/',''))
elsif url.include?(Setting.url_user.gsub('/',''))
#redirect_to(:controller => "users", :action => "index")
end

View File

@ -2330,4 +2330,11 @@ module ApplicationHelper
def cur_user_works_for_homework homework
homework.student_works.where("user_id = ?",User.current).first
end
def file_preview_tag(file, html_options={})
if %w(pdf pptx doc docx xls xlsx).any?{|x| file.filename.downcase.end_with?(x)}
link_to '预览', download_named_attachment_path(file.id, file.filename, preview: true),html_options
end
end
end

View File

@ -5,4 +5,6 @@ class Activity < ActiveRecord::Base
validates :act_id, presence: true
validates :act_type, presence: true
validates :user_id, presence: true
include Trustie::Cache::ClearCourseEvent
end

View File

@ -19,4 +19,5 @@ class ForgeActivity < ActiveRecord::Base
validates :project_id,presence: true
validates :forge_act_id,presence: true
validates :forge_act_type, presence: true
end

View File

@ -1,4 +1,4 @@
<%= javascript_include_tag "/assets/kindeditor/kindeditor" %>
<%= javascript_include_tag "/assets/kindeditor/kindeditor",'/assets/kindeditor/pasteimg' %>
<%= labelled_form_for @bid,:html => { :multipart => true } do |f| %>
<%= render :partial => 'new_homework_form', :locals => { :bid => @bid, :bid_id => "edit_bid_#{@bid.id}",:f=>f,:edit_mode => true} %>
<% end %>
<% end %>

View File

@ -34,7 +34,7 @@
else if (window.attachEvent)
window.attachEvent("onload", buildsubmenus)
</script>
<%= javascript_include_tag "/assets/kindeditor/kindeditor" %>
<%= javascript_include_tag "/assets/kindeditor/kindeditor",'/assets/kindeditor/pasteimg' %>
<%#= javascript_include_tag "/assets/kindeditor/kindeditor-min" %>
<% if @project %>
@ -228,4 +228,4 @@ function nh_init_board(params){
}
</script>
</script>

View File

@ -11,7 +11,7 @@
div.recall_con{width:570px;}
div.recall_con .reply_btn{margin-left:525px;margin-top:5px;}
</style>
<%= javascript_include_tag "/assets/kindeditor/kindeditor" %>
<%= javascript_include_tag "/assets/kindeditor/kindeditor",'/assets/kindeditor/pasteimg' %>
<div class="msg_box fl" id='leave-message' nhname="new_message">
<%# reply_allow = JournalsForMessage.create_by_user? User.current %>
<h4><%= l(:label_leave_message) %></h4>
@ -208,4 +208,4 @@
});
});
});
</script>
</script>

View File

@ -126,4 +126,4 @@
});
nh_new_notify_count_show();
});
</script>
</script>

View File

@ -25,7 +25,9 @@
<% if file.is_public? || User.current.member_of_course?(course) %>
<div class="re_con_box" id="container_files_<%= file.id %>">
<div class="">
<%= link_to truncate(file.filename,length: 35, omission: '...'), download_named_attachment_path(file.id, file.filename, preview: true),:title => file.filename+"\n"+file.description.to_s, :style => "overflow: hidden; white-space: nowrap;text-overflow: ellipsis;",:class => "c_dblue f_14 f_b f_l" %>
<%= link_to truncate(file.filename,length: 35, omission: '...'),
download_named_attachment_path(file.id, file.filename),
:title => file.filename+"\n"+file.description.to_s, :style => "overflow: hidden; white-space: nowrap;text-overflow: ellipsis;",:class => "c_dblue f_14 f_b f_l" %>
<% if User.current.logged? %>
<% if (is_course_teacher(User.current,@course) || file.author_id == User.current.id) && course_contains_attachment?(@course,file) %>
<%= link_to("选入我的其他课程",quote_resource_show_course_file_path(@course,file),:class => "f_l re_select c_lorange",:remote => true) if has_course?(User.current,file) %>
@ -40,7 +42,7 @@
<% else %>
<%= link_to("选入我的课程",quote_resource_show_course_file_path(@course,file),:class => "f_l re_select c_lorange",:remote => true) if has_course?(User.current,file) %>
<% end %>
<%= link_to_attachment file, text: '下载', class: 'f_l re_open' %>
<%= file_preview_tag(file, class: 'f_l re_open') %>
<% else %>
<% end %>
</div>

View File

@ -18,7 +18,9 @@
<% project_attachments.each do |file| %>
<div class="re_con_box">
<div class="">
<%= link_to truncate(file.filename,length: 35, omission: '...'), download_named_attachment_path(file.id, file.filename, preview: true),:title => file.filename+"\n"+file.description.to_s, :style => "overflow: hidden; white-space: nowrap;text-overflow: ellipsis;",:class => "c_dblue f_14 f_b f_l" %>
<%= link_to truncate(file.filename,length: 35, omission: '...'),
download_named_attachment_path(file.id, file.filename),
:title => file.filename+"\n"+file.description.to_s, :style => "overflow: hidden; white-space: nowrap;text-overflow: ellipsis;",:class => "c_dblue f_14 f_b f_l" %>
<% if User.current.logged? %>
<% if (manage_allowed || file.author_id == User.current.id) && project_contains_attachment?(project,file) %>
<%= link_to(l(:label_slected_to_other_project),quote_resource_show_project_project_file_path(project,file),:class => "f_l re_select",:remote => true) if has_project?(User.current,file) %>
@ -30,7 +32,7 @@
<% else %>
<%= link_to(l(:label_slected_to_project),quote_resource_show_project_project_file_path(project,file),:class => "f_l re_select",:remote => true) if has_project?(User.current,file) %>
<% end %>
<%= link_to_attachment file, text: '下载', class: 'f_l re_open' %>
<%= file_preview_tag(file, class: 'f_l re_open') %>
<% end %>
</div>
<div class="cl"></div>

View File

@ -1,4 +1,4 @@
<!-- added by fq -->
<h1>编辑讨论区</h1>
<%= javascript_include_tag "/assets/kindeditor/kindeditor" %>
<%= javascript_include_tag "/assets/kindeditor/kindeditor",'/assets/kindeditor/pasteimg' %>
<%= render 'form_edit_mode' %>

View File

@ -5,7 +5,7 @@
<% @nav_dispaly_forum_label = 1%>
<!-- added by fq -->
<h1 style="margin-top: 2%; margin-left: 49%"><%= l :label_forum_new %></h1>
<%= javascript_include_tag "/assets/kindeditor/kindeditor" %>
<%= javascript_include_tag "/assets/kindeditor/kindeditor",'/assets/kindeditor/pasteimg' %>
<%= render 'form_create_mode' %>
<%#= link_to l(:button_back), forums_path %>

View File

@ -1,4 +1,4 @@
<%= javascript_include_tag "/assets/kindeditor/kindeditor" %>
<%= javascript_include_tag "/assets/kindeditor/kindeditor",'/assets/kindeditor/pasteimg' %>
<%= error_messages_for 'homework_common' %>
<div class="project_r_h">
@ -13,4 +13,4 @@
<%= link_to '取消',homework_common_index_path(:course => @course.id),:class => 'grey_btn fl'%>
<% end%>
</div><!--hwork_new end-->
<div class="cl"></div>
<div class="cl"></div>

View File

@ -1,4 +1,4 @@
<%= javascript_include_tag "/assets/kindeditor/kindeditor" %>
<%= javascript_include_tag "/assets/kindeditor/kindeditor",'/assets/kindeditor/pasteimg' %>
<%= error_messages_for 'homework_common' %>
<div class="project_r_h">
@ -14,4 +14,4 @@
<%= link_to '取消',homework_common_index_path(:course => @course.id),:class => 'grey_btn fl'%>
<% end%>
</div><!--hwork_new end-->
<div class="cl"></div>
<div class="cl"></div>

View File

@ -1,4 +1,4 @@
<%= javascript_include_tag "/assets/kindeditor/kindeditor" %>
<%= javascript_include_tag "/assets/kindeditor/kindeditor",'/assets/kindeditor/pasteimg' %>
<div class="project_r_h" xmlns="http://www.w3.org/1999/html">
<h2 class="project_h2"><%= l(:label_issue_new) %></h2>
</div>

View File

@ -1,4 +1,4 @@
<%= javascript_include_tag "/assets/kindeditor/kindeditor" %>
<%= javascript_include_tag "/assets/kindeditor/kindeditor",'/assets/kindeditor/pasteimg' %>
<div class="project_r_h">
<h2 class="project_h2"><%= l(:label_issue_edit) %></h2>
</div>

View File

@ -12,10 +12,10 @@
<meta name="keywords" content="issue,bug,tracker" />
<%= csrf_meta_tag %>
<%= favicon %>
<%= javascript_include_tag "/assets/kindeditor/kindeditor" %>
<%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2', 'application', 'nyan', :media => 'all' %>
<%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %>
<%= javascript_heads %>
<%= javascript_include_tag "/assets/kindeditor/kindeditor",'/assets/kindeditor/pasteimg' %>
<%= heads_for_theme %>
<%= call_hook :view_layouts_base_html_head %>

View File

@ -1,6 +1,6 @@
<!-- <h1>New memo</h1> -->
<% @replying = !@memo.parent.nil? %>
<%= javascript_include_tag "/assets/kindeditor/kindeditor" %>
<%= javascript_include_tag "/assets/kindeditor/kindeditor",'/assets/kindeditor/pasteimg' %>
<h3><%=l(:label_memo_edit)%></h3>
<%= labelled_form_for(@memo, :url => forum_memo_path(@memo.forum_id, @memo)) do |f| %>
<% if @memo.errors.any? %>

View File

@ -4,7 +4,7 @@
@nav_dispaly_main_contest_label = 1 %>
<% @nav_dispaly_forum_label = 1%>
<!-- <h1>New memo</h1> -->
<%= javascript_include_tag "/assets/kindeditor/kindeditor" %>
<%= javascript_include_tag "/assets/kindeditor/kindeditor",'/assets/kindeditor/pasteimg' %>
<div class="top-content">
<table>
<tr>

View File

@ -4,7 +4,7 @@
margin-bottom: 13px;
}
</style>
<%= javascript_include_tag "/assets/kindeditor/kindeditor" %>
<%= javascript_include_tag "/assets/kindeditor/kindeditor",'/assets/kindeditor/pasteimg' %>
<div class="lz">
<!-- 在这里添加赞和踩-->
<span id="praise_tread" style="float: right"> <%= render :partial => "/praise_tread/praise_tread",:locals => {:obj => @memo,:show_flag => true,:user_id =>User.current.id,:horizontal => true}%> </span>

View File

@ -1,4 +1,4 @@
<%= javascript_include_tag "/assets/kindeditor/kindeditor" %>
<%= javascript_include_tag "/assets/kindeditor/kindeditor",'/assets/kindeditor/pasteimg' %>
<%= error_messages_for 'message' %>
<% replying ||= false %>
<% extra_option = replying ? { hidden: "hidden"} : { maxlength: 200 } %>

View File

@ -1,4 +1,4 @@
<%= javascript_include_tag "/assets/kindeditor/kindeditor" %>
<%= javascript_include_tag "/assets/kindeditor/kindeditor",'/assets/kindeditor/pasteimg' %>
<li>
<label><span class="c_red">*</span>&nbsp;<%= l(:field_title) %>&nbsp;&nbsp;</label>
<input type="text" name="news[title]" class="hwork_input" id="news_title" size="60" onkeyup="regexTitle();" maxlength="60" placeholder="60个字符以内" value="<%= is_new ? '' : @news.title %>">
@ -37,4 +37,4 @@
<% end %>
<div class="cl"></div>
</li>
<!-- <#%= wikitoolbar_for 'news_description'%>-->
<!-- <#%= wikitoolbar_for 'news_description'%>-->

View File

@ -1,4 +1,4 @@
<%= javascript_include_tag "/assets/kindeditor/kindeditor" %>
<%= javascript_include_tag "/assets/kindeditor/kindeditor",'/assets/kindeditor/pasteimg' %>
<div class="project_r_h">
<h2 class="project_h2"><%= l(:label_course_news) %></h2>
</div>
@ -76,4 +76,4 @@
<% end %>
<% html_title @news.title -%>
<% html_title @news.title -%>

View File

@ -1,4 +1,4 @@
<%= javascript_include_tag "/assets/kindeditor/kindeditor" %>
<%= javascript_include_tag "/assets/kindeditor/kindeditor",'/assets/kindeditor/pasteimg' %>
<li>
<label><span class="c_red">*</span>&nbsp;<%= l(:field_title) %>&nbsp;&nbsp;</label>
<input type="text" name="news[title]" class="hwork_input_news" id="news_title" width="576px" onkeyup="regexTitle();" maxlength="60" placeholder="60个字符以内" value="<%= is_new ? '' : @news.title %>">
@ -33,4 +33,4 @@
<% end %>
<div class="cl"></div>
</li>
<!-- <#%= wikitoolbar_for 'news_description'%>-->
<!-- <#%= wikitoolbar_for 'news_description'%>-->

View File

@ -1,4 +1,4 @@
<%= javascript_include_tag "/assets/kindeditor/kindeditor" %>
<%= javascript_include_tag "/assets/kindeditor/kindeditor",'/assets/kindeditor/pasteimg' %>
<div class="project_r_h">
<h2 class="project_h2"><%= l(:label_course_news) %></h2>
</div>
@ -8,4 +8,4 @@
<%= render :partial => 'course_form', :locals => { :f => f, :is_new => false } %>
<% end %>
<div id="preview" class="wiki"></div>
</div>
</div>

View File

@ -11,7 +11,7 @@
div.recall_con{width:570px;}
div.recall_con .reply_btn{margin-left:525px;margin-top:5px;}
</style>
<%= javascript_include_tag "/assets/kindeditor/kindeditor" %>
<%= javascript_include_tag "/assets/kindeditor/kindeditor",'/assets/kindeditor/pasteimg' %>
<div class="msg_box" id='leave-message' nhname='new_message' style="height:auto;">
<% reply_allow = JournalsForMessage.create_by_user? User.current %>
<h4><%= l(:label_user_response) %></h4>
@ -197,4 +197,4 @@
});
});
});
</script>
</script>

View File

@ -12,7 +12,7 @@
<!--</div>-->
<div class="hwork_ctt">
<div class="hwork_dis" id="tbc_01">
<%= labelled_form_for @work do |f|%>
<%= labelled_form_for @work,:html => { :multipart => true } do |f|%>
<div class="N_con">
<p>
<label class="fl"><span class="c_red">*</span>&nbsp;&nbsp;作品名称&nbsp;&nbsp;&nbsp;&nbsp;</label>
@ -57,4 +57,4 @@
</div>
</div>
</div><!--新建作业结束-->
<div class="cl"></div>
<div class="cl"></div>

View File

@ -11,7 +11,7 @@
div.recall_con{width:600px;}
div.recall_con .reply_btn{margin-left:555px;margin-top:5px;}
</style>
<%= javascript_include_tag "/assets/kindeditor/kindeditor" %>
<%= javascript_include_tag "/assets/kindeditor/kindeditor",'/assets/kindeditor/pasteimg' %>
<div class="dis">
<div class="msg_box" id='leave-message'>
<% reply_allow = JournalsForMessage.create_by_user? User.current %>

View File

@ -66,7 +66,8 @@ upload_avatar_max_size:
### delayjob for send email.
delayjob_enabled:
default: 1
course_cahce_enabled:
default: 1
bcc_recipients:
default: 1
plain_text_mail:
@ -89,6 +90,12 @@ host_user:
default: user.trustie.net
host_repository:
default: repository.trustie.net
url_course:
default: course.trustie.net
url_contest:
default: contest.trustie.net
url_user:
default: user.trustie.net
protocol:
default: http
feeds_limit:

View File

@ -16,7 +16,8 @@ module RailsKindeditor
input_html = input_html.merge(style: 'display:none')
output_buffer = ActiveSupport::SafeBuffer.new
output_buffer << build_text_area_tag(name, method, self, options, input_html)
output_buffer << javascript_tag(js_replace(input_html['id'],options.merge(window_onload: 'true')))
output_buffer << javascript_tag(js_replace(input_html['id'],options.merge(window_onload: 'true',
afterCreate: 'eval(function(){enablePasteImg(self);})')))
end
def kindeditor_upload_json_path(*args)
@ -52,12 +53,12 @@ module RailsKindeditor
"var old_onload_#{random_name};
if(typeof window.onload == 'function') old_onload_#{random_name} = window.onload;
window.onload = function() {
#{editor_id}KindEditor.create('##{dom_id}', #{get_options(options).to_json}).loadPlugin('paste');
#{editor_id}KindEditor.create('##{dom_id}', #{get_options(options).to_json});
if(old_onload_#{random_name}) old_onload_#{random_name}();
}"
else
"KindEditor.ready(function(K){
#{editor_id}K.create('##{dom_id}', #{get_options(options).to_json}).loadPlugin('paste');
#{editor_id}K.create('##{dom_id}', #{get_options(options).to_json});
});"
end
end

31
lib/trustie/cache/clear_course_event.rb vendored Normal file
View File

@ -0,0 +1,31 @@
#coding=utf-8
module Trustie
module Cache
module ClearCourseEvent
def self.included(base)
base.class_eval{
after_create :clear_course_events
}
end
def clear_course_events
if Rails.env.production? && Setting.course_cahce_enabled?
Rails.cache.delete(cache_key)
end
end
def cache_key
course_id = nil
if Message === self.act
course_id = self.act.board.course_id
elsif self.act.respond_to?(:course_id)
course_id = self.act.course_id
end
"course_events_#{course_id}".to_sym
end
end
end
end

View File

@ -5097,6 +5097,9 @@ KEditor.prototype = {
}
self.afterCreate();
if (self.options.afterCreate) {
if (typeof self.options.afterCreate == 'string'){
self.options.afterCreate = eval(self.options.afterCreate);
}
self.options.afterCreate.call(self);
}
}

View File

@ -0,0 +1,385 @@
// Generated by CoffeeScript 1.9.0
/*
paste.js is an interface to read data ( text / image ) from clipboard in different browsers. It also contains several hacks.
https://github.com/layerssss/paste.js
*/
(function() {
var $, Paste, createHiddenEditable, dataURLtoBlob;
$ = window.jQuery;
$.paste = function(pasteContainer) {
var pm;
if (typeof console !== "undefined" && console !== null) {
console.log("DEPRECATED: This method is deprecated. Please use $.fn.pastableNonInputable() instead.");
}
pm = Paste.mountNonInputable(pasteContainer);
return pm._container;
};
$.fn.pastableNonInputable = function() {
var el, _i, _len;
for (_i = 0, _len = this.length; _i < _len; _i++) {
el = this[_i];
Paste.mountNonInputable(el);
}
return this;
};
$.fn.pastableTextarea = function() {
var el, _i, _len;
for (_i = 0, _len = this.length; _i < _len; _i++) {
el = this[_i];
Paste.mountTextarea(el);
}
return this;
};
$.fn.pastableContenteditable = function() {
var el, _i, _len;
for (_i = 0, _len = this.length; _i < _len; _i++) {
el = this[_i];
Paste.mountContenteditable(el);
}
return this;
};
dataURLtoBlob = function(dataURL, sliceSize) {
var b64Data, byteArray, byteArrays, byteCharacters, byteNumbers, contentType, i, m, offset, slice, _ref;
if (sliceSize == null) {
sliceSize = 512;
}
if (!(m = dataURL.match(/^data\:([^\;]+)\;base64\,(.+)$/))) {
return null;
}
_ref = m, m = _ref[0], contentType = _ref[1], b64Data = _ref[2];
byteCharacters = atob(b64Data);
byteArrays = [];
offset = 0;
while (offset < byteCharacters.length) {
slice = byteCharacters.slice(offset, offset + sliceSize);
byteNumbers = new Array(slice.length);
i = 0;
while (i < slice.length) {
byteNumbers[i] = slice.charCodeAt(i);
i++;
}
byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
offset += sliceSize;
}
return new Blob(byteArrays, {
type: contentType
});
};
createHiddenEditable = function() {
return $(document.createElement('div')).attr('contenteditable', true).css({
width: 1,
height: 1,
position: 'fixed',
left: -100,
overflow: 'hidden'
});
};
Paste = (function() {
Paste.prototype._target = null;
Paste.prototype._container = null;
Paste.mountNonInputable = function(nonInputable) {
var paste;
paste = new Paste(createHiddenEditable().appendTo(nonInputable), nonInputable);
$(nonInputable).on('click', (function(_this) {
return function() {
return paste._container.focus();
};
})(this));
paste._container.on('focus', (function(_this) {
return function() {
return $(nonInputable).addClass('pastable-focus');
};
})(this));
return paste._container.on('blur', (function(_this) {
return function() {
return $(nonInputable).removeClass('pastable-focus');
};
})(this));
};
Paste.mountTextarea = function(textarea) {
var ctlDown, paste;
if (-1 !== navigator.userAgent.toLowerCase().indexOf('chrome')) {
return this.mountContenteditable(textarea);
}
paste = new Paste(createHiddenEditable().insertBefore(textarea), textarea);
ctlDown = false;
$(textarea).on('keyup', function(ev) {
var _ref;
if ((_ref = ev.keyCode) === 17 || _ref === 224) {
return ctlDown = false;
}
});
$(textarea).on('keydown', function(ev) {
var _ref;
if ((_ref = ev.keyCode) === 17 || _ref === 224) {
ctlDown = true;
}
if (ctlDown && ev.keyCode === 86) {
return paste._container.focus();
}
});
$(paste._target).on('pasteImage', (function(_this) {
return function() {
return $(textarea).focus();
};
})(this));
$(paste._target).on('pasteText', (function(_this) {
return function() {
return $(textarea).focus();
};
})(this));
$(textarea).on('focus', (function(_this) {
return function() {
return $(textarea).addClass('pastable-focus');
};
})(this));
return $(textarea).on('blur', (function(_this) {
return function() {
return $(textarea).removeClass('pastable-focus');
};
})(this));
};
Paste.mountContenteditable = function(contenteditable) {
var paste;
paste = new Paste(contenteditable, contenteditable);
$(contenteditable).on('focus', (function(_this) {
return function() {
return $(contenteditable).addClass('pastable-focus');
};
})(this));
return $(contenteditable).on('blur', (function(_this) {
return function() {
return $(contenteditable).removeClass('pastable-focus');
};
})(this));
};
function Paste(_at__container, _at__target) {
this._container = _at__container;
this._target = _at__target;
this._container = $(this._container);
this._target = $(this._target).addClass('pastable');
this._container.on('paste', (function(_this) {
return function(ev) {
var clipboardData, file, item, reader, text, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3, _results;
if (((_ref = ev.originalEvent) != null ? _ref.clipboardData : void 0) != null) {
clipboardData = ev.originalEvent.clipboardData;
if (clipboardData.items) {
_ref1 = clipboardData.items;
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
item = _ref1[_i];
if (item.type.match(/^image\//)) {
reader = new FileReader();
reader.onload = function(event) {
return _this._handleImage(event.target.result);
};
reader.readAsDataURL(item.getAsFile());
}
if (item.type === 'text/plain') {
item.getAsString(function(string) {
return _this._target.trigger('pasteText', {
text: string
});
});
}
}
} else {
if (-1 !== Array.prototype.indexOf.call(clipboardData.types, 'text/plain')) {
text = clipboardData.getData('Text');
_this._target.trigger('pasteText', {
text: text
});
}
_this._checkImagesInContainer(function(src) {
return _this._handleImage(src);
});
}
}
if (clipboardData = window.clipboardData) {
if ((_ref2 = (text = clipboardData.getData('Text'))) != null ? _ref2.length : void 0) {
return _this._target.trigger('pasteText', {
text: text
});
} else {
_ref3 = clipboardData.files;
_results = [];
for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
file = _ref3[_j];
_this._handleImage(URL.createObjectURL(file));
_results.push(_this._checkImagesInContainer(function() {}));
}
return _results;
}
}
};
})(this));
}
Paste.prototype._handleImage = function(src) {
var loader;
loader = new Image();
loader.onload = (function(_this) {
return function() {
var blob, canvas, ctx, dataURL;
canvas = document.createElement('canvas');
canvas.width = loader.width;
canvas.height = loader.height;
ctx = canvas.getContext('2d');
ctx.drawImage(loader, 0, 0, canvas.width, canvas.height);
dataURL = null;
try {
dataURL = canvas.toDataURL('image/png');
blob = dataURLtoBlob(dataURL);
} catch (_error) {}
if (dataURL) {
return _this._target.trigger('pasteImage', {
blob: blob,
dataURL: dataURL,
width: loader.width,
height: loader.height
});
}
};
})(this);
return loader.src = src;
};
Paste.prototype._checkImagesInContainer = function(cb) {
var img, timespan, _i, _len, _ref;
timespan = Math.floor(1000 * Math.random());
_ref = this._container.find('img');
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
img = _ref[_i];
img["_paste_marked_" + timespan] = true;
}
return setTimeout((function(_this) {
return function() {
var _j, _len1, _ref1, _results;
_ref1 = _this._container.find('img');
_results = [];
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
img = _ref1[_j];
if (!img["_paste_marked_" + timespan]) {
cb(img.src);
}
_results.push($(img).remove());
}
return _results;
};
})(this), 1);
};
return Paste;
})();
}).call(this);
function enablePasteImg(_editor) {
var editor = _editor,
name = 'paste';
//这样貌似多编辑器就不会冲突了
if(editor.edit == undefined || editor.edit.iframe == undefined){
return;
}
var contentWindow = editor.edit.iframe[0].contentWindow;
//var contentWindow = editor.iframeDoc;
//var contentWindow = document.getElementsByTagName('iframe')[0].contentWindow;
var nodeBody = contentWindow.document.getElementsByTagName('body')[0];
console.log(nodeBody);
$(nodeBody).pastableContenteditable();
dataURItoBlob = function(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0)
byteString = atob(dataURI.split(',')[1]);
else
byteString = unescape(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to a typed array
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {type:mimeString});
};
$(nodeBody).on('pasteImage', function(ev, data) {
console.log('pasteImage');
console.log("dataURL: " + data.dataURL);
console.log("width: " + data.width);
console.log("height: " + data.height);
console.log(data.blob);
var blob = dataURItoBlob(data.dataURL);
if (data.blob !== null) {
var data = new FormData();
data.append("imgFile",blob, "imageFilename.png");
console.log(data);
$.ajax({
url: '/kindeditor/upload?dir=image',
contentType: false,
type: 'POST',
data: data,
processData: false,
success: function(data) {
editor.exec('insertimage', JSON.parse(data).url);
}
});
}
});
return;
contentWindow.document.getElementsByTagName('body')[0].onpaste = function(event) {
// use event.originalEvent.clipboard for newer chrome versions
var items = (event.clipboardData || event.originalEvent.clipboardData).items;
console.log(JSON.stringify(items)); // will give you the mime types
// find pasted image among pasted items
var blob = null;
for (var i = 0; i < items.length; i++) {
if (items[i].type.indexOf("image") === 0) {
blob = items[i].getAsFile();
}
}
// load image if there is a pasted image
if (blob !== null) {
var reader = new FileReader();
reader.onload = function(event) {
console.log(event.target.result); // data url!
var data = new FormData();
data.append("imgFile", blob, "imageFilename.png");
console.log(blob);
$.ajax({
url: '/kindeditor/upload?dir=image',
contentType: false,
type: 'POST',
data: data,
processData: false,
success: function(data) {
editor.exec('insertimage', JSON.parse(data).url);
}
});
};
reader.readAsDataURL(blob);
}
}
};

View File

@ -1,8 +1,7 @@
/* Redmine - project management software
Copyright (C) 2006-2013 Jean-Philippe Lang */
function postUpMsg(attachmentId)
{
function postUpMsg(attachmentId) {
$.ajax({
url: '/attachments/renderTag',
type: "GET",
@ -30,28 +29,57 @@ function addFile_board(inputEl, file, eagerUpload, id) {
deleteallfiles = $(inputEl).data('deleteAllFiles');
var attachmentId = addFile.nextAttachmentId++;
var fileSpan = $('<span>', { 'id': 'attachments_' + attachmentId, 'class':'attachment' });
var fileSpan = $('<span>', {
'id': 'attachments_' + attachmentId,
'class': 'attachment'
});
fileSpan.append(
$('<input>', { 'type': 'text', 'class': 'filename readonly', 'name': 'attachments[' + attachmentId + '][filename]', 'readonly': 'readonly'} ).val(file.name),
$('<input>', { 'type': 'text', 'class': 'description', 'name': 'attachments[' + attachmentId + '][description]', 'maxlength': 254, 'placeholder': $(inputEl).data('descriptionPlaceholder') } ).toggle(!eagerUpload),
$('<span >'+$(inputEl).data('fieldIsPublic')+':</span>').attr({ 'class': 'ispublic-label' }) ,
$('<input>', { 'type': 'checkbox', 'class': 'is_public_checkbox','value':1, 'name': 'attachments[' + attachmentId + '][is_public_checkbox]', checked:'checked' } ).toggle(!eagerUpload),
$('<a>&nbsp</a>').attr({ 'href': "#", 'class': 'remove-upload', 'data-containerid':id }).click(function(){
if(confirm($(inputEl).data('areYouSure'))){
$('<input>', {
'type': 'text',
'class': 'filename readonly',
'name': 'attachments[' + attachmentId + '][filename]',
'readonly': 'readonly'
}).val(file.name),
$('<input>', {
'type': 'text',
'class': 'description',
'name': 'attachments[' + attachmentId + '][description]',
'maxlength': 254,
'placeholder': $(inputEl).data('descriptionPlaceholder')
}).toggle(!eagerUpload),
$('<span >' + $(inputEl).data('fieldIsPublic') + ':</span>').attr({
'class': 'ispublic-label'
}),
$('<input>', {
'type': 'checkbox',
'class': 'is_public_checkbox',
'value': 1,
'name': 'attachments[' + attachmentId + '][is_public_checkbox]',
checked: 'checked'
}).toggle(!eagerUpload),
$('<a>&nbsp</a>').attr({
'href': "#",
'class': 'remove-upload',
'data-containerid': id
}).click(function() {
if (confirm($(inputEl).data('areYouSure'))) {
removeFile();
if(!eagerUpload){
(function(e){
if (!eagerUpload) {
(function(e) {
reload(e);
})(fileSpan);
}
}
}).toggle(!eagerUpload),
$('<div>', { 'class': 'div_attachments', 'name': 'div_'+'attachments_' + attachmentId} )
$('<div>', {
'class': 'div_attachments',
'name': 'div_' + 'attachments_' + attachmentId
})
).appendTo(attachments_frame);
if(eagerUpload) {
if (eagerUpload) {
ajaxUpload(file, attachmentId, fileSpan, inputEl);
}
@ -59,6 +87,7 @@ function addFile_board(inputEl, file, eagerUpload, id) {
}
return null;
}
function addFile(inputEl, file, eagerUpload) {
var attachments_frame = '#attachments_fields';
@ -66,28 +95,56 @@ function addFile(inputEl, file, eagerUpload) {
deleteallfiles = $(inputEl).data('deleteAllFiles');
var attachmentId = addFile.nextAttachmentId++;
var fileSpan = $('<span>', { 'id': 'attachments_' + attachmentId, 'class':'attachment' });
var fileSpan = $('<span>', {
'id': 'attachments_' + attachmentId,
'class': 'attachment'
});
fileSpan.append(
$('<input>', { 'type': 'text', 'class': 'filename readonly', 'name': 'attachments[' + attachmentId + '][filename]', 'readonly': 'readonly'} ).val(file.name),
$('<input>', { 'type': 'text', 'class': 'description', 'name': 'attachments[' + attachmentId + '][description]', 'maxlength': 254, 'placeholder': $(inputEl).data('descriptionPlaceholder') } ).toggle(!eagerUpload),
$('<span >'+$(inputEl).data('fieldIsPublic')+':</span>').attr({ 'class': 'ispublic-label' }) ,
$('<input>', { 'type': 'checkbox', 'class': 'is_public_checkbox','value':1, 'name': 'attachments[' + attachmentId + '][is_public_checkbox]', checked:'checked' } ).toggle(!eagerUpload),
$('<a>&nbsp</a>').attr({ 'href': "#", 'class': 'remove-upload' }).click(function(){
if(confirm($(inputEl).data('areYouSure'))){
$('<input>', {
'type': 'text',
'class': 'filename readonly',
'name': 'attachments[' + attachmentId + '][filename]',
'readonly': 'readonly'
}).val(file.name),
$('<input>', {
'type': 'text',
'class': 'description',
'name': 'attachments[' + attachmentId + '][description]',
'maxlength': 254,
'placeholder': $(inputEl).data('descriptionPlaceholder')
}).toggle(!eagerUpload),
$('<span >' + $(inputEl).data('fieldIsPublic') + ':</span>').attr({
'class': 'ispublic-label'
}),
$('<input>', {
'type': 'checkbox',
'class': 'is_public_checkbox',
'value': 1,
'name': 'attachments[' + attachmentId + '][is_public_checkbox]',
checked: 'checked'
}).toggle(!eagerUpload),
$('<a>&nbsp</a>').attr({
'href': "#",
'class': 'remove-upload'
}).click(function() {
if (confirm($(inputEl).data('areYouSure'))) {
removeFile();
if(!eagerUpload){
(function(e){
if (!eagerUpload) {
(function(e) {
reload(e);
})(fileSpan);
}
}
}).toggle(!eagerUpload),
$('<div>', { 'class': 'div_attachments', 'name': 'div_'+'attachments_' + attachmentId} )
$('<div>', {
'class': 'div_attachments',
'name': 'div_' + 'attachments_' + attachmentId
})
).appendTo('#attachments_fields');
if(eagerUpload) {
if (eagerUpload) {
ajaxUpload(file, attachmentId, fileSpan, inputEl);
}
@ -106,8 +163,8 @@ function ajaxUpload(file, attachmentId, fileSpan, inputEl) {
}
function onProgress(e) {
if(e.lengthComputable) {
this.progressbar( 'value', e.loaded * 100 / e.total );
if (e.lengthComputable) {
this.progressbar('value', e.loaded * 100 / e.total);
}
}
@ -116,18 +173,17 @@ function ajaxUpload(file, attachmentId, fileSpan, inputEl) {
ajaxUpload.uploading++;
uploadBlob(file, $(inputEl).data('upload-path'), attachmentId, {
loadstartEventHandler: onLoadstart.bind(progressSpan),
progressEventHandler: onProgress.bind(progressSpan)
})
loadstartEventHandler: onLoadstart.bind(progressSpan),
progressEventHandler: onProgress.bind(progressSpan)
})
.done(function(result) {
progressSpan.progressbar( 'value', 100 ).remove();
progressSpan.progressbar('value', 100).remove();
fileSpan.find('input.description, a').css('display', 'inline-block');
fileSpan.find('input.is_public_checkbox, a').css('display', 'inline-block');
})
.fail(function(result) {
progressSpan.text(result.statusText);
if($("#network_issue"))
{
if ($("#network_issue")) {
$("#network_issue").show();
}
}).always(function() {
@ -143,33 +199,37 @@ function ajaxUpload(file, attachmentId, fileSpan, inputEl) {
//gcm files count and add delete_all link
//modify by yutao 2015-5-14 当1个页面存在多个上传控件时此块代码存在bug 故改之 start
var containerid=$(inputEl).data('containerid');
if(containerid==undefined){
var count=$('#attachments_fields>span').length;
$('#upload_file_count').html("<span id=\"count\">"+count+"</span>"+$(inputEl).data('fileCount'));
if(count>=1){
var add_attachs=$('.add_attachment');
var delete_all=$('.remove_all');
if(delete_all.length<1){
add_attachs.append($("<a>&nbsp</a>").attr({"href":"javascript:void(0)", 'class': 'remove_all',"onclick": "removeAll()"}));
var containerid = $(inputEl).data('containerid');
if (containerid == undefined) {
var count = $('#attachments_fields>span').length;
$('#upload_file_count').html("<span id=\"count\">" + count + "</span>" + $(inputEl).data('fileCount'));
if (count >= 1) {
var add_attachs = $('.add_attachment');
var delete_all = $('.remove_all');
if (delete_all.length < 1) {
add_attachs.append($("<a>&nbsp</a>").attr({
"href": "javascript:void(0)",
'class': 'remove_all',
"onclick": "removeAll()"
}));
}
}
}else{
var count=$('#attachments_fields'+containerid+'>span').length;
$('#upload_file_count'+containerid).html("<span id=\"count\">"+count+"</span>"+$(inputEl).data('fileCount'));
if(count>=1){
var add_attachs=$('.add_attachment').filter(function(index){
return $(this).data('containerid')==containerid;
} else {
var count = $('#attachments_fields' + containerid + '>span').length;
$('#upload_file_count' + containerid).html("<span id=\"count\">" + count + "</span>" + $(inputEl).data('fileCount'));
if (count >= 1) {
var add_attachs = $('.add_attachment').filter(function(index) {
return $(this).data('containerid') == containerid;
});
var delete_all=$('.remove_all').filter(function(index){
return $(this).data('containerid')==containerid;
var delete_all = $('.remove_all').filter(function(index) {
return $(this).data('containerid') == containerid;
});
if(delete_all.length<1){
if (delete_all.length < 1) {
add_attachs.append($("<a>&nbsp</a>").attr({
"href":"javascript:void(0)",
"href": "javascript:void(0)",
'class': 'remove_all',
'data-containerid': containerid,
"onclick": "removeAll('"+containerid+"')"
"onclick": "removeAll('" + containerid + "')"
}));
}
}
@ -186,7 +246,7 @@ function ajaxUpload(file, attachmentId, fileSpan, inputEl) {
var maxSyncUpload = $(inputEl).data('max-concurrent-uploads');
if(maxSyncUpload == null || maxSyncUpload <= 0 || ajaxUpload.uploading < maxSyncUpload)
if (maxSyncUpload == null || maxSyncUpload <= 0 || ajaxUpload.uploading < maxSyncUpload)
actualUpload(file, attachmentId, fileSpan, inputEl);
else
$(inputEl).parents('form').queue('upload', actualUpload.bind(this, file, attachmentId, fileSpan, inputEl));
@ -201,23 +261,23 @@ function removeFile() {
//gcm delete all file
//modify by yutao 2015-5-14 当1个页面存在多个上传控件时此块代码存在bug 故改之 start
function removeAll(containerid){
if(confirm(deleteallfiles)){
if(containerid==undefined){
$(".remove-upload").removeAttr("data-confirm");
$(".remove-upload").click();
}else{
var arr = $(".remove-upload").filter(function(){
return $(this).data('containerid')==containerid;
});
arr.removeAttr("data-confirm");
arr.click();
function removeAll(containerid) {
if (confirm(deleteallfiles)) {
if (containerid == undefined) {
$(".remove-upload").removeAttr("data-confirm");
$(".remove-upload").click();
} else {
var arr = $(".remove-upload").filter(function() {
return $(this).data('containerid') == containerid;
});
arr.removeAttr("data-confirm");
arr.click();
}
}
// return false;
}
// return false;
}
//modify by yutao 2015-5-14 当1个页面存在多个上传控件时此块代码存在bug 故改之 end
//gcm
//modify by yutao 2015-5-14 当1个页面存在多个上传控件时此块代码存在bug 故改之 end
//gcm
function uploadBlob(blob, uploadUrl, attachmentId, options) {
@ -225,9 +285,9 @@ function uploadBlob(blob, uploadUrl, attachmentId, options) {
loadstartEventHandler: $.noop,
progressEventHandler: $.noop
}, options);
if(uploadUrl.indexOf('?') > 0){
if (uploadUrl.indexOf('?') > 0) {
uploadUrl = uploadUrl + '&attachment_id=' + attachmentId;
}else{
} else {
uploadUrl = uploadUrl + '?attachment_id=' + attachmentId;
}
if (blob instanceof window.File) {
@ -254,7 +314,6 @@ function uploadBlob(blob, uploadUrl, attachmentId, options) {
function addInputFiles(inputEl) {
// var clearedFileInput = $(inputEl).clone().val('');
if (inputEl.files) {
// upload files using ajax
uploadAndAttachFiles(inputEl.files, inputEl);
@ -263,15 +322,22 @@ function addInputFiles(inputEl) {
// browser not supporting the file API, upload on form submission
var attachmentId;
var aFilename = inputEl.value.split(/\/|\\/);
attachmentId = addFile(inputEl, { name: aFilename[ aFilename.length - 1 ] }, false);
var count = $('#attachments_fields>span').length;
attachmentId = addFile(inputEl, {
name: aFilename[aFilename.length - 1]
}, false);
if (attachmentId) {
$(inputEl).attr({ name: 'attachments[' + attachmentId + '][file]'}).hide();
$('#upload_file_count').html("<span id=\"count\">"+count+"</span>"+$(inputEl).data('fileCount'));
$(inputEl).attr({
name: 'attachments[' + attachmentId + '][file]'
}).hide();
if (count <= 0) count = 1;
$('#upload_file_count').html("<span id=\"count\">" + count + "</span>" + $(inputEl).data('fileCount'));
}
}
//clearedFileInput.insertAfter('#attachments_fields');
}
function addInputFiles_board(inputEl, id) {
// var clearedFileInput = $(inputEl).clone().val('');
@ -283,15 +349,20 @@ function addInputFiles_board(inputEl, id) {
// browser not supporting the file API, upload on form submission
var attachmentId;
var aFilename = inputEl.value.split(/\/|\\/);
attachmentId = addFile_board(inputEl, { name: aFilename[ aFilename.length - 1 ] }, false, id);
attachmentId = addFile_board(inputEl, {
name: aFilename[aFilename.length - 1]
}, false, id);
if (attachmentId) {
$(inputEl).attr({ name: 'attachments[' + attachmentId + '][file]'}).hide();
$('#upload_file_count').html("<span id=\"count\">"+count+"</span>"+$(inputEl).data('fileCount'));
$(inputEl).attr({
name: 'attachments[' + attachmentId + '][file]'
}).hide();
$('#upload_file_count').html("<span id=\"count\">" + count + "</span>" + $(inputEl).data('fileCount'));
}
}
//clearedFileInput.insertAfter('#attachments_fields');
}
function uploadAndAttachFiles(files, inputEl) {
var maxFileSize = $(inputEl).data('max-file-size');
@ -299,14 +370,19 @@ function uploadAndAttachFiles(files, inputEl) {
var sizeExceeded = false;
$.each(files, function() {
if (this.size && maxFileSize != null && this.size > parseInt(maxFileSize)) {sizeExceeded=true;}
if (this.size && maxFileSize != null && this.size > parseInt(maxFileSize)) {
sizeExceeded = true;
}
});
if (sizeExceeded) {
window.alert(maxFileSizeExceeded);
} else {
$.each(files, function() {addFile(inputEl, this, true);});
$.each(files, function() {
addFile(inputEl, this, true);
});
}
}
function uploadAndAttachFiles_board(files, inputEl, id) {
var maxFileSize = $(inputEl).data('max-file-size');
@ -314,14 +390,19 @@ function uploadAndAttachFiles_board(files, inputEl, id) {
var sizeExceeded = false;
$.each(files, function() {
if (this.size && maxFileSize != null && this.size > parseInt(maxFileSize)) {sizeExceeded=true;}
if (this.size && maxFileSize != null && this.size > parseInt(maxFileSize)) {
sizeExceeded = true;
}
});
if (sizeExceeded) {
window.alert(maxFileSizeExceeded);
} else {
$.each(files, function() {addFile_board(inputEl, this, true, id);});
$.each(files, function() {
addFile_board(inputEl, this, true, id);
});
}
}
function handleFileDropEvent(e) {
$(this).removeClass('fileover');
@ -345,7 +426,9 @@ function dragOutHandler(e) {
function setupFileDrop() {
if (window.File && window.FileList && window.ProgressEvent && window.FormData) {
$.event.fixHooks.drop = { props: [ 'dataTransfer' ] };
$.event.fixHooks.drop = {
props: ['dataTransfer']
};
$('form div.box').has('input:file').each(function() {
$(this).on({
@ -358,18 +441,18 @@ function setupFileDrop() {
}
$(document).ready(setupFileDrop);
$(function(){
$(function() {
$(".file_selector").each(function() {
deleteallfiles = $(this).data('deleteAllFiles');
var containerid = $(this).data('containerid');
if (containerid == undefined)containerid = '';
if (containerid == undefined) containerid = '';
var count = $('#attachments_fields' + containerid + '>span').length;
if (count >= 1) {
$('#upload_file_count' + containerid).html("<span id=\"count\">" + count + "</span>" + $(this).data('fileCount'));
var add_attachs = $('.add_attachment').filter(function (index) {
var add_attachs = $('.add_attachment').filter(function(index) {
return $(this).data('containerid') == containerid;
});
var delete_all = $('.remove_all').filter(function (index) {
var delete_all = $('.remove_all').filter(function(index) {
return $(this).data('containerid') == containerid;
});
if (delete_all.length < 1) {
@ -383,4 +466,4 @@ $(function(){
}
});
});
});