[#369] add templates; add codemirror
This commit is contained in:
parent
09b75e4110
commit
1a1838a363
3
Gemfile
3
Gemfile
|
@ -75,6 +75,7 @@ gem 'angular-i18n', '0.1.2'
|
|||
gem 'js-routes'
|
||||
gem 'soundmanager-rails'
|
||||
gem 'angular-ui-bootstrap-rails'
|
||||
gem 'angular-rails-templates'
|
||||
|
||||
gem 'time_diff'
|
||||
|
||||
|
@ -88,6 +89,8 @@ gem 'therubyrhino', '~> 1.73.1', platforms: :jruby
|
|||
gem 'bootstrap-sass', '~> 3.1.1'
|
||||
gem 'font-awesome-rails'
|
||||
|
||||
gem 'codemirror-rails'
|
||||
|
||||
group :production do
|
||||
gem "airbrake", '~> 3.1.2'
|
||||
gem 'bluepill', '~> 0.0.60', require: false
|
||||
|
|
|
@ -64,6 +64,9 @@ GEM
|
|||
ancestry (2.0.0)
|
||||
activerecord (>= 3.0.0)
|
||||
angular-i18n (0.1.2)
|
||||
angular-rails-templates (0.0.7)
|
||||
railties (>= 3.1)
|
||||
sprockets
|
||||
angular-ui-bootstrap-rails (0.10.0)
|
||||
angularjs-rails (1.2.15)
|
||||
arel (4.0.2)
|
||||
|
@ -102,6 +105,8 @@ GEM
|
|||
activesupport (>= 3.0)
|
||||
cocaine (0.5.3)
|
||||
climate_control (>= 0.0.3, < 1.0)
|
||||
codemirror-rails (3.22)
|
||||
railties (>= 3.0, < 5)
|
||||
coderay (1.1.0)
|
||||
coffee-rails (4.0.1)
|
||||
coffee-script (>= 2.2.0)
|
||||
|
@ -468,6 +473,7 @@ DEPENDENCIES
|
|||
airbrake (~> 3.1.2)
|
||||
ancestry (~> 2.0.0)
|
||||
angular-i18n (= 0.1.2)
|
||||
angular-rails-templates
|
||||
angular-ui-bootstrap-rails
|
||||
angularjs-rails (~> 1.2.15)
|
||||
attr_encrypted (~> 1.3.2)
|
||||
|
@ -480,6 +486,7 @@ DEPENDENCIES
|
|||
capistrano
|
||||
capistrano_colors
|
||||
charlock_holmes (~> 0.6.9)
|
||||
codemirror-rails
|
||||
coffee-rails (~> 4.0.1)
|
||||
compass-rails (~> 1.1.6)
|
||||
creole
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
//var RosaABF = angular.module('RosaABF', ['ngResource', 'ng-rails-csrf', 'angular-i18n', 'angularMoment']);
|
||||
var RosaABF = angular.module('RosaABF', ['ui.bootstrap', 'angular-i18n', 'angularMoment',
|
||||
'chieffancypants.loadingBar', 'ngSanitize']);
|
||||
'chieffancypants.loadingBar', 'ngSanitize', 'templates',
|
||||
'ui.codemirror']);
|
||||
|
||||
var LocalesHelper = function($locale) {
|
||||
var locales = {
|
||||
|
|
|
@ -55,4 +55,12 @@ RosaABF.controller('ActivityCtrl', ['$scope', '$http', '$timeout', '$q', '$filte
|
|||
return content.kind === 'new_comment_notification' ||
|
||||
content.kind === 'new_comment_commit_notification';
|
||||
};
|
||||
|
||||
$scope.getTemplate = function(content) {
|
||||
if(content.kind == 'new_commit_notification' || content.kind == 'git_new_push_notification' ||
|
||||
content.kind == 'git_delete_branch_notification' || content.kind == 'new_issue_notification') {
|
||||
return content.kind + '.html';}
|
||||
else return 'new_comment_notification.html';
|
||||
};
|
||||
|
||||
}]);
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
%i.img-circle.btn-danger.fa.fa-times
|
||||
.timeline-item{ 'ng-cloak' => true }
|
||||
%h3.timeline-header
|
||||
%a{ 'ng-href' => "{{item.user.link}}" }
|
||||
%img{ 'ng-src' => "{{item.user.image}}" }
|
||||
{{item.user.uname}}
|
||||
%span.time{ popover: "{{item.date | amDateFormat:'ddd, LLL'}}",
|
||||
"popover-trigger" => "mouseenter", 'popover-append-to-body' => 'true' }
|
||||
%span.glyphicon.glyphicon-time
|
||||
%span {{item.date | amDateFormat:'HH:mm'}}
|
||||
.clearfix
|
||||
.timeline-body
|
||||
%p
|
||||
{{'notification.push.delete_branch' | i18n}}
|
||||
{{ item.branch_name + ('notification.in_project' | i18n)}}
|
||||
%a{ 'ng-href' => "{{item.project_link}}" } {{item.project_name_with_owner}}
|
|
@ -0,0 +1,27 @@
|
|||
%i.img-circle.bg-primary.fa.fa-sign-in
|
||||
.timeline-item{ 'ng-cloak' => true }
|
||||
%h3.timeline-header
|
||||
%a{ 'ng-href' => "{{item.user.link}}" }
|
||||
%img{ 'ng-src' => "{{item.user.image}}" }
|
||||
{{item.user.uname}}
|
||||
%span.time{ popover: "{{item.date | amDateFormat:'ddd, LLL'}}",
|
||||
"popover-trigger" => "mouseenter", 'popover-append-to-body' => 'true' }
|
||||
%span.glyphicon.glyphicon-time
|
||||
%span {{item.date | amDateFormat:'HH:mm'}}
|
||||
.clearfix
|
||||
.timeline-body
|
||||
%p
|
||||
{{'notification.push.' + item.change_type + '_branch' | i18n}}
|
||||
{{ item.branch_name + ('notification.in_project' | i18n)}}
|
||||
%a{ 'ng-href' => "{{item.project_link}}" } {{item.project_name_with_owner}}
|
||||
|
||||
.timeline-footer
|
||||
.row
|
||||
.container-fluid{ 'ng-repeat' => 'commit in item.last_commits' }
|
||||
.col-sm-3.col-md-2
|
||||
%a{ 'ng-href' => "{{commit.commit_path}}" } {{commit.hash}}
|
||||
.col-sm-8.col-md-9{ 'ng-bind-html' => "commit.message" }
|
||||
.clearfix
|
||||
|
||||
%br{ 'ng-if' => "item.other_commits" }
|
||||
%a{ 'ng-if' => "item.other_commits", 'ng-href' => "{{item.other_commits_path}}" } {{item.other_commits}}
|
|
@ -0,0 +1,22 @@
|
|||
%i.img-circle.btn-warning.fa.fa-comment
|
||||
.timeline-item{ 'ng-cloak' => true }
|
||||
%h3.timeline-header
|
||||
%a{ 'ng-href' => "{{item.user.link}}" }
|
||||
%img{ 'ng-src' => "{{item.user.image}}" }
|
||||
{{item.user.uname}}
|
||||
%span.time{ popover: "{{item.date | amDateFormat:'ddd, LLL'}}",
|
||||
"popover-trigger" => "mouseenter", 'popover-append-to-body' => 'true' }
|
||||
%span.glyphicon.glyphicon-time
|
||||
%span {{item.date | amDateFormat:'HH:mm'}}
|
||||
.clearfix
|
||||
.timeline-body
|
||||
%p
|
||||
{{'notification.new_comment.title' | i18n}}
|
||||
%a{ 'ng-href' => "{{item.issue.link}}" } {{item.issue.title}}
|
||||
|
||||
%blockquote{ 'ng-bind-html' => "item.body" }
|
||||
|
||||
.timeline-footer
|
||||
%a.btn.btn-primary.btn-xs{ 'ng-href' => "{{item.issue.link + '#comment' + item.issue.read_more}}" }
|
||||
{{'read_more' | i18n}}
|
||||
{{item.kind}}
|
|
@ -0,0 +1,16 @@
|
|||
%i.img-circle.btn-success.fa.fa-check
|
||||
.timeline-item{ 'ng-cloak' => true }
|
||||
%h3.timeline-header
|
||||
%a{ 'ng-href' => "{{item.user.link}}" }
|
||||
%img{ 'ng-src' => "{{item.user.image}}" }
|
||||
{{item.user.uname}}
|
||||
%span.time{ popover: "{{item.date | amDateFormat:'ddd, LLL'}}",
|
||||
"popover-trigger" => "mouseenter", 'popover-append-to-body' => 'true' }
|
||||
%span.glyphicon.glyphicon-time
|
||||
%span {{item.date | amDateFormat:'HH:mm'}}
|
||||
.clearfix
|
||||
.timeline-body
|
||||
%p
|
||||
{{('notification.new_issue' | i18n) + ('notification.in_project' | i18n)}}
|
||||
%a{ 'ng-href' => "{{item.project_link}}" } {{item.project_name_with_owner}}
|
||||
%a{ 'ng-href' => "{{item.issue.link}}" } {{item.issue.title}}
|
|
@ -17,7 +17,19 @@ var _locales = {
|
|||
'autostart_statuses.1': 'Раз в день',
|
||||
'autostart_statuses.2': 'Раз в неделю',
|
||||
<%= BuildList::STATUSES.map{|s| "'build_list.status.#{s}': '#{BuildList.human_status(s)}'"}.join(',') %>,
|
||||
<%= I18n.t('activity_menu').map{ |k,v| "'activity_menu.#{k}': '#{v}'" }.join(',') %>
|
||||
|
||||
//
|
||||
<%= I18n.t('activity_menu').map{ |k,v| "'activity_menu.#{k}': '#{v}'" }.join(',') %>,
|
||||
|
||||
'notification.new_comment.title': 'добавил новый комментарий к задаче ',
|
||||
'notification.push.delete_branch': 'удалил ветку ',
|
||||
'notification.push.create_branch': 'создал новую ветку ',
|
||||
'notification.push.update_branch': 'внес изменения в ветку ',
|
||||
'notification.in_project': ' в проекте ',
|
||||
'notification.new_issue': 'добавил новую задачу',
|
||||
|
||||
'read_more': 'Читать дальше',
|
||||
|
||||
},
|
||||
<%I18n.locale = :en%>
|
||||
'en-us': {
|
||||
|
@ -35,6 +47,18 @@ var _locales = {
|
|||
'autostart_statuses.1': 'Once a day',
|
||||
'autostart_statuses.2': 'Once a week',
|
||||
<%= BuildList::STATUSES.map{|s| "'build_list.status.#{s}': '#{BuildList.human_status(s)}'"}.join(',') %>,
|
||||
<%= I18n.t('activity_menu').map{ |k,v| "'activity_menu.#{k}': '#{v}'" }.join(',') %>
|
||||
|
||||
//
|
||||
<%= I18n.t('activity_menu').map{ |k,v| "'activity_menu.#{k}': '#{v}'" }.join(',') %>,
|
||||
|
||||
'notification.new_comment.title': 'added a new comment in issue ',
|
||||
'notification.push.delete_branch': 'deleted a branch ',
|
||||
'notification.push.create_branch': 'created a new branch ',
|
||||
'notification.push.update_branch': 'pushed to branch ',
|
||||
'notification.in_project': ' in project ',
|
||||
'notification.new_issue': 'added a new issue ',
|
||||
|
||||
'read_more': 'Read more',
|
||||
|
||||
}
|
||||
};
|
|
@ -1,4 +1,5 @@
|
|||
//= require jquery
|
||||
//= require jquery_ujs
|
||||
//= require js-routes
|
||||
|
||||
// Loads all Bootstrap javascripts
|
||||
|
@ -8,6 +9,7 @@
|
|||
//= require angular
|
||||
//= require angular-sanitize
|
||||
//= require angular-ui-bootstrap-tpls
|
||||
//= require ui-codemirror
|
||||
//= require angular-i18n
|
||||
//= require angularjs/locales
|
||||
|
||||
|
@ -16,3 +18,19 @@
|
|||
|
||||
//= require_tree ./angular-new
|
||||
//= require loading-bar
|
||||
|
||||
//= require codemirror
|
||||
// ### TODO require all files in codemirror/modes ###
|
||||
//= require codemirror/modes/ruby
|
||||
//= require codemirror/modes/javascript
|
||||
//= require codemirror/modes/markdown
|
||||
|
||||
$(document).ready(function() {
|
||||
window.CodeMirrorRun = function(code) {
|
||||
//CodeMirror.runMode(code.innerHTML.replace(/&/gi, '&').replace(/</gi, '<').replace(/>/gi, '>'), code.className, code);
|
||||
CodeMirror.runMode(code.innerHTML, 'markdown', code);
|
||||
}
|
||||
|
||||
$('.md_and_cm').each(function (code) { CodeMirrorRun(this); });
|
||||
|
||||
});
|
||||
|
|
|
@ -10,3 +10,4 @@ $navbar-default-link-hover-color: #CEE7FF;
|
|||
@import "timeline";
|
||||
@import "font-awesome";
|
||||
@import "loading-bar";
|
||||
@import "codemirror";
|
||||
|
|
|
@ -11,6 +11,7 @@ class HomeController < ApplicationController
|
|||
@activity_feeds = current_user.activity_feeds
|
||||
@activity_feeds = @activity_feeds.where(kind: "ActivityFeed::#{@filter.upcase}".constantize) unless @filter == :all
|
||||
@activity_feeds = @activity_feeds.paginate page: params[:page]
|
||||
|
||||
respond_to do |format|
|
||||
format.html { request.xhr? ? render('_list', layout: false) : render('activity') }
|
||||
format.json {}
|
||||
|
|
|
@ -18,30 +18,4 @@ module ActivityFeedsHelper
|
|||
def user_link(user, user_name, full_url = false)
|
||||
user.persisted? ? link_to(user_name, full_url ? user_url(user) : user_path(user)) : user_name
|
||||
end
|
||||
|
||||
def get_title_from_activity_item(item, opts = {})
|
||||
case item.kind
|
||||
when 'new_comment_notification'
|
||||
res = t('notifications.bodies.new_comment_notification.title', { user_link: nil })
|
||||
res << ' ' << t('notifications.bodies.new_comment_notification.content',
|
||||
{ issue_link: link_to(item.data[:issue_title], opts[:path]) })
|
||||
when 'git_new_push_notification'
|
||||
res = t("notifications.bodies.#{item.data[:change_type]}_branch",
|
||||
{ branch_name: item.data[:branch_name], user_link: nil })
|
||||
res << ' ' << t('notifications.bodies.project', project_link: link_to(opts[:project_name_with_owner], opts[:path]))
|
||||
else nil
|
||||
end
|
||||
raw res
|
||||
end
|
||||
|
||||
def get_path_from_activity_item(item, opts = {})
|
||||
case item.kind
|
||||
when 'new_comment_notification'
|
||||
project_issue_path(opts[:project_name_with_owner], item.data[:issue_serial_id])
|
||||
when 'git_new_push_notification'
|
||||
project_path(opts[:project_name_with_owner])
|
||||
else
|
||||
'?'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,7 +23,7 @@ module Feed::Comment
|
|||
user_name: user.name,
|
||||
user_email: user.email,
|
||||
user_id: user_id,
|
||||
comment_body: truncate(body, length: 1000, omission: '…'),
|
||||
comment_body: truncate(body, length: 100, omission: '…'),
|
||||
issue_title: commentable.title,
|
||||
issue_serial_id: commentable.serial_id,
|
||||
project_id: commentable.project.id,
|
||||
|
|
|
@ -43,28 +43,7 @@
|
|||
%span{ 'ng-show' => "needShowTimeLabel($index)", 'ng-cloak' => true }
|
||||
{{item.date | amDateFormat:'ll'}}
|
||||
/ timeline item
|
||||
%li
|
||||
%i.img-circle.fa{ 'ng-class' => "getTimeLinefaClass(item)" }
|
||||
.timeline-item
|
||||
%h3.timeline-header
|
||||
%a{ 'ng-href' => "{{item.user.link}}" }
|
||||
%img{ 'ng-src' => "{{item.user.image}}" }
|
||||
{{item.user.uname}}
|
||||
%span.time{ 'ng-cloak' => true, popover: "{{item.date | amDateFormat:'ddd, LLL'}}",
|
||||
"popover-trigger" => "mouseenter", 'popover-append-to-body' => 'true' }
|
||||
%span.glyphicon.glyphicon-time
|
||||
%span {{item.date | amDateFormat:'HH:mm'}}
|
||||
.clearfix
|
||||
.timeline-body
|
||||
-#%p{ 'ng-bind-html' => "item.title" }
|
||||
%p{ 'ng-bind-html' => "item.title" }
|
||||
%blockquote{ 'ng-if' => "isComment(item)" }
|
||||
{{item.body}}
|
||||
%p{ 'ng-if' => "!isComment(item)", 'ng-bind-html' => "item.body" }
|
||||
|
||||
.timeline-footer
|
||||
%a.btn.btn-primary.btn-xs{ 'ng-href' => "{{item.read_more}}", 'ng-if' => "isComment(item)" }
|
||||
= t('layout.read_more')
|
||||
%li{ 'ng-include' => "getTemplate(item)" }
|
||||
.hide{ 'ng-repeat-end' => true }
|
||||
%li
|
||||
%i.img-circle.bg-primary.fa.fa-clock-o
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
json.array!(@activity_feeds) do |item|
|
||||
json.cache! item do
|
||||
#json.cache! item, expires_in: 10.minutes do
|
||||
json.date item.created_at
|
||||
json.kind item.kind
|
||||
user = get_user_from_activity_item(item)
|
||||
|
@ -8,18 +8,50 @@ json.array!(@activity_feeds) do |item|
|
|||
json.image avatar_url(user, :small) if user.persisted?
|
||||
json.uname (user.fullname || user.email)
|
||||
end if user
|
||||
|
||||
project_name_with_owner = "#{item.data[:project_owner]}/#{item.data[:project_name]}"
|
||||
@project = Project.find_by_owner_and_name(item.data[:project_owner], item.data[:project_name])
|
||||
|
||||
json.project_name_with_owner project_name_with_owner
|
||||
path = get_path_from_activity_item(item, project_name_with_owner: project_name_with_owner)
|
||||
json.title get_title_from_activity_item(item, user: user, project_name_with_owner: project_name_with_owner, path: path)
|
||||
|
||||
case item.kind
|
||||
when 'new_comment_notification'
|
||||
json.read_more path + "#comment#{item.data[:comment_id]}"
|
||||
json.body short_message(item.data[:comment_body], 1000)
|
||||
json.issue do
|
||||
json.link project_issue_path(project_name_with_owner, item.data[:issue_serial_id]) if item.data[:issue_serial_id].present?
|
||||
json.title short_message(item.data[:issue_title], 50)
|
||||
json.read_more item.data[:comment_id]
|
||||
end
|
||||
json.body markdown(short_message(item.data[:comment_body], 100))
|
||||
|
||||
when 'git_new_push_notification'
|
||||
json.body render('commits_list', item: item, project_name_with_owner: project_name_with_owner).html_safe
|
||||
json.change_type item.data[:change_type]
|
||||
json.project_link project_path(project_name_with_owner)
|
||||
json.branch_name item.data[:branch_name]
|
||||
|
||||
json.last_commits do
|
||||
json.array! item.data[:last_commits] do |commit|
|
||||
json.hash shortest_hash_id(commit[0])
|
||||
json.message markdown(short_message(commit[1], 70))
|
||||
json.commit_path commit_path(project_name_with_owner, commit[0])
|
||||
end
|
||||
end
|
||||
if item.data[:other_commits].present?
|
||||
json.other_commits t('notifications.bodies.more_commits', count: item.data[:other_commits_count], commits: commits_pluralize(item.data[:other_commits_count]))
|
||||
json.other_commits_path diff_path(project_name_with_owner, diff: item.data[:other_commits])
|
||||
end
|
||||
|
||||
when 'git_delete_branch_notification'
|
||||
json.branch_name item.data[:branch_name]
|
||||
json.project_link project_path(project_name_with_owner)
|
||||
|
||||
when 'new_issue_notification'
|
||||
json.project_link project_path(project_name_with_owner)
|
||||
json.issue do
|
||||
json.title item.data[:issue_title]
|
||||
json.link project_issue_path(project_name_with_owner, item.data[:issue_serial_id]) if item.data[:issue_serial_id].present?
|
||||
end
|
||||
|
||||
end
|
||||
json.id item.id
|
||||
end
|
||||
#end
|
||||
end
|
|
@ -56,5 +56,7 @@ module Rosa
|
|||
config.assets.version = '1.0'
|
||||
|
||||
config.log_redis = false
|
||||
|
||||
config.angular_templates.ignore_prefix = 'angular-new/templates/'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* UI.Codemirror directive
|
||||
* https://github.com/angular-ui/ui-codemirror
|
||||
*
|
||||
* This directive allows you to add CodeMirror to your textarea elements.
|
||||
*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2012 the AngularUI Team, http://angular-ui.github.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Binds a CodeMirror widget to a <textarea> element.
|
||||
*/
|
||||
angular.module('ui.codemirror', [])
|
||||
.constant('uiCodemirrorConfig', {})
|
||||
.directive('uiCodemirror', ['uiCodemirrorConfig', function (uiCodemirrorConfig) {
|
||||
|
||||
return {
|
||||
restrict: 'EA',
|
||||
require: '?ngModel',
|
||||
priority: 1,
|
||||
compile: function compile(tElement) {
|
||||
|
||||
// Require CodeMirror
|
||||
if (angular.isUndefined(window.CodeMirror)) {
|
||||
throw new Error('ui-codemirror need CodeMirror to work... (o rly?)');
|
||||
}
|
||||
|
||||
// Create a codemirror instance with
|
||||
// - the function that will to place the editor into the document.
|
||||
// - the initial content of the editor.
|
||||
// see http://codemirror.net/doc/manual.html#api_constructor
|
||||
var value = tElement.text();
|
||||
var codeMirror = new window.CodeMirror(function (cm_el) {
|
||||
|
||||
angular.forEach(tElement.prop('attributes'), function (a) {
|
||||
if (a.name === 'ui-codemirror') {
|
||||
cm_el.setAttribute('ui-codemirror-opts', a.textContent);
|
||||
} else {
|
||||
cm_el.setAttribute(a.name, a.textContent);
|
||||
}
|
||||
});
|
||||
|
||||
// FIX replaceWith throw not parent Error !
|
||||
if (tElement.parent().length <= 0) {
|
||||
tElement.wrap('<div>');
|
||||
}
|
||||
|
||||
tElement.replaceWith(cm_el);
|
||||
}, {value: value});
|
||||
|
||||
return function postLink(scope, iElement, iAttrs, ngModel) {
|
||||
|
||||
var options, opts;
|
||||
|
||||
options = uiCodemirrorConfig.codemirror || {};
|
||||
opts = angular.extend({}, options, scope.$eval(iAttrs.uiCodemirror), scope.$eval(iAttrs.uiCodemirrorOpts));
|
||||
|
||||
function updateOptions(newValues) {
|
||||
for (var key in newValues) {
|
||||
if (newValues.hasOwnProperty(key)) {
|
||||
codeMirror.setOption(key, newValues[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateOptions(opts);
|
||||
|
||||
if (angular.isDefined(scope.$eval(iAttrs.uiCodemirror))) {
|
||||
scope.$watch(iAttrs.uiCodemirror, updateOptions, true);
|
||||
}
|
||||
// Specialize change event
|
||||
codeMirror.on('change', function (instance) {
|
||||
var newValue = instance.getValue();
|
||||
if (ngModel && newValue !== ngModel.$viewValue) {
|
||||
ngModel.$setViewValue(newValue);
|
||||
}
|
||||
if (!scope.$$phase) {
|
||||
scope.$apply();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (ngModel) {
|
||||
// CodeMirror expects a string, so make sure it gets one.
|
||||
// This does not change the model.
|
||||
ngModel.$formatters.push(function (value) {
|
||||
if (angular.isUndefined(value) || value === null) {
|
||||
return '';
|
||||
}
|
||||
else if (angular.isObject(value) || angular.isArray(value)) {
|
||||
throw new Error('ui-codemirror cannot use an object or an array as a model');
|
||||
}
|
||||
return value;
|
||||
});
|
||||
|
||||
|
||||
// Override the ngModelController $render method, which is what gets called when the model is updated.
|
||||
// This takes care of the synchronizing the codeMirror element with the underlying model, in the case that it is changed by something else.
|
||||
ngModel.$render = function () {
|
||||
//Code mirror expects a string so make sure it gets one
|
||||
//Although the formatter have already done this, it can be possible that another formatter returns undefined (for example the required directive)
|
||||
var safeViewValue = ngModel.$viewValue || '';
|
||||
codeMirror.setValue(safeViewValue);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// Watch ui-refresh and refresh the directive
|
||||
if (iAttrs.uiRefresh) {
|
||||
scope.$watch(iAttrs.uiRefresh, function (newVal, oldVal) {
|
||||
// Skip the initial watch firing
|
||||
if (newVal !== oldVal) {
|
||||
codeMirror.refresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// onLoad callback
|
||||
if (angular.isFunction(opts.onLoad)) {
|
||||
opts.onLoad(codeMirror);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}]);
|
|
@ -3,9 +3,9 @@
|
|||
//= require gollum/gollum.placeholder
|
||||
//= require gollum/editor/gollum.editor
|
||||
//= require jquery.dataTables
|
||||
//= require codemirror
|
||||
//= require codemirror/runmode
|
||||
//= require_tree ./codemirror/modes
|
||||
//= require old-codemirror
|
||||
//= require old-codemirror/runmode
|
||||
//= require_tree ./old-codemirror/modes
|
||||
//= require cusel
|
||||
//= require bootstrap-modal
|
||||
//= require bootstrap-button
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
//@import "gollum/template";
|
||||
@import "gollum/editor";
|
||||
|
||||
@import "codemirror";
|
||||
@import "codemirror/themes/eclipse";
|
||||
@import "codemirror/modes/diff";
|
||||
@import "codemirror/modes/rpm-spec";
|
||||
@import "codemirror/modes/tiddlywiki";
|
||||
@import "old-codemirror";
|
||||
@import "old-codemirror/themes/eclipse";
|
||||
@import "old-codemirror/modes/diff";
|
||||
@import "old-codemirror/modes/rpm-spec";
|
||||
@import "old-codemirror/modes/tiddlywiki";
|
||||
|
||||
@import "old-bootstrap";
|
||||
@import "chosen.scss";
|
Loading…
Reference in New Issue