mirror of
https://github.com/QingdaoU/Spirit.git
synced 2025-01-01 09:31:48 +00:00
gulp minify & concat JS
This commit is contained in:
parent
b34194981a
commit
84e875edb9
42
gulpfile.js
42
gulpfile.js
@ -7,6 +7,7 @@ var Server = require('karma').Server;
|
|||||||
var minifyCss = require('gulp-minify-css');
|
var minifyCss = require('gulp-minify-css');
|
||||||
var rename = require("gulp-rename");
|
var rename = require("gulp-rename");
|
||||||
var concat = require('gulp-concat');
|
var concat = require('gulp-concat');
|
||||||
|
var uglify = require('gulp-uglify');
|
||||||
|
|
||||||
var assetsPath = 'spirit/core/static/spirit/';
|
var assetsPath = 'spirit/core/static/spirit/';
|
||||||
var cssPath = assetsPath + 'stylesheets/';
|
var cssPath = assetsPath + 'stylesheets/';
|
||||||
@ -29,11 +30,9 @@ gulp.task('_css-minify', ['_sass'], function () {
|
|||||||
|
|
||||||
|
|
||||||
gulp.task('_css-concat', ['_css-minify'], function() {
|
gulp.task('_css-concat', ['_css-minify'], function() {
|
||||||
var path = cssPath + 'vendors/'
|
var path = cssPath + 'vendors/';
|
||||||
return gulp.src([
|
return gulp.src([
|
||||||
path + 'font-awesome.min.css',
|
path + '*.min.css',
|
||||||
path + 'github.min.css',
|
|
||||||
path + 'jquery.atwho.min.css',
|
|
||||||
cssPath + 'styles.min.css',
|
cssPath + 'styles.min.css',
|
||||||
])
|
])
|
||||||
.pipe(concat('styles.all.min.css'))
|
.pipe(concat('styles.all.min.css'))
|
||||||
@ -57,7 +56,7 @@ var coffeeTask = function coffeeTask(opts) {
|
|||||||
gulp.task('coffee', function(done) {
|
gulp.task('coffee', function(done) {
|
||||||
coffeeTask({
|
coffeeTask({
|
||||||
srcPath: jsPath + 'src/*.coffee',
|
srcPath: jsPath + 'src/*.coffee',
|
||||||
destPath: jsPath,
|
destPath: jsPath + 'js',
|
||||||
}).on('end', done)
|
}).on('end', done)
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -81,3 +80,36 @@ gulp.task('_test', ['coffee', '_coffee-test'], function (done) {
|
|||||||
|
|
||||||
|
|
||||||
gulp.task('test', ['coffee', '_coffee-test', '_test']);
|
gulp.task('test', ['coffee', '_coffee-test', '_test']);
|
||||||
|
|
||||||
|
|
||||||
|
gulp.task('_js-uglify', ['coffee'], function() {
|
||||||
|
var path = jsPath + 'js/';
|
||||||
|
return gulp.src([
|
||||||
|
'!' + path + '*.min.js', // Exclude
|
||||||
|
path + '*.js'
|
||||||
|
])
|
||||||
|
.pipe(uglify({mangle: false}))
|
||||||
|
.pipe(rename({suffix: ".min"}))
|
||||||
|
.pipe(gulp.dest(path));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
gulp.task('_js-concat', ['_js-uglify'], function() {
|
||||||
|
var path = jsPath + 'js/';
|
||||||
|
var pathVendors = jsPath + 'vendors/';
|
||||||
|
return gulp.src([
|
||||||
|
pathVendors + 'jquery.min.js',
|
||||||
|
pathVendors + 'atwho/jquery.caret.min.js',
|
||||||
|
pathVendors + 'atwho/jquery.atwho.min.js',
|
||||||
|
pathVendors + '**/*.js',
|
||||||
|
path + 'util.min.js',
|
||||||
|
path + 'tab.min.js',
|
||||||
|
path + 'editor_image_upload.min.js',
|
||||||
|
path + '*.min.js'
|
||||||
|
])
|
||||||
|
.pipe(concat('all.min.js'))
|
||||||
|
.pipe(gulp.dest(jsPath));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
gulp.task('js', ['_js-concat']);
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
"gulp-rename": "^1.2.2",
|
"gulp-rename": "^1.2.2",
|
||||||
"gulp-ruby-sass": "^1.4.0",
|
"gulp-ruby-sass": "^1.4.0",
|
||||||
"gulp-sourcemaps": "^1.6.0",
|
"gulp-sourcemaps": "^1.6.0",
|
||||||
|
"gulp-uglify": "^1.4.2",
|
||||||
"gulp-util": "^3.0.6",
|
"gulp-util": "^3.0.6",
|
||||||
"karma": "^0.13.10",
|
"karma": "^0.13.10",
|
||||||
"karma-cli": "^0.1.1",
|
"karma-cli": "^0.1.1",
|
||||||
|
32
spirit/core/static/spirit/scripts/all.min.js
vendored
Normal file
32
spirit/core/static/spirit/scripts/all.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
spirit/core/static/spirit/scripts/js/bookmark.min.js
vendored
Normal file
1
spirit/core/static/spirit/scripts/js/bookmark.min.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
(function(){var $,Bookmark,Mark,bind=function(fn,me){return function(){return fn.apply(me,arguments)}};$=jQuery,Mark=function(){function Mark(){this.isSending=!1,this.commentNumber=this._getCommentNumber()}return Mark.prototype._getCommentNumber=function(){var commentNumber;return commentNumber=window.location.hash.split("#c")[1],commentNumber=parseInt(commentNumber,10),isNaN(commentNumber)?commentNumber=0:commentNumber-=1,commentNumber},Mark}(),Bookmark=function(){function Bookmark(el,mark,options){this.sendCommentNumber=bind(this.sendCommentNumber,this),this.onWaypoint=bind(this.onWaypoint,this),this.el=$(el),this.mark=mark,this.options=$.extend({},this.defaults,options),this.setUp()}return Bookmark.prototype.defaults={csrfToken:"csrf_token",target:"target url"},Bookmark.prototype.setUp=function(){return this.el.waypoint(this.onWaypoint,{offset:"100%"})},Bookmark.prototype.onWaypoint=function(){var newCommentNumber;newCommentNumber=this.el.data("number"),newCommentNumber>this.mark.commentNumber&&(this.mark.commentNumber=newCommentNumber,this.sendCommentNumber())},Bookmark.prototype.sendCommentNumber=function(){var post,sentCommentNumber;if(!this.mark.isSending)return this.mark.isSending=!0,sentCommentNumber=this.mark.commentNumber,post=$.post(this.options.target,{csrfmiddlewaretoken:this.options.csrfToken,comment_number:this.mark.commentNumber}),post.always(function(_this){return function(){return _this.mark.isSending=!1,_this.mark.commentNumber>sentCommentNumber?_this.sendCommentNumber():void 0}}(this))},Bookmark}(),$.fn.extend({bookmark:function(options){var mark;return mark=new Mark,this.each(function(){return $(this).data("plugin_bookmark")?void 0:$(this).data("plugin_bookmark",new Bookmark(this,mark,options))})}}),$.fn.bookmark.Bookmark=Bookmark,$.fn.bookmark.Mark=Mark}).call(this);
|
1
spirit/core/static/spirit/scripts/js/editor.min.js
vendored
Normal file
1
spirit/core/static/spirit/scripts/js/editor.min.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
(function(){var $,Editor,bind=function(fn,me){return function(){return fn.apply(me,arguments)}};$=jQuery,Editor=function(){function Editor(el,options){this.togglePreview=bind(this.togglePreview,this),this.addPoll=bind(this.addPoll,this),this.addImage=bind(this.addImage,this),this.addUrl=bind(this.addUrl,this),this.addList=bind(this.addList,this),this.addItalic=bind(this.addItalic,this),this.addBold=bind(this.addBold,this),this.wrapSelection=bind(this.wrapSelection,this),this.el=$(el),this.options=$.extend({},this.defaults,options),this.pollCounter=1,this.setUp()}return Editor.prototype.defaults={boldedText:"bolded text",italicisedText:"italicised text",listItemText:"list item",linkText:"link text",linkUrlText:"link url",imageText:"image text",imageUrlText:"image url",pollTitleText:"Title",pollChoiceText:"Description"},Editor.prototype.setUp=function(){return $(".js-box-bold").on("click",this.addBold),$(".js-box-italic").on("click",this.addItalic),$(".js-box-list").on("click",this.addList),$(".js-box-url").on("click",this.addUrl),$(".js-box-image").on("click",this.addImage),$(".js-box-poll").on("click",this.addPoll),$(".js-box-preview").on("click",this.togglePreview)},Editor.prototype.wrapSelection=function(preTxt,postTxt,defaultTxt){var postSelection,preSelection,selection;return preSelection=this.el.val().substring(0,this.el[0].selectionStart),selection=this.el.val().substring(this.el[0].selectionStart,this.el[0].selectionEnd),postSelection=this.el.val().substring(this.el[0].selectionEnd),selection||(selection=defaultTxt),this.el.val(preSelection+preTxt+selection+postTxt+postSelection)},Editor.prototype.addBold=function(){return this.wrapSelection("**","**",this.options.boldedText),!1},Editor.prototype.addItalic=function(){return this.wrapSelection("*","*",this.options.italicisedText),!1},Editor.prototype.addList=function(){return this.wrapSelection("\n* ","",this.options.listItemText),!1},Editor.prototype.addUrl=function(){return this.wrapSelection("[","]("+this.options.linkUrlText+")",this.options.linkText),!1},Editor.prototype.addImage=function(){return this.wrapSelection("![","]("+this.options.imageUrlText+")",this.options.imageText),!1},Editor.prototype.addPoll=function(){var poll;return poll="\n\n[poll name="+this.pollCounter+"]\n"+("# "+this.options.pollTitleText+"\n")+("1. "+this.options.pollChoiceText+"\n")+("2. "+this.options.pollChoiceText+"\n")+"[/poll]\n",this.wrapSelection("",poll,""),this.pollCounter++,!1},Editor.prototype.togglePreview=function(){var $preview;return $preview=$(".js-box-preview-content"),this.el.toggle(),$preview.toggle(),$preview.html(marked(this.el.val())),!1},Editor}(),$.fn.extend({editor:function(options){return this.each(function(){return $(this).data("plugin_editor")?void 0:$(this).data("plugin_editor",new Editor(this,options))})}}),$.fn.editor.Editor=Editor}).call(this);
|
1
spirit/core/static/spirit/scripts/js/editor_image_upload.min.js
vendored
Normal file
1
spirit/core/static/spirit/scripts/js/editor_image_upload.min.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
(function(){var $,EditorImageUpload,bind=function(fn,me){return function(){return fn.apply(me,arguments)}};$=jQuery,EditorImageUpload=function(){function EditorImageUpload(el,options){this.openFileDialog=bind(this.openFileDialog,this),this.textReplace=bind(this.textReplace,this),this.addStatusError=bind(this.addStatusError,this),this.addError=bind(this.addError,this),this.addImage=bind(this.addImage,this),this.buildFormData=bind(this.buildFormData,this),this.addPlaceholder=bind(this.addPlaceholder,this),this.sendFile=bind(this.sendFile,this),this.el=$(el),this.options=$.extend({},this.defaults,options),this.inputFile=$("<input/>",{type:"file",accept:"image/*"}),this.setUp()}return EditorImageUpload.prototype.defaults={csrfToken:"csrf_token",target:"target url",placeholderText:"uploading {image_name}"},EditorImageUpload.prototype.setUp=function(){var $boxImage;if(null!=window.FormData)return this.inputFile.on("change",this.sendFile),$boxImage=$(".js-box-image"),$boxImage.on("click",this.openFileDialog),$boxImage.on("click",this.stopClick)},EditorImageUpload.prototype.sendFile=function(){var file,formData,placeholder,post;file=this.inputFile.get(0).files[0],placeholder=this.addPlaceholder(file),formData=this.buildFormData(file),post=$.ajax({url:this.options.target,data:formData,processData:!1,contentType:!1,type:"POST"}),post.done(function(_this){return function(data){return"url"in data?_this.addImage(data,file,placeholder):_this.addError(data,placeholder)}}(this)),post.fail(function(_this){return function(jqxhr,textStatus,error){return _this.addStatusError(textStatus,error,placeholder)}}(this))},EditorImageUpload.prototype.addPlaceholder=function(file){var placeholder;return placeholder=$.format("!["+this.options.placeholderText+"]()",{image_name:file.name}),this.el.val(this.el.val()+placeholder),placeholder},EditorImageUpload.prototype.buildFormData=function(file){var formData;return formData=new FormData,formData.append("csrfmiddlewaretoken",this.options.csrfToken),formData.append("image",file),formData},EditorImageUpload.prototype.addImage=function(data,file,placeholder){var imageTag;return imageTag=$.format("![{name}]({url})",{name:file.name,url:data.url}),this.textReplace(placeholder,imageTag)},EditorImageUpload.prototype.addError=function(data,placeholder){var error;return error=JSON.stringify(data),this.textReplace(placeholder,"!["+error+"]()")},EditorImageUpload.prototype.addStatusError=function(textStatus,error,placeholder){var errorTag;return errorTag=$.format("![error: {code} {error}]()",{code:textStatus,error:error}),this.textReplace(placeholder,errorTag)},EditorImageUpload.prototype.textReplace=function(find,replace){this.el.val(this.el.val().replace(find,replace))},EditorImageUpload.prototype.openFileDialog=function(){this.inputFile.trigger("click")},EditorImageUpload.prototype.stopClick=function(e){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation()},EditorImageUpload}(),$.fn.extend({editor_image_upload:function(options){return this.each(function(){return $(this).data("plugin_editor_image_upload")?void 0:$(this).data("plugin_editor_image_upload",new EditorImageUpload(this,options))})}}),$.fn.editor_image_upload.EditorImageUpload=EditorImageUpload}).call(this);
|
1
spirit/core/static/spirit/scripts/js/emoji_list.min.js
vendored
Normal file
1
spirit/core/static/spirit/scripts/js/emoji_list.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
371
spirit/core/static/spirit/scripts/js/htmldiff.js
Normal file
371
spirit/core/static/spirit/scripts/js/htmldiff.js
Normal file
@ -0,0 +1,371 @@
|
|||||||
|
(function() {
|
||||||
|
var Match, calculate_operations, consecutive_where, create_index, diff, find_match, find_matching_blocks, html_to_tokens, is_end_of_tag, is_start_of_tag, is_tag, is_whitespace, isnt_tag, op_map, recursively_find_matching_blocks, render_operations, wrap;
|
||||||
|
|
||||||
|
is_end_of_tag = function(char) {
|
||||||
|
return char === '>';
|
||||||
|
};
|
||||||
|
|
||||||
|
is_start_of_tag = function(char) {
|
||||||
|
return char === '<';
|
||||||
|
};
|
||||||
|
|
||||||
|
is_whitespace = function(char) {
|
||||||
|
return /^\s+$/.test(char);
|
||||||
|
};
|
||||||
|
|
||||||
|
is_tag = function(token) {
|
||||||
|
return /^\s*<[^>]+>\s*$/.test(token);
|
||||||
|
};
|
||||||
|
|
||||||
|
isnt_tag = function(token) {
|
||||||
|
return !is_tag(token);
|
||||||
|
};
|
||||||
|
|
||||||
|
Match = (function() {
|
||||||
|
function Match(start_in_before1, start_in_after1, length1) {
|
||||||
|
this.start_in_before = start_in_before1;
|
||||||
|
this.start_in_after = start_in_after1;
|
||||||
|
this.length = length1;
|
||||||
|
this.end_in_before = (this.start_in_before + this.length) - 1;
|
||||||
|
this.end_in_after = (this.start_in_after + this.length) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Match;
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
|
html_to_tokens = function(html) {
|
||||||
|
var char, current_word, i, len, mode, words;
|
||||||
|
mode = 'char';
|
||||||
|
current_word = '';
|
||||||
|
words = [];
|
||||||
|
for (i = 0, len = html.length; i < len; i++) {
|
||||||
|
char = html[i];
|
||||||
|
switch (mode) {
|
||||||
|
case 'tag':
|
||||||
|
if (is_end_of_tag(char)) {
|
||||||
|
current_word += '>';
|
||||||
|
words.push(current_word);
|
||||||
|
current_word = '';
|
||||||
|
if (is_whitespace(char)) {
|
||||||
|
mode = 'whitespace';
|
||||||
|
} else {
|
||||||
|
mode = 'char';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
current_word += char;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'char':
|
||||||
|
if (is_start_of_tag(char)) {
|
||||||
|
if (current_word) {
|
||||||
|
words.push(current_word);
|
||||||
|
}
|
||||||
|
current_word = '<';
|
||||||
|
mode = 'tag';
|
||||||
|
} else if (/\s/.test(char)) {
|
||||||
|
if (current_word) {
|
||||||
|
words.push(current_word);
|
||||||
|
}
|
||||||
|
current_word = char;
|
||||||
|
mode = 'whitespace';
|
||||||
|
} else if (/[\w\#@]+/i.test(char)) {
|
||||||
|
current_word += char;
|
||||||
|
} else {
|
||||||
|
if (current_word) {
|
||||||
|
words.push(current_word);
|
||||||
|
}
|
||||||
|
current_word = char;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'whitespace':
|
||||||
|
if (is_start_of_tag(char)) {
|
||||||
|
if (current_word) {
|
||||||
|
words.push(current_word);
|
||||||
|
}
|
||||||
|
current_word = '<';
|
||||||
|
mode = 'tag';
|
||||||
|
} else if (is_whitespace(char)) {
|
||||||
|
current_word += char;
|
||||||
|
} else {
|
||||||
|
if (current_word) {
|
||||||
|
words.push(current_word);
|
||||||
|
}
|
||||||
|
current_word = char;
|
||||||
|
mode = 'char';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error("Unknown mode " + mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (current_word) {
|
||||||
|
words.push(current_word);
|
||||||
|
}
|
||||||
|
return words;
|
||||||
|
};
|
||||||
|
|
||||||
|
find_match = function(before_tokens, after_tokens, index_of_before_locations_in_after_tokens, start_in_before, end_in_before, start_in_after, end_in_after) {
|
||||||
|
var best_match_in_after, best_match_in_before, best_match_length, i, index_in_after, index_in_before, j, len, locations_in_after, looking_for, match, match_length_at, new_match_length, new_match_length_at, ref, ref1;
|
||||||
|
best_match_in_before = start_in_before;
|
||||||
|
best_match_in_after = start_in_after;
|
||||||
|
best_match_length = 0;
|
||||||
|
match_length_at = {};
|
||||||
|
for (index_in_before = i = ref = start_in_before, ref1 = end_in_before; ref <= ref1 ? i < ref1 : i > ref1; index_in_before = ref <= ref1 ? ++i : --i) {
|
||||||
|
new_match_length_at = {};
|
||||||
|
looking_for = before_tokens[index_in_before];
|
||||||
|
locations_in_after = index_of_before_locations_in_after_tokens[looking_for];
|
||||||
|
for (j = 0, len = locations_in_after.length; j < len; j++) {
|
||||||
|
index_in_after = locations_in_after[j];
|
||||||
|
if (index_in_after < start_in_after) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (index_in_after >= end_in_after) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (match_length_at[index_in_after - 1] == null) {
|
||||||
|
match_length_at[index_in_after - 1] = 0;
|
||||||
|
}
|
||||||
|
new_match_length = match_length_at[index_in_after - 1] + 1;
|
||||||
|
new_match_length_at[index_in_after] = new_match_length;
|
||||||
|
if (new_match_length > best_match_length) {
|
||||||
|
best_match_in_before = index_in_before - new_match_length + 1;
|
||||||
|
best_match_in_after = index_in_after - new_match_length + 1;
|
||||||
|
best_match_length = new_match_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match_length_at = new_match_length_at;
|
||||||
|
}
|
||||||
|
if (best_match_length !== 0) {
|
||||||
|
match = new Match(best_match_in_before, best_match_in_after, best_match_length);
|
||||||
|
}
|
||||||
|
return match;
|
||||||
|
};
|
||||||
|
|
||||||
|
recursively_find_matching_blocks = function(before_tokens, after_tokens, index_of_before_locations_in_after_tokens, start_in_before, end_in_before, start_in_after, end_in_after, matching_blocks) {
|
||||||
|
var match;
|
||||||
|
match = find_match(before_tokens, after_tokens, index_of_before_locations_in_after_tokens, start_in_before, end_in_before, start_in_after, end_in_after);
|
||||||
|
if (match != null) {
|
||||||
|
if (start_in_before < match.start_in_before && start_in_after < match.start_in_after) {
|
||||||
|
recursively_find_matching_blocks(before_tokens, after_tokens, index_of_before_locations_in_after_tokens, start_in_before, match.start_in_before, start_in_after, match.start_in_after, matching_blocks);
|
||||||
|
}
|
||||||
|
matching_blocks.push(match);
|
||||||
|
if (match.end_in_before <= end_in_before && match.end_in_after <= end_in_after) {
|
||||||
|
recursively_find_matching_blocks(before_tokens, after_tokens, index_of_before_locations_in_after_tokens, match.end_in_before + 1, end_in_before, match.end_in_after + 1, end_in_after, matching_blocks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return matching_blocks;
|
||||||
|
};
|
||||||
|
|
||||||
|
create_index = function(p) {
|
||||||
|
var i, idx, index, len, ref, token;
|
||||||
|
if (p.find_these == null) {
|
||||||
|
throw new Error('params must have find_these key');
|
||||||
|
}
|
||||||
|
if (p.in_these == null) {
|
||||||
|
throw new Error('params must have in_these key');
|
||||||
|
}
|
||||||
|
index = {};
|
||||||
|
ref = p.find_these;
|
||||||
|
for (i = 0, len = ref.length; i < len; i++) {
|
||||||
|
token = ref[i];
|
||||||
|
index[token] = [];
|
||||||
|
idx = p.in_these.indexOf(token);
|
||||||
|
while (idx !== -1) {
|
||||||
|
index[token].push(idx);
|
||||||
|
idx = p.in_these.indexOf(token, idx + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
};
|
||||||
|
|
||||||
|
find_matching_blocks = function(before_tokens, after_tokens) {
|
||||||
|
var index_of_before_locations_in_after_tokens, matching_blocks;
|
||||||
|
matching_blocks = [];
|
||||||
|
index_of_before_locations_in_after_tokens = create_index({
|
||||||
|
find_these: before_tokens,
|
||||||
|
in_these: after_tokens
|
||||||
|
});
|
||||||
|
return recursively_find_matching_blocks(before_tokens, after_tokens, index_of_before_locations_in_after_tokens, 0, before_tokens.length, 0, after_tokens.length, matching_blocks);
|
||||||
|
};
|
||||||
|
|
||||||
|
calculate_operations = function(before_tokens, after_tokens) {
|
||||||
|
var action_map, action_up_to_match_positions, i, index, is_single_whitespace, j, last_op, len, len1, match, match_starts_at_current_position_in_after, match_starts_at_current_position_in_before, matches, op, operations, position_in_after, position_in_before, post_processed;
|
||||||
|
if (before_tokens == null) {
|
||||||
|
throw new Error('before_tokens?');
|
||||||
|
}
|
||||||
|
if (after_tokens == null) {
|
||||||
|
throw new Error('after_tokens?');
|
||||||
|
}
|
||||||
|
position_in_before = position_in_after = 0;
|
||||||
|
operations = [];
|
||||||
|
action_map = {
|
||||||
|
'false,false': 'replace',
|
||||||
|
'true,false': 'insert',
|
||||||
|
'false,true': 'delete',
|
||||||
|
'true,true': 'none'
|
||||||
|
};
|
||||||
|
matches = find_matching_blocks(before_tokens, after_tokens);
|
||||||
|
matches.push(new Match(before_tokens.length, after_tokens.length, 0));
|
||||||
|
for (index = i = 0, len = matches.length; i < len; index = ++i) {
|
||||||
|
match = matches[index];
|
||||||
|
match_starts_at_current_position_in_before = position_in_before === match.start_in_before;
|
||||||
|
match_starts_at_current_position_in_after = position_in_after === match.start_in_after;
|
||||||
|
action_up_to_match_positions = action_map[[match_starts_at_current_position_in_before, match_starts_at_current_position_in_after].toString()];
|
||||||
|
if (action_up_to_match_positions !== 'none') {
|
||||||
|
operations.push({
|
||||||
|
action: action_up_to_match_positions,
|
||||||
|
start_in_before: position_in_before,
|
||||||
|
end_in_before: (action_up_to_match_positions !== 'insert' ? match.start_in_before - 1 : void 0),
|
||||||
|
start_in_after: position_in_after,
|
||||||
|
end_in_after: (action_up_to_match_positions !== 'delete' ? match.start_in_after - 1 : void 0)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (match.length !== 0) {
|
||||||
|
operations.push({
|
||||||
|
action: 'equal',
|
||||||
|
start_in_before: match.start_in_before,
|
||||||
|
end_in_before: match.end_in_before,
|
||||||
|
start_in_after: match.start_in_after,
|
||||||
|
end_in_after: match.end_in_after
|
||||||
|
});
|
||||||
|
}
|
||||||
|
position_in_before = match.end_in_before + 1;
|
||||||
|
position_in_after = match.end_in_after + 1;
|
||||||
|
}
|
||||||
|
post_processed = [];
|
||||||
|
last_op = {
|
||||||
|
action: 'none'
|
||||||
|
};
|
||||||
|
is_single_whitespace = function(op) {
|
||||||
|
if (op.action !== 'equal') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (op.end_in_before - op.start_in_before !== 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return /^\s$/.test(before_tokens.slice(op.start_in_before, +op.end_in_before + 1 || 9e9));
|
||||||
|
};
|
||||||
|
for (j = 0, len1 = operations.length; j < len1; j++) {
|
||||||
|
op = operations[j];
|
||||||
|
if (((is_single_whitespace(op)) && last_op.action === 'replace') || (op.action === 'replace' && last_op.action === 'replace')) {
|
||||||
|
last_op.end_in_before = op.end_in_before;
|
||||||
|
last_op.end_in_after = op.end_in_after;
|
||||||
|
} else {
|
||||||
|
post_processed.push(op);
|
||||||
|
last_op = op;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return post_processed;
|
||||||
|
};
|
||||||
|
|
||||||
|
consecutive_where = function(start, content, predicate) {
|
||||||
|
var answer, i, index, last_matching_index, len, token;
|
||||||
|
content = content.slice(start, +content.length + 1 || 9e9);
|
||||||
|
last_matching_index = void 0;
|
||||||
|
for (index = i = 0, len = content.length; i < len; index = ++i) {
|
||||||
|
token = content[index];
|
||||||
|
answer = predicate(token);
|
||||||
|
if (answer === true) {
|
||||||
|
last_matching_index = index;
|
||||||
|
}
|
||||||
|
if (answer === false) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (last_matching_index != null) {
|
||||||
|
return content.slice(0, +last_matching_index + 1 || 9e9);
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
wrap = function(tag, content) {
|
||||||
|
var length, non_tags, position, rendering, tags;
|
||||||
|
rendering = '';
|
||||||
|
position = 0;
|
||||||
|
length = content.length;
|
||||||
|
while (true) {
|
||||||
|
if (position >= length) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
non_tags = consecutive_where(position, content, isnt_tag);
|
||||||
|
position += non_tags.length;
|
||||||
|
if (non_tags.length !== 0) {
|
||||||
|
rendering += "<" + tag + ">" + (non_tags.join('')) + "</" + tag + ">";
|
||||||
|
}
|
||||||
|
if (position >= length) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tags = consecutive_where(position, content, is_tag);
|
||||||
|
position += tags.length;
|
||||||
|
rendering += tags.join('');
|
||||||
|
}
|
||||||
|
return rendering;
|
||||||
|
};
|
||||||
|
|
||||||
|
op_map = {
|
||||||
|
equal: function(op, before_tokens, after_tokens) {
|
||||||
|
return before_tokens.slice(op.start_in_before, +op.end_in_before + 1 || 9e9).join('');
|
||||||
|
},
|
||||||
|
insert: function(op, before_tokens, after_tokens) {
|
||||||
|
var val;
|
||||||
|
val = after_tokens.slice(op.start_in_after, +op.end_in_after + 1 || 9e9);
|
||||||
|
return wrap('ins', val);
|
||||||
|
},
|
||||||
|
"delete": function(op, before_tokens, after_tokens) {
|
||||||
|
var val;
|
||||||
|
val = before_tokens.slice(op.start_in_before, +op.end_in_before + 1 || 9e9);
|
||||||
|
return wrap('del', val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
op_map.replace = function(op, before_tokens, after_tokens) {
|
||||||
|
return (op_map["delete"](op, before_tokens, after_tokens)) + (op_map.insert(op, before_tokens, after_tokens));
|
||||||
|
};
|
||||||
|
|
||||||
|
render_operations = function(before_tokens, after_tokens, operations) {
|
||||||
|
var i, len, op, rendering;
|
||||||
|
rendering = '';
|
||||||
|
for (i = 0, len = operations.length; i < len; i++) {
|
||||||
|
op = operations[i];
|
||||||
|
rendering += op_map[op.action](op, before_tokens, after_tokens);
|
||||||
|
}
|
||||||
|
return rendering;
|
||||||
|
};
|
||||||
|
|
||||||
|
diff = function(before, after) {
|
||||||
|
var ops;
|
||||||
|
if (before === after) {
|
||||||
|
return before;
|
||||||
|
}
|
||||||
|
before = html_to_tokens(before);
|
||||||
|
after = html_to_tokens(after);
|
||||||
|
ops = calculate_operations(before, after);
|
||||||
|
return render_operations(before, after, ops);
|
||||||
|
};
|
||||||
|
|
||||||
|
diff.html_to_tokens = html_to_tokens;
|
||||||
|
|
||||||
|
diff.find_matching_blocks = find_matching_blocks;
|
||||||
|
|
||||||
|
find_matching_blocks.find_match = find_match;
|
||||||
|
|
||||||
|
find_matching_blocks.create_index = create_index;
|
||||||
|
|
||||||
|
diff.calculate_operations = calculate_operations;
|
||||||
|
|
||||||
|
diff.render_operations = render_operations;
|
||||||
|
|
||||||
|
if (typeof define === 'function') {
|
||||||
|
define([], function() {
|
||||||
|
return diff;
|
||||||
|
});
|
||||||
|
} else if (typeof module !== "undefined" && module !== null) {
|
||||||
|
module.exports = diff;
|
||||||
|
} else {
|
||||||
|
this.htmldiff = diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
}).call(this);
|
||||||
|
|
||||||
|
//# sourceMappingURL=htmldiff.js.map
|
1
spirit/core/static/spirit/scripts/js/htmldiff.js.map
Normal file
1
spirit/core/static/spirit/scripts/js/htmldiff.js.map
Normal file
File diff suppressed because one or more lines are too long
1
spirit/core/static/spirit/scripts/js/htmldiff.min.js
vendored
Normal file
1
spirit/core/static/spirit/scripts/js/htmldiff.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
spirit/core/static/spirit/scripts/js/like.min.js
vendored
Normal file
1
spirit/core/static/spirit/scripts/js/like.min.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
(function(){var $,Like,bind=function(fn,me){return function(){return fn.apply(me,arguments)}};$=jQuery,Like=function(){function Like(el,options){this.apiError=bind(this.apiError,this),this.removeLike=bind(this.removeLike,this),this.addLike=bind(this.addLike,this),this.sendLike=bind(this.sendLike,this),this.el=$(el),this.options=$.extend({},this.defaults,options),this.isSending=!1,this.setUp()}return Like.prototype.defaults={csrfToken:"csrf_token",likeText:"like ({count})",removeLikeText:"remove like ({count})"},Like.prototype.setUp=function(){return this.el.on("click",this.sendLike),this.el.on("click",this.stopClick)},Like.prototype.sendLike=function(){var post;this.isSending||(this.isSending=!0,post=$.post(this.el.attr("href"),{csrfmiddlewaretoken:this.options.csrfToken}),post.done(function(_this){return function(data){return data.url_delete?_this.addLike(data):data.url_create?_this.removeLike(data):_this.apiError()}}(this)),post.always(function(_this){return function(){return _this.isSending=!1}}(this)))},Like.prototype.addLike=function(data){var count,removeLikeText;return this.el.attr("href",data.url_delete),count=this.el.data("count"),count+=1,this.el.data("count",count),removeLikeText=$.format(this.options.removeLikeText,{count:count}),this.el.text(removeLikeText)},Like.prototype.removeLike=function(data){var count,likeText;return this.el.attr("href",data.url_create),count=this.el.data("count"),count-=1,this.el.data("count",count),likeText=$.format(this.options.likeText,{count:count}),this.el.text(likeText)},Like.prototype.apiError=function(){return this.el.text("api error")},Like.prototype.stopClick=function(e){e.preventDefault(),e.stopPropagation()},Like}(),$.fn.extend({like:function(options){return this.each(function(){return $(this).data("plugin_like")?void 0:$(this).data("plugin_like",new Like(this,options))})}}),$.fn.like.Like=Like}).call(this);
|
1
spirit/core/static/spirit/scripts/js/messages.min.js
vendored
Normal file
1
spirit/core/static/spirit/scripts/js/messages.min.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
(function(){var $,Messages,bind=function(fn,me){return function(){return fn.apply(me,arguments)}};$=jQuery,Messages=function(){function Messages(el){this.hasVisibleMessages=bind(this.hasVisibleMessages,this),this.hideMessage=bind(this.hideMessage,this),this.showAllCloseButtons=bind(this.showAllCloseButtons,this),this.placeMessages=bind(this.placeMessages,this),this.el=$(el),this.allCloseButtons=this.el.find(".js-messages-close-button"),this.setUp()}return Messages.prototype.setUp=function(){return this.placeMessages(),this.showAllCloseButtons(),this.allCloseButtons.on("click",this.hideMessage),this.allCloseButtons.on("click",this.stopClick)},Messages.prototype.placeMessages=function(){return this.hasHash()?this.el.addClass("is-fixed"):void 0},Messages.prototype.showAllCloseButtons=function(){return this.hasHash()?this.el.find(".js-messages-close").show():void 0},Messages.prototype.hideMessage=function(e){$(e.currentTarget).closest(".js-messages-set").hide(),this.hasVisibleMessages()||(this.el.hide(),this.el.removeClass("is-fixed"))},Messages.prototype.hasVisibleMessages=function(){return this.el.find(".js-messages-set").is(":visible")},Messages.prototype.stopClick=function(e){e.preventDefault(),e.stopPropagation()},Messages.prototype.hasHash=function(){var hash;return hash=window.location.hash.split("#")[1],null!=hash&&hash.length>0},Messages}(),$.fn.extend({messages:function(){return this.each(function(){return $(this).data("plugin_messages")?void 0:$(this).data("plugin_messages",new Messages(this))})}}),$.fn.messages.Messages=Messages}).call(this);
|
1
spirit/core/static/spirit/scripts/js/move_comments.min.js
vendored
Normal file
1
spirit/core/static/spirit/scripts/js/move_comments.min.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
(function(){var $,MoveComment,bind=function(fn,me){return function(){return fn.apply(me,arguments)}};$=jQuery,MoveComment=function(){function MoveComment(el,options){this.moveComments=bind(this.moveComments,this),this.addCommentSelection=bind(this.addCommentSelection,this),this.showMoveComments=bind(this.showMoveComments,this),this.el=$(el),this.options=$.extend({},this.defaults,options),this.setUp()}return MoveComment.prototype.defaults={csrfToken:"csrf_token",target:"#post_url"},MoveComment.prototype.setUp=function(){var $move_comments;return this.el.on("click",this.showMoveComments),this.el.on("click",this.stopClick),$move_comments=$(".js-move-comments"),$move_comments.on("click",this.moveComments),$move_comments.on("click",this.stopClick)},MoveComment.prototype.showMoveComments=function(){$(".move-comments").is(":hidden")&&($(".move-comments").show(),this.addCommentSelection())},MoveComment.prototype.addCommentSelection=function(){var $checkbox,$li;return $li=$("<li/>").appendTo(".comment-date"),$checkbox=$("<input/>",{"class":"move-comment-checkbox",name:"comments",type:"checkbox",value:""}).appendTo($li),$checkbox.each(function(){var $commentId;return $commentId=$(this).closest(".comment").data("pk"),$(this).val($commentId)})},MoveComment.prototype.moveComments=function(){var $form,topicId;$form=$("<form/>",{action:this.options.target,method:"post"}).hide().appendTo($("body")),$("<input/>",{name:"csrfmiddlewaretoken",type:"hidden",value:this.options.csrfToken}).appendTo($form),topicId=$("#id_move_comments_topic").val(),$("<input/>",{name:"topic",type:"text",value:topicId}).appendTo($form),$(".move-comment-checkbox").clone().appendTo($form),this.formSubmit($form)},MoveComment.prototype.formSubmit=function($form){return $form.submit()},MoveComment.prototype.stopClick=function(e){e.preventDefault(),e.stopPropagation()},MoveComment}(),$.fn.extend({move_comments:function(options){return this.each(function(){return $(this).data("plugin_move_comments")?void 0:$(this).data("plugin_move_comments",new MoveComment(this,options))})}}),$.fn.move_comments.MoveComment=MoveComment}).call(this);
|
1
spirit/core/static/spirit/scripts/js/notification.min.js
vendored
Normal file
1
spirit/core/static/spirit/scripts/js/notification.min.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
(function(){var $,Notification,bind=function(fn,me){return function(){return fn.apply(me,arguments)}};$=jQuery,Notification=function(){function Notification(el,options){this.ajaxDone=bind(this.ajaxDone,this),this.addErrorTxt=bind(this.addErrorTxt,this),this.addIsEmptyTxt=bind(this.addIsEmptyTxt,this),this.addNotifications=bind(this.addNotifications,this),this.tabSwitch=bind(this.tabSwitch,this),this.el=$(el),this.options=$.extend({},this.defaults,options),this.tabNotificationContent=$(this.el.data("related")),this.setUp()}return Notification.prototype.defaults={notificationUrl:"#ajax",notificationListUrl:"#show-all",mentionTxt:"{user} mention you on {topic}",commentTxt:"{user} has commented on {topic}",showAll:"Show all",empty:"Nothing to show",unread:"unread"},Notification.prototype.setUp=function(){return this.el.one("click",this.tabSwitch),this.el.one("click",this.stopClick)},Notification.prototype.tabSwitch=function(){var get;get=$.getJSON(this.options.notificationUrl),get.done(function(_this){return function(data,status,jqXHR){return data.n.length>0?_this.addNotifications(data):_this.addIsEmptyTxt()}}(this)),get.fail(function(_this){return function(jqxhr,textStatus,error){return _this.addErrorTxt(textStatus,error)}}(this)),get.always(function(_this){return function(){return _this.ajaxDone()}}(this))},Notification.prototype.addNotifications=function(data){var showAllLink,unread;return unread='<span class="row-unread">'+this.options.unread+"</span>",$.each(data.n,function(_this){return function(i,obj){var link,txt;return txt=1===obj.action?_this.options.mentionTxt:_this.options.commentTxt,obj.is_read||(txt=txt+" "+unread),link='<a href="'+obj.url+'">'+obj.title+"</a>",txt=$.format(txt,{user:obj.user,topic:link}),_this.tabNotificationContent.append("<div>"+txt+"</div>")}}(this)),showAllLink='<a href="'+this.options.notificationListUrl+'">'+this.options.showAll+"</a>",this.tabNotificationContent.append("<div>"+showAllLink+"</div>")},Notification.prototype.addIsEmptyTxt=function(){return this.tabNotificationContent.append("<div>"+this.options.empty+"</div>")},Notification.prototype.addErrorTxt=function(textStatus,error){return this.tabNotificationContent.append("<div>Error: "+textStatus+", "+error+"</div>")},Notification.prototype.ajaxDone=function(){return this.el.addClass("js-tab"),$.tab(),this.el.trigger("click")},Notification.prototype.stopClick=function(e){e.preventDefault(),e.stopPropagation()},Notification}(),$.extend({notification:function(options){return $(".js-tab-notification").each(function(){return $(this).data("plugin_notification")?void 0:$(this).data("plugin_notification",new Notification(this,options))})}}),$.notification.Notification=Notification}).call(this);
|
1
spirit/core/static/spirit/scripts/js/postify.min.js
vendored
Normal file
1
spirit/core/static/spirit/scripts/js/postify.min.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
(function(){var $,Postify,bind=function(fn,me){return function(){return fn.apply(me,arguments)}};$=jQuery,Postify=function(){function Postify(el,options){this.makePost=bind(this.makePost,this),this.el=$(el),this.options=$.extend({},this.defaults,options),this.setUp()}return Postify.prototype.defaults={csrfToken:"csrf_token"},Postify.prototype.setUp=function(){return this.el.on("click",this.makePost),this.el.on("click",this.stopClick)},Postify.prototype.makePost=function(){var $form;$form=$("<form/>",{action:this.el.attr("href"),method:"post"}).hide().appendTo($("body")),$("<input/>",{name:"csrfmiddlewaretoken",type:"hidden",value:this.options.csrfToken}).appendTo($form),this.formSubmit($form)},Postify.prototype.formSubmit=function($form){return $form.submit()},Postify.prototype.stopClick=function(e){e.preventDefault(),e.stopPropagation()},Postify}(),$.fn.extend({postify:function(options){return this.each(function(){return $(this).data("plugin_postify")?void 0:$(this).data("plugin_postify",new Postify(this,options))})}}),$.fn.postify.Postify=Postify}).call(this);
|
1
spirit/core/static/spirit/scripts/js/social_share.min.js
vendored
Normal file
1
spirit/core/static/spirit/scripts/js/social_share.min.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
(function(){var $,SocialShare,bind=function(fn,me){return function(){return fn.apply(me,arguments)}};$=jQuery,SocialShare=function(){function SocialShare(el){this.closeDialog=bind(this.closeDialog,this),this.showDialog=bind(this.showDialog,this),this.el=$(el),this.dialog=$(this.el.data("dialog")),this.setUp()}return SocialShare.prototype.setUp=function(){var $shareClose,$shareInput;return this.el.on("click",this.showDialog),this.el.on("click",this.stopClick),$shareClose=this.dialog.find(".share-close"),$shareClose.on("click",this.closeDialog),$shareClose.on("click",this.stopClick),$shareInput=this.dialog.find(".share-url"),$shareInput.on("focus",this.select),$shareInput.on("mouseup",this.stopClick)},SocialShare.prototype.showDialog=function(){$(".share").hide(),this.dialog.show()},SocialShare.prototype.closeDialog=function(){this.dialog.hide()},SocialShare.prototype.select=function(){$(this).select()},SocialShare.prototype.stopClick=function(e){e.preventDefault(),e.stopPropagation()},SocialShare}(),$.fn.extend({social_share:function(){return this.each(function(){return $(this).data("plugin_social_share")?void 0:$(this).data("plugin_social_share",new SocialShare(this))})}}),$.fn.social_share.SocialShare=SocialShare}).call(this);
|
1
spirit/core/static/spirit/scripts/js/store.min.js
vendored
Normal file
1
spirit/core/static/spirit/scripts/js/store.min.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
(function(){var $,Storage,bind=function(fn,me){return function(){return fn.apply(me,arguments)}};$=jQuery,Storage=function(){function Storage(el,lsKey){this.clearStorage=bind(this.clearStorage,this),this.updateField=bind(this.updateField,this),this.updateStorage=bind(this.updateStorage,this),this.el=$(el),this.lsKey=lsKey,this.setUp()}return Storage.prototype.setUp=function(){var $form;if("undefined"!=typeof localStorage&&null!==localStorage)return this.lsKey in localStorage&&this.updateField(),$(window).on("storage",this.updateField),this.el.on("input change propertychange",function(_this){return function(){$(window).off("storage",_this.updateField),_this.updateStorage(),$(window).on("storage",_this.updateField)}}(this)),$form=this.el.closest("form"),$form.on("submit",this.clearStorage)},Storage.prototype.updateStorage=function(){var err,error,value;value=this.el.val();try{localStorage[this.lsKey]=value}catch(error){err=error,localStorage.clear()}},Storage.prototype.updateField=function(){this.el.val(localStorage[this.lsKey])},Storage.prototype.clearStorage=function(){delete localStorage[this.lsKey]},Storage}(),$.fn.extend({store:function(lsKey){return this.each(function(){return $(this).data("plugin_store")?void 0:$(this).data("plugin_store",new Storage(this,lsKey))})}}),$.fn.store.Storage=Storage}).call(this);
|
1
spirit/core/static/spirit/scripts/js/tab.min.js
vendored
Normal file
1
spirit/core/static/spirit/scripts/js/tab.min.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
(function(){var $,Tab,bind=function(fn,me){return function(){return fn.apply(me,arguments)}};$=jQuery,Tab=function(){function Tab(el){this.showTabContent=bind(this.showTabContent,this),this.selectTab=bind(this.selectTab,this),this.unselectAllTabs=bind(this.unselectAllTabs,this),this.hideAllTabsContent=bind(this.hideAllTabsContent,this),this.tabSwitch=bind(this.tabSwitch,this),this.el=$(el),this.setUp()}return Tab.prototype.setUp=function(){return this.el.on("click",this.tabSwitch),this.el.on("click",this.stopClick)},Tab.prototype.tabSwitch=function(){this.hideAllTabsContent(),this.el.hasClass("is-selected")?this.el.removeClass("is-selected"):(this.unselectAllTabs(),this.selectTab(),this.showTabContent())},Tab.prototype.hideAllTabsContent=function(){var $tabs_container,$tabs_content;return $tabs_container=this.el.closest(".js-tabs-container"),$tabs_content=$tabs_container.find(".js-tab-content"),$tabs_content.hide()},Tab.prototype.unselectAllTabs=function(){var $tabs,$tabs_container;return $tabs_container=this.el.closest(".js-tabs-container"),$tabs=$tabs_container.find(".js-tab"),$tabs.removeClass("is-selected")},Tab.prototype.selectTab=function(){return this.el.addClass("is-selected")},Tab.prototype.showTabContent=function(){var tab_content;return tab_content=this.el.data("related"),$(tab_content).show()},Tab.prototype.stopClick=function(e){e.preventDefault(),e.stopPropagation()},Tab}(),$.extend({tab:function(){return $(".js-tab").each(function(){return $(this).data("plugin_tab")?void 0:$(this).data("plugin_tab",new Tab(this))})}}),$.tab.Tab=Tab}).call(this);
|
1
spirit/core/static/spirit/scripts/js/util.min.js
vendored
Normal file
1
spirit/core/static/spirit/scripts/js/util.min.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
(function(){var $;$=jQuery,$.extend({format:function(str,kwargs){var key,value;for(key in kwargs)value=kwargs[key],str=str.replace("{"+key+"}",String(value));return str}})}).call(this);
|
@ -15,5 +15,11 @@ $ npm install -y .
|
|||||||
## Build
|
## Build
|
||||||
|
|
||||||
```
|
```
|
||||||
$ npm run gulp coffee
|
$ npm run gulp js
|
||||||
|
```
|
||||||
|
|
||||||
|
## Test
|
||||||
|
|
||||||
|
```
|
||||||
|
$ npm run gulp test
|
||||||
```
|
```
|
||||||
|
298
spirit/core/static/spirit/scripts/src/htmldiff.coffee
Normal file
298
spirit/core/static/spirit/scripts/src/htmldiff.coffee
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
is_end_of_tag = (char)-> char is '>'
|
||||||
|
is_start_of_tag = (char)-> char is '<'
|
||||||
|
is_whitespace = (char)-> /^\s+$/.test char
|
||||||
|
is_tag = (token)-> /^\s*<[^>]+>\s*$/.test token
|
||||||
|
isnt_tag = (token)-> not is_tag token
|
||||||
|
|
||||||
|
class Match
|
||||||
|
constructor: (@start_in_before, @start_in_after, @length)->
|
||||||
|
@end_in_before = (@start_in_before + @length) - 1
|
||||||
|
@end_in_after = (@start_in_after + @length) - 1
|
||||||
|
|
||||||
|
html_to_tokens = (html)->
|
||||||
|
mode = 'char'
|
||||||
|
current_word = ''
|
||||||
|
words = []
|
||||||
|
|
||||||
|
for char in html
|
||||||
|
switch mode
|
||||||
|
when 'tag'
|
||||||
|
if is_end_of_tag char
|
||||||
|
current_word += '>'
|
||||||
|
words.push current_word
|
||||||
|
current_word = ''
|
||||||
|
if is_whitespace char
|
||||||
|
mode = 'whitespace'
|
||||||
|
else
|
||||||
|
mode = 'char'
|
||||||
|
else
|
||||||
|
current_word += char
|
||||||
|
when 'char'
|
||||||
|
if is_start_of_tag char
|
||||||
|
words.push current_word if current_word
|
||||||
|
current_word = '<'
|
||||||
|
mode = 'tag'
|
||||||
|
else if /\s/.test char
|
||||||
|
words.push current_word if current_word
|
||||||
|
current_word = char
|
||||||
|
mode = 'whitespace'
|
||||||
|
else if /[\w\#@]+/i.test char
|
||||||
|
current_word += char
|
||||||
|
else
|
||||||
|
words.push current_word if current_word
|
||||||
|
current_word = char
|
||||||
|
when 'whitespace'
|
||||||
|
if is_start_of_tag char
|
||||||
|
words.push current_word if current_word
|
||||||
|
current_word = '<'
|
||||||
|
mode = 'tag'
|
||||||
|
else if is_whitespace char
|
||||||
|
current_word += char
|
||||||
|
else
|
||||||
|
words.push current_word if current_word
|
||||||
|
current_word = char
|
||||||
|
mode = 'char'
|
||||||
|
else throw new Error "Unknown mode #{mode}"
|
||||||
|
|
||||||
|
words.push current_word if current_word
|
||||||
|
return words
|
||||||
|
|
||||||
|
find_match = (before_tokens, after_tokens,
|
||||||
|
index_of_before_locations_in_after_tokens,
|
||||||
|
start_in_before, end_in_before,
|
||||||
|
start_in_after, end_in_after)->
|
||||||
|
|
||||||
|
best_match_in_before = start_in_before
|
||||||
|
best_match_in_after = start_in_after
|
||||||
|
best_match_length = 0
|
||||||
|
|
||||||
|
match_length_at = {}
|
||||||
|
|
||||||
|
for index_in_before in [start_in_before...end_in_before]
|
||||||
|
new_match_length_at = {}
|
||||||
|
looking_for = before_tokens[index_in_before]
|
||||||
|
locations_in_after =
|
||||||
|
index_of_before_locations_in_after_tokens[looking_for]
|
||||||
|
|
||||||
|
for index_in_after in locations_in_after
|
||||||
|
continue if index_in_after < start_in_after
|
||||||
|
break if index_in_after >= end_in_after
|
||||||
|
|
||||||
|
unless match_length_at[index_in_after - 1]?
|
||||||
|
match_length_at[index_in_after - 1] = 0
|
||||||
|
new_match_length = match_length_at[index_in_after - 1] + 1
|
||||||
|
new_match_length_at[index_in_after] = new_match_length
|
||||||
|
|
||||||
|
if new_match_length > best_match_length
|
||||||
|
best_match_in_before = index_in_before - new_match_length + 1
|
||||||
|
best_match_in_after = index_in_after - new_match_length + 1
|
||||||
|
best_match_length = new_match_length
|
||||||
|
|
||||||
|
match_length_at = new_match_length_at
|
||||||
|
|
||||||
|
unless best_match_length is 0
|
||||||
|
match = (new Match best_match_in_before, best_match_in_after,\
|
||||||
|
best_match_length)
|
||||||
|
|
||||||
|
return match
|
||||||
|
|
||||||
|
recursively_find_matching_blocks = (before_tokens, after_tokens,
|
||||||
|
index_of_before_locations_in_after_tokens,
|
||||||
|
start_in_before, end_in_before,
|
||||||
|
start_in_after, end_in_after,
|
||||||
|
matching_blocks)->
|
||||||
|
|
||||||
|
match = (find_match before_tokens, after_tokens,
|
||||||
|
index_of_before_locations_in_after_tokens,
|
||||||
|
start_in_before, end_in_before,
|
||||||
|
start_in_after, end_in_after)
|
||||||
|
|
||||||
|
if match?
|
||||||
|
if start_in_before < match.start_in_before\
|
||||||
|
and start_in_after < match.start_in_after
|
||||||
|
recursively_find_matching_blocks before_tokens, after_tokens,
|
||||||
|
index_of_before_locations_in_after_tokens,
|
||||||
|
start_in_before, match.start_in_before,
|
||||||
|
start_in_after, match.start_in_after,
|
||||||
|
matching_blocks
|
||||||
|
|
||||||
|
matching_blocks.push match
|
||||||
|
|
||||||
|
if match.end_in_before <= end_in_before\
|
||||||
|
and match.end_in_after <= end_in_after
|
||||||
|
recursively_find_matching_blocks before_tokens, after_tokens,
|
||||||
|
index_of_before_locations_in_after_tokens,
|
||||||
|
match.end_in_before + 1, end_in_before,
|
||||||
|
match.end_in_after + 1, end_in_after,
|
||||||
|
matching_blocks
|
||||||
|
|
||||||
|
return matching_blocks
|
||||||
|
|
||||||
|
create_index = (p)->
|
||||||
|
throw new Error 'params must have find_these key' unless p.find_these?
|
||||||
|
throw new Error 'params must have in_these key' unless p.in_these?
|
||||||
|
|
||||||
|
index = {}
|
||||||
|
for token in p.find_these
|
||||||
|
index[token] = []
|
||||||
|
idx = p.in_these.indexOf token
|
||||||
|
while idx isnt -1
|
||||||
|
index[token].push idx
|
||||||
|
idx = p.in_these.indexOf token, idx+1
|
||||||
|
|
||||||
|
return index
|
||||||
|
|
||||||
|
find_matching_blocks = (before_tokens, after_tokens)->
|
||||||
|
matching_blocks = []
|
||||||
|
index_of_before_locations_in_after_tokens =
|
||||||
|
create_index
|
||||||
|
find_these: before_tokens
|
||||||
|
in_these: after_tokens
|
||||||
|
|
||||||
|
recursively_find_matching_blocks before_tokens, after_tokens,
|
||||||
|
index_of_before_locations_in_after_tokens,
|
||||||
|
0, before_tokens.length,
|
||||||
|
0, after_tokens.length,
|
||||||
|
matching_blocks
|
||||||
|
|
||||||
|
calculate_operations = (before_tokens, after_tokens)->
|
||||||
|
throw new Error 'before_tokens?' unless before_tokens?
|
||||||
|
throw new Error 'after_tokens?' unless after_tokens?
|
||||||
|
position_in_before = position_in_after = 0
|
||||||
|
operations = []
|
||||||
|
action_map =
|
||||||
|
'false,false': 'replace'
|
||||||
|
'true,false' : 'insert'
|
||||||
|
'false,true' : 'delete'
|
||||||
|
'true,true' : 'none'
|
||||||
|
|
||||||
|
matches = find_matching_blocks before_tokens, after_tokens
|
||||||
|
matches.push new Match before_tokens.length, after_tokens.length, 0
|
||||||
|
|
||||||
|
for match, index in matches
|
||||||
|
match_starts_at_current_position_in_before =
|
||||||
|
position_in_before is match.start_in_before
|
||||||
|
match_starts_at_current_position_in_after =
|
||||||
|
position_in_after is match.start_in_after
|
||||||
|
|
||||||
|
action_up_to_match_positions =
|
||||||
|
action_map[[match_starts_at_current_position_in_before,\
|
||||||
|
match_starts_at_current_position_in_after].toString()]
|
||||||
|
|
||||||
|
if action_up_to_match_positions isnt 'none'
|
||||||
|
operations.push
|
||||||
|
action: action_up_to_match_positions
|
||||||
|
start_in_before: position_in_before
|
||||||
|
end_in_before: (match.start_in_before - 1 \
|
||||||
|
unless action_up_to_match_positions is 'insert')
|
||||||
|
start_in_after: position_in_after
|
||||||
|
end_in_after: (match.start_in_after - 1 \
|
||||||
|
unless action_up_to_match_positions is 'delete')
|
||||||
|
|
||||||
|
unless match.length is 0
|
||||||
|
operations.push
|
||||||
|
action: 'equal'
|
||||||
|
start_in_before: match.start_in_before
|
||||||
|
end_in_before: match.end_in_before
|
||||||
|
start_in_after: match.start_in_after
|
||||||
|
end_in_after: match.end_in_after
|
||||||
|
|
||||||
|
position_in_before = match.end_in_before + 1
|
||||||
|
position_in_after = match.end_in_after + 1
|
||||||
|
|
||||||
|
post_processed = []
|
||||||
|
last_op = action: 'none'
|
||||||
|
is_single_whitespace = (op)->
|
||||||
|
return no unless op.action is 'equal'
|
||||||
|
return no unless op.end_in_before - op.start_in_before is 0
|
||||||
|
return /^\s$/.test before_tokens[op.start_in_before..op.end_in_before]
|
||||||
|
|
||||||
|
for op in operations
|
||||||
|
if ((is_single_whitespace op) and last_op.action is 'replace') or
|
||||||
|
(op.action is 'replace' and last_op.action is 'replace')
|
||||||
|
last_op.end_in_before = op.end_in_before
|
||||||
|
last_op.end_in_after = op.end_in_after
|
||||||
|
else
|
||||||
|
post_processed.push op
|
||||||
|
last_op = op
|
||||||
|
|
||||||
|
return post_processed
|
||||||
|
|
||||||
|
consecutive_where = (start, content, predicate)->
|
||||||
|
content = content[start..content.length]
|
||||||
|
last_matching_index = undefined
|
||||||
|
|
||||||
|
for token, index in content
|
||||||
|
answer = predicate token
|
||||||
|
last_matching_index = index if answer is yes
|
||||||
|
break if answer is no
|
||||||
|
|
||||||
|
return content[0..last_matching_index] if last_matching_index?
|
||||||
|
return []
|
||||||
|
|
||||||
|
wrap = (tag, content)->
|
||||||
|
rendering = ''
|
||||||
|
position = 0
|
||||||
|
length = content.length
|
||||||
|
|
||||||
|
loop
|
||||||
|
break if position >= length
|
||||||
|
non_tags = consecutive_where position, content, isnt_tag
|
||||||
|
position += non_tags.length
|
||||||
|
if non_tags.length isnt 0
|
||||||
|
rendering += "<#{tag}>#{non_tags.join ''}</#{tag}>"
|
||||||
|
|
||||||
|
break if position >= length
|
||||||
|
tags = consecutive_where position, content, is_tag
|
||||||
|
position += tags.length
|
||||||
|
rendering += tags.join ''
|
||||||
|
|
||||||
|
return rendering
|
||||||
|
|
||||||
|
op_map =
|
||||||
|
equal: (op, before_tokens, after_tokens)->
|
||||||
|
before_tokens[op.start_in_before..op.end_in_before].join ''
|
||||||
|
|
||||||
|
insert: (op, before_tokens, after_tokens)->
|
||||||
|
val = after_tokens[op.start_in_after..op.end_in_after]
|
||||||
|
wrap 'ins', val
|
||||||
|
|
||||||
|
delete: (op, before_tokens, after_tokens)->
|
||||||
|
val = before_tokens[op.start_in_before..op.end_in_before]
|
||||||
|
wrap 'del', val
|
||||||
|
|
||||||
|
op_map.replace = (op, before_tokens, after_tokens)->
|
||||||
|
(op_map.delete op, before_tokens, after_tokens) +
|
||||||
|
(op_map.insert op, before_tokens, after_tokens)
|
||||||
|
|
||||||
|
render_operations = (before_tokens, after_tokens, operations)->
|
||||||
|
rendering = ''
|
||||||
|
for op in operations
|
||||||
|
rendering += op_map[op.action] op, before_tokens, after_tokens
|
||||||
|
|
||||||
|
return rendering
|
||||||
|
|
||||||
|
diff = (before, after)->
|
||||||
|
return before if before is after
|
||||||
|
|
||||||
|
before = html_to_tokens before
|
||||||
|
after = html_to_tokens after
|
||||||
|
|
||||||
|
ops = calculate_operations before, after
|
||||||
|
|
||||||
|
render_operations before, after, ops
|
||||||
|
|
||||||
|
|
||||||
|
diff.html_to_tokens = html_to_tokens
|
||||||
|
diff.find_matching_blocks = find_matching_blocks
|
||||||
|
find_matching_blocks.find_match = find_match
|
||||||
|
find_matching_blocks.create_index = create_index
|
||||||
|
diff.calculate_operations = calculate_operations
|
||||||
|
diff.render_operations = render_operations
|
||||||
|
|
||||||
|
if typeof define is 'function'
|
||||||
|
define [], ()-> diff
|
||||||
|
else if module?
|
||||||
|
module.exports = diff
|
||||||
|
else
|
||||||
|
this.htmldiff = diff
|
@ -14,12 +14,14 @@ module.exports = function(config) {
|
|||||||
|
|
||||||
|
|
||||||
// list of files / patterns to load in the browser
|
// list of files / patterns to load in the browser
|
||||||
|
// todo: load the all.min.js instead of individual files
|
||||||
files: [
|
files: [
|
||||||
'vendors/jquery.min.js',
|
'vendors/jquery.min.js',
|
||||||
'vendors/**/*.js',
|
'vendors/**/*.js',
|
||||||
'test/jasmine-jquery.js',
|
'test/jasmine-jquery.js',
|
||||||
'test/suites/*-spec.js',
|
'test/suites/*-spec.js',
|
||||||
'*.js',
|
'!js/*.min.js', // Exclude
|
||||||
|
'js/*.js',
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -12,31 +12,30 @@
|
|||||||
|
|
||||||
<link rel="stylesheet" href="{% static "spirit/stylesheets/styles.all.min.css" %}">
|
<link rel="stylesheet" href="{% static "spirit/stylesheets/styles.all.min.css" %}">
|
||||||
|
|
||||||
<script src="{% static "spirit/scripts/vendors/jquery.min.js" %}"></script>
|
<script src="{% static "spirit/scripts/all.min.js" %}"></script>
|
||||||
<script src="{% static "spirit/scripts/vendors/highlightjs/highlight.min.js" %}"></script>
|
|
||||||
<script src="{% static "spirit/scripts/util.js" %}"></script>
|
|
||||||
<script src="{% static "spirit/scripts/tab.js" %}"></script>
|
|
||||||
<script src="{% static "spirit/scripts/postify.js" %}"></script>
|
|
||||||
<script src="{% static "spirit/scripts/social_share.js" %}"></script>
|
|
||||||
<script src="{% static "spirit/scripts/messages.js" %}"></script>
|
|
||||||
|
|
||||||
{% if user.is_authenticated %}
|
{# todo: use this if debug=true #}
|
||||||
|
{% comment %}
|
||||||
|
<script src="{% static "spirit/scripts/vendors/jquery.min.js" %}"></script>
|
||||||
|
<script src="{% static "spirit/scripts/vendors/highlightjs/highlight.min.js" %}"></script>
|
||||||
<script src="{% static "spirit/scripts/vendors/atwho/jquery.caret.min.js" %}"></script>
|
<script src="{% static "spirit/scripts/vendors/atwho/jquery.caret.min.js" %}"></script>
|
||||||
<script src="{% static "spirit/scripts/vendors/atwho/jquery.atwho.min.js" %}"></script>
|
<script src="{% static "spirit/scripts/vendors/atwho/jquery.atwho.min.js" %}"></script>
|
||||||
<script src="{% static "spirit/scripts/vendors/marked/marked.min.js" %}"></script>
|
<script src="{% static "spirit/scripts/vendors/marked/marked.min.js" %}"></script>
|
||||||
<script src="{% static "spirit/scripts/vendors/waypoints/waypoints.min.js" %}"></script>
|
<script src="{% static "spirit/scripts/vendors/waypoints/waypoints.min.js" %}"></script>
|
||||||
<script src="{% static "spirit/scripts/store.js" %}"></script>
|
<script src="{% static "spirit/scripts/js/util.js" %}"></script>
|
||||||
<script src="{% static "spirit/scripts/editor_image_upload.js" %}"></script>
|
<script src="{% static "spirit/scripts/js/tab.js" %}"></script>
|
||||||
<script src="{% static "spirit/scripts/editor.js" %}"></script>
|
<script src="{% static "spirit/scripts/js/postify.js" %}"></script>
|
||||||
<script src="{% static "spirit/scripts/emoji_list.js" %}"></script>
|
<script src="{% static "spirit/scripts/js/social_share.js" %}"></script>
|
||||||
<script src="{% static "spirit/scripts/like.js" %}"></script>
|
<script src="{% static "spirit/scripts/js/messages.js" %}"></script>
|
||||||
<script src="{% static "spirit/scripts/bookmark.js" %}"></script>
|
<script src="{% static "spirit/scripts/js/store.js" %}"></script>
|
||||||
<script src="{% static "spirit/scripts/notification.js" %}"></script>
|
<script src="{% static "spirit/scripts/js/editor_image_upload.js" %}"></script>
|
||||||
{% endif %}
|
<script src="{% static "spirit/scripts/js/editor.js" %}"></script>
|
||||||
|
<script src="{% static "spirit/scripts/js/emoji_list.js" %}"></script>
|
||||||
{% if user.st.is_moderator %}
|
<script src="{% static "spirit/scripts/js/like.js" %}"></script>
|
||||||
<script src="{% static "spirit/scripts/move_comments.js" %}"></script>
|
<script src="{% static "spirit/scripts/js/bookmark.js" %}"></script>
|
||||||
{% endif %}
|
<script src="{% static "spirit/scripts/js/notification.js" %}"></script>
|
||||||
|
<script src="{% static "spirit/scripts/js/move_comments.js" %}"></script>
|
||||||
|
{% endcomment %}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user