scrivito_editors 0.66.0 → 0.70.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/images/imgly_sdk/ui/night/blur/blur.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/buttons/back.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/buttons/done-highlighted.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/buttons/done.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/cancel.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/close.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/crop/16-9.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/crop/4-3.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/crop/custom.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/crop/square.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/crosshair.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/a15.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/breeze.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/bw.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/bwhard.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/celsius.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/chest.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/default.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/fixie.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/food.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/fridge.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/front.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/glam.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/gobblin.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/identity.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/k1.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/k2.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/k6.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/kdynamic.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/lenin.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/lomo.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/mellow.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/morning.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/orchid.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/pola.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/pola669.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/quozi.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/semired.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/sunny.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/texas.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/filters/x400.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/flip/horizontal.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/flip/vertical.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/loading.gif +0 -0
- data/app/assets/images/imgly_sdk/ui/night/operations/brightness.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/operations/contrast.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/operations/crop.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/operations/filters.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/operations/flip.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/operations/focus.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/operations/frames.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/operations/orientation.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/operations/radial-blur.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/operations/rotation.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/operations/saturation.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/operations/stickers.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/operations/text.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/operations/tilt-shift.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/rotation/left.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/rotation/right.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/slider/minus.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/slider/plus.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/top/aspect.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/top/new.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/top/original.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/top/undo.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/top/zoom-in.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/top/zoom-out.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/transparency.png +0 -0
- data/app/assets/images/imgly_sdk/ui/night/upload.png +0 -0
- data/app/assets/javascripts/canvas-to-blob.js +95 -0
- data/app/assets/javascripts/imglykit.js +19998 -0
- data/app/assets/javascripts/scrivito_editors/binary_editor.js.coffee +21 -18
- data/app/assets/javascripts/scrivito_editors/date_editor.js.coffee +15 -6
- data/app/assets/javascripts/scrivito_editors/helpers/file_dropzone.js.coffee +11 -5
- data/app/assets/javascripts/scrivito_editors/helpers/setup_binary_button_container.js.coffee +6 -0
- data/app/assets/javascripts/scrivito_editors/html_editor.js.coffee +1 -0
- data/app/assets/javascripts/scrivito_editors/{image_editor.js.coffee → image_drop_editor.js.coffee} +1 -1
- data/app/assets/javascripts/scrivito_editors/image_editor.js.coffee.erb +76 -0
- data/app/assets/javascripts/scrivito_editors/reload.js.coffee +12 -0
- data/app/assets/javascripts/scrivito_editors/slider_editor.js.coffee +1 -1
- data/app/assets/javascripts/scrivito_editors/string_editor.js.coffee +6 -3
- data/app/assets/javascripts/scrivito_editors/stringlist_editor.js.coffee +13 -0
- data/app/assets/javascripts/scrivito_editors_core.js +2 -0
- data/app/assets/stylesheets/imglykit-night-ui.css +1098 -0
- data/app/assets/stylesheets/scrivito-editors-imglykit-override.css +9 -0
- data/app/assets/stylesheets/scrivito_editors.css +2 -0
- data/app/assets/stylesheets/scrivito_editors/editors/button_container.css +29 -0
- data/app/assets/stylesheets/scrivito_editors/editors/{image_editor.css → image_drop_editor.css} +0 -0
- data/app/assets/stylesheets/scrivito_editors/icons.css.erb +1 -54
- data/app/assets/stylesheets/scrivito_editors/stringlist_editor.css +24 -0
- data/lib/scrivito_editors/engine.rb +20 -0
- data/vendor/assets/javascripts/jquery.caret.js +2 -0
- data/vendor/assets/javascripts/jquery.tag-editor.js +340 -0
- data/vendor/assets/stylesheets/jquery.tag-editor.css +49 -0
- metadata +91 -10
- data/Rakefile +0 -16
- data/app/assets/stylesheets/scrivito_editors/binary_editor.css +0 -14
@@ -0,0 +1,9 @@
|
|
1
|
+
/* override for scrivito */
|
2
|
+
.image_kit_start {height: 100%;}
|
3
|
+
.imglykit,
|
4
|
+
.imglykit-container {border-radius:0!important;}
|
5
|
+
.imglykit-header-row,
|
6
|
+
.imglykit-container .imglykit-header {display:none!important;}
|
7
|
+
.imglykit-container .imglykit-canvas-container.imglykit-header-padding {padding-top:40px;}
|
8
|
+
.imglykit-container .imglykit-top-controls.imglykit-header-padding {top:0;}
|
9
|
+
.imglykit-container .imglykit-controls img {display: inline;}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
.scrivito-editor-image-button-container {
|
3
|
+
display:inline-block; position: relative;
|
4
|
+
max-width:100%;
|
5
|
+
}
|
6
|
+
.scrivito-editor-binary-button-container:not(.scrivito-editor-image-button-container) {
|
7
|
+
display:block; position: relative;
|
8
|
+
background: rgba(0,0,0,.1);
|
9
|
+
box-shadow: 0 0 0 2px rgba(0,0,0,.2);
|
10
|
+
min-height: 90px; padding:5px;
|
11
|
+
}
|
12
|
+
.scrivito-editor-image-button-container .editing-button,
|
13
|
+
.scrivito-editor-binary-button-container .editing-button {
|
14
|
+
padding: 5px 8px; margin: 0px;
|
15
|
+
position: absolute; right: 10px; top: 10px;
|
16
|
+
background: rgba(0,0,0,.7);
|
17
|
+
border:1px solid rgba(255, 255, 255, 0.3);
|
18
|
+
box-shadow: 0 0 3px 2px rgba(255, 255, 255, 0.2);
|
19
|
+
}
|
20
|
+
.scrivito-editor-image-button-container .editing-button:hover,
|
21
|
+
.scrivito-editor-binary-button-container .editing-button:hover {
|
22
|
+
background: rgba(88,88,88,.8);
|
23
|
+
}
|
24
|
+
.scrivito-editor-image-button-container .editing-button + .editing-button,
|
25
|
+
.scrivito-editor-binary-button-container .editing-button + .editing-button {
|
26
|
+
right: 50px;
|
27
|
+
}
|
28
|
+
.scrivito-editor-image-button-container .editing-button .editing-icon,
|
29
|
+
.scrivito-editor-binary-button-container .editing-button .editing-icon { color:#fff;}
|
data/app/assets/stylesheets/scrivito_editors/editors/{image_editor.css → image_drop_editor.css}
RENAMED
File without changes
|
@@ -25,60 +25,7 @@
|
|
25
25
|
}
|
26
26
|
|
27
27
|
/* kept for backwards compatibility reasons */
|
28
|
+
.editing-icon-edit:after { content: "\F026"; }
|
28
29
|
.editing-icon-search:after { content: "\F043"; }
|
29
30
|
.editing-icon-trash:after { content: "\F038"; }
|
30
31
|
.editing-icon-plus:after { content: "\F044"; }
|
31
|
-
|
32
|
-
/* deprecated */
|
33
|
-
.editing-icon-ip:after,
|
34
|
-
.editing-icon-text:after,
|
35
|
-
.editing-icon-image:after,
|
36
|
-
.editing-icon-headline:after,
|
37
|
-
.editing-icon-video:after,
|
38
|
-
.editing-icon-map:after,
|
39
|
-
.editing-icon-table:after,
|
40
|
-
.editing-icon-slider:after,
|
41
|
-
.editing-icon-list:after,
|
42
|
-
.editing-icon-downloads:after,
|
43
|
-
.editing-icon-person:after,
|
44
|
-
.editing-icon-presentation:after,
|
45
|
-
.editing-icon-login:after,
|
46
|
-
.editing-icon-teaser:after,
|
47
|
-
.editing-icon-interactive:after,
|
48
|
-
.editing-icon-hr:after,
|
49
|
-
.editing-icon-1col:after,
|
50
|
-
.editing-icon-2cols:after,
|
51
|
-
.editing-icon-2colsl:after,
|
52
|
-
.editing-icon-2colsr:after,
|
53
|
-
.editing-icon-3cols:after,
|
54
|
-
.editing-icon-workspaces:after,
|
55
|
-
.editing-icon-tag:after,
|
56
|
-
.editing-icon-link:after,
|
57
|
-
.editing-icon-box:after,
|
58
|
-
.editing-icon-puzzle:after,
|
59
|
-
.editing-icon-dates:after,
|
60
|
-
.editing-icon-newsletter:after,
|
61
|
-
.editing-icon-special:after,
|
62
|
-
.editing-icon-edit:after,
|
63
|
-
.editing-icon-ok:after,
|
64
|
-
.editing-icon-cancel:after,
|
65
|
-
.editing-icon-eye:after,
|
66
|
-
.editing-icon-ok-box:after,
|
67
|
-
.editing-icon-group:after,
|
68
|
-
.editing-icon-generic:after,
|
69
|
-
.editing-icon-pdf:after,
|
70
|
-
.editing-icon-chevron-up:after,
|
71
|
-
.editing-icon-chevron-down:after,
|
72
|
-
.editing-icon-chevron-left:after,
|
73
|
-
.editing-icon-chevron-right:after,
|
74
|
-
.editing-icon-refresh:after,
|
75
|
-
.editing-icon-reorder:after,
|
76
|
-
.editing-icon-th-small:after,
|
77
|
-
.editing-icon-th-medium:after,
|
78
|
-
.editing-icon-th:after,
|
79
|
-
.editing-icon-th-large:after {
|
80
|
-
content: "\F000";
|
81
|
-
font-family: 'scrivito_content_browser_iconsregular';
|
82
|
-
vertical-align: top;
|
83
|
-
font-size: 110px;
|
84
|
-
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
/*
|
2
|
+
*= require jquery.tag-editor
|
3
|
+
*/
|
4
|
+
|
5
|
+
[data-scrivito-field-type=stringlist]+.tag-editor .tag-editor-delete { padding-right: 10px; }
|
6
|
+
[data-scrivito-field-type=stringlist]+.tag-editor .tag-editor-delete i {
|
7
|
+
-moz-osx-font-smoothing: grayscale;
|
8
|
+
-webkit-font-smoothing: antialiased;
|
9
|
+
color: #666;
|
10
|
+
font-family: "scrivito_customer_icons";
|
11
|
+
font-size: 10px;
|
12
|
+
font-style: normal;
|
13
|
+
font-weight: normal;
|
14
|
+
line-height: 9px!important;
|
15
|
+
text-decoration: none;
|
16
|
+
vertical-align: middle;
|
17
|
+
}
|
18
|
+
[data-scrivito-field-type=stringlist]+.tag-editor .tag-editor-delete i { background: none; }
|
19
|
+
[data-scrivito-field-type=stringlist]+.tag-editor .tag-editor-delete i:after { content: "\F03c"; }
|
20
|
+
[data-scrivito-field-type=stringlist]+.tag-editor .tag-editor-tag.active+.tag-editor-delete,
|
21
|
+
[data-scrivito-field-type=stringlist]+.tag-editor .tag-editor-tag.active+.tag-editor-delete i:after {
|
22
|
+
content: "";
|
23
|
+
cursor: text;
|
24
|
+
}
|
@@ -9,5 +9,25 @@ module ScrivitoEditors
|
|
9
9
|
ActionView::Base.send :include, CmsTagHelper
|
10
10
|
ActionView::Base.send :include, ScrivitoTagHelper
|
11
11
|
end
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def imgly_assets
|
15
|
+
imgly_assets_paths.inject({}) do |asset_map, file|
|
16
|
+
asset_map[file] = yield(file)
|
17
|
+
asset_map
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def imgly_assets_paths
|
24
|
+
images_path = ScrivitoEditors::Engine.root + 'app/assets/images/'
|
25
|
+
absolute_paths = Dir[images_path + 'imgly_sdk/**/*'].select { |f| File.file?(f) }
|
26
|
+
|
27
|
+
absolute_paths.map do |absolute_path|
|
28
|
+
Pathname.new(absolute_path).relative_path_from(images_path).to_s
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
12
32
|
end
|
13
33
|
end
|
@@ -0,0 +1,2 @@
|
|
1
|
+
// http://code.accursoft.com/caret - 1.3.3
|
2
|
+
!function(e){e.fn.caret=function(e){var t=this[0],n="true"===t.contentEditable;if(0==arguments.length){if(window.getSelection){if(n){t.focus();var o=window.getSelection().getRangeAt(0),r=o.cloneRange();return r.selectNodeContents(t),r.setEnd(o.endContainer,o.endOffset),r.toString().length}return t.selectionStart}if(document.selection){if(t.focus(),n){var o=document.selection.createRange(),r=document.body.createTextRange();return r.moveToElementText(t),r.setEndPoint("EndToEnd",o),r.text.length}var e=0,c=t.createTextRange(),r=document.selection.createRange().duplicate(),a=r.getBookmark();for(c.moveToBookmark(a);0!==c.moveStart("character",-1);)e++;return e}return t.selectionStart?t.selectionStart:0}if(-1==e&&(e=this[n?"text":"val"]().length),window.getSelection)n?(t.focus(),window.getSelection().collapse(t.firstChild,e)):t.setSelectionRange(e,e);else if(document.body.createTextRange)if(n){var c=document.body.createTextRange();c.moveToElementText(t),c.moveStart("character",e),c.collapse(!0),c.select()}else{var c=t.createTextRange();c.move("character",e),c.select()}return n||t.focus(),e}}(jQuery);
|
@@ -0,0 +1,340 @@
|
|
1
|
+
/*
|
2
|
+
jQuery tagEditor v1.0.14
|
3
|
+
Copyright (c) 2014 Simon Steinberger / Pixabay
|
4
|
+
GitHub: https://github.com/Pixabay/jQuery-tagEditor
|
5
|
+
License: http://www.opensource.org/licenses/mit-license.php
|
6
|
+
*/
|
7
|
+
|
8
|
+
(function($){
|
9
|
+
// auto grow input (stackoverflow.com/questions/931207)
|
10
|
+
$.fn.tagEditorInput=function(){var t=" ",e=$(this),n=parseInt(e.css("fontSize")),i=$("<span/>").css({position:"absolute",top:-9999,left:-9999,width:"auto",fontSize:e.css("fontSize"),fontFamily:e.css("fontFamily"),fontWeight:e.css("fontWeight"),letterSpacing:e.css("letterSpacing"),whiteSpace:"nowrap"}),s=function(){if(t!==(t=e.val())){i.html(t.replace(/&/g,"&").replace(/\s/g," ").replace(/</g,"<").replace(/>/g,">"));var s=i.width()+n;20>s&&(s=20),s!=e.width()&&e.width(s)}};return i.insertAfter(e),e.bind("keyup keydown focus",s)};
|
11
|
+
|
12
|
+
// plugin with val as parameter for public methods
|
13
|
+
$.fn.tagEditor = function(options, val, blur){
|
14
|
+
|
15
|
+
// build options dictionary with default values
|
16
|
+
var blur_result, o = $.extend({}, $.fn.tagEditor.defaults, options), selector = this;
|
17
|
+
|
18
|
+
// store regex and default delimiter in options for later use
|
19
|
+
o.dregex = new RegExp('['+o.delimiter.replace('-', '\-')+']', 'g');
|
20
|
+
|
21
|
+
// public methods
|
22
|
+
if (typeof options == 'string') {
|
23
|
+
|
24
|
+
// depending on selector, response may contain tag lists of multiple editor instances
|
25
|
+
var response = [];
|
26
|
+
selector.each(function(){
|
27
|
+
// the editor is the next sibling to the hidden, original field
|
28
|
+
var el = $(this), o = el.data('options'), ed = el.next('.tag-editor');
|
29
|
+
if (options == 'getTags')
|
30
|
+
response.push({field: el[0], editor: ed, tags: ed.data('tags')});
|
31
|
+
else if (options == 'addTag') {
|
32
|
+
// insert new tag
|
33
|
+
$('<li><div class="tag-editor-spacer"> '+o.delimiter[0]+'</div><div class="tag-editor-tag"></div><div class="tag-editor-delete"><i></i></div></li>').appendTo(ed).find('.tag-editor-tag')
|
34
|
+
.html('<input type="text" maxlength="'+o.maxLength+'">').addClass('active').find('input').val(val).blur();
|
35
|
+
if (!blur) ed.click();
|
36
|
+
else $('.placeholder', ed).remove();
|
37
|
+
} else if (options == 'removeTag') {
|
38
|
+
// trigger delete on matching tag, then click editor to create a new tag
|
39
|
+
$('.tag-editor-tag', ed).filter(function(){return $(this).html()==val;}).closest('li').find('.tag-editor-delete').click();
|
40
|
+
if (!blur) ed.click();
|
41
|
+
} else if (options == 'destroy') {
|
42
|
+
el.removeClass('tag-editor-hidden-src').removeData('options').off('focus.tag-editor').next('.tag-editor').remove();
|
43
|
+
}
|
44
|
+
});
|
45
|
+
return options == 'getTags' ? response : this;
|
46
|
+
}
|
47
|
+
|
48
|
+
// delete selected tags on backspace, delete, ctrl+x
|
49
|
+
function delete_selected_tags(e){
|
50
|
+
if (e.which == 8 || e.which == 46 || e.ctrlKey && e.which == 88) {
|
51
|
+
try {
|
52
|
+
var sel = getSelection(), el = $(sel.getRangeAt(0).commonAncestorContainer);
|
53
|
+
} catch(e){ el = 0; }
|
54
|
+
if (el && el.hasClass('tag-editor')) {
|
55
|
+
var tags = [], splits = sel.toString().split(el.prev().data('options').dregex);
|
56
|
+
for (i=0; i<splits.length; i++){ var tag = $.trim(splits[i]); if (tag) tags.push(tag); }
|
57
|
+
$('.tag-editor-tag', el).each(function(){
|
58
|
+
if (~$.inArray($(this).html(), tags)) $(this).closest('li').find('.tag-editor-delete').click();
|
59
|
+
});
|
60
|
+
}
|
61
|
+
}
|
62
|
+
}
|
63
|
+
if (window.getSelection) $(document).off('keydown.tag-editor').on('keydown.tag-editor', delete_selected_tags);
|
64
|
+
|
65
|
+
return selector.each(function(){
|
66
|
+
var el = $(this), tag_list = []; // cache current tags
|
67
|
+
|
68
|
+
// create editor (ed) instance
|
69
|
+
var ed = $('<ul '+(o.clickDelete ? 'oncontextmenu="return false;" ' : '')+'class="tag-editor"></ul>').insertAfter(el);
|
70
|
+
el.addClass('tag-editor-hidden-src') // hide original field
|
71
|
+
.data('options', o) // set data on hidden field
|
72
|
+
.on('focus.tag-editor', function(){ ed.click(); }); // simulate tabindex
|
73
|
+
|
74
|
+
// add dummy item for min-height on empty editor
|
75
|
+
ed.append('<li style="width:1px"> </li>');
|
76
|
+
|
77
|
+
// markup for new tag
|
78
|
+
var new_tag = '<li><div class="tag-editor-spacer"> '+o.delimiter[0]+'</div><div class="tag-editor-tag"></div><div class="tag-editor-delete"><i></i></div></li>';
|
79
|
+
|
80
|
+
// helper: update global data
|
81
|
+
function set_placeholder(){
|
82
|
+
if (o.placeholder && !tag_list.length && !$('.deleted, .placeholder, input', ed).length)
|
83
|
+
ed.append('<li class="placeholder"><div>'+o.placeholder+'</div></li>');
|
84
|
+
}
|
85
|
+
|
86
|
+
// helper: update global data
|
87
|
+
function update_globals(init){
|
88
|
+
var old_tags = tag_list.toString();
|
89
|
+
tag_list = $('.tag-editor-tag:not(.deleted)', ed).map(function(i, e) {
|
90
|
+
var val = $.trim($(this).hasClass('active') ? $(this).find('input').val() : $(e).text());
|
91
|
+
if (val) return val;
|
92
|
+
}).get();
|
93
|
+
ed.data('tags', tag_list);
|
94
|
+
el.val(tag_list.join(o.delimiter[0]));
|
95
|
+
// change callback except for plugin init
|
96
|
+
if (!init) if (old_tags != tag_list.toString()) o.onChange(el, ed, tag_list);
|
97
|
+
set_placeholder();
|
98
|
+
}
|
99
|
+
|
100
|
+
ed.click(function(e, closest_tag){
|
101
|
+
var d, dist = 99999, loc;
|
102
|
+
|
103
|
+
// do not create tag when user selects tags by text selection
|
104
|
+
if (window.getSelection && getSelection() != '') return;
|
105
|
+
|
106
|
+
blur_result = true
|
107
|
+
$('input:focus', ed).blur();
|
108
|
+
if (!blur_result) return false;
|
109
|
+
blur_result = true
|
110
|
+
|
111
|
+
// always remove placeholder on click
|
112
|
+
$('.placeholder', ed).remove();
|
113
|
+
if (closest_tag && closest_tag.length)
|
114
|
+
loc = 'before';
|
115
|
+
else {
|
116
|
+
// calculate tag closest to click position
|
117
|
+
$('.tag-editor-tag', ed).each(function(){
|
118
|
+
var tag = $(this), to = tag.offset(), tag_x = to.left, tag_y = to.top;
|
119
|
+
if (e.pageY >= tag_y && e.pageY <= tag_y+tag.height()) {
|
120
|
+
if (e.pageX < tag_x) loc = 'before', d = tag_x - e.pageX;
|
121
|
+
else loc = 'after', d = e.pageX - tag_x - tag.width();
|
122
|
+
if (d < dist) dist = d, closest_tag = tag;
|
123
|
+
}
|
124
|
+
});
|
125
|
+
}
|
126
|
+
|
127
|
+
if (loc == 'before') {
|
128
|
+
$(new_tag).insertBefore(closest_tag.closest('li')).find('.tag-editor-tag').click();
|
129
|
+
} else if (loc == 'after')
|
130
|
+
$(new_tag).insertAfter(closest_tag.closest('li')).find('.tag-editor-tag').click();
|
131
|
+
else // empty editor
|
132
|
+
$(new_tag).appendTo(ed).find('.tag-editor-tag').click();
|
133
|
+
return false;
|
134
|
+
});
|
135
|
+
|
136
|
+
ed.on('click', '.tag-editor-delete', function(e){
|
137
|
+
// delete icon is hidden when input is visible; place cursor near invisible delete icon on click
|
138
|
+
if ($(this).prev().hasClass('active')) { $(this).closest('li').find('input').caret(-1); return false; }
|
139
|
+
|
140
|
+
var li = $(this).closest('li'), tag = li.find('.tag-editor-tag');
|
141
|
+
if (o.beforeTagDelete(el, ed, tag_list, tag.html()) === false) return false;
|
142
|
+
tag.addClass('deleted').animate({width: 0}, 175, function(){ li.remove(); set_placeholder(); });
|
143
|
+
update_globals();
|
144
|
+
return false;
|
145
|
+
});
|
146
|
+
|
147
|
+
// delete on right mouse click or ctrl+click
|
148
|
+
if (o.clickDelete)
|
149
|
+
ed.on('mousedown', '.tag-editor-tag', function(e){
|
150
|
+
if (e.ctrlKey || e.which > 1) {
|
151
|
+
var li = $(this).closest('li'), tag = li.find('.tag-editor-tag');
|
152
|
+
if (o.beforeTagDelete(el, ed, tag_list, tag.html()) === false) return false;
|
153
|
+
tag.addClass('deleted').animate({width: 0}, 175, function(){ li.remove(); set_placeholder(); });
|
154
|
+
update_globals();
|
155
|
+
return false;
|
156
|
+
}
|
157
|
+
});
|
158
|
+
|
159
|
+
ed.on('click', '.tag-editor-tag', function(e){
|
160
|
+
// delete on right click or ctrl+click -> exit
|
161
|
+
if (o.clickDelete && (e.ctrlKey || e.which > 1)) return false;
|
162
|
+
|
163
|
+
if (!$(this).hasClass('active')) {
|
164
|
+
var tag = $(this).html();
|
165
|
+
// guess cursor position in text input
|
166
|
+
var left_percent = Math.abs(($(this).offset().left - e.pageX)/$(this).width()), caret_pos = parseInt(tag.length*left_percent),
|
167
|
+
input = $(this).html('<input type="text" maxlength="'+o.maxLength+'" value="'+tag+'">').addClass('active').find('input');
|
168
|
+
input.data('old_tag', tag).tagEditorInput().focus().caret(caret_pos);
|
169
|
+
if (o.autocomplete) {
|
170
|
+
var aco = $.extend({}, o.autocomplete);
|
171
|
+
// extend user provided autocomplete select method
|
172
|
+
var ac_select = 'select' in aco ? o.autocomplete.select : '';
|
173
|
+
aco.select = function(e, ui){ if (ac_select) ac_select(e, ui); setTimeout(function(){
|
174
|
+
ed.trigger('click', [$('.active', ed).find('input').closest('li').next('li').find('.tag-editor-tag')]);
|
175
|
+
}, 20); };
|
176
|
+
input.autocomplete(aco);
|
177
|
+
}
|
178
|
+
}
|
179
|
+
return false;
|
180
|
+
});
|
181
|
+
|
182
|
+
// helper: split into multiple tags, e.g. after paste
|
183
|
+
function split_cleanup(input){
|
184
|
+
var li = input.closest('li'), sub_tags = input.val().replace(/ +/, ' ').split(o.dregex), old_tag = input.data('old_tag');
|
185
|
+
var old_tags = tag_list.slice(0); // copy tag_list
|
186
|
+
for (i=0; i<sub_tags.length; i++) {
|
187
|
+
tag = $.trim(sub_tags[i]).slice(0, o.maxLength);
|
188
|
+
if (tag) {
|
189
|
+
if (o.forceLowercase) tag = tag.toLowerCase();
|
190
|
+
tag = o.beforeTagSave(el, ed, old_tags, old_tag, tag) || tag;
|
191
|
+
// remove duplicates
|
192
|
+
if (~$.inArray(tag, old_tags))
|
193
|
+
$('.tag-editor-tag', ed).each(function(){ if ($(this).html() == tag) $(this).closest('li').remove(); });
|
194
|
+
old_tags.push(tag);
|
195
|
+
li.before('<li><div class="tag-editor-spacer"> '+o.delimiter[0]+'</div><div class="tag-editor-tag">'+tag+'</div><div class="tag-editor-delete"><i></i></div></li>');
|
196
|
+
}
|
197
|
+
}
|
198
|
+
input.attr('maxlength', o.maxLength).removeData('old_tag').val('').focus();
|
199
|
+
update_globals();
|
200
|
+
}
|
201
|
+
|
202
|
+
ed.on('blur', 'input', function(e){
|
203
|
+
var input = $(this), old_tag = input.data('old_tag'), tag = $.trim(input.val().replace(/ +/, ' ').replace(o.dregex, o.delimiter[0]));
|
204
|
+
if (!tag) {
|
205
|
+
if (old_tag && o.beforeTagDelete(el, ed, tag_list, old_tag) === false) {
|
206
|
+
input.val(old_tag).focus();
|
207
|
+
blur_result = false;
|
208
|
+
update_globals();
|
209
|
+
return;
|
210
|
+
}
|
211
|
+
try { input.closest('li').remove(); } catch(e){}
|
212
|
+
if (old_tag) update_globals();
|
213
|
+
}
|
214
|
+
else if (tag.indexOf(o.delimiter[0])>=0) { split_cleanup(input); return; }
|
215
|
+
else if (tag != old_tag) {
|
216
|
+
if (o.forceLowercase) tag = tag.toLowerCase();
|
217
|
+
tag = o.beforeTagSave(el, ed, tag_list, old_tag, tag) || tag;
|
218
|
+
// remove duplicates
|
219
|
+
$('.tag-editor-tag:not(.active)', ed).each(function(){ if ($(this).html() == tag) $(this).closest('li').remove(); });
|
220
|
+
}
|
221
|
+
input.parent().html(tag).removeClass('active');
|
222
|
+
if (tag != old_tag) update_globals();
|
223
|
+
set_placeholder();
|
224
|
+
});
|
225
|
+
|
226
|
+
var pasted_content;
|
227
|
+
ed.on('paste', 'input', function(e){
|
228
|
+
$(this).removeAttr('maxlength');
|
229
|
+
pasted_content = $(this);
|
230
|
+
setTimeout(function(){ split_cleanup(pasted_content); }, 30);
|
231
|
+
});
|
232
|
+
|
233
|
+
// keypress delimiter
|
234
|
+
var inp;
|
235
|
+
ed.on('keypress', 'input', function(e){
|
236
|
+
if (o.delimiter.indexOf(String.fromCharCode(e.which))>=0) {
|
237
|
+
inp = $(this);
|
238
|
+
setTimeout(function(){ split_cleanup(inp); }, 20);
|
239
|
+
}
|
240
|
+
});
|
241
|
+
|
242
|
+
ed.on('keydown', 'input', function(e){
|
243
|
+
var $t = $(this);
|
244
|
+
|
245
|
+
// left/up key + backspace key on empty field
|
246
|
+
if ((e.which == 37 || !o.autocomplete && e.which == 38) && !$t.caret() || e.which == 8 && !$t.val()) {
|
247
|
+
var prev_tag = $t.closest('li').prev('li').find('.tag-editor-tag');
|
248
|
+
if (prev_tag.length) prev_tag.click().find('input').caret(-1);
|
249
|
+
else if ($t.val()) $(new_tag).insertBefore($t.closest('li')).find('.tag-editor-tag').click();
|
250
|
+
return false;
|
251
|
+
}
|
252
|
+
// right/down key
|
253
|
+
else if ((e.which == 39 || !o.autocomplete && e.which == 40) && ($t.caret() == $t.val().length)) {
|
254
|
+
var next_tag = $t.closest('li').next('li').find('.tag-editor-tag');
|
255
|
+
if (next_tag.length) next_tag.click().find('input').caret(0);
|
256
|
+
else if ($t.val()) ed.click();
|
257
|
+
return false;
|
258
|
+
}
|
259
|
+
// tab key
|
260
|
+
else if (e.which == 9) {
|
261
|
+
// shift+tab
|
262
|
+
if (e.shiftKey) {
|
263
|
+
var prev_tag = $t.closest('li').prev('li').find('.tag-editor-tag');
|
264
|
+
if (prev_tag.length) prev_tag.click().find('input').caret(0);
|
265
|
+
else if ($t.val()) $(new_tag).insertBefore($t.closest('li')).find('.tag-editor-tag').click();
|
266
|
+
// allow tabbing to previous element
|
267
|
+
else {
|
268
|
+
el.attr('disabled', 'disabled');
|
269
|
+
setTimeout(function(){ el.removeAttr('disabled'); }, 30);
|
270
|
+
return;
|
271
|
+
}
|
272
|
+
return false;
|
273
|
+
// tab
|
274
|
+
} else {
|
275
|
+
var next_tag = $t.closest('li').next('li').find('.tag-editor-tag');
|
276
|
+
if (next_tag.length) next_tag.click().find('input').caret(0);
|
277
|
+
else if ($t.val()) ed.click();
|
278
|
+
else return; // allow tabbing to next element
|
279
|
+
return false;
|
280
|
+
}
|
281
|
+
}
|
282
|
+
// del key
|
283
|
+
else if (e.which == 46 && (!$.trim($t.val()) || ($t.caret() == $t.val().length))) {
|
284
|
+
var next_tag = $t.closest('li').next('li').find('.tag-editor-tag');
|
285
|
+
if (next_tag.length) next_tag.click().find('input').caret(0);
|
286
|
+
else if ($t.val()) ed.click();
|
287
|
+
return false;
|
288
|
+
}
|
289
|
+
// enter key
|
290
|
+
else if (e.which == 13) {
|
291
|
+
ed.trigger('click', [$t.closest('li').next('li').find('.tag-editor-tag')]);
|
292
|
+
return false;
|
293
|
+
}
|
294
|
+
// pos1
|
295
|
+
else if (e.which == 36 && !$t.caret()) ed.find('.tag-editor-tag').first().click();
|
296
|
+
// end
|
297
|
+
else if (e.which == 35 && $t.caret() == $t.val().length) ed.find('.tag-editor-tag').last().click();
|
298
|
+
// esc
|
299
|
+
else if (e.which == 27) {
|
300
|
+
$t.val($t.data('old_tag') ? $t.data('old_tag') : '').blur();
|
301
|
+
return false;
|
302
|
+
}
|
303
|
+
});
|
304
|
+
|
305
|
+
// create initial tags
|
306
|
+
var tags = o.initialTags.length ? o.initialTags : el.val().split(o.dregex);
|
307
|
+
for (i=0; i<tags.length; i++) {
|
308
|
+
var tag = $.trim(tags[i].replace(/ +/, ' '));
|
309
|
+
if (tag) {
|
310
|
+
if (o.forceLowercase) tag = tag.toLowerCase();
|
311
|
+
tag_list.push(tag);
|
312
|
+
ed.append('<li><div class="tag-editor-spacer"> '+o.delimiter[0]+'</div><div class="tag-editor-tag">'+tag+'</div><div class="tag-editor-delete"><i></i></div></li>');
|
313
|
+
}
|
314
|
+
}
|
315
|
+
update_globals(true); // true -> no onChange callback
|
316
|
+
|
317
|
+
// init sortable
|
318
|
+
if (o.sortable && $.fn.sortable) ed.sortable({
|
319
|
+
distance: 5, cancel: '.tag-editor-spacer, input', helper: 'clone',
|
320
|
+
update: function(){ update_globals(); }
|
321
|
+
});
|
322
|
+
});
|
323
|
+
};
|
324
|
+
|
325
|
+
$.fn.tagEditor.defaults = {
|
326
|
+
initialTags: [],
|
327
|
+
maxLength: 50,
|
328
|
+
delimiter: ',;',
|
329
|
+
placeholder: '',
|
330
|
+
forceLowercase: true,
|
331
|
+
clickDelete: false,
|
332
|
+
sortable: true, // jQuery UI sortable
|
333
|
+
autocomplete: null, // options dict for jQuery UI autocomplete
|
334
|
+
|
335
|
+
// callbacks
|
336
|
+
onChange: function(){},
|
337
|
+
beforeTagSave: function(){},
|
338
|
+
beforeTagDelete: function(){}
|
339
|
+
};
|
340
|
+
}(jQuery));
|