dante-editor 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.travis.yml +4 -0
- data/Gemfile +23 -0
- data/Gemfile.lock +146 -0
- data/Procfile +1 -0
- data/README.md +129 -0
- data/TODO.md +45 -0
- data/bower.json +10 -0
- data/config.rb +82 -0
- data/config.ru +31 -0
- data/dante-editor.gemspec +19 -0
- data/lib/dante-editor.rb +3 -0
- data/lib/dante-editor/version.rb +5 -0
- data/license.md +22 -0
- data/rakefile +2 -0
- data/source/assets/fonts/fontello.eot +0 -0
- data/source/assets/fonts/fontello.svg +36 -0
- data/source/assets/fonts/fontello.ttf +0 -0
- data/source/assets/fonts/fontello.woff +0 -0
- data/source/assets/images/background.png +0 -0
- data/source/assets/images/icon-logo.png +0 -0
- data/source/assets/images/icon.png +0 -0
- data/source/assets/images/media-loading-placeholder.png +0 -0
- data/source/assets/images/middleman.png +0 -0
- data/source/assets/javascripts/all.js +3 -0
- data/source/assets/javascripts/dante.js +7 -0
- data/source/assets/javascripts/dante/dante.js.coffee.erb +7 -0
- data/source/assets/javascripts/dante/editor.js.coffee +917 -0
- data/source/assets/javascripts/dante/menu.js.coffee +202 -0
- data/source/assets/javascripts/dante/tooltip.js.coffee +302 -0
- data/source/assets/javascripts/dante/utils.js.coffee +235 -0
- data/source/assets/javascripts/dante/view.js.coffee +56 -0
- data/source/assets/javascripts/deps.js +4 -0
- data/source/assets/javascripts/spec.js +2 -0
- data/source/assets/javascripts/specs/cleaner.js.coffee +8 -0
- data/source/assets/javascripts/specs/dante_view.js.coffee +74 -0
- data/source/assets/javascripts/specs/editor.js.coffee +57 -0
- data/source/assets/stylesheets/all.css.scss +4 -0
- data/source/assets/stylesheets/dante.css.scss +3 -0
- data/source/assets/stylesheets/dante/base.css.scss +57 -0
- data/source/assets/stylesheets/dante/editor.css.scss +662 -0
- data/source/assets/stylesheets/dante/fonts.css.scss +106 -0
- data/source/assets/stylesheets/normalize.css +375 -0
- data/source/embeds.html.erb +29 -0
- data/source/index.html.erb +28 -0
- data/source/layouts/layout.erb +21 -0
- data/source/layouts/spec.html.erb +24 -0
- data/source/partials/_example_1.erb +30 -0
- data/source/partials/_example_2.erb +33 -0
- data/source/partials/_example_3.erb +17 -0
- data/source/partials/_readme.markdown +78 -0
- data/source/partials/test/_example_1.erb +18 -0
- data/source/readme.html.erb +28 -0
- data/source/tests/dante_view.html.erb +11 -0
- data/source/tests/index.html.erb +32 -0
- data/tmp/.gitkeep +0 -0
- metadata +99 -0
data/config.ru
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'middleman/rack'
|
3
|
+
|
4
|
+
class UploadServer < Sinatra::Base
|
5
|
+
|
6
|
+
use Rack::Static, :urls => ["/images"], :root => "tmp"
|
7
|
+
# Info
|
8
|
+
get "/info" do
|
9
|
+
"Dante Upload server, hello!"
|
10
|
+
end
|
11
|
+
|
12
|
+
# Handle POST-request (Receive and save the uploaded file)
|
13
|
+
post "/new.?:format?" do
|
14
|
+
|
15
|
+
name = [Time.now.to_i , params['file'][:filename]].join("-")
|
16
|
+
path = File.join(File.dirname(__FILE__), 'tmp/images', name)
|
17
|
+
File.open(path, "wb") do |f|
|
18
|
+
f.write(params['file'][:tempfile].read)
|
19
|
+
end
|
20
|
+
|
21
|
+
return "/uploads/images/#{name}"
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
#Mounts upload server & middleman app
|
28
|
+
run Rack::URLMap.new(
|
29
|
+
"/" => Middleman.server,
|
30
|
+
"/uploads" => UploadServer.new
|
31
|
+
)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'dante-editor/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "dante-editor"
|
8
|
+
gem.version = DanteEditor::VERSION
|
9
|
+
gem.authors = ["Miguel Michelson"]
|
10
|
+
gem.email = ["miguelmichelson@gmail.com"]
|
11
|
+
gem.description = %q{dante-editor yet another Medium editor clone.}
|
12
|
+
gem.summary = %q{dante-editor yet another Medium editor clone.}
|
13
|
+
gem.homepage = ""
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
end
|
data/lib/dante-editor.rb
ADDED
data/license.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Miguel Michelson
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/rakefile
ADDED
Binary file
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<?xml version="1.0" standalone="no"?>
|
2
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
3
|
+
<svg xmlns="http://www.w3.org/2000/svg">
|
4
|
+
<metadata>Copyright (C) 2012 by original authors @ fontello.com</metadata>
|
5
|
+
<defs>
|
6
|
+
<font id="fontello" horiz-adv-x="1000" >
|
7
|
+
<font-face font-family="fontello" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
|
8
|
+
<missing-glyph horiz-adv-x="1000" />
|
9
|
+
<glyph glyph-name="location" unicode="" d="M429 493q0 59-42 101t-101 42-101-42-42-101 42-101 101-42 101 42 42 101z m143 0q0-61-18-100l-203-432q-9-18-27-29t-38-11-38 11-26 29l-204 432q-18 39-18 100 0 118 84 202t202 84 202-84 84-202z" horiz-adv-x="571.429" />
|
10
|
+
<glyph glyph-name="fit" unicode="" d="M429 314l0-250q0-15-11-25t-25-11-25 11l-80 80-185-185q-6-6-13-6t-13 6l-64 64q-6 6-6 13t6 13l185 185-80 80q-11 11-11 25t11 25 25 11l250 0q15 0 25-11t11-25z m421 375q0-7-6-13l-185-185 80-80q11-11 11-25t-11-25-25-11l-250 0q-15 0-25 11t-11 25l0 250q0 15 11 25t25 11 25-11l80-80 185 185q6 6 13 6t13-6l64-64q6-6 6-13z" horiz-adv-x="857.143" />
|
11
|
+
<glyph glyph-name="bold" unicode="" d="M310 1q42-18 78-18 73 0 121 23t68 63q21 39 21 101 0 64-23 100-32 52-79 70-45 18-138 18-41 0-56-6l0-80-1-97 2-151q0-8 7-25z m-8 416q24-4 61-4 98 0 147 36t50 125q0 62-47 104t-142 42q-29 0-73-7 0-25 1-43 4-68 3-156l-1-55q0-24 1-43z m-302-496l1 52q25 5 38 7 43 7 69 17 9 15 12 28 5 37 5 108l-1 277q-3 143-5 225-1 49-6 61-1 2-7 7-10 7-39 8-17 1-64 7l-2 46 145 3 212 7 25 1q3 0 8 0t8 0q1 0 12 0t23 0l41 0q49 0 107-15 24-7 54-22 32-16 57-42t36-58 12-68q0-39-18-71t-53-59q-15-11-84-43 99-23 149-81 51-59 51-132 0-42-16-90-12-35-40-65-37-40-78-60t-113-33q-46-8-110-6l-110 2q-47 1-166-6-18-2-152-6z" horiz-adv-x="785.714" />
|
12
|
+
<glyph glyph-name="italic" unicode="" d="M0-77l9 47q2 1 43 11 42 11 65 22 16 21 23 56l15 78 31 150 7 36q4 25 9 47t9 37 7 26 5 17 2 6l16 88 9 35 12 75 4 28 0 21q-23 12-80 16-16 1-21 2l11 57 177-8q22-1 41-1 37 0 119 5 18 1 38 3t20 1q-1-11-3-21-4-16-7-28-31-11-61-17-36-9-56-17-7-17-13-49-5-25-7-46-25-111-37-171l-34-174-21-88-24-131-7-25q-1-4 1-15 36-8 66-12 20-3 37-6-1-16-4-32-4-17-5-23-10 0-13-1-13-1-23-1-5 0-16 2t-81 9l-110 1q-23 1-97-6-41-4-55-5z" horiz-adv-x="571.429" />
|
13
|
+
<glyph glyph-name="justifyleft" unicode="" d="M1000 100l0-71q0-15-11-25t-25-11l-929 0q-15 0-25 11t-11 25l0 71q0 15 11 25t25 11l929 0q15 0 25-11t11-25z m-214 214l0-71q0-15-11-25t-25-11l-714 0q-15 0-25 11t-11 25l0 71q0 15 11 25t25 11l714 0q15 0 25-11t11-25z m143 214l0-71q0-15-11-25t-25-11l-857 0q-15 0-25 11t-11 25l0 71q0 15 11 25t25 11l857 0q15 0 25-11t11-25z m-214 214l0-71q0-15-11-25t-25-11l-643 0q-15 0-25 11t-11 25l0 71q0 15 11 25t25 11l643 0q15 0 25-11t11-25z" horiz-adv-x="1000" />
|
14
|
+
<glyph glyph-name="justifycenter" unicode="" d="M1000 100l0-71q0-15-11-25t-25-11l-929 0q-15 0-25 11t-11 25l0 71q0 15 11 25t25 11l929 0q15 0 25-11t11-25z m-214 214l0-71q0-15-11-25t-25-11l-500 0q-15 0-25 11t-11 25l0 71q0 15 11 25t25 11l500 0q15 0 25-11t11-25z m143 214l0-71q0-15-11-25t-25-11l-786 0q-15 0-25 11t-11 25l0 71q0 15 11 25t25 11l786 0q15 0 25-11t11-25z m-214 214l0-71q0-15-11-25t-25-11l-357 0q-15 0-25 11t-11 25l0 71q0 15 11 25t25 11l357 0q15 0 25-11t11-25z" horiz-adv-x="1000" />
|
15
|
+
<glyph glyph-name="justifyright" unicode="" d="M1000 100l0-71q0-15-11-25t-25-11l-929 0q-15 0-25 11t-11 25l0 71q0 15 11 25t25 11l929 0q15 0 25-11t11-25z m0 214l0-71q0-15-11-25t-25-11l-714 0q-15 0-25 11t-11 25l0 71q0 15 11 25t25 11l714 0q15 0 25-11t11-25z m0 214l0-71q0-15-11-25t-25-11l-857 0q-15 0-25 11t-11 25l0 71q0 15 11 25t25 11l857 0q15 0 25-11t11-25z m0 214l0-71q0-15-11-25t-25-11l-643 0q-15 0-25 11t-11 25l0 71q0 15 11 25t25 11l643 0q15 0 25-11t11-25z" horiz-adv-x="1000" />
|
16
|
+
<glyph glyph-name="justifyfull" unicode="" d="M1000 100l0-71q0-15-11-25t-25-11l-929 0q-15 0-25 11t-11 25l0 71q0 15 11 25t25 11l929 0q15 0 25-11t11-25z m0 214l0-71q0-15-11-25t-25-11l-929 0q-15 0-25 11t-11 25l0 71q0 15 11 25t25 11l929 0q15 0 25-11t11-25z m0 214l0-71q0-15-11-25t-25-11l-929 0q-15 0-25 11t-11 25l0 71q0 15 11 25t25 11l929 0q15 0 25-11t11-25z m0 214l0-71q0-15-11-25t-25-11l-929 0q-15 0-25 11t-11 25l0 71q0 15 11 25t25 11l929 0q15 0 25-11t11-25z" horiz-adv-x="1000" />
|
17
|
+
<glyph glyph-name="outdent" unicode="" d="M214 546l0-321q0-7-5-13t-13-5q-8 0-13 5l-161 161q-5 5-5 13t5 13l161 161q5 5 13 5 7 0 13-5t5-13z m786-429l0-107q0-7-5-13t-13-5l-964 0q-7 0-13 5t-5 13l0 107q0 7 5 13t13 5l964 0q7 0 13-5t5-13z m0 214l0-107q0-7-5-13t-13-5l-607 0q-7 0-13 5t-5 13l0 107q0 7 5 13t13 5l607 0q7 0 13-5t5-13z m0 214l0-107q0-7-5-13t-13-5l-607 0q-7 0-13 5t-5 13l0 107q0 7 5 13t13 5l607 0q7 0 13-5t5-13z m0 214l0-107q0-7-5-13t-13-5l-964 0q-7 0-13 5t-5 13l0 107q0 7 5 13t13 5l964 0q7 0 13-5t5-13z" horiz-adv-x="1000" />
|
18
|
+
<glyph glyph-name="indent" unicode="" d="M196 386q0-8-5-13l-161-161q-5-5-13-5-7 0-13 5t-5 13l0 321q0 7 5 13t13 5q8 0 13-5l161-161q5-5 5-13z m804-268l0-107q0-7-5-13t-13-5l-964 0q-7 0-13 5t-5 13l0 107q0 7 5 13t13 5l964 0q7 0 13-5t5-13z m0 214l0-107q0-7-5-13t-13-5l-607 0q-7 0-13 5t-5 13l0 107q0 7 5 13t13 5l607 0q7 0 13-5t5-13z m0 214l0-107q0-7-5-13t-13-5l-607 0q-7 0-13 5t-5 13l0 107q0 7 5 13t13 5l607 0q7 0 13-5t5-13z m0 214l0-107q0-7-5-13t-13-5l-964 0q-7 0-13 5t-5 13l0 107q0 7 5 13t13 5l964 0q7 0 13-5t5-13z" horiz-adv-x="1000" />
|
19
|
+
<glyph glyph-name="mode" unicode="" d="M429 46l0 607q-83 0-152-41t-110-110-41-152 41-152 110-110 152-41z m429 304q0-117-57-215t-156-156-215-57-215 57-156 156-57 215 57 215 156 156 215 57 215-57 156-156 57-215z" horiz-adv-x="857.143" />
|
20
|
+
<glyph glyph-name="fullscreen" unicode="" d="M716 548l-198-198 198-198 80 80q16 17 39 8 22-9 22-33l0-250q0-15-11-25t-25-11l-250 0q-23 0-33 22-9 22 8 39l80 80-198 198-198-198 80-80q17-17 8-39t-33-22l-250 0q-15 0-25 11t-11 25l0 250q0 23 22 33 22 9 39-8l80-80 198 198-198 198-80-80q-11-11-25-11-7 0-13 3-22 9-22 33l0 250q0 15 11 25t25 11l250 0q23 0 33-22 9-22-8-39l-80-80 198-198 198 198-80 80q-17 17-8 39t33 22l250 0q15 0 25-11t11-25l0-250q0-23-22-33-7-3-14-3-15 0-25 11z" horiz-adv-x="857.143" />
|
21
|
+
<glyph glyph-name="insertunorderedlist" unicode="" d="M214 64q0-45-31-76t-76-31-76 31-31 76 31 76 76 31 76-31 31-76z m0 286q0-45-31-76t-76-31-76 31-31 76 31 76 76 31 76-31 31-76z m786-232l0-107q0-7-5-13t-13-5l-679 0q-7 0-13 5t-5 13l0 107q0 7 5 13t13 5l679 0q7 0 13-5t5-13z m-786 518q0-45-31-76t-76-31-76 31-31 76 31 76 76 31 76-31 31-76z m786-232l0-107q0-7-5-13t-13-5l-679 0q-7 0-13 5t-5 13l0 107q0 7 5 13t13 5l679 0q7 0 13-5t5-13z m0 286l0-107q0-7-5-13t-13-5l-679 0q-7 0-13 5t-5 13l0 107q0 7 5 13t13 5l679 0q7 0 13-5t5-13z" horiz-adv-x="1000" />
|
22
|
+
<glyph glyph-name="insertorderedlist" unicode="" d="M213-54q0-45-30-70t-76-26q-59 0-96 37l32 49q27-25 59-25 16 0 28 8t12 24q0 36-59 31l-15 31q4 6 18 24t24 30 21 21l0 1q-9 0-27-1t-27-1l0-30-59 0 0 85 186 0 0-49-53-64q28-7 45-27t17-49z m1 350l0-89-202 0q-3 20-3 30 0 28 13 52t32 38 37 27 32 24 13 25q0 14-8 21t-22 8q-26 0-45-32l-47 33q13 28 40 44t59 16q41 0 69-23t28-63q0-28-19-51t-42-36-42-28-20-29l71 0 0 33 59 0z m786-178l0-107q0-7-5-13t-13-5l-679 0q-7 0-13 5t-5 13l0 107q0 8 5 13t13 5l679 0q7 0 13-5t5-13z m-786 502l0-55-187 0 0 55 60 0q0 23 0 68t0 68l0 7-1 0q-4-9-28-30l-40 42 76 71 59 0 0-225 60 0z m786-216l0-107q0-7-5-13t-13-5l-679 0q-7 0-13 5t-5 13l0 107q0 8 5 13t13 5l679 0q7 0 13-5t5-13z m0 286l0-107q0-7-5-13t-13-5l-679 0q-7 0-13 5t-5 13l0 107q0 7 5 13t13 5l679 0q7 0 13-5t5-13z" horiz-adv-x="1000" />
|
23
|
+
<glyph glyph-name="strikethrough" unicode="" d="M982 350q8 0 13-5t5-13l0-36q0-8-5-13t-13-5l-964 0q-8 0-13 5t-5 13l0 36q0 8 5 13t13 5l964 0z m-713 36q-16 20-28 45-27 54-27 105 0 101 75 172 74 71 219 71 28 0 93-11 37-7 99-27 6-21 12-66 8-69 8-102 0-10-3-25l-7-2-47 3-8 1q-28 83-57 114-49 51-117 51-64 0-102-33-37-32-37-81 0-41 37-78t156-72q39-11 97-37 32-16 53-29l-415 0z m283-143l229 0q4-22 4-51 0-62-23-118-13-31-40-58-21-20-61-45-45-27-85-37-45-12-113-12-64 0-109 13l-78 22q-32 9-40 16-4 4-4 12l0 7q0 60-1 87-1 17 0 38l1 21 0 25 57 1q8-19 17-40t13-31 7-15q20-32 45-52 24-20 59-32 33-12 74-12 36 0 78 15 43 15 68 48 26 34 26 72 0 47-45 88-19 16-76 40z" horiz-adv-x="1000" />
|
24
|
+
<glyph glyph-name="underline" unicode="" d="M27 726q-21 1-25 2l-2 49q7 1 22 1 33 0 62-2 74-4 93-4 48 0 94 2 65 2 81 3 31 0 48 1l-1-8 1-36 0-5q-33-5-69-5-33 0-44-14-7-8-7-74 0-7 0-18t0-14l1-128 8-156q3-69 28-113 20-33 54-51 49-26 99-26 58 0 107 16 31 10 55 28 27 20 36 36 20 31 30 64 12 41 12 128 0 44-2 71t-6 68-8 89l-2 33q-3 37-13 49-19 20-43 19l-56-1-8 2 1 48 47 0 114-6q42-2 109 6l10-1q3-21 3-28 0-4-2-17-25-7-47-7-41-6-44-9-8-8-8-23 0-4 1-15t1-17q4-11 12-221 3-109-8-170-8-42-23-68-21-36-62-69-42-32-102-50-61-18-142-18-93 0-158 26-66 26-100 68t-46 109q-9 45-9 132l0 186q0 105-9 119-14 20-82 22z m830-786l0 36q0 8-5 13t-13 5l-821 0q-8 0-13-5t-5-13l0-36q0-8 5-13t13-5l821 0q8 0 13 5t5 13z" horiz-adv-x="857.143" />
|
25
|
+
<glyph glyph-name="blockquote" unicode="" d="M429 671l0-393q0-58-23-111t-61-91-91-61-111-23l-36 0q-15 0-25 11t-11 25l0 71q0 15 11 25t25 11l36 0q59 0 101 42t42 101l0 18q0 22-16 38t-38 16l-125 0q-45 0-76 31t-31 76l0 214q0 45 31 76t76 31l214 0q45 0 76-31t31-76z m500 0l0-393q0-58-23-111t-61-91-91-61-111-23l-36 0q-15 0-25 11t-11 25l0 71q0 15 11 25t25 11l36 0q59 0 101 42t42 101l0 18q0 22-16 38t-38 16l-125 0q-45 0-76 31t-31 76l0 214q0 45 31 76t76 31l214 0q45 0 76-31t31-76z" horiz-adv-x="928.571" />
|
26
|
+
<glyph glyph-name="undo" unicode="" d="M1000 225q0-93-71-252-2-4-6-13t-8-17-7-12q-7-9-16-9-8 0-13 6t-5 14q0 5 1 15t1 13q3 38 3 69 0 56-10 101t-27 77-45 56-59 39-74 24-86 12-98 3l-125 0 0-143q0-15-11-25t-25-11-25 11l-286 286q-11 11-11 25t11 25l286 286q11 11 25 11t25-11 11-25l0-143 125 0q398 0 488-225 30-75 30-186z" horiz-adv-x="1000" />
|
27
|
+
<glyph glyph-name="code" unicode="" d="M344 69l-28-28q-6-6-13-6t-13 6l-260 260q-6 6-6 13t6 13l260 260q6 6 13 6t13-6l28-28q6-6 6-13t-6-13l-219-219 219-219q6-6 6-13t-6-13z m330 595l-208-720q-2-7-9-11t-13-1l-35 9q-7 2-11 9t-1 14l208 720q2 7 9 11t13 1l35-9q7-2 11-9t1-14z m367-363l-260-260q-6-6-13-6t-13 6l-28 28q-6 6-6 13t6 13l219 219-219 219q-6 6-6 13t6 13l28 28q6 6 13 6t13-6l260-260q6-6 6-13t-6-13z" horiz-adv-x="1071.429" />
|
28
|
+
<glyph glyph-name="unlink" unicode="" d="M245 141l-143-143q-6-5-13-5t-13 5q-5 6-5 13t5 13l143 143q6 5 13 5t13-5q5-6 5-13t-5-13z m94-23l0-179q0-8-5-13t-13-5-13 5-5 13l0 179q0 8 5 13t13 5 13-5 5-13z m-125 125q0-8-5-13t-13-5l-179 0q-8 0-13 5t-5 13 5 13 13 5l179 0q8 0 13-5t5-13z m705-71q0-67-47-113l-82-81q-46-46-113-46-68 0-114 47l-186 187q-12 12-23 31l133 10 152-153q15-15 38-15t38 15l82 81q16 16 16 37 0 22-16 38l-153 153 10 133q20-12 31-23l187-187q47-48 47-114z m-344 404l-133-10-152 153q-16 16-38 16t-38-15l-82-81q-16-16-16-37 0-22 16-38l153-153-10-134q-20 12-31 23l-187 187q-47 48-47 114 0 67 47 113l82 81q46 46 113 46 68 0 114-47l186-187q12-12 23-31z m353-47q0-8-5-13t-13-5l-179 0q-8 0-13 5t-5 13 5 13 13 5l179 0q8 0 13-5t5-13z m-304 304l0-179q0-8-5-13t-13-5-13 5-5 13l0 179q0 8 5 13t13 5 13-5 5-13z m227-84l-143-143q-6-5-13-5t-13 5q-5 6-5 13t5 13l143 143q6 5 13 5t13-5q5-6 5-13t-5-13z" horiz-adv-x="928.571" />
|
29
|
+
<glyph glyph-name="superscript" unicode="" d="M501 86l0-93-138 0-89 141-13 23q-4 5-6 12l-2 0-5-12q-6-11-14-25l-86-140-144 0 0 93 71 0 110 162-103 152-76 0 0 94 154 0 78-127q1-2 13-23 4-5 6-12l2 0q2 5 6 12l14 23 78 127 143 0 0-94-70 0-103-149 114-165 61 0z m355 379l0-115-287 0-2 15q-2 16-2 26 0 36 15 65t36 48 47 36 47 30 36 30 15 36q0 21-16 35t-39 14q-28 0-54-22-8-6-20-21l-59 51q15 21 35 37 46 36 105 36 61 0 99-33t38-88q0-31-14-57t-35-43-45-33-46-28-37-29-17-35l129 0 0 45 70 0z" horiz-adv-x="857.143" />
|
30
|
+
<glyph glyph-name="subscript" unicode="" d="M501 86l0-93-138 0-89 141-13 23q-4 5-6 12l-2 0-5-12q-6-11-14-25l-86-140-144 0 0 93 71 0 110 162-103 152-76 0 0 94 154 0 78-127q1-2 13-23 4-5 6-12l2 0q2 5 6 12l14 23 78 127 143 0 0-94-70 0-103-149 114-165 61 0z m357-121l0-115-287 0-2 15q-2 25-2 26 0 36 15 65t36 48 47 36 47 30 36 30 15 36q0 21-16 35t-39 14q-28 0-54-22-8-6-20-21l-59 51q15 21 35 37 45 36 105 36 61 0 99-33t38-88q0-37-19-66t-47-48-56-35-49-35-23-41l129 0 0 45 70 0z" horiz-adv-x="857.143" />
|
31
|
+
<glyph glyph-name="inserthorizontalrule" unicode="" d="M214 439l0-107q0-22-16-38t-38-16l-107 0q-22 0-38 16t-16 38l0 107q0 22 16 38t38 16l107 0q22 0 38-16t16-38z m286 0l0-107q0-22-16-38t-38-16l-107 0q-22 0-38 16t-16 38l0 107q0 22 16 38t38 16l107 0q22 0 38-16t16-38z m286 0l0-107q0-22-16-38t-38-16l-107 0q-22 0-38 16t-16 38l0 107q0 22 16 38t38 16l107 0q22 0 38-16t16-38z" horiz-adv-x="785.714" />
|
32
|
+
<glyph glyph-name="pin" unicode="" d="M268 368l0 250q0 8-5 13t-13 5-13-5-5-13l0-250q0-8 5-13t13-5 13 5 5 13z m375-196q0-15-11-25t-25-11l-239 0-28-270q-1-7-6-11t-11-5l-1 0q-15 0-18 15l-42 271-225 0q-15 0-25 11t-11 25q0 69 44 124t99 55l0 286q-29 0-50 21t-21 50 21 50 50 21l357 0q29 0 50-21t21-50-21-50-50-21l0-286q55 0 99-55t44-124z" horiz-adv-x="642.857" />
|
33
|
+
<glyph glyph-name="createlink" unicode="" d="M812 171q0 22-16 38l-116 116q-16 16-38 16-23 0-40-18 2-2 11-10t12-12 8-11 7-14 2-15q0-22-16-38t-38-16q-8 0-15 2t-14 7-11 8-12 12-10 11q-18-17-18-41 0-22 16-38l115-116q15-15 38-15 22 0 38 15l82 81q16 16 16 37z m-392 393q0 22-16 38l-115 116q-16 16-38 16t-38-15l-82-81q-16-16-16-37 0-22 16-38l116-116q15-15 38-15t40 17q-2 2-11 10t-12 12-8 11-7 14-2 15q0 22 16 38t38 16q8 0 15-2t14-7 11-8 12-12 10-11q18 17 18 41z m499-393q0-67-47-113l-82-81q-46-46-113-46-68 0-114 47l-115 116q-46 46-46 113 0 69 49 117l-49 49q-48-49-116-49-67 0-114 47l-116 116q-47 47-47 114t47 113l82 81q46 46 113 46 68 0 114-47l115-116q46-46 46-113 0-69-49-117l49-49q48 49 116 49 67 0 114-47l116-116q47-47 47-114z" horiz-adv-x="928.571" />
|
34
|
+
</font>
|
35
|
+
</defs>
|
36
|
+
</svg>
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,917 @@
|
|
1
|
+
|
2
|
+
selected_menu = false
|
3
|
+
utils = Dante.utils
|
4
|
+
|
5
|
+
class Dante.Editor extends Dante.View
|
6
|
+
#el: "#editor"
|
7
|
+
|
8
|
+
events:
|
9
|
+
"blur" : "handleBlur"
|
10
|
+
"mouseup" : "handleMouseUp"
|
11
|
+
"keydown" : "handleKeyDown"
|
12
|
+
"keyup" : "handleKeyUp"
|
13
|
+
"paste" : "handlePaste"
|
14
|
+
"click .graf--figure" : "handleGrafFigureSelect"
|
15
|
+
|
16
|
+
initialize: (opts = {})=>
|
17
|
+
@editor_options = opts
|
18
|
+
#globals for selected text and node
|
19
|
+
@initial_html = $(@el).html()
|
20
|
+
@current_range = null
|
21
|
+
@current_node = null
|
22
|
+
@el = opts.el || "#editor"
|
23
|
+
window.debugMode = opts.debug || false
|
24
|
+
$(@el).addClass("debug") if window.debugMode
|
25
|
+
@upload_url = opts.upload_url || "/uploads.json"
|
26
|
+
@oembed_url = opts.oembed_url || "http://api.embed.ly/1/oembed?url="
|
27
|
+
@extract_url = opts.extract_url || "http://api.embed.ly/1/extract?key=86c28a410a104c8bb58848733c82f840&url="
|
28
|
+
@default_loading_placeholder = opts.default_loading_placeholder || "/images/media-loading-placeholder.png"
|
29
|
+
@store_url = opts.store_url
|
30
|
+
if (localStorage.getItem('contenteditable'))
|
31
|
+
$(@el).html localStorage.getItem('contenteditable')
|
32
|
+
|
33
|
+
@store()
|
34
|
+
|
35
|
+
@title_placeholder = "<span class='defaultValue defaultValue--root'>Title…</span><br>"
|
36
|
+
@body_placeholder = "<span class='defaultValue defaultValue--root'>Tell your story…</span><br>"
|
37
|
+
@embed_placeholder = "<span class='defaultValue defaultValue--prompt'>Paste a YouTube, Vine, Vimeo, or other video link, and press Enter</span><br>"
|
38
|
+
@extract_placeholder = "<span class='defaultValue defaultValue--prompt'>Paste a link to embed content from another site (e.g. Twitter) and press Enter</span><br>"
|
39
|
+
|
40
|
+
store: ()->
|
41
|
+
#localStorage.setItem("contenteditable", $(@el).html() )
|
42
|
+
return unless @store_url
|
43
|
+
setTimeout ()=>
|
44
|
+
@checkforStore()
|
45
|
+
, 15000
|
46
|
+
|
47
|
+
checkforStore: ()->
|
48
|
+
if @content is @getContent()
|
49
|
+
utils.log "content not changed skip store"
|
50
|
+
@store()
|
51
|
+
else
|
52
|
+
utils.log "content changed! update"
|
53
|
+
@content = @getContent()
|
54
|
+
$.ajax
|
55
|
+
url: @store_url
|
56
|
+
method: "post"
|
57
|
+
data: @getContent()
|
58
|
+
success: (res)->
|
59
|
+
utils.log "store!"
|
60
|
+
utils.log res
|
61
|
+
complete: (jxhr) =>
|
62
|
+
@store()
|
63
|
+
|
64
|
+
getContent: ()->
|
65
|
+
$(@el).find(".section-inner").html()
|
66
|
+
|
67
|
+
template: ()=>
|
68
|
+
"<section class='section--first section--last'>
|
69
|
+
|
70
|
+
<div class='section-divider layoutSingleColumn'>
|
71
|
+
<hr class='section-divider'>
|
72
|
+
</div>
|
73
|
+
|
74
|
+
<div class='section-content'>
|
75
|
+
<div class='section-inner'>
|
76
|
+
<p class='graf graf--h3'>#{@title_placeholder}</p>
|
77
|
+
<p class='graf graf--p'>#{@body_placeholder}<p>
|
78
|
+
</div>
|
79
|
+
</div>
|
80
|
+
|
81
|
+
</section>"
|
82
|
+
|
83
|
+
baseParagraphTmpl: ()->
|
84
|
+
"<p class='graf--p' name='#{utils.generateUniqueName()}'><br></p>"
|
85
|
+
|
86
|
+
appendMenus: ()=>
|
87
|
+
$("<div id='dante-menu' class='dante-menu' style='opacity: 0;'></div>").insertAfter(@el)
|
88
|
+
$("<div class='inlineTooltip2 button-scalableGroup'></div>").insertAfter(@el)
|
89
|
+
@editor_menu = new Dante.Editor.Menu(editor: @)
|
90
|
+
@tooltip_view = new Dante.Editor.Tooltip(editor: @)
|
91
|
+
@tooltip_view.render()
|
92
|
+
|
93
|
+
appendInitialContent: ()=>
|
94
|
+
$(@el).find(".section-inner").html(@initial_html)
|
95
|
+
|
96
|
+
start: ()=>
|
97
|
+
@render()
|
98
|
+
$(@el).attr("contenteditable", "true")
|
99
|
+
$(@el).addClass("postField--body")
|
100
|
+
$(@el).wrap("<div class='notesSource'></div>")
|
101
|
+
@appendMenus()
|
102
|
+
@appendInitialContent() unless _.isEmpty @initial_html.trim()
|
103
|
+
@setupElementsClasses()
|
104
|
+
|
105
|
+
restart: ()=>
|
106
|
+
@render()
|
107
|
+
|
108
|
+
render: ()=>
|
109
|
+
@template()
|
110
|
+
$(@el).html @template()
|
111
|
+
|
112
|
+
getSelectedText: () ->
|
113
|
+
text = ""
|
114
|
+
if typeof window.getSelection != "undefined"
|
115
|
+
text = window.getSelection().toString()
|
116
|
+
else if typeof document.selection != "undefined" && document.selection.type == "Text"
|
117
|
+
text = document.selection.createRange().text
|
118
|
+
text
|
119
|
+
|
120
|
+
selection: ()=>
|
121
|
+
selection
|
122
|
+
if (window.getSelection)
|
123
|
+
selection = window.getSelection()
|
124
|
+
else if (document.selection && document.selection.type != "Control")
|
125
|
+
selection = document.selection
|
126
|
+
|
127
|
+
getRange: () ->
|
128
|
+
editor = $(@el)[0]
|
129
|
+
range = selection && selection.rangeCount && selection.getRangeAt(0)
|
130
|
+
range = document.createRange() if (!range)
|
131
|
+
if !editor.contains(range.commonAncestorContainer)
|
132
|
+
range.selectNodeContents(editor)
|
133
|
+
range.collapse(false)
|
134
|
+
range
|
135
|
+
|
136
|
+
setRange: (range)->
|
137
|
+
range = range || this.current_range
|
138
|
+
if !range
|
139
|
+
range = this.getRange()
|
140
|
+
range.collapse(false); # set to end
|
141
|
+
|
142
|
+
@selection().removeAllRanges()
|
143
|
+
@selection().addRange(range)
|
144
|
+
@
|
145
|
+
|
146
|
+
getCharacterPrecedingCaret: ->
|
147
|
+
precedingChar = ""
|
148
|
+
sel = undefined
|
149
|
+
range = undefined
|
150
|
+
precedingRange = undefined
|
151
|
+
if window.getSelection
|
152
|
+
sel = window.getSelection()
|
153
|
+
if sel.rangeCount > 0
|
154
|
+
range = sel.getRangeAt(0).cloneRange()
|
155
|
+
range.collapse true
|
156
|
+
range.setStart @getNode(), 0
|
157
|
+
precedingChar = range.toString().slice(0)
|
158
|
+
else if (sel = document.selection) and sel.type isnt "Control"
|
159
|
+
range = sel.createRange()
|
160
|
+
precedingRange = range.duplicate()
|
161
|
+
precedingRange.moveToElementText containerEl
|
162
|
+
precedingRange.setEndPoint "EndToStart", range
|
163
|
+
precedingChar = precedingRange.text.slice(0)
|
164
|
+
precedingChar
|
165
|
+
|
166
|
+
isLastChar: ()->
|
167
|
+
#utils.log "#{$(@getNode()).text().trim().length} | #{@getCharacterPrecedingCaret().trim().length}"
|
168
|
+
$(@getNode()).text().trim().length is @getCharacterPrecedingCaret().trim().length
|
169
|
+
|
170
|
+
isFirstChar: ()->
|
171
|
+
@getCharacterPrecedingCaret().trim().length is 0
|
172
|
+
|
173
|
+
isSelectingAll: (element)->
|
174
|
+
a = @getSelectedText().killWhiteSpace().length
|
175
|
+
b = $(element).text().killWhiteSpace().length
|
176
|
+
a is b
|
177
|
+
|
178
|
+
#set focus and caret position on element
|
179
|
+
setRangeAt: (element, int=0)->
|
180
|
+
range = document.createRange()
|
181
|
+
sel = window.getSelection()
|
182
|
+
#node = element.firstChild;
|
183
|
+
range.setStart(element, int); #DANGER this is supported by IE 9
|
184
|
+
#range.setStartAfter(element)
|
185
|
+
#range.setEnd(element, int);
|
186
|
+
range.collapse(true)
|
187
|
+
sel.removeAllRanges()
|
188
|
+
sel.addRange(range)
|
189
|
+
#@el.focus()
|
190
|
+
element.focus()
|
191
|
+
|
192
|
+
#set focus and caret position on element
|
193
|
+
setRangeAtText: (element, int=0)->
|
194
|
+
range = document.createRange()
|
195
|
+
sel = window.getSelection()
|
196
|
+
node = element.firstChild;
|
197
|
+
range.setStart(node, 0); #DANGER this is supported by IE 9
|
198
|
+
range.setEnd(node, 0);
|
199
|
+
range.collapse(true)
|
200
|
+
sel.removeAllRanges()
|
201
|
+
sel.addRange(range)
|
202
|
+
element.focus()
|
203
|
+
|
204
|
+
focus: (focusStart) ->
|
205
|
+
@.setRange() if (!focusStart)
|
206
|
+
$(@el).focus()
|
207
|
+
@
|
208
|
+
|
209
|
+
#NOT USED
|
210
|
+
focusNode: (node, range)->
|
211
|
+
range.setStartAfter(node)
|
212
|
+
range.setEndBefore(node)
|
213
|
+
range.collapse(false)
|
214
|
+
@.setRange(range)
|
215
|
+
|
216
|
+
#get the element that wraps Caret position while is inside section
|
217
|
+
getNode: ()->
|
218
|
+
node = undefined
|
219
|
+
root = $(@el).find(".section-inner")[0]
|
220
|
+
return if @selection().rangeCount < 1
|
221
|
+
range = @selection().getRangeAt(0)
|
222
|
+
node = range.commonAncestorContainer
|
223
|
+
return null if not node or node is root
|
224
|
+
node = node.parentNode while node and (node.nodeType isnt 1) and (node.parentNode isnt root)
|
225
|
+
node = node.parentNode while node and (node.parentNode isnt root)
|
226
|
+
(if root && root.contains(node) then node else null)
|
227
|
+
|
228
|
+
displayMenu: (sel)->
|
229
|
+
setTimeout ()=>
|
230
|
+
@editor_menu.render()
|
231
|
+
pos = utils.getSelectionDimensions()
|
232
|
+
@relocateMenu(pos)
|
233
|
+
@editor_menu.show()
|
234
|
+
, 10
|
235
|
+
|
236
|
+
#get text of selected and displays menu
|
237
|
+
handleTextSelection: (anchor_node)->
|
238
|
+
@editor_menu.hide()
|
239
|
+
text = @getSelectedText()
|
240
|
+
unless _.isEmpty text.trim()
|
241
|
+
#@current_range = @getRange()
|
242
|
+
@current_node = anchor_node
|
243
|
+
@.displayMenu()
|
244
|
+
|
245
|
+
relocateMenu: (position)->
|
246
|
+
padd = @editor_menu.$el.width() / 2
|
247
|
+
top = position.top + $(window).scrollTop() - 43
|
248
|
+
l = position.left + (position.width / 2) - padd
|
249
|
+
@editor_menu.$el.offset({left: l , top: top })
|
250
|
+
|
251
|
+
hidePlaceholder: (element)->
|
252
|
+
$(element).find("span.defaultValue").remove().html("<br>")
|
253
|
+
|
254
|
+
displayEmptyPlaceholder: (element)->
|
255
|
+
$(".graf--first").html(@title_placeholder)
|
256
|
+
$(".graf--last").html(@body_placeholder)
|
257
|
+
|
258
|
+
handleGrafFigureSelect: (ev)->
|
259
|
+
element = ev.currentTarget
|
260
|
+
@markAsSelected( element )
|
261
|
+
@setRangeAt( $(element).find('.imageCaption')[0] )
|
262
|
+
|
263
|
+
handleBlur: (ev)=>
|
264
|
+
#hide menu only if is not in use
|
265
|
+
setTimeout ()=>
|
266
|
+
@editor_menu.hide() unless selected_menu
|
267
|
+
, 200
|
268
|
+
false
|
269
|
+
|
270
|
+
handleMouseUp: (ev)=>
|
271
|
+
utils.log "MOUSE UP"
|
272
|
+
anchor_node = @getNode()
|
273
|
+
utils.log anchor_node
|
274
|
+
utils.log ev.currentTarget
|
275
|
+
return if _.isNull(anchor_node)
|
276
|
+
@handleTextSelection(anchor_node)
|
277
|
+
@hidePlaceholder(anchor_node)
|
278
|
+
@markAsSelected( anchor_node )
|
279
|
+
@displayTooltipAt( anchor_node )
|
280
|
+
|
281
|
+
scrollTo: (node)->
|
282
|
+
return if utils.isElementInViewport($(node))
|
283
|
+
|
284
|
+
top = node.offset().top
|
285
|
+
#scroll to element top
|
286
|
+
$('html, body').animate
|
287
|
+
scrollTop: top
|
288
|
+
, 20
|
289
|
+
|
290
|
+
#handle arrow direction from keyUp.
|
291
|
+
handleArrow: (ev)=>
|
292
|
+
current_node = $(@getNode())
|
293
|
+
if current_node
|
294
|
+
@markAsSelected( current_node )
|
295
|
+
@displayTooltipAt( current_node )
|
296
|
+
|
297
|
+
#handle arrow direction from keyDown.
|
298
|
+
handleArrowForKeyDown: (ev)=>
|
299
|
+
current_node = $(@getNode())
|
300
|
+
utils.log(ev)
|
301
|
+
ev_type = ev.originalEvent.key || ev.originalEvent.keyIdentifier
|
302
|
+
|
303
|
+
utils.log("ENTER ARROW for key #{ev_type}")
|
304
|
+
|
305
|
+
#handle keys for image figure
|
306
|
+
switch ev_type
|
307
|
+
|
308
|
+
when "Down"
|
309
|
+
next_node = current_node.next()
|
310
|
+
utils.log "NEXT NODE IS #{next_node.attr('class')}"
|
311
|
+
utils.log "CURRENT NODE IS #{current_node.attr('class')}"
|
312
|
+
|
313
|
+
return unless $(current_node).hasClass("graf")
|
314
|
+
return unless $(current_node).editableCaretOnLastLine()
|
315
|
+
|
316
|
+
utils.log "ENTER ARROW PASSED RETURNS"
|
317
|
+
|
318
|
+
#if next element is embed select & focus it
|
319
|
+
if next_node.hasClass("graf--figure")
|
320
|
+
n = next_node.find(".imageCaption")
|
321
|
+
@setRangeAt n[0]
|
322
|
+
@scrollTo(n)
|
323
|
+
utils.log "1 down"
|
324
|
+
utils.log n[0]
|
325
|
+
next_node.addClass("is-mediaFocused is-selected")
|
326
|
+
return false
|
327
|
+
#if current node is embed
|
328
|
+
else if next_node.hasClass("graf--mixtapeEmbed")
|
329
|
+
n = current_node.next(".graf--mixtapeEmbed")
|
330
|
+
num = n[0].childNodes.length
|
331
|
+
@setRangeAt n[0], num
|
332
|
+
@scrollTo(n)
|
333
|
+
utils.log "2 down"
|
334
|
+
return false
|
335
|
+
|
336
|
+
if current_node.hasClass("graf--figure") && next_node.hasClass("graf")
|
337
|
+
@setRangeAt next_node[0]
|
338
|
+
@scrollTo(next_node)
|
339
|
+
utils.log "3 down"
|
340
|
+
return false
|
341
|
+
|
342
|
+
###
|
343
|
+
else if next_node.hasClass("graf")
|
344
|
+
n = current_node.next(".graf")
|
345
|
+
@setRangeAt n[0]
|
346
|
+
@scrollTo(n)
|
347
|
+
false
|
348
|
+
###
|
349
|
+
|
350
|
+
when "Up"
|
351
|
+
prev_node = current_node.prev()
|
352
|
+
utils.log "PREV NODE IS #{prev_node.attr('class')}"
|
353
|
+
utils.log "CURRENT NODE IS up #{current_node.attr('class')}"
|
354
|
+
|
355
|
+
return unless $(current_node).hasClass("graf")
|
356
|
+
return unless $(current_node).editableCaretOnFirstLine()
|
357
|
+
|
358
|
+
utils.log "ENTER ARROW PASSED RETURNS"
|
359
|
+
|
360
|
+
if prev_node.hasClass("graf--figure")
|
361
|
+
utils.log "1 up"
|
362
|
+
n = prev_node.find(".imageCaption")
|
363
|
+
@setRangeAt n[0]
|
364
|
+
@scrollTo(n)
|
365
|
+
prev_node.addClass("is-mediaFocused is-selected")
|
366
|
+
return false
|
367
|
+
|
368
|
+
else if prev_node.hasClass("graf--mixtapeEmbed")
|
369
|
+
n = current_node.prev(".graf--mixtapeEmbed")
|
370
|
+
num = n[0].childNodes.length
|
371
|
+
@setRangeAt n[0], num
|
372
|
+
@scrollTo(n)
|
373
|
+
utils.log "2 up"
|
374
|
+
return false
|
375
|
+
|
376
|
+
if current_node.hasClass("graf--figure") && prev_node.hasClass("graf")
|
377
|
+
@setRangeAt prev_node[0]
|
378
|
+
@scrollTo(prev_node)
|
379
|
+
utils.log "3 up"
|
380
|
+
return false
|
381
|
+
|
382
|
+
else if prev_node.hasClass("graf")
|
383
|
+
n = current_node.prev(".graf")
|
384
|
+
num = n[0].childNodes.length
|
385
|
+
@setRangeAt n[0], num
|
386
|
+
@scrollTo(n)
|
387
|
+
utils.log "4 up"
|
388
|
+
return false
|
389
|
+
|
390
|
+
utils.log "noting"
|
391
|
+
|
392
|
+
#detects html data , creates a hidden node to paste ,
|
393
|
+
#then clean up the content and copies to currentNode, very clever uh?
|
394
|
+
handlePaste: (ev)=>
|
395
|
+
utils.log("pasted!")
|
396
|
+
@aa = @getNode()
|
397
|
+
|
398
|
+
pastedText = undefined
|
399
|
+
if (window.clipboardData && window.clipboardData.getData) #IE
|
400
|
+
pastedText = window.clipboardData.getData('Text')
|
401
|
+
else if (ev.originalEvent.clipboardData && ev.originalEvent.clipboardData.getData)
|
402
|
+
cbd = ev.originalEvent.clipboardData
|
403
|
+
pastedText = if _.isEmpty(cbd.getData('text/html')) then cbd.getData('text/plain') else cbd.getData('text/html')
|
404
|
+
|
405
|
+
#alert(pastedText) # Process and handle text...
|
406
|
+
#detect if is html
|
407
|
+
if pastedText.match(/<\/*[a-z][^>]+?>/gi)
|
408
|
+
utils.log("HTML DETECTED ON PASTE")
|
409
|
+
$(pastedText)
|
410
|
+
|
411
|
+
document.body.appendChild($("<div id='paste'></div>")[0])
|
412
|
+
$("#paste").html(pastedText)
|
413
|
+
@setupElementsClasses $("#paste"), ()=>
|
414
|
+
nodes = $($("#paste").html()).insertAfter($(@aa))
|
415
|
+
$("#paste").remove()
|
416
|
+
#set caret on newly created node
|
417
|
+
last_node = nodes.last()[0]
|
418
|
+
num = last_node.childNodes.length
|
419
|
+
@setRangeAt(last_node, num)
|
420
|
+
new_node = $(@getNode())
|
421
|
+
top = new_node.offset().top
|
422
|
+
@markAsSelected(new_node)
|
423
|
+
@displayTooltipAt($(@el).find(".is-selected"))
|
424
|
+
#scroll to element top
|
425
|
+
@handleUnwrappedImages(nodes)
|
426
|
+
$('html, body').animate
|
427
|
+
scrollTop: top
|
428
|
+
, 200
|
429
|
+
|
430
|
+
return false # Prevent the default handler from running.
|
431
|
+
|
432
|
+
handleUnwrappedImages: (elements)->
|
433
|
+
#http://stackoverflow.com/questions/4998908/convert-data-uri-to-file-then-append-to-formdata
|
434
|
+
_.each elements.find("img"), (image)=>
|
435
|
+
utils.log ("process image here!")
|
436
|
+
@tooltip_view.uploadExistentImage(image)
|
437
|
+
|
438
|
+
#TODO: remove this, not used
|
439
|
+
handleInmediateDeletion: (element)->
|
440
|
+
@inmediateDeletion = false
|
441
|
+
new_node = $( @baseParagraphTmpl() ).insertBefore( $(element) )
|
442
|
+
new_node.addClass("is-selected")
|
443
|
+
@setRangeAt($(element).prev()[0])
|
444
|
+
$(element).remove()
|
445
|
+
|
446
|
+
#TODO: not used anymore, remove this
|
447
|
+
#when found that the current node is text node
|
448
|
+
#create a new <p> and focus
|
449
|
+
handleUnwrappedNode: (element)->
|
450
|
+
tmpl = $(@baseParagraphTmpl())
|
451
|
+
@setElementName(tmpl)
|
452
|
+
$(element).wrap(tmpl)
|
453
|
+
new_node = $("[name='#{tmpl.attr('name')}']")
|
454
|
+
new_node.addClass("is-selected")
|
455
|
+
@setRangeAt(new_node[0])
|
456
|
+
return false
|
457
|
+
|
458
|
+
###
|
459
|
+
This is a rare hack only for FF (I hope),
|
460
|
+
when there is no range it creates a new element as a placeholder,
|
461
|
+
then finds previous element from that placeholder,
|
462
|
+
then it focus the prev and removes the placeholder.
|
463
|
+
a nasty nasty one...
|
464
|
+
###
|
465
|
+
handleNullAnchor: ()->
|
466
|
+
utils.log "WARNING! this is an empty node"
|
467
|
+
sel = @selection();
|
468
|
+
|
469
|
+
if (sel.isCollapsed && sel.rangeCount > 0)
|
470
|
+
range = sel.getRangeAt(0)
|
471
|
+
span = $( @baseParagraphTmpl())[0]
|
472
|
+
range.insertNode(span)
|
473
|
+
range.setStart(span, 0)
|
474
|
+
range.setEnd(span, 0)
|
475
|
+
sel.removeAllRanges()
|
476
|
+
sel.addRange(range)
|
477
|
+
|
478
|
+
node = $(range.commonAncestorContainer)
|
479
|
+
prev = node.prev()
|
480
|
+
num = prev[0].childNodes.length
|
481
|
+
utils.log prev
|
482
|
+
if prev.hasClass("graf")
|
483
|
+
@setRangeAt(prev[0], num)
|
484
|
+
node.remove()
|
485
|
+
@markAsSelected(@getNode())
|
486
|
+
else if prev.hasClass("graf--mixtapeEmbed")
|
487
|
+
@setRangeAt(prev[0], num)
|
488
|
+
node.remove()
|
489
|
+
@markAsSelected(@getNode())
|
490
|
+
else if !prev
|
491
|
+
@.setRangeAt(@.$el.find(".section-inner p")[0])
|
492
|
+
|
493
|
+
@displayTooltipAt($(@el).find(".is-selected"))
|
494
|
+
|
495
|
+
#used when all the content is removed, then it re render
|
496
|
+
handleCompleteDeletion: (element)->
|
497
|
+
if _.isEmpty( $(element).text().trim() )
|
498
|
+
utils.log "HANDLE COMPLETE DELETION"
|
499
|
+
@selection().removeAllRanges()
|
500
|
+
@render()
|
501
|
+
|
502
|
+
setTimeout =>
|
503
|
+
@setRangeAt($(@el).find(".section-inner p")[0])
|
504
|
+
, 20
|
505
|
+
@completeDeletion = true
|
506
|
+
|
507
|
+
#handles tab navigation
|
508
|
+
handleTab: (anchor_node)->
|
509
|
+
utils.log "HANDLE TAB"
|
510
|
+
classes = ".graf, .graf--mixtapeEmbed, .graf--figure, .graf--figure"
|
511
|
+
next = $(anchor_node).next(classes)
|
512
|
+
|
513
|
+
if $(next).hasClass("graf--figure")
|
514
|
+
next = $(next).find("figcaption")
|
515
|
+
@setRangeAt next[0]
|
516
|
+
@markAsSelected $(next).parent(".graf--figure")
|
517
|
+
@displayTooltipAt next
|
518
|
+
@scrollTo $(next)
|
519
|
+
return false
|
520
|
+
|
521
|
+
if _.isEmpty(next) or _.isUndefined(next[0])
|
522
|
+
next = $(".graf:first")
|
523
|
+
|
524
|
+
@setRangeAt next[0]
|
525
|
+
@markAsSelected next
|
526
|
+
@displayTooltipAt next
|
527
|
+
@scrollTo $(next)
|
528
|
+
|
529
|
+
handleKeyDown: (e)->
|
530
|
+
utils.log "KEYDOWN"
|
531
|
+
|
532
|
+
anchor_node = @getNode() #current node on which cursor is positioned
|
533
|
+
|
534
|
+
@markAsSelected( anchor_node ) if anchor_node
|
535
|
+
|
536
|
+
if e.which is 9
|
537
|
+
|
538
|
+
@handleTab(anchor_node)
|
539
|
+
return false
|
540
|
+
|
541
|
+
if e.which == 13
|
542
|
+
|
543
|
+
#removes previous selected nodes
|
544
|
+
$(@el).find(".is-selected").removeClass("is-selected")
|
545
|
+
|
546
|
+
parent = $(anchor_node)
|
547
|
+
|
548
|
+
utils.log @isLastChar()
|
549
|
+
|
550
|
+
#embeds or extracts
|
551
|
+
if parent.hasClass("is-embedable")
|
552
|
+
@tooltip_view.getEmbedFromNode($(anchor_node))
|
553
|
+
else if parent.hasClass("is-extractable")
|
554
|
+
@tooltip_view.getExtractFromNode($(anchor_node))
|
555
|
+
|
556
|
+
|
557
|
+
#supress linebreak into embed page text unless last char
|
558
|
+
if parent.hasClass("graf--mixtapeEmbed") or parent.hasClass("graf--iframe") or parent.hasClass("graf--figure")
|
559
|
+
utils.log("supress linebreak from embed !(last char)")
|
560
|
+
return false unless @isLastChar()
|
561
|
+
|
562
|
+
#supress linebreak or create new <p> into embed caption unless last char el
|
563
|
+
if parent.hasClass("graf--iframe") or parent.hasClass("graf--figure")
|
564
|
+
if @isLastChar()
|
565
|
+
@handleLineBreakWith("p", parent)
|
566
|
+
@setRangeAtText($(".is-selected")[0])
|
567
|
+
|
568
|
+
$(".is-selected").trigger("mouseup") #is not making any change
|
569
|
+
return false
|
570
|
+
else
|
571
|
+
return false
|
572
|
+
|
573
|
+
@tooltip_view.cleanOperationClasses($(anchor_node))
|
574
|
+
|
575
|
+
|
576
|
+
if (anchor_node && @editor_menu.lineBreakReg.test(anchor_node.nodeName))
|
577
|
+
#new paragraph if it the last character
|
578
|
+
if @isLastChar()
|
579
|
+
utils.log "new paragraph if it the last character"
|
580
|
+
e.preventDefault()
|
581
|
+
@handleLineBreakWith("p", parent)
|
582
|
+
|
583
|
+
setTimeout ()=>
|
584
|
+
node = @getNode()
|
585
|
+
@markAsSelected( @getNode() ) #if anchor_node
|
586
|
+
@setupFirstAndLast()
|
587
|
+
#set name on new element
|
588
|
+
@setElementName($(node))
|
589
|
+
|
590
|
+
#empty childs if text is empty
|
591
|
+
if _.isEmpty $(node).text().trim()
|
592
|
+
_.each $(node).children(), (n)->
|
593
|
+
$(n).remove()
|
594
|
+
$(node).append("<br>")
|
595
|
+
|
596
|
+
#shows tooltip
|
597
|
+
@displayTooltipAt($(@el).find(".is-selected"))
|
598
|
+
, 2
|
599
|
+
|
600
|
+
|
601
|
+
#delete key
|
602
|
+
if (e.which == 8)
|
603
|
+
@tooltip_view.hide()
|
604
|
+
utils.log("removing from down")
|
605
|
+
utils.log "REACHED TOP" if @reachedTop
|
606
|
+
return false if @prevented or @reachedTop && @isFirstChar()
|
607
|
+
#return false if !anchor_node or anchor_node.nodeType is 3
|
608
|
+
utils.log("pass initial validations")
|
609
|
+
anchor_node = @getNode()
|
610
|
+
utils.log "anchor_node"
|
611
|
+
utils.log anchor_node
|
612
|
+
utils.log "UTILS anchor_node"
|
613
|
+
utils_anchor_node = utils.getNode()
|
614
|
+
utils.log utils_anchor_node
|
615
|
+
|
616
|
+
if $(utils_anchor_node).hasClass("section-content") || $(utils_anchor_node).hasClass("graf--first")
|
617
|
+
utils.log "SECTION DETECTED FROM KEYDOWN #{_.isEmpty($(utils_anchor_node).text())}"
|
618
|
+
return false if _.isEmpty($(utils_anchor_node).text())
|
619
|
+
|
620
|
+
if anchor_node && anchor_node.nodeType is 3
|
621
|
+
#@displayEmptyPlaceholder()
|
622
|
+
utils.log("TextNode detected from Down!")
|
623
|
+
#return false
|
624
|
+
|
625
|
+
#supress del into embed if first char or delete if empty content
|
626
|
+
if $(anchor_node).hasClass("graf--mixtapeEmbed") or $(anchor_node).hasClass("graf--iframe")
|
627
|
+
if _.isEmpty $(anchor_node).text().trim()
|
628
|
+
utils.log "EMPTY CHAR"
|
629
|
+
return false
|
630
|
+
else
|
631
|
+
if @isFirstChar()
|
632
|
+
utils.log "FIRST CHAR"
|
633
|
+
@inmediateDeletion = true if @isSelectingAll(anchor_node)
|
634
|
+
return false
|
635
|
+
|
636
|
+
#TODO: supress del when the prev el is embed and current_node is at first char
|
637
|
+
if $(anchor_node).prev().hasClass("graf--mixtapeEmbed")
|
638
|
+
return false if @isFirstChar() && !_.isEmpty( $(anchor_node).text().trim() )
|
639
|
+
|
640
|
+
#arrows key
|
641
|
+
#if _.contains([37,38,39,40], e.which)
|
642
|
+
#up & down
|
643
|
+
if _.contains([38, 40], e.which)
|
644
|
+
utils.log e.which
|
645
|
+
@handleArrowForKeyDown(e)
|
646
|
+
#return false
|
647
|
+
|
648
|
+
handleKeyUp: (e , node)->
|
649
|
+
utils.log "KEYUP"
|
650
|
+
|
651
|
+
@editor_menu.hide() #hides menu just in case
|
652
|
+
@reachedTop = false
|
653
|
+
anchor_node = @getNode() #current node on which cursor is positioned
|
654
|
+
utils_anchor_node = utils.getNode()
|
655
|
+
|
656
|
+
@handleTextSelection(anchor_node)
|
657
|
+
|
658
|
+
if (e.which == 8)
|
659
|
+
|
660
|
+
#if detect all text deleted , re render
|
661
|
+
if $(utils_anchor_node).hasClass("postField--body")
|
662
|
+
utils.log "ALL GONE from UP"
|
663
|
+
@handleCompleteDeletion($(@el))
|
664
|
+
if @completeDeletion
|
665
|
+
@completeDeletion = false
|
666
|
+
return false
|
667
|
+
|
668
|
+
if $(utils_anchor_node).hasClass("section-content") || $(utils_anchor_node).hasClass("graf--first")
|
669
|
+
utils.log "SECTION DETECTED FROM KEYUP #{_.isEmpty($(utils_anchor_node).text())}"
|
670
|
+
return false if _.isEmpty($(utils_anchor_node).text())
|
671
|
+
|
672
|
+
if _.isNull(anchor_node)
|
673
|
+
@handleNullAnchor()
|
674
|
+
return false
|
675
|
+
|
676
|
+
if $(anchor_node).hasClass("graf--first")
|
677
|
+
utils.log "THE FIRST ONE! UP"
|
678
|
+
@markAsSelected(anchor_node)
|
679
|
+
@setupFirstAndLast()
|
680
|
+
false
|
681
|
+
|
682
|
+
if anchor_node
|
683
|
+
@markAsSelected(anchor_node)
|
684
|
+
@setupFirstAndLast()
|
685
|
+
@displayTooltipAt($(@el).find(".is-selected"))
|
686
|
+
|
687
|
+
#arrows key
|
688
|
+
if _.contains([37,38,39,40], e.which)
|
689
|
+
@handleArrow(e)
|
690
|
+
#return false
|
691
|
+
|
692
|
+
#TODO: Separate in little functions
|
693
|
+
handleLineBreakWith: (element_type, from_element)->
|
694
|
+
new_paragraph = $("<#{element_type} class='graf graf--#{element_type} graf--empty is-selected'><br/></#{element_type}>")
|
695
|
+
if from_element.parent().is('[class^="graf--"]')
|
696
|
+
new_paragraph.insertAfter(from_element.parent())
|
697
|
+
else
|
698
|
+
new_paragraph.insertAfter(from_element)
|
699
|
+
#set caret on new <p>
|
700
|
+
@setRangeAt(new_paragraph[0])
|
701
|
+
@scrollTo new_paragraph
|
702
|
+
|
703
|
+
#shows the (+) tooltip at current element
|
704
|
+
displayTooltipAt: (element)->
|
705
|
+
utils.log ("POSITION FOR TOOLTIP")
|
706
|
+
#utils.log $(element)
|
707
|
+
return if !element
|
708
|
+
@tooltip_view.hide()
|
709
|
+
return unless _.isEmpty( $(element).text() )
|
710
|
+
@position = $(element).offset()
|
711
|
+
@tooltip_view.render()
|
712
|
+
@tooltip_view.move(left: @position.left - 60 , top: @position.top - 5 )
|
713
|
+
|
714
|
+
#mark the current row as selected
|
715
|
+
markAsSelected: (element)->
|
716
|
+
|
717
|
+
return if _.isUndefined element
|
718
|
+
|
719
|
+
$(@el).find(".is-selected").removeClass("is-mediaFocused is-selected")
|
720
|
+
$(element).addClass("is-selected")
|
721
|
+
|
722
|
+
if $(element).prop("tagName").toLowerCase() is "figure"
|
723
|
+
$(element).addClass("is-mediaFocused")
|
724
|
+
|
725
|
+
$(element).find(".defaultValue").remove()
|
726
|
+
#set reached top if element is first!
|
727
|
+
if $(element).hasClass("graf--first")
|
728
|
+
@reachedTop = true
|
729
|
+
$(element).append("<br>") if $(element).find("br").length is 0
|
730
|
+
|
731
|
+
addClassesToElement: (element)=>
|
732
|
+
n = element
|
733
|
+
name = n.nodeName.toLowerCase()
|
734
|
+
switch name
|
735
|
+
when "p", "h2", "h3", "pre", "div"
|
736
|
+
#utils.log n
|
737
|
+
unless $(n).hasClass("graf--mixtapeEmbed")
|
738
|
+
$(n).removeClass().addClass("graf graf--#{name}")
|
739
|
+
|
740
|
+
if name is "p" and $(n).find("br").length is 0
|
741
|
+
$(n).append("<br>")
|
742
|
+
|
743
|
+
when "code"
|
744
|
+
#utils.log n
|
745
|
+
$(n).unwrap().wrap("<p class='graf graf--pre'></p>")
|
746
|
+
n = $(n).parent()
|
747
|
+
|
748
|
+
when "ol", "ul"
|
749
|
+
#utils.log "lists"
|
750
|
+
$(n).removeClass().addClass("postList")
|
751
|
+
_.each $(n).find("li"), (li)->
|
752
|
+
$(n).removeClass().addClass("graf graf--li")
|
753
|
+
#postList , and li as graf
|
754
|
+
|
755
|
+
when "img"
|
756
|
+
utils.log "images"
|
757
|
+
#@handleUnwrappedImages(n)
|
758
|
+
#@handleUnwrappedImages(nodes)
|
759
|
+
@tooltip_view.uploadExistentImage(n)
|
760
|
+
#set figure non editable
|
761
|
+
|
762
|
+
when "a", 'strong', 'em', 'br', 'b', 'u', 'i'
|
763
|
+
utils.log "links"
|
764
|
+
$(n).wrap("<p class='graf graf--#{name}'></p>")
|
765
|
+
n = $(n).parent()
|
766
|
+
#dont know
|
767
|
+
|
768
|
+
when "blockquote"
|
769
|
+
#TODO remove inner elements like P
|
770
|
+
#$(n).find("p").unwrap()
|
771
|
+
n = $(n).removeClass().addClass("graf graf--#{name}")
|
772
|
+
|
773
|
+
else
|
774
|
+
#TODO: for now leave this relaxed, because this is
|
775
|
+
#overwriting embeds
|
776
|
+
#wrap all the rest
|
777
|
+
$(n).wrap("<p class='graf graf--#{name}'></p>")
|
778
|
+
n = $(n).parent()
|
779
|
+
|
780
|
+
return n
|
781
|
+
|
782
|
+
setupElementsClasses: (element, cb)->
|
783
|
+
if _.isUndefined(element)
|
784
|
+
@element = $(@el).find('.section-inner')
|
785
|
+
else
|
786
|
+
@element = element
|
787
|
+
|
788
|
+
setTimeout ()=>
|
789
|
+
#clean context and wrap text nodes
|
790
|
+
@cleanContents(@element)
|
791
|
+
@wrapTextNodes(@element)
|
792
|
+
#setup classes
|
793
|
+
_.each @element.children(), (n)=>
|
794
|
+
name = $(n).prop("tagName").toLowerCase()
|
795
|
+
n = @addClassesToElement(n)
|
796
|
+
|
797
|
+
@setElementName(n)
|
798
|
+
|
799
|
+
@setupLinks(@element.find("a"))
|
800
|
+
@setupFirstAndLast()
|
801
|
+
|
802
|
+
cb() if _.isFunction(cb)
|
803
|
+
, 20
|
804
|
+
|
805
|
+
cleanContents: (element)->
|
806
|
+
#TODO: should config tags
|
807
|
+
if _.isUndefined(element)
|
808
|
+
@element = $(@el).find('.section-inner')
|
809
|
+
else
|
810
|
+
@element = element
|
811
|
+
|
812
|
+
s = new Sanitize
|
813
|
+
elements: ['strong','img', 'em', 'br', 'a', 'blockquote', 'b', 'u', 'i', 'pre', 'p', 'h2', 'h3']
|
814
|
+
|
815
|
+
attributes:
|
816
|
+
'__ALL__': ['class']
|
817
|
+
a: ['href', 'title', 'target']
|
818
|
+
img: ['src']
|
819
|
+
|
820
|
+
protocols:
|
821
|
+
a: { href: ['http', 'https', 'mailto'] }
|
822
|
+
|
823
|
+
transformers: [(input)->
|
824
|
+
if (input.node_name == "span" && $(input.node).hasClass("defaultValue") )
|
825
|
+
return whitelist_nodes: [input.node]
|
826
|
+
else
|
827
|
+
return null
|
828
|
+
(input)->
|
829
|
+
#page embeds
|
830
|
+
if(input.node_name == 'div' && $(input.node).hasClass("graf--mixtapeEmbed") )
|
831
|
+
return whitelist_nodes: [input.node]
|
832
|
+
else if(input.node_name == 'a' && $(input.node).parent(".graf--mixtapeEmbed").exists() )
|
833
|
+
return attr_whitelist: ["style"]
|
834
|
+
else
|
835
|
+
return null
|
836
|
+
,
|
837
|
+
(input)->
|
838
|
+
#embeds
|
839
|
+
if( input.node_name == 'figure' && $(input.node).hasClass("graf--iframe") )
|
840
|
+
return whitelist_nodes: [input.node]
|
841
|
+
else if(input.node_name == 'div' && $(input.node).hasClass("iframeContainer") && $(input.node).parent(".graf--iframe").exists() )
|
842
|
+
return whitelist_nodes: [input.node]
|
843
|
+
else if(input.node_name == 'iframe' && $(input.node).parent(".iframeContainer").exists() )
|
844
|
+
return whitelist_nodes: [input.node]
|
845
|
+
else if(input.node_name == 'figcaption' && $(input.node).parent(".graf--iframe").exists() )
|
846
|
+
return whitelist_nodes: [input.node]
|
847
|
+
else
|
848
|
+
return null
|
849
|
+
,
|
850
|
+
(input)->
|
851
|
+
#image embeds
|
852
|
+
if(input.node_name == 'figure' && $(input.node).hasClass("graf--figure") )
|
853
|
+
return whitelist_nodes: [input.node]
|
854
|
+
|
855
|
+
else if(input.node_name == 'div' && ($(input.node).hasClass("aspect-ratio-fill") || $(input.node).hasClass("aspectRatioPlaceholder")) && $(input.node).parent(".graf--figure").exists() )
|
856
|
+
return whitelist_nodes: [input.node]
|
857
|
+
|
858
|
+
else if(input.node_name == 'img' && $(input.node).parent(".graf--figure").exists() )
|
859
|
+
return whitelist_nodes: [input.node]
|
860
|
+
|
861
|
+
else if(input.node_name == 'a' && $(input.node).parent(".graf--mixtapeEmbed").exists() )
|
862
|
+
return attr_whitelist: ["style"]
|
863
|
+
|
864
|
+
else if(input.node_name == 'span' && $(input.node).parent(".imageCaption").exists())
|
865
|
+
return whitelist_nodes: [input.node]
|
866
|
+
else
|
867
|
+
return null
|
868
|
+
]
|
869
|
+
|
870
|
+
if @element.exists()
|
871
|
+
utils.log "CLEAN HTML"
|
872
|
+
@element.html(s.clean_node( @element[0] ))
|
873
|
+
|
874
|
+
setupLinks: (elems)->
|
875
|
+
_.each elems, (n)=>
|
876
|
+
@setupLink(n)
|
877
|
+
|
878
|
+
setupLink: (n)->
|
879
|
+
parent_name = $(n).parent().prop("tagName").toLowerCase()
|
880
|
+
$(n).addClass("markup--anchor markup--#{parent_name}-anchor")
|
881
|
+
href = $(n).attr("href")
|
882
|
+
$(n).attr("data-href", href)
|
883
|
+
|
884
|
+
preCleanNode: (element)->
|
885
|
+
s = new Sanitize
|
886
|
+
elements: ['strong', 'em', 'br', 'a', 'b', 'u', 'i']
|
887
|
+
|
888
|
+
attributes:
|
889
|
+
a: ['href', 'title', 'target']
|
890
|
+
|
891
|
+
protocols:
|
892
|
+
a: { href: ['http', 'https', 'mailto'] }
|
893
|
+
|
894
|
+
$(element).html s.clean_node( element[0] )
|
895
|
+
|
896
|
+
element = @addClassesToElement( $(element)[0] )
|
897
|
+
|
898
|
+
$(element)
|
899
|
+
|
900
|
+
setupFirstAndLast: ()=>
|
901
|
+
childs = $(@el).find(".section-inner").children()
|
902
|
+
childs.removeClass("graf--last , graf--first")
|
903
|
+
childs.first().addClass("graf--first")
|
904
|
+
childs.last().addClass("graf--last")
|
905
|
+
|
906
|
+
wrapTextNodes: (element)->
|
907
|
+
if _.isUndefined(element)
|
908
|
+
element = $(@el).find('.section-inner')
|
909
|
+
else
|
910
|
+
element = element
|
911
|
+
|
912
|
+
element.contents().filter(->
|
913
|
+
@nodeType is 3 and @data.trim().length > 0
|
914
|
+
).wrap "<p class='graf grap--p'></p>"
|
915
|
+
|
916
|
+
setElementName: (element)->
|
917
|
+
$(element).attr("name", utils.generateUniqueName())
|