sketchily 0.0.2 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +64 -9
- data/app/views/sketchily/_embed.html.erb~ +2 -9
- data/app/views/sketchily/_embed.js.erb +9 -4
- data/app/views/sketchily/_embed.js.erb~ +10 -5
- data/app/views/sketchily/_sketchily.html.erb~ +3 -7
- data/app/views/sketchily/_sketchily_tag.html.erb~ +1 -6
- data/lib/sketchily.rb~ +1 -1
- data/lib/sketchily/sketchily.rb~ +28 -0
- data/lib/sketchily/sketchily_tag.rb~ +15 -0
- data/lib/sketchily/svg_edit.rb~ +15 -0
- data/lib/sketchily/svg_edit_tag.rb~ +1 -1
- data/lib/sketchily/version.rb +1 -1
- data/lib/sketchily/version.rb~ +1 -1
- data/spec/dummy/log/development.log +9 -0
- data/spec/spec_helper.rb~ +18 -0
- data/vendor/assets/svg-edit-2.6/extensions/ext-imagelib.js~ +453 -0
- data/vendor/assets/svg-edit-2.6/extensions/ext-server_opensave.js~ +180 -0
- data/vendor/assets/svg-edit-2.6/svg-editor.html~ +2 -2
- data/vendor/assets/svg-edit-2.6/svg-editor.js~ +4969 -0
- data/vendor/assets/svg-edit-2.6/svgedit.compiled.js~ +465 -0
- metadata +258 -252
- data/app/helpers/sketchily.rb~ +0 -10
- data/app/views/sketchily/_svg_edit_tag.html.erb~ +0 -51
- data/app/views/sketchily/svg_edit_tag_.html~ +0 -35
- data/lib/sketchily/sketchily_show.rb~ +0 -13
- data/vendor/assets/svg-edit-2.6/svg-editor.css~ +0 -1500
data/README.md
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# Sketchily
|
2
2
|
|
3
3
|
Sketchily allows the easy integration of svg-edit with any rails application.
|
4
|
-
|
4
|
+
|
5
|
+
Currently supports and provides `svg-edit-2.6`.
|
5
6
|
|
6
7
|
## Installation
|
7
8
|
|
@@ -19,13 +20,68 @@ Or install it yourself as:
|
|
19
20
|
|
20
21
|
## Usage
|
21
22
|
|
22
|
-
Sketchily adds new form elements which can be accessed by calling
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
23
|
+
Sketchily adds new form elements which can be accessed by calling:
|
24
|
+
|
25
|
+
- `f.sketchily` or simply `sketchily` from inside a `form_for @my_object |f|`
|
26
|
+
- `sketchily_tag` from inside a `form_tag`
|
27
|
+
|
28
|
+
This gem also adds a helper method that can be called to display the resulting SVG images (without an editor):
|
29
|
+
|
30
|
+
- `sketchily_show` from any view template
|
31
|
+
|
32
|
+
### `sketchily` and `sketchily_tag` functions
|
33
|
+
|
34
|
+
- Both of these functions work exactly like the equivalent `hidden_field` functions, except that svg-edit is displayed instead.
|
35
|
+
- The `f.sketchily` format accepts a method name and an options hash.
|
36
|
+
- The sketchily format accepts an object name, a method name and an options hash.
|
37
|
+
- The `sketchily_tag` format accepts a tag name, the svg string to be edited and an options hash.
|
38
|
+
|
39
|
+
Currently available options are:
|
40
|
+
|
41
|
+
- `width`
|
42
|
+
- `height`
|
43
|
+
- `show_menu` (true if you want svg-edit's menu to be displayed)
|
44
|
+
- `hide_image_tool` (true if you want to hide the image tool button)
|
45
|
+
- `canvas_width` (number specifying initial canvas width)
|
46
|
+
- `canvas_height` (number specifying initial canvas height)
|
47
|
+
- `canvas_expansion` (0 if you want to disable scrolling)
|
48
|
+
- `hide_rulers` (true if you want to hide the canvas rulers)
|
49
|
+
- other standard html attributes for the input tag
|
50
|
+
|
51
|
+
It is recommended that the database entries associated with sketchily form elements be of type `text`.
|
52
|
+
|
53
|
+
Example usage (haml):
|
54
|
+
|
55
|
+
= form_for @shirt do |f|
|
56
|
+
f.text_field :title
|
57
|
+
f.sketchily :svg
|
58
|
+
|
59
|
+
### `sketchily_show` helper
|
60
|
+
|
61
|
+
- This function takes the base64-encoded SVG string as an argument and an options hash.
|
62
|
+
- The SVG string can be directly read from the field used by the previous functions.
|
63
|
+
|
64
|
+
Currently available options are:
|
65
|
+
|
66
|
+
- `width`
|
67
|
+
- `height`
|
68
|
+
|
69
|
+
Passing only one of those options should keep the aspect ratio constant in most browsers.
|
70
|
+
|
71
|
+
Example usage (haml):
|
72
|
+
|
73
|
+
= sketchily_show @shirt.svg, :width => "500"
|
74
|
+
|
75
|
+
## Browser Support
|
76
|
+
|
77
|
+
Although more testing is needed, we currently believe sketchily supports any browsers that svg-edit 2.6 supports, namely:
|
78
|
+
|
79
|
+
- Firefox 1.5+
|
80
|
+
- Opera 9.50+
|
81
|
+
- Safari 4+
|
82
|
+
- Chrome 1+
|
83
|
+
- IE 9+
|
84
|
+
- IE 6+ (with the Chrome Frame plugin)
|
29
85
|
|
30
86
|
## Contributing
|
31
87
|
|
@@ -36,4 +92,3 @@ It is recommended that the database entries associated with sketchily form eleme
|
|
36
92
|
5. Commit your changes (`git commit -am 'Add some feature'`)
|
37
93
|
6. Push to the branch (`git push origin my-new-feature`)
|
38
94
|
7. Create new pull request
|
39
|
-
|
@@ -4,25 +4,18 @@
|
|
4
4
|
#
|
5
5
|
# Additionally, they may override the following variables:
|
6
6
|
show_menu ||= false
|
7
|
-
hide_image_tool ||= false
|
8
|
-
canvas_width ||= 640,
|
9
|
-
canvas_height ||= 480,
|
10
|
-
canvas_expansion ||= 3
|
11
|
-
hide_rulers ||= false
|
12
7
|
width ||= "750px"
|
13
8
|
height ||= "650px" %>
|
14
9
|
|
15
10
|
<%= javascript_include_tag "embedapi" %>
|
16
11
|
<%= javascript_include_tag "svgutils" %>
|
17
|
-
|
18
12
|
<script type="text/javascript">
|
19
13
|
<%= render :partial => "sketchily/embed",
|
20
14
|
:formats => :js,
|
21
15
|
:locals => {:id => id,
|
22
16
|
:value => value,
|
23
|
-
:show_menu => show_menu
|
24
|
-
:hide_image_tool => hide_image_tool} %>
|
17
|
+
:show_menu => show_menu} %>
|
25
18
|
</script>
|
26
19
|
|
27
|
-
<iframe src="/assets/svg-editor.html?source
|
20
|
+
<iframe src="/assets/svg-editor.html?source="
|
28
21
|
width="<%= width %>" height="<%= height %>" id="svgedit_<%= id %>" onload="initEmbed_<%= id %>();"></iframe>
|
@@ -8,6 +8,13 @@
|
|
8
8
|
|
9
9
|
var svgCanvas_<%= id %> = null;
|
10
10
|
|
11
|
+
function attachSubmitHandler_<%= id %>() {
|
12
|
+
$("input#<%= id %>").closest("form").one("submit", function(event) {
|
13
|
+
svgCanvas_<%= id %>.getSvgString()(handleSvgData_<%= id %>);
|
14
|
+
return false;
|
15
|
+
});
|
16
|
+
}
|
17
|
+
|
11
18
|
function handleSvgData_<%= id %>(data, error) {
|
12
19
|
if (error) {
|
13
20
|
alert('Error: ' + error);
|
@@ -15,6 +22,7 @@ function handleSvgData_<%= id %>(data, error) {
|
|
15
22
|
else {
|
16
23
|
$("input#<%= id %>").attr("value", svgedit.utilities.encode64("<?xml version=\"1.0\"?>\n" + data));
|
17
24
|
$("input#<%= id %>").closest("form").submit();
|
25
|
+
attachSubmitHandler_<%= id %>();
|
18
26
|
}
|
19
27
|
}
|
20
28
|
|
@@ -41,10 +49,7 @@ function initEmbed_<%= id %>() {
|
|
41
49
|
imageTool.style.display = 'none';
|
42
50
|
<% end %>
|
43
51
|
|
44
|
-
|
45
|
-
svgCanvas_<%= id %>.getSvgString()(handleSvgData_<%= id %>);
|
46
|
-
event.preventDefault();
|
47
|
-
});
|
52
|
+
attachSubmitHandler_<%= id %>();
|
48
53
|
|
49
54
|
svgCanvas_<%= id %>.setSvgString(svgedit.utilities.decode64("<%= value.try(:squish) %>"));
|
50
55
|
}
|
@@ -8,6 +8,13 @@
|
|
8
8
|
|
9
9
|
var svgCanvas_<%= id %> = null;
|
10
10
|
|
11
|
+
function attachSubmitHandler_<%= id %>() {
|
12
|
+
$("input#<%= id %>").closest("form").one("submit", function(event) {
|
13
|
+
svgCanvas_<%= id %>.getSvgString()(handleSvgData_<%= id %>);
|
14
|
+
event.preventDefault();
|
15
|
+
});
|
16
|
+
}
|
17
|
+
|
11
18
|
function handleSvgData_<%= id %>(data, error) {
|
12
19
|
if (error) {
|
13
20
|
alert('Error: ' + error);
|
@@ -15,6 +22,7 @@ function handleSvgData_<%= id %>(data, error) {
|
|
15
22
|
else {
|
16
23
|
$("input#<%= id %>").attr("value", svgedit.utilities.encode64("<?xml version=\"1.0\"?>\n" + data));
|
17
24
|
$("input#<%= id %>").closest("form").submit();
|
25
|
+
attachSubmitHandler_<%= id %>();
|
18
26
|
}
|
19
27
|
}
|
20
28
|
|
@@ -36,15 +44,12 @@ function initEmbed_<%= id %>() {
|
|
36
44
|
toolsTop.style.right = '2px';
|
37
45
|
<% end %>
|
38
46
|
|
39
|
-
<% if
|
47
|
+
<% if hide_image_tool %>
|
40
48
|
var imageTool = doc.getElementById('tool_image');
|
41
49
|
imageTool.style.display = 'none';
|
42
50
|
<% end %>
|
43
51
|
|
44
|
-
|
45
|
-
svgCanvas_<%= id %>.getSvgString()(handleSvgData_<%= id %>);
|
46
|
-
event.preventDefault();
|
47
|
-
});
|
52
|
+
attachSubmitHandler_<%= id %>();
|
48
53
|
|
49
54
|
svgCanvas_<%= id %>.setSvgString(svgedit.utilities.decode64("<%= value.try(:squish) %>"));
|
50
55
|
}
|
@@ -4,20 +4,16 @@
|
|
4
4
|
# method
|
5
5
|
# options %>
|
6
6
|
|
7
|
-
<% sketchily_tag = ActionView::Helpers::InstanceTag.new(object_name, method, template, options.delete(:object))
|
7
|
+
<% sketchily_tag = ActionView::Helpers::InstanceTag.new(object_name, method, template, options.delete(:object))
|
8
|
+
sketchily_tag.value = sketchily_tag.value(sketchily_tag.object).try(:squish).try(:html_safe) %>
|
8
9
|
|
9
10
|
<%= render :partial => "sketchily/embed",
|
10
11
|
:formats => :html,
|
11
12
|
:locals => {:id => sketchily_tag.send(:tag_id),
|
12
13
|
:value => sketchily_tag.value(sketchily_tag.object),
|
13
14
|
:show_menu => options[:show_menu],
|
14
|
-
:hide_image_tool => options[:hide_image_tool],
|
15
|
-
:canvas_width => options[:canvas_width],
|
16
|
-
:canvas_height => options[:canvas_height],
|
17
|
-
:canvas_expansion => options[:canvas_expansion],
|
18
|
-
:hide_rulers => options[:hide_rulers],
|
19
15
|
:width => options[:width],
|
20
16
|
:height => options[:height]} %>
|
21
17
|
|
22
|
-
<%= sketchily_tag.to_input_field_tag("hidden", options.except(:show_menu, :
|
18
|
+
<%= sketchily_tag.to_input_field_tag("hidden", options.except(:show_menu, :width, :height)) %>
|
23
19
|
|
@@ -9,13 +9,8 @@
|
|
9
9
|
:locals => {:id => id,
|
10
10
|
:value => value,
|
11
11
|
:show_menu => options[:show_menu],
|
12
|
-
:hide_image_tool => options[:hide_image_tool],
|
13
|
-
:canvas_width => options[:canvas_width],
|
14
|
-
:canvas_height => options[:canvas_height],
|
15
|
-
:canvas_expansion => options[:canvas_expansion],
|
16
|
-
:hide_rulers => options[:hide_rulers],
|
17
12
|
:width => options[:width],
|
18
13
|
:height => options[:height]} %>
|
19
14
|
|
20
|
-
<%= tag :input, { "type" => "hidden", "name" => name, "id" => id, "value" => value }.update(options.except(:show_menu, :
|
15
|
+
<%= tag :input, { "type" => "hidden", "name" => name, "id" => id, "value" => value.try(:squish).try(:html_safe) }.update(options.except(:show_menu, :width, :height).stringify_keys) %>
|
21
16
|
|
data/lib/sketchily.rb~
CHANGED
@@ -3,6 +3,7 @@ module Sketchily
|
|
3
3
|
|
4
4
|
VIEW = ActionView::Base.new
|
5
5
|
VIEW.view_paths << "#{ROOT}/app/views"
|
6
|
+
VIEW.view_paths << "#{ROOT}/app/views/sketchily"
|
6
7
|
|
7
8
|
def self.render(options = {}, local_assigns = {}, &block)
|
8
9
|
VIEW.render(options, local_assigns, &block)
|
@@ -12,5 +13,4 @@ end
|
|
12
13
|
require "sketchily/engine"
|
13
14
|
require "sketchily/sketchily"
|
14
15
|
require "sketchily/sketchily_tag"
|
15
|
-
require "sketchily/sketchily_show"
|
16
16
|
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Sketchily
|
2
|
+
module FormBuilderInstanceMethods
|
3
|
+
def sketchily(method, options = {})
|
4
|
+
Sketchily.render(:partial => "sketchily/sketchily",
|
5
|
+
:locals => {:template => @template, :object_name => @object_name,
|
6
|
+
:method => method, :options => objectify_options(options)}).html_safe
|
7
|
+
end
|
8
|
+
|
9
|
+
def svg_edit(method, options = {})
|
10
|
+
sketchily(method, options)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module ActionViewBaseInstanceMethods
|
15
|
+
def sketchily(object_name, method, options = {})
|
16
|
+
Sketchily.render(:partial => "sketchily/sketchily",
|
17
|
+
:locals => {:template => self, :object_name => object_name,
|
18
|
+
:method => method, :options => objectify_options(options)}).html_safe
|
19
|
+
end
|
20
|
+
|
21
|
+
def svg_edit(object_name, method, options = {})
|
22
|
+
sketchily(object_name, method, options)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
ActionView::Helpers::FormBuilder.send :include, Sketchily::FormBuilderInstanceMethods
|
28
|
+
ActionView::Base.send :include, Sketchily::ActionViewBaseInstanceMethods
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module SketchilyTag
|
2
|
+
module ActionViewBaseInstanceMethods
|
3
|
+
def sketchily_tag(name, value = nil, options = {})
|
4
|
+
Sketchily.render(:partial => "sketchily/sketchily_tag",
|
5
|
+
:locals => {:name => name, :id => sanitize_to_id(name),
|
6
|
+
:value => value, :options => options}).html_safe
|
7
|
+
end
|
8
|
+
|
9
|
+
def svg_edit_tag(name, value = nil, options = {})
|
10
|
+
sketchily_tag(name, value, options)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
ActionView::Base.send :include, SketchilyTag::ActionViewBaseInstanceMethods
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Sketchily
|
2
|
+
module FormHelperInstanceMethods
|
3
|
+
def sketchily(object_name, method, options = {})
|
4
|
+
ActionView::Helpers::InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("hidden", options)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
module FormBuilderInstanceMethods
|
9
|
+
def sketchily(method, options = {})
|
10
|
+
@template.hidden_field(@object_name, method, objectify_options(options))
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
ActionView::Helpers::FormBuilder.send :include, Sketchily::InstanceMethods
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module SvgEditTag
|
2
2
|
module InstanceMethods
|
3
3
|
def svg_edit_tag(name, value = nil, options = {})
|
4
|
-
|
4
|
+
tag :input, { "type" => "text", "name" => name, "id" => sanitize_to_id(name), "value" => value }.update(options.stringify_keys)
|
5
5
|
end
|
6
6
|
end
|
7
7
|
end
|
data/lib/sketchily/version.rb
CHANGED
data/lib/sketchily/version.rb~
CHANGED
@@ -0,0 +1,9 @@
|
|
1
|
+
Connecting to database specified by database.yml
|
2
|
+
Rendered /home/dantemss/Desktop/sketchily/app/views/sketchily/_sketchily.html.erb (24.5ms)
|
3
|
+
Rendered /home/dantemss/Desktop/sketchily/app/views/sketchily/_sketchily.html.erb (4.7ms)
|
4
|
+
Rendered /home/dantemss/Desktop/sketchily/app/views/sketchily/_sketchily.html.erb (4.6ms)
|
5
|
+
Connecting to database specified by database.yml
|
6
|
+
Rendered /home/dantemss/Desktop/sketchily/app/views/sketchily/_sketchily.html.erb (6.7ms)
|
7
|
+
Connecting to database specified by database.yml
|
8
|
+
Rendered /home/dantemss/Desktop/sketchily/app/views/sketchily/_sketchily.html.erb (17.6ms)
|
9
|
+
Connecting to database specified by database.yml
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Configure Rails Environment
|
2
|
+
ENV["RAILS_ENV"] = "test"
|
3
|
+
|
4
|
+
require File.expand_path("../dummy/config/environment.rb", __FILE__)
|
5
|
+
require "rails/test_help"
|
6
|
+
|
7
|
+
require "minitest/autorun"
|
8
|
+
require "minitest/rails"
|
9
|
+
|
10
|
+
Rails.backtrace_cleaner.remove_silencers!
|
11
|
+
|
12
|
+
# Load support files
|
13
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
14
|
+
|
15
|
+
# Load fixtures from the engine
|
16
|
+
if ActiveSupport::TestCase.method_defined?(:fixture_path=)
|
17
|
+
ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
|
18
|
+
end
|
@@ -0,0 +1,453 @@
|
|
1
|
+
/*
|
2
|
+
* ext-imagelib.js
|
3
|
+
*
|
4
|
+
* Licensed under the MIT License
|
5
|
+
*
|
6
|
+
* Copyright(c) 2010 Alexis Deveria
|
7
|
+
*
|
8
|
+
*/
|
9
|
+
|
10
|
+
svgEditor.addExtension("imagelib", function() {
|
11
|
+
|
12
|
+
var uiStrings = svgEditor.uiStrings;
|
13
|
+
|
14
|
+
$.extend(uiStrings, {
|
15
|
+
imagelib: {
|
16
|
+
select_lib: 'Select an image library',
|
17
|
+
show_list: 'Show library list',
|
18
|
+
import_single: 'Import single',
|
19
|
+
import_multi: 'Import multiple',
|
20
|
+
open: 'Open as new document'
|
21
|
+
}
|
22
|
+
});
|
23
|
+
|
24
|
+
var img_libs = [/*{
|
25
|
+
name: 'Demo library (local)',
|
26
|
+
url: '/assets/extensions/imagelib/index.html',
|
27
|
+
description: 'Demonstration library for SVG-edit on this server'
|
28
|
+
}, */
|
29
|
+
{
|
30
|
+
name: 'IAN Symbol Libraries',
|
31
|
+
url: 'http://ian.umces.edu/symbols/catalog/svgedit/album_chooser.php',
|
32
|
+
description: 'Free library of illustrations'
|
33
|
+
}
|
34
|
+
];
|
35
|
+
|
36
|
+
var xlinkns = "http://www.w3.org/1999/xlink";
|
37
|
+
|
38
|
+
function closeBrowser() {
|
39
|
+
$('#imgbrowse_holder').hide();
|
40
|
+
}
|
41
|
+
|
42
|
+
function importImage(url) {
|
43
|
+
var newImage = svgCanvas.addSvgElementFromJson({
|
44
|
+
"element": "image",
|
45
|
+
"attr": {
|
46
|
+
"x": 0,
|
47
|
+
"y": 0,
|
48
|
+
"width": 0,
|
49
|
+
"height": 0,
|
50
|
+
"id": svgCanvas.getNextId(),
|
51
|
+
"style": "pointer-events:inherit"
|
52
|
+
}
|
53
|
+
});
|
54
|
+
svgCanvas.clearSelection();
|
55
|
+
svgCanvas.addToSelection([newImage]);
|
56
|
+
svgCanvas.setImageURL(url);
|
57
|
+
}
|
58
|
+
|
59
|
+
var mode = 's';
|
60
|
+
var multi_arr = [];
|
61
|
+
var cur_meta;
|
62
|
+
var tranfer_stopped = false;
|
63
|
+
var pending = {};
|
64
|
+
|
65
|
+
window.addEventListener("message", function(evt) {
|
66
|
+
// Receive postMessage data
|
67
|
+
var response = evt.data;
|
68
|
+
|
69
|
+
if(!response) {
|
70
|
+
// Do nothing
|
71
|
+
return;
|
72
|
+
}
|
73
|
+
|
74
|
+
var char1 = response.charAt(0);
|
75
|
+
|
76
|
+
var svg_str;
|
77
|
+
var img_str;
|
78
|
+
|
79
|
+
if(char1 != "{" && tranfer_stopped) {
|
80
|
+
tranfer_stopped = false;
|
81
|
+
return;
|
82
|
+
}
|
83
|
+
|
84
|
+
if(char1 == '|') {
|
85
|
+
var secondpos = response.indexOf('|', 1);
|
86
|
+
var id = response.substr(1, secondpos-1);
|
87
|
+
response = response.substr(secondpos+1);
|
88
|
+
char1 = response.charAt(0);
|
89
|
+
|
90
|
+
}
|
91
|
+
|
92
|
+
|
93
|
+
// Hide possible transfer dialog box
|
94
|
+
$('#dialog_box').hide();
|
95
|
+
|
96
|
+
switch (char1) {
|
97
|
+
case '{':
|
98
|
+
// Metadata
|
99
|
+
tranfer_stopped = false;
|
100
|
+
var cur_meta = JSON.parse(response);
|
101
|
+
|
102
|
+
pending[cur_meta.id] = cur_meta;
|
103
|
+
|
104
|
+
var name = (cur_meta.name || 'file');
|
105
|
+
|
106
|
+
var message = uiStrings.notification.retrieving.replace('%s', name);
|
107
|
+
|
108
|
+
if(mode != 'm') {
|
109
|
+
$.process_cancel(message, function() {
|
110
|
+
tranfer_stopped = true;
|
111
|
+
// Should a message be sent back to the frame?
|
112
|
+
|
113
|
+
$('#dialog_box').hide();
|
114
|
+
});
|
115
|
+
} else {
|
116
|
+
var entry = $('<div>' + message + '</div>').data('id', cur_meta.id);
|
117
|
+
preview.append(entry);
|
118
|
+
cur_meta.entry = entry;
|
119
|
+
}
|
120
|
+
|
121
|
+
return;
|
122
|
+
case '<':
|
123
|
+
svg_str = true;
|
124
|
+
break;
|
125
|
+
case 'd':
|
126
|
+
if(response.indexOf('data:image/svg+xml') === 0) {
|
127
|
+
var pre = 'data:image/svg+xml;base64,';
|
128
|
+
var src = response.substring(pre.length);
|
129
|
+
response = svgCanvas.Utils.decode64(src);
|
130
|
+
svg_str = true;
|
131
|
+
break;
|
132
|
+
} else if(response.indexOf('data:image/') === 0) {
|
133
|
+
img_str = true;
|
134
|
+
break;
|
135
|
+
}
|
136
|
+
// Else fall through
|
137
|
+
default:
|
138
|
+
// TODO: See if there's a way to base64 encode the binary data stream
|
139
|
+
// var str = 'data:;base64,' + svgCanvas.Utils.encode64(response, true);
|
140
|
+
|
141
|
+
// Assume it's raw image data
|
142
|
+
// importImage(str);
|
143
|
+
|
144
|
+
// Don't give warning as postMessage may have been used by something else
|
145
|
+
if(mode !== 'm') {
|
146
|
+
closeBrowser();
|
147
|
+
} else {
|
148
|
+
pending[id].entry.remove();
|
149
|
+
}
|
150
|
+
// $.alert('Unexpected data was returned: ' + response, function() {
|
151
|
+
// if(mode !== 'm') {
|
152
|
+
// closeBrowser();
|
153
|
+
// } else {
|
154
|
+
// pending[id].entry.remove();
|
155
|
+
// }
|
156
|
+
// });
|
157
|
+
return;
|
158
|
+
}
|
159
|
+
|
160
|
+
switch (mode) {
|
161
|
+
case 's':
|
162
|
+
// Import one
|
163
|
+
if(svg_str) {
|
164
|
+
svgCanvas.importSvgString(response);
|
165
|
+
} else if(img_str) {
|
166
|
+
importImage(response);
|
167
|
+
}
|
168
|
+
closeBrowser();
|
169
|
+
break;
|
170
|
+
case 'm':
|
171
|
+
// Import multiple
|
172
|
+
multi_arr.push([(svg_str ? 'svg' : 'img'), response]);
|
173
|
+
var cur_meta = pending[id];
|
174
|
+
if(svg_str) {
|
175
|
+
if(cur_meta && cur_meta.name) {
|
176
|
+
var title = cur_meta.name;
|
177
|
+
} else {
|
178
|
+
// Try to find a title
|
179
|
+
var xml = new DOMParser().parseFromString(response, 'text/xml').documentElement;
|
180
|
+
var title = $(xml).children('title').first().text() || '(SVG #' + response.length + ')';
|
181
|
+
}
|
182
|
+
if(cur_meta) {
|
183
|
+
preview.children().each(function() {
|
184
|
+
if($(this).data('id') == id) {
|
185
|
+
if(cur_meta.preview_url) {
|
186
|
+
$(this).html('<img src="' + cur_meta.preview_url + '">' + title);
|
187
|
+
} else {
|
188
|
+
$(this).text(title);
|
189
|
+
}
|
190
|
+
submit.removeAttr('disabled');
|
191
|
+
}
|
192
|
+
});
|
193
|
+
} else {
|
194
|
+
preview.append('<div>'+title+'</div>');
|
195
|
+
submit.removeAttr('disabled');
|
196
|
+
}
|
197
|
+
} else {
|
198
|
+
if(cur_meta && cur_meta.preview_url) {
|
199
|
+
var title = cur_meta.name || '';
|
200
|
+
}
|
201
|
+
if(cur_meta && cur_meta.preview_url) {
|
202
|
+
var entry = '<img src="' + cur_meta.preview_url + '">' + title;
|
203
|
+
} else {
|
204
|
+
var entry = '<img src="' + response + '">';
|
205
|
+
}
|
206
|
+
|
207
|
+
if(cur_meta) {
|
208
|
+
preview.children().each(function() {
|
209
|
+
if($(this).data('id') == id) {
|
210
|
+
$(this).html(entry);
|
211
|
+
submit.removeAttr('disabled');
|
212
|
+
}
|
213
|
+
});
|
214
|
+
} else {
|
215
|
+
preview.append($('<div>').append(entry));
|
216
|
+
submit.removeAttr('disabled');
|
217
|
+
}
|
218
|
+
|
219
|
+
}
|
220
|
+
break;
|
221
|
+
case 'o':
|
222
|
+
// Open
|
223
|
+
if(!svg_str) break;
|
224
|
+
svgEditor.openPrep(function(ok) {
|
225
|
+
if(!ok) return;
|
226
|
+
svgCanvas.clear();
|
227
|
+
svgCanvas.setSvgString(response);
|
228
|
+
// updateCanvas();
|
229
|
+
});
|
230
|
+
closeBrowser();
|
231
|
+
break;
|
232
|
+
}
|
233
|
+
}, true);
|
234
|
+
|
235
|
+
var preview, submit;
|
236
|
+
|
237
|
+
function toggleMulti(show) {
|
238
|
+
|
239
|
+
$('#lib_framewrap, #imglib_opts').css({right: (show ? 200 : 10)});
|
240
|
+
if(!preview) {
|
241
|
+
preview = $('<div id=imglib_preview>').css({
|
242
|
+
position: 'absolute',
|
243
|
+
top: 45,
|
244
|
+
right: 10,
|
245
|
+
width: 180,
|
246
|
+
bottom: 45,
|
247
|
+
background: '#fff',
|
248
|
+
overflow: 'auto'
|
249
|
+
}).insertAfter('#lib_framewrap');
|
250
|
+
|
251
|
+
submit = $('<button disabled>Import selected</button>')
|
252
|
+
.appendTo('#imgbrowse')
|
253
|
+
.on("click touchend", function() {
|
254
|
+
$.each(multi_arr, function(i) {
|
255
|
+
var type = this[0];
|
256
|
+
var data = this[1];
|
257
|
+
if(type == 'svg') {
|
258
|
+
svgCanvas.importSvgString(data);
|
259
|
+
} else {
|
260
|
+
importImage(data);
|
261
|
+
}
|
262
|
+
svgCanvas.moveSelectedElements(i*20, i*20, false);
|
263
|
+
});
|
264
|
+
preview.empty();
|
265
|
+
multi_arr = [];
|
266
|
+
$('#imgbrowse_holder').hide();
|
267
|
+
}).css({
|
268
|
+
position: 'absolute',
|
269
|
+
bottom: 10,
|
270
|
+
right: -10
|
271
|
+
});
|
272
|
+
|
273
|
+
}
|
274
|
+
|
275
|
+
preview.toggle(show);
|
276
|
+
submit.toggle(show);
|
277
|
+
}
|
278
|
+
|
279
|
+
function showBrowser() {
|
280
|
+
|
281
|
+
var browser = $('#imgbrowse');
|
282
|
+
if(!browser.length) {
|
283
|
+
$('<div id=imgbrowse_holder><div id=imgbrowse class=toolbar_button>\
|
284
|
+
</div></div>').insertAfter('#svg_docprops');
|
285
|
+
browser = $('#imgbrowse');
|
286
|
+
|
287
|
+
var all_libs = uiStrings.imagelib.select_lib;
|
288
|
+
|
289
|
+
var lib_opts = $('<ul id=imglib_opts>').appendTo(browser);
|
290
|
+
var frame = $('<iframe/>').prependTo(browser).hide().wrap('<div id=lib_framewrap>');
|
291
|
+
|
292
|
+
var header = $('<h1>').prependTo(browser).text(all_libs).css({
|
293
|
+
position: 'absolute',
|
294
|
+
top: 0,
|
295
|
+
left: 0,
|
296
|
+
width: '100%'
|
297
|
+
});
|
298
|
+
|
299
|
+
var cancel = $('<button>' + uiStrings.common.cancel + '</button>')
|
300
|
+
.appendTo(browser)
|
301
|
+
.on("click touchend", function() {
|
302
|
+
$('#imgbrowse_holder').hide();
|
303
|
+
}).css({
|
304
|
+
position: 'absolute',
|
305
|
+
top: 5,
|
306
|
+
right: -10
|
307
|
+
});
|
308
|
+
|
309
|
+
var leftBlock = $('<span>').css({position:'absolute',top:5,left:10}).appendTo(browser);
|
310
|
+
|
311
|
+
var back = $('<button hidden>' + uiStrings.imagelib.show_list + '</button>')
|
312
|
+
.appendTo(leftBlock)
|
313
|
+
.on("click touchend", function() {
|
314
|
+
frame.attr('src', 'about:blank').hide();
|
315
|
+
lib_opts.show();
|
316
|
+
header.text(all_libs);
|
317
|
+
back.hide();
|
318
|
+
}).css({
|
319
|
+
'margin-right': 5
|
320
|
+
}).hide();
|
321
|
+
|
322
|
+
var type = $('<select><option value=s>' +
|
323
|
+
uiStrings.imagelib.import_single + '</option><option value=m>' +
|
324
|
+
uiStrings.imagelib.import_multi + '</option><option value=o>' +
|
325
|
+
uiStrings.imagelib.open + '</option></select>').appendTo(leftBlock).change(function() {
|
326
|
+
mode = $(this).val();
|
327
|
+
switch (mode) {
|
328
|
+
case 's':
|
329
|
+
case 'o':
|
330
|
+
toggleMulti(false);
|
331
|
+
break;
|
332
|
+
|
333
|
+
case 'm':
|
334
|
+
// Import multiple
|
335
|
+
toggleMulti(true);
|
336
|
+
}
|
337
|
+
}).css({
|
338
|
+
'margin-top': 10
|
339
|
+
});
|
340
|
+
|
341
|
+
cancel.prepend($.getSvgIcon('cancel', true));
|
342
|
+
back.prepend($.getSvgIcon('tool_imagelib', true));
|
343
|
+
|
344
|
+
$.each(img_libs, function(i, opts) {
|
345
|
+
$('<li>')
|
346
|
+
.appendTo(lib_opts)
|
347
|
+
.text(opts.name)
|
348
|
+
.on("click touchend", function() {
|
349
|
+
frame.attr('src', opts.url).show();
|
350
|
+
header.text(opts.name);
|
351
|
+
lib_opts.hide();
|
352
|
+
back.show();
|
353
|
+
}).append('<span>' + opts.description + '</span>');
|
354
|
+
});
|
355
|
+
|
356
|
+
} else {
|
357
|
+
$('#imgbrowse_holder').show();
|
358
|
+
}
|
359
|
+
}
|
360
|
+
|
361
|
+
return {
|
362
|
+
svgicons: "/assets/extensions/ext-imagelib.xml",
|
363
|
+
buttons: [{
|
364
|
+
id: "tool_imagelib",
|
365
|
+
type: "app_menu", // _flyout
|
366
|
+
position: 4,
|
367
|
+
title: "Image library",
|
368
|
+
events: {
|
369
|
+
"mouseup": showBrowser
|
370
|
+
}
|
371
|
+
}],
|
372
|
+
callback: function() {
|
373
|
+
|
374
|
+
$('<style>').text('\
|
375
|
+
#imgbrowse_holder {\
|
376
|
+
position: absolute;\
|
377
|
+
top: 0;\
|
378
|
+
left: 0;\
|
379
|
+
width: 100%;\
|
380
|
+
height: 100%;\
|
381
|
+
background-color: rgba(0, 0, 0, .5);\
|
382
|
+
z-index: 5;\
|
383
|
+
}\
|
384
|
+
\
|
385
|
+
#imgbrowse {\
|
386
|
+
position: absolute;\
|
387
|
+
top: 25px;\
|
388
|
+
left: 25px;\
|
389
|
+
right: 25px;\
|
390
|
+
bottom: 25px;\
|
391
|
+
min-width: 300px;\
|
392
|
+
min-height: 200px;\
|
393
|
+
background: #B0B0B0;\
|
394
|
+
border: 1px outset #777;\
|
395
|
+
}\
|
396
|
+
#imgbrowse h1 {\
|
397
|
+
font-size: 20px;\
|
398
|
+
margin: .4em;\
|
399
|
+
text-align: center;\
|
400
|
+
}\
|
401
|
+
#lib_framewrap,\
|
402
|
+
#imgbrowse > ul {\
|
403
|
+
position: absolute;\
|
404
|
+
top: 45px;\
|
405
|
+
left: 10px;\
|
406
|
+
right: 10px;\
|
407
|
+
bottom: 10px;\
|
408
|
+
background: white;\
|
409
|
+
margin: 0;\
|
410
|
+
padding: 0;\
|
411
|
+
}\
|
412
|
+
#imgbrowse > ul {\
|
413
|
+
overflow: auto;\
|
414
|
+
}\
|
415
|
+
#imgbrowse > div {\
|
416
|
+
border: 1px solid #666;\
|
417
|
+
}\
|
418
|
+
#imglib_preview > div {\
|
419
|
+
padding: 5px;\
|
420
|
+
font-size: 12px;\
|
421
|
+
}\
|
422
|
+
#imglib_preview img {\
|
423
|
+
display: block;\
|
424
|
+
margin: 0 auto;\
|
425
|
+
max-height: 100px;\
|
426
|
+
}\
|
427
|
+
#imgbrowse li {\
|
428
|
+
list-style: none;\
|
429
|
+
padding: .5em;\
|
430
|
+
background: #E8E8E8;\
|
431
|
+
border-bottom: 1px solid #B0B0B0;\
|
432
|
+
line-height: 1.2em;\
|
433
|
+
font-style: sans-serif;\
|
434
|
+
}\
|
435
|
+
#imgbrowse li > span {\
|
436
|
+
color: #666;\
|
437
|
+
font-size: 15px;\
|
438
|
+
display: block;\
|
439
|
+
}\
|
440
|
+
#imgbrowse li:hover {\
|
441
|
+
background: #FFC;\
|
442
|
+
cursor: pointer;\
|
443
|
+
}\
|
444
|
+
#imgbrowse iframe {\
|
445
|
+
width: 100%;\
|
446
|
+
height: 100%;\
|
447
|
+
border: 0;\
|
448
|
+
}\
|
449
|
+
').appendTo('head');
|
450
|
+
}
|
451
|
+
}
|
452
|
+
});
|
453
|
+
|