tui_editor-rails 1.0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (887) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +6 -0
  5. data/Gemfile.lock +20 -0
  6. data/README.md +69 -0
  7. data/Rakefile +2 -0
  8. data/bin/console +14 -0
  9. data/bin/setup +8 -0
  10. data/example/.gitignore +30 -0
  11. data/example/.ruby-version +1 -0
  12. data/example/Gemfile +64 -0
  13. data/example/Gemfile.lock +224 -0
  14. data/example/README.md +67 -0
  15. data/example/Rakefile +6 -0
  16. data/example/app/assets/config/manifest.js +3 -0
  17. data/example/app/assets/images/.keep +0 -0
  18. data/example/app/assets/images/screen_capture.png +0 -0
  19. data/example/app/assets/javascripts/application.js +23 -0
  20. data/example/app/assets/javascripts/cable.js +13 -0
  21. data/example/app/assets/javascripts/channels/.keep +0 -0
  22. data/example/app/assets/javascripts/home.coffee +3 -0
  23. data/example/app/assets/javascripts/posts.coffee +3 -0
  24. data/example/app/assets/stylesheets/application.scss +4 -0
  25. data/example/app/assets/stylesheets/home.scss +3 -0
  26. data/example/app/assets/stylesheets/posts.scss +3 -0
  27. data/example/app/assets/stylesheets/scaffolds.scss +84 -0
  28. data/example/app/channels/application_cable/channel.rb +4 -0
  29. data/example/app/channels/application_cable/connection.rb +4 -0
  30. data/example/app/controllers/application_controller.rb +2 -0
  31. data/example/app/controllers/concerns/.keep +0 -0
  32. data/example/app/controllers/home_controller.rb +4 -0
  33. data/example/app/controllers/posts_controller.rb +74 -0
  34. data/example/app/helpers/application_helper.rb +2 -0
  35. data/example/app/helpers/home_helper.rb +2 -0
  36. data/example/app/helpers/posts_helper.rb +2 -0
  37. data/example/app/jobs/application_job.rb +2 -0
  38. data/example/app/mailers/application_mailer.rb +4 -0
  39. data/example/app/models/application_record.rb +3 -0
  40. data/example/app/models/concerns/.keep +0 -0
  41. data/example/app/models/post.rb +2 -0
  42. data/example/app/views/home/index.html.erb +11 -0
  43. data/example/app/views/layouts/application.html.erb +14 -0
  44. data/example/app/views/layouts/mailer.html.erb +13 -0
  45. data/example/app/views/layouts/mailer.text.erb +1 -0
  46. data/example/app/views/posts/_form.html.erb +27 -0
  47. data/example/app/views/posts/_post.json.jbuilder +2 -0
  48. data/example/app/views/posts/edit.html.erb +6 -0
  49. data/example/app/views/posts/index.html.erb +29 -0
  50. data/example/app/views/posts/index.json.jbuilder +1 -0
  51. data/example/app/views/posts/new.html.erb +5 -0
  52. data/example/app/views/posts/show.html.erb +14 -0
  53. data/example/app/views/posts/show.json.jbuilder +1 -0
  54. data/example/bin/bundle +3 -0
  55. data/example/bin/rails +9 -0
  56. data/example/bin/rake +9 -0
  57. data/example/bin/setup +36 -0
  58. data/example/bin/spring +17 -0
  59. data/example/bin/update +31 -0
  60. data/example/bin/yarn +11 -0
  61. data/example/config.ru +5 -0
  62. data/example/config/application.rb +19 -0
  63. data/example/config/boot.rb +4 -0
  64. data/example/config/cable.yml +10 -0
  65. data/example/config/credentials.yml.enc +1 -0
  66. data/example/config/database.yml +25 -0
  67. data/example/config/environment.rb +5 -0
  68. data/example/config/environments/development.rb +61 -0
  69. data/example/config/environments/production.rb +94 -0
  70. data/example/config/environments/test.rb +46 -0
  71. data/example/config/initializers/application_controller_renderer.rb +8 -0
  72. data/example/config/initializers/assets.rb +14 -0
  73. data/example/config/initializers/backtrace_silencers.rb +7 -0
  74. data/example/config/initializers/content_security_policy.rb +22 -0
  75. data/example/config/initializers/cookies_serializer.rb +5 -0
  76. data/example/config/initializers/filter_parameter_logging.rb +4 -0
  77. data/example/config/initializers/inflections.rb +16 -0
  78. data/example/config/initializers/mime_types.rb +4 -0
  79. data/example/config/initializers/wrap_parameters.rb +14 -0
  80. data/example/config/locales/en.yml +33 -0
  81. data/example/config/puma.rb +34 -0
  82. data/example/config/routes.rb +6 -0
  83. data/example/config/spring.rb +6 -0
  84. data/example/config/storage.yml +35 -0
  85. data/example/db/migrate/20180208210404_create_posts.rb +10 -0
  86. data/example/db/schema.rb +22 -0
  87. data/example/db/seeds.rb +7 -0
  88. data/example/lib/assets/.keep +0 -0
  89. data/example/lib/tasks/.keep +0 -0
  90. data/example/log/.keep +0 -0
  91. data/example/package.json +5 -0
  92. data/example/public/404.html +67 -0
  93. data/example/public/422.html +67 -0
  94. data/example/public/500.html +66 -0
  95. data/example/public/apple-touch-icon-precomposed.png +0 -0
  96. data/example/public/apple-touch-icon.png +0 -0
  97. data/example/public/favicon.ico +0 -0
  98. data/example/public/robots.txt +1 -0
  99. data/example/test/application_system_test_case.rb +5 -0
  100. data/example/test/controllers/.keep +0 -0
  101. data/example/test/controllers/home_controller_test.rb +9 -0
  102. data/example/test/controllers/posts_controller_test.rb +48 -0
  103. data/example/test/fixtures/.keep +0 -0
  104. data/example/test/fixtures/files/.keep +0 -0
  105. data/example/test/fixtures/posts.yml +9 -0
  106. data/example/test/helpers/.keep +0 -0
  107. data/example/test/integration/.keep +0 -0
  108. data/example/test/mailers/.keep +0 -0
  109. data/example/test/models/.keep +0 -0
  110. data/example/test/models/post_test.rb +7 -0
  111. data/example/test/system/.keep +0 -0
  112. data/example/test/system/posts_test.rb +45 -0
  113. data/example/test/test_helper.rb +10 -0
  114. data/example/tmp/.keep +0 -0
  115. data/example/vendor/.keep +0 -0
  116. data/lib/tui_editor/rails.rb +8 -0
  117. data/lib/tui_editor/rails/version.rb +5 -0
  118. data/tui_editor-rails.gemspec +34 -0
  119. data/vendor/assets/components/codemirror/.bower.json +31 -0
  120. data/vendor/assets/components/codemirror/AUTHORS +714 -0
  121. data/vendor/assets/components/codemirror/CHANGELOG.md +1316 -0
  122. data/vendor/assets/components/codemirror/CONTRIBUTING.md +92 -0
  123. data/vendor/assets/components/codemirror/LICENSE +21 -0
  124. data/vendor/assets/components/codemirror/README.md +35 -0
  125. data/vendor/assets/components/codemirror/addon/comment/comment.js +209 -0
  126. data/vendor/assets/components/codemirror/addon/comment/continuecomment.js +78 -0
  127. data/vendor/assets/components/codemirror/addon/dialog/dialog.css +32 -0
  128. data/vendor/assets/components/codemirror/addon/dialog/dialog.js +157 -0
  129. data/vendor/assets/components/codemirror/addon/display/autorefresh.js +47 -0
  130. data/vendor/assets/components/codemirror/addon/display/fullscreen.css +6 -0
  131. data/vendor/assets/components/codemirror/addon/display/fullscreen.js +41 -0
  132. data/vendor/assets/components/codemirror/addon/display/panel.js +123 -0
  133. data/vendor/assets/components/codemirror/addon/display/placeholder.js +63 -0
  134. data/vendor/assets/components/codemirror/addon/display/rulers.js +51 -0
  135. data/vendor/assets/components/codemirror/addon/edit/closebrackets.js +194 -0
  136. data/vendor/assets/components/codemirror/addon/edit/closetag.js +175 -0
  137. data/vendor/assets/components/codemirror/addon/edit/continuelist.js +89 -0
  138. data/vendor/assets/components/codemirror/addon/edit/matchbrackets.js +145 -0
  139. data/vendor/assets/components/codemirror/addon/edit/matchtags.js +66 -0
  140. data/vendor/assets/components/codemirror/addon/edit/trailingspace.js +27 -0
  141. data/vendor/assets/components/codemirror/addon/fold/brace-fold.js +105 -0
  142. data/vendor/assets/components/codemirror/addon/fold/comment-fold.js +59 -0
  143. data/vendor/assets/components/codemirror/addon/fold/foldcode.js +152 -0
  144. data/vendor/assets/components/codemirror/addon/fold/foldgutter.css +20 -0
  145. data/vendor/assets/components/codemirror/addon/fold/foldgutter.js +146 -0
  146. data/vendor/assets/components/codemirror/addon/fold/indent-fold.js +48 -0
  147. data/vendor/assets/components/codemirror/addon/fold/markdown-fold.js +49 -0
  148. data/vendor/assets/components/codemirror/addon/fold/xml-fold.js +182 -0
  149. data/vendor/assets/components/codemirror/addon/hint/anyword-hint.js +41 -0
  150. data/vendor/assets/components/codemirror/addon/hint/css-hint.js +60 -0
  151. data/vendor/assets/components/codemirror/addon/hint/html-hint.js +348 -0
  152. data/vendor/assets/components/codemirror/addon/hint/javascript-hint.js +155 -0
  153. data/vendor/assets/components/codemirror/addon/hint/show-hint.css +36 -0
  154. data/vendor/assets/components/codemirror/addon/hint/show-hint.js +432 -0
  155. data/vendor/assets/components/codemirror/addon/hint/sql-hint.js +286 -0
  156. data/vendor/assets/components/codemirror/addon/hint/xml-hint.js +110 -0
  157. data/vendor/assets/components/codemirror/addon/lint/coffeescript-lint.js +47 -0
  158. data/vendor/assets/components/codemirror/addon/lint/css-lint.js +40 -0
  159. data/vendor/assets/components/codemirror/addon/lint/html-lint.js +53 -0
  160. data/vendor/assets/components/codemirror/addon/lint/javascript-lint.js +63 -0
  161. data/vendor/assets/components/codemirror/addon/lint/json-lint.js +37 -0
  162. data/vendor/assets/components/codemirror/addon/lint/lint.css +73 -0
  163. data/vendor/assets/components/codemirror/addon/lint/lint.js +252 -0
  164. data/vendor/assets/components/codemirror/addon/lint/yaml-lint.js +41 -0
  165. data/vendor/assets/components/codemirror/addon/merge/merge.css +113 -0
  166. data/vendor/assets/components/codemirror/addon/merge/merge.js +1001 -0
  167. data/vendor/assets/components/codemirror/addon/mode/loadmode.js +64 -0
  168. data/vendor/assets/components/codemirror/addon/mode/multiplex.js +123 -0
  169. data/vendor/assets/components/codemirror/addon/mode/multiplex_test.js +33 -0
  170. data/vendor/assets/components/codemirror/addon/mode/overlay.js +90 -0
  171. data/vendor/assets/components/codemirror/addon/mode/simple.js +216 -0
  172. data/vendor/assets/components/codemirror/addon/runmode/colorize.js +40 -0
  173. data/vendor/assets/components/codemirror/addon/runmode/runmode-standalone.js +158 -0
  174. data/vendor/assets/components/codemirror/addon/runmode/runmode.js +72 -0
  175. data/vendor/assets/components/codemirror/addon/runmode/runmode.node.js +197 -0
  176. data/vendor/assets/components/codemirror/addon/scroll/annotatescrollbar.js +122 -0
  177. data/vendor/assets/components/codemirror/addon/scroll/scrollpastend.js +48 -0
  178. data/vendor/assets/components/codemirror/addon/scroll/simplescrollbars.css +66 -0
  179. data/vendor/assets/components/codemirror/addon/scroll/simplescrollbars.js +152 -0
  180. data/vendor/assets/components/codemirror/addon/search/jump-to-line.js +49 -0
  181. data/vendor/assets/components/codemirror/addon/search/match-highlighter.js +165 -0
  182. data/vendor/assets/components/codemirror/addon/search/matchesonscrollbar.css +8 -0
  183. data/vendor/assets/components/codemirror/addon/search/matchesonscrollbar.js +97 -0
  184. data/vendor/assets/components/codemirror/addon/search/search.js +252 -0
  185. data/vendor/assets/components/codemirror/addon/search/searchcursor.js +289 -0
  186. data/vendor/assets/components/codemirror/addon/selection/active-line.js +72 -0
  187. data/vendor/assets/components/codemirror/addon/selection/mark-selection.js +119 -0
  188. data/vendor/assets/components/codemirror/addon/selection/selection-pointer.js +98 -0
  189. data/vendor/assets/components/codemirror/addon/tern/tern.css +87 -0
  190. data/vendor/assets/components/codemirror/addon/tern/tern.js +718 -0
  191. data/vendor/assets/components/codemirror/addon/tern/worker.js +44 -0
  192. data/vendor/assets/components/codemirror/addon/wrap/hardwrap.js +144 -0
  193. data/vendor/assets/components/codemirror/bower.json +17 -0
  194. data/vendor/assets/components/codemirror/component-tools/bower.json +17 -0
  195. data/vendor/assets/components/codemirror/component-tools/build.sh +31 -0
  196. data/vendor/assets/components/codemirror/component-tools/update.py +38 -0
  197. data/vendor/assets/components/codemirror/keymap/emacs.js +416 -0
  198. data/vendor/assets/components/codemirror/keymap/sublime.js +685 -0
  199. data/vendor/assets/components/codemirror/keymap/vim.js +5219 -0
  200. data/vendor/assets/components/codemirror/lib/codemirror.css +346 -0
  201. data/vendor/assets/components/codemirror/lib/codemirror.js +9669 -0
  202. data/vendor/assets/components/codemirror/mode/apl/apl.js +174 -0
  203. data/vendor/assets/components/codemirror/mode/asciiarmor/asciiarmor.js +74 -0
  204. data/vendor/assets/components/codemirror/mode/asn.1/asn.1.js +204 -0
  205. data/vendor/assets/components/codemirror/mode/asterisk/asterisk.js +196 -0
  206. data/vendor/assets/components/codemirror/mode/brainfuck/brainfuck.js +85 -0
  207. data/vendor/assets/components/codemirror/mode/clike/clike.js +817 -0
  208. data/vendor/assets/components/codemirror/mode/clojure/clojure.js +306 -0
  209. data/vendor/assets/components/codemirror/mode/cmake/cmake.js +97 -0
  210. data/vendor/assets/components/codemirror/mode/cobol/cobol.js +255 -0
  211. data/vendor/assets/components/codemirror/mode/coffeescript/coffeescript.js +359 -0
  212. data/vendor/assets/components/codemirror/mode/commonlisp/commonlisp.js +124 -0
  213. data/vendor/assets/components/codemirror/mode/crystal/crystal.js +433 -0
  214. data/vendor/assets/components/codemirror/mode/css/css.js +832 -0
  215. data/vendor/assets/components/codemirror/mode/cypher/cypher.js +150 -0
  216. data/vendor/assets/components/codemirror/mode/d/d.js +218 -0
  217. data/vendor/assets/components/codemirror/mode/dart/dart.js +157 -0
  218. data/vendor/assets/components/codemirror/mode/diff/diff.js +47 -0
  219. data/vendor/assets/components/codemirror/mode/django/django.js +356 -0
  220. data/vendor/assets/components/codemirror/mode/dockerfile/dockerfile.js +79 -0
  221. data/vendor/assets/components/codemirror/mode/dtd/dtd.js +142 -0
  222. data/vendor/assets/components/codemirror/mode/dylan/dylan.js +352 -0
  223. data/vendor/assets/components/codemirror/mode/ebnf/ebnf.js +195 -0
  224. data/vendor/assets/components/codemirror/mode/ecl/ecl.js +206 -0
  225. data/vendor/assets/components/codemirror/mode/eiffel/eiffel.js +160 -0
  226. data/vendor/assets/components/codemirror/mode/elm/elm.js +205 -0
  227. data/vendor/assets/components/codemirror/mode/erlang/erlang.js +619 -0
  228. data/vendor/assets/components/codemirror/mode/factor/factor.js +85 -0
  229. data/vendor/assets/components/codemirror/mode/fcl/fcl.js +173 -0
  230. data/vendor/assets/components/codemirror/mode/forth/forth.js +180 -0
  231. data/vendor/assets/components/codemirror/mode/fortran/fortran.js +188 -0
  232. data/vendor/assets/components/codemirror/mode/gas/gas.js +345 -0
  233. data/vendor/assets/components/codemirror/mode/gfm/gfm.js +129 -0
  234. data/vendor/assets/components/codemirror/mode/gherkin/gherkin.js +178 -0
  235. data/vendor/assets/components/codemirror/mode/go/go.js +187 -0
  236. data/vendor/assets/components/codemirror/mode/groovy/groovy.js +230 -0
  237. data/vendor/assets/components/codemirror/mode/haml/haml.js +161 -0
  238. data/vendor/assets/components/codemirror/mode/handlebars/handlebars.js +62 -0
  239. data/vendor/assets/components/codemirror/mode/haskell-literate/haskell-literate.js +43 -0
  240. data/vendor/assets/components/codemirror/mode/haskell/haskell.js +267 -0
  241. data/vendor/assets/components/codemirror/mode/haxe/haxe.js +515 -0
  242. data/vendor/assets/components/codemirror/mode/htmlembedded/htmlembedded.js +37 -0
  243. data/vendor/assets/components/codemirror/mode/htmlmixed/htmlmixed.js +152 -0
  244. data/vendor/assets/components/codemirror/mode/http/http.js +113 -0
  245. data/vendor/assets/components/codemirror/mode/idl/idl.js +290 -0
  246. data/vendor/assets/components/codemirror/mode/javascript/javascript.js +865 -0
  247. data/vendor/assets/components/codemirror/mode/jinja2/jinja2.js +142 -0
  248. data/vendor/assets/components/codemirror/mode/jsx/jsx.js +148 -0
  249. data/vendor/assets/components/codemirror/mode/julia/julia.js +418 -0
  250. data/vendor/assets/components/codemirror/mode/livescript/livescript.js +280 -0
  251. data/vendor/assets/components/codemirror/mode/lua/lua.js +159 -0
  252. data/vendor/assets/components/codemirror/mode/markdown/markdown.js +872 -0
  253. data/vendor/assets/components/codemirror/mode/mathematica/mathematica.js +176 -0
  254. data/vendor/assets/components/codemirror/mode/mbox/mbox.js +129 -0
  255. data/vendor/assets/components/codemirror/mode/meta.js +217 -0
  256. data/vendor/assets/components/codemirror/mode/mirc/mirc.js +193 -0
  257. data/vendor/assets/components/codemirror/mode/mllike/mllike.js +356 -0
  258. data/vendor/assets/components/codemirror/mode/modelica/modelica.js +245 -0
  259. data/vendor/assets/components/codemirror/mode/mscgen/mscgen.js +175 -0
  260. data/vendor/assets/components/codemirror/mode/mumps/mumps.js +148 -0
  261. data/vendor/assets/components/codemirror/mode/nginx/nginx.js +178 -0
  262. data/vendor/assets/components/codemirror/mode/nsis/nsis.js +95 -0
  263. data/vendor/assets/components/codemirror/mode/ntriples/ntriples.js +195 -0
  264. data/vendor/assets/components/codemirror/mode/octave/octave.js +139 -0
  265. data/vendor/assets/components/codemirror/mode/oz/oz.js +252 -0
  266. data/vendor/assets/components/codemirror/mode/pascal/pascal.js +109 -0
  267. data/vendor/assets/components/codemirror/mode/pegjs/pegjs.js +114 -0
  268. data/vendor/assets/components/codemirror/mode/perl/perl.js +837 -0
  269. data/vendor/assets/components/codemirror/mode/php/php.js +234 -0
  270. data/vendor/assets/components/codemirror/mode/pig/pig.js +178 -0
  271. data/vendor/assets/components/codemirror/mode/powershell/powershell.js +398 -0
  272. data/vendor/assets/components/codemirror/mode/properties/properties.js +78 -0
  273. data/vendor/assets/components/codemirror/mode/protobuf/protobuf.js +69 -0
  274. data/vendor/assets/components/codemirror/mode/pug/pug.js +591 -0
  275. data/vendor/assets/components/codemirror/mode/puppet/puppet.js +220 -0
  276. data/vendor/assets/components/codemirror/mode/python/python.js +334 -0
  277. data/vendor/assets/components/codemirror/mode/q/q.js +139 -0
  278. data/vendor/assets/components/codemirror/mode/r/r.js +183 -0
  279. data/vendor/assets/components/codemirror/mode/rpm/rpm.js +109 -0
  280. data/vendor/assets/components/codemirror/mode/rst/rst.js +557 -0
  281. data/vendor/assets/components/codemirror/mode/ruby/ruby.js +296 -0
  282. data/vendor/assets/components/codemirror/mode/rust/rust.js +72 -0
  283. data/vendor/assets/components/codemirror/mode/sas/sas.js +303 -0
  284. data/vendor/assets/components/codemirror/mode/sass/sass.js +454 -0
  285. data/vendor/assets/components/codemirror/mode/scheme/scheme.js +249 -0
  286. data/vendor/assets/components/codemirror/mode/shell/shell.js +151 -0
  287. data/vendor/assets/components/codemirror/mode/sieve/sieve.js +193 -0
  288. data/vendor/assets/components/codemirror/mode/slim/slim.js +575 -0
  289. data/vendor/assets/components/codemirror/mode/smalltalk/smalltalk.js +168 -0
  290. data/vendor/assets/components/codemirror/mode/smarty/smarty.js +225 -0
  291. data/vendor/assets/components/codemirror/mode/solr/solr.js +104 -0
  292. data/vendor/assets/components/codemirror/mode/soy/soy.js +354 -0
  293. data/vendor/assets/components/codemirror/mode/sparql/sparql.js +180 -0
  294. data/vendor/assets/components/codemirror/mode/spreadsheet/spreadsheet.js +112 -0
  295. data/vendor/assets/components/codemirror/mode/sql/sql.js +488 -0
  296. data/vendor/assets/components/codemirror/mode/stex/stex.js +251 -0
  297. data/vendor/assets/components/codemirror/mode/stylus/stylus.js +771 -0
  298. data/vendor/assets/components/codemirror/mode/swift/swift.js +219 -0
  299. data/vendor/assets/components/codemirror/mode/tcl/tcl.js +139 -0
  300. data/vendor/assets/components/codemirror/mode/textile/textile.js +469 -0
  301. data/vendor/assets/components/codemirror/mode/tiddlywiki/tiddlywiki.css +14 -0
  302. data/vendor/assets/components/codemirror/mode/tiddlywiki/tiddlywiki.js +308 -0
  303. data/vendor/assets/components/codemirror/mode/tiki/tiki.css +26 -0
  304. data/vendor/assets/components/codemirror/mode/tiki/tiki.js +312 -0
  305. data/vendor/assets/components/codemirror/mode/toml/toml.js +88 -0
  306. data/vendor/assets/components/codemirror/mode/tornado/tornado.js +68 -0
  307. data/vendor/assets/components/codemirror/mode/troff/troff.js +84 -0
  308. data/vendor/assets/components/codemirror/mode/ttcn-cfg/ttcn-cfg.js +214 -0
  309. data/vendor/assets/components/codemirror/mode/ttcn/ttcn.js +283 -0
  310. data/vendor/assets/components/codemirror/mode/turtle/turtle.js +162 -0
  311. data/vendor/assets/components/codemirror/mode/twig/twig.js +141 -0
  312. data/vendor/assets/components/codemirror/mode/vb/vb.js +275 -0
  313. data/vendor/assets/components/codemirror/mode/vbscript/vbscript.js +350 -0
  314. data/vendor/assets/components/codemirror/mode/velocity/velocity.js +201 -0
  315. data/vendor/assets/components/codemirror/mode/verilog/verilog.js +675 -0
  316. data/vendor/assets/components/codemirror/mode/vhdl/vhdl.js +189 -0
  317. data/vendor/assets/components/codemirror/mode/vue/vue.js +77 -0
  318. data/vendor/assets/components/codemirror/mode/webidl/webidl.js +195 -0
  319. data/vendor/assets/components/codemirror/mode/xml/xml.js +401 -0
  320. data/vendor/assets/components/codemirror/mode/xquery/xquery.js +448 -0
  321. data/vendor/assets/components/codemirror/mode/yacas/yacas.js +204 -0
  322. data/vendor/assets/components/codemirror/mode/yaml-frontmatter/yaml-frontmatter.js +68 -0
  323. data/vendor/assets/components/codemirror/mode/yaml/yaml.js +118 -0
  324. data/vendor/assets/components/codemirror/mode/z80/z80.js +116 -0
  325. data/vendor/assets/components/codemirror/rollup.config.js +18 -0
  326. data/vendor/assets/components/codemirror/src/codemirror.js +3 -0
  327. data/vendor/assets/components/codemirror/src/display/Display.js +106 -0
  328. data/vendor/assets/components/codemirror/src/display/focus.js +47 -0
  329. data/vendor/assets/components/codemirror/src/display/gutters.js +34 -0
  330. data/vendor/assets/components/codemirror/src/display/highlight_worker.js +55 -0
  331. data/vendor/assets/components/codemirror/src/display/line_numbers.js +48 -0
  332. data/vendor/assets/components/codemirror/src/display/mode_state.js +22 -0
  333. data/vendor/assets/components/codemirror/src/display/operations.js +205 -0
  334. data/vendor/assets/components/codemirror/src/display/scroll_events.js +115 -0
  335. data/vendor/assets/components/codemirror/src/display/scrollbars.js +192 -0
  336. data/vendor/assets/components/codemirror/src/display/scrolling.js +184 -0
  337. data/vendor/assets/components/codemirror/src/display/selection.js +158 -0
  338. data/vendor/assets/components/codemirror/src/display/update_display.js +260 -0
  339. data/vendor/assets/components/codemirror/src/display/update_line.js +188 -0
  340. data/vendor/assets/components/codemirror/src/display/update_lines.js +64 -0
  341. data/vendor/assets/components/codemirror/src/display/view_tracking.js +153 -0
  342. data/vendor/assets/components/codemirror/src/edit/CodeMirror.js +214 -0
  343. data/vendor/assets/components/codemirror/src/edit/commands.js +178 -0
  344. data/vendor/assets/components/codemirror/src/edit/deleteNearSelection.js +30 -0
  345. data/vendor/assets/components/codemirror/src/edit/drop_events.js +119 -0
  346. data/vendor/assets/components/codemirror/src/edit/fromTextArea.js +61 -0
  347. data/vendor/assets/components/codemirror/src/edit/global_events.js +44 -0
  348. data/vendor/assets/components/codemirror/src/edit/key_events.js +159 -0
  349. data/vendor/assets/components/codemirror/src/edit/legacy.js +62 -0
  350. data/vendor/assets/components/codemirror/src/edit/main.js +69 -0
  351. data/vendor/assets/components/codemirror/src/edit/methods.js +539 -0
  352. data/vendor/assets/components/codemirror/src/edit/mouse_events.js +407 -0
  353. data/vendor/assets/components/codemirror/src/edit/options.js +191 -0
  354. data/vendor/assets/components/codemirror/src/edit/utils.js +7 -0
  355. data/vendor/assets/components/codemirror/src/input/ContentEditableInput.js +517 -0
  356. data/vendor/assets/components/codemirror/src/input/TextareaInput.js +350 -0
  357. data/vendor/assets/components/codemirror/src/input/indent.js +71 -0
  358. data/vendor/assets/components/codemirror/src/input/input.js +135 -0
  359. data/vendor/assets/components/codemirror/src/input/keymap.js +148 -0
  360. data/vendor/assets/components/codemirror/src/input/keynames.js +17 -0
  361. data/vendor/assets/components/codemirror/src/input/movement.js +110 -0
  362. data/vendor/assets/components/codemirror/src/line/highlight.js +284 -0
  363. data/vendor/assets/components/codemirror/src/line/line_data.js +337 -0
  364. data/vendor/assets/components/codemirror/src/line/pos.js +40 -0
  365. data/vendor/assets/components/codemirror/src/line/saw_special_spans.js +10 -0
  366. data/vendor/assets/components/codemirror/src/line/spans.js +372 -0
  367. data/vendor/assets/components/codemirror/src/line/utils_line.js +85 -0
  368. data/vendor/assets/components/codemirror/src/measurement/position_measurement.js +700 -0
  369. data/vendor/assets/components/codemirror/src/measurement/widgets.js +26 -0
  370. data/vendor/assets/components/codemirror/src/model/Doc.js +432 -0
  371. data/vendor/assets/components/codemirror/src/model/change_measurement.js +61 -0
  372. data/vendor/assets/components/codemirror/src/model/changes.js +330 -0
  373. data/vendor/assets/components/codemirror/src/model/chunk.js +167 -0
  374. data/vendor/assets/components/codemirror/src/model/document_data.js +111 -0
  375. data/vendor/assets/components/codemirror/src/model/history.js +228 -0
  376. data/vendor/assets/components/codemirror/src/model/line_widget.js +78 -0
  377. data/vendor/assets/components/codemirror/src/model/mark_text.js +292 -0
  378. data/vendor/assets/components/codemirror/src/model/selection.js +82 -0
  379. data/vendor/assets/components/codemirror/src/model/selection_updates.js +208 -0
  380. data/vendor/assets/components/codemirror/src/modes.js +96 -0
  381. data/vendor/assets/components/codemirror/src/util/StringStream.js +90 -0
  382. data/vendor/assets/components/codemirror/src/util/bidi.js +214 -0
  383. data/vendor/assets/components/codemirror/src/util/browser.js +33 -0
  384. data/vendor/assets/components/codemirror/src/util/dom.js +97 -0
  385. data/vendor/assets/components/codemirror/src/util/event.js +103 -0
  386. data/vendor/assets/components/codemirror/src/util/feature_detection.js +84 -0
  387. data/vendor/assets/components/codemirror/src/util/misc.js +150 -0
  388. data/vendor/assets/components/codemirror/src/util/operation_group.js +72 -0
  389. data/vendor/assets/components/codemirror/theme/3024-day.css +41 -0
  390. data/vendor/assets/components/codemirror/theme/3024-night.css +39 -0
  391. data/vendor/assets/components/codemirror/theme/abcdef.css +32 -0
  392. data/vendor/assets/components/codemirror/theme/ambiance-mobile.css +5 -0
  393. data/vendor/assets/components/codemirror/theme/ambiance.css +74 -0
  394. data/vendor/assets/components/codemirror/theme/base16-dark.css +38 -0
  395. data/vendor/assets/components/codemirror/theme/base16-light.css +38 -0
  396. data/vendor/assets/components/codemirror/theme/bespin.css +34 -0
  397. data/vendor/assets/components/codemirror/theme/blackboard.css +32 -0
  398. data/vendor/assets/components/codemirror/theme/cobalt.css +25 -0
  399. data/vendor/assets/components/codemirror/theme/colorforth.css +33 -0
  400. data/vendor/assets/components/codemirror/theme/dracula.css +40 -0
  401. data/vendor/assets/components/codemirror/theme/duotone-dark.css +35 -0
  402. data/vendor/assets/components/codemirror/theme/duotone-light.css +36 -0
  403. data/vendor/assets/components/codemirror/theme/eclipse.css +23 -0
  404. data/vendor/assets/components/codemirror/theme/elegant.css +13 -0
  405. data/vendor/assets/components/codemirror/theme/erlang-dark.css +34 -0
  406. data/vendor/assets/components/codemirror/theme/hopscotch.css +34 -0
  407. data/vendor/assets/components/codemirror/theme/icecoder.css +43 -0
  408. data/vendor/assets/components/codemirror/theme/isotope.css +34 -0
  409. data/vendor/assets/components/codemirror/theme/lesser-dark.css +47 -0
  410. data/vendor/assets/components/codemirror/theme/liquibyte.css +95 -0
  411. data/vendor/assets/components/codemirror/theme/material.css +53 -0
  412. data/vendor/assets/components/codemirror/theme/mbo.css +37 -0
  413. data/vendor/assets/components/codemirror/theme/mdn-like.css +46 -0
  414. data/vendor/assets/components/codemirror/theme/midnight.css +43 -0
  415. data/vendor/assets/components/codemirror/theme/monokai.css +36 -0
  416. data/vendor/assets/components/codemirror/theme/neat.css +12 -0
  417. data/vendor/assets/components/codemirror/theme/neo.css +43 -0
  418. data/vendor/assets/components/codemirror/theme/night.css +27 -0
  419. data/vendor/assets/components/codemirror/theme/oceanic-next.css +44 -0
  420. data/vendor/assets/components/codemirror/theme/panda-syntax.css +85 -0
  421. data/vendor/assets/components/codemirror/theme/paraiso-dark.css +38 -0
  422. data/vendor/assets/components/codemirror/theme/paraiso-light.css +38 -0
  423. data/vendor/assets/components/codemirror/theme/pastel-on-dark.css +52 -0
  424. data/vendor/assets/components/codemirror/theme/railscasts.css +34 -0
  425. data/vendor/assets/components/codemirror/theme/rubyblue.css +25 -0
  426. data/vendor/assets/components/codemirror/theme/seti.css +44 -0
  427. data/vendor/assets/components/codemirror/theme/shadowfox.css +52 -0
  428. data/vendor/assets/components/codemirror/theme/solarized.css +168 -0
  429. data/vendor/assets/components/codemirror/theme/the-matrix.css +30 -0
  430. data/vendor/assets/components/codemirror/theme/tomorrow-night-bright.css +35 -0
  431. data/vendor/assets/components/codemirror/theme/tomorrow-night-eighties.css +38 -0
  432. data/vendor/assets/components/codemirror/theme/ttcn.css +64 -0
  433. data/vendor/assets/components/codemirror/theme/twilight.css +32 -0
  434. data/vendor/assets/components/codemirror/theme/vibrant-ink.css +34 -0
  435. data/vendor/assets/components/codemirror/theme/xq-dark.css +53 -0
  436. data/vendor/assets/components/codemirror/theme/xq-light.css +43 -0
  437. data/vendor/assets/components/codemirror/theme/yeti.css +44 -0
  438. data/vendor/assets/components/codemirror/theme/zenburn.css +37 -0
  439. data/vendor/assets/components/eve/.bower.json +12 -0
  440. data/vendor/assets/components/eve/LICENSE +202 -0
  441. data/vendor/assets/components/eve/README.md +7 -0
  442. data/vendor/assets/components/eve/component.json +13 -0
  443. data/vendor/assets/components/eve/e.html +66 -0
  444. data/vendor/assets/components/eve/eve.js +371 -0
  445. data/vendor/assets/components/eve/package.json +18 -0
  446. data/vendor/assets/components/highlightjs/.bower.json +24 -0
  447. data/vendor/assets/components/highlightjs/LICENSE +24 -0
  448. data/vendor/assets/components/highlightjs/Makefile +21 -0
  449. data/vendor/assets/components/highlightjs/README.md +12 -0
  450. data/vendor/assets/components/highlightjs/bower.json +14 -0
  451. data/vendor/assets/components/highlightjs/component.json +12 -0
  452. data/vendor/assets/components/highlightjs/composer.json +26 -0
  453. data/vendor/assets/components/highlightjs/highlight.pack.js +16645 -0
  454. data/vendor/assets/components/highlightjs/highlight.pack.min.js +15 -0
  455. data/vendor/assets/components/highlightjs/package.json +8 -0
  456. data/vendor/assets/components/highlightjs/styles/agate.css +108 -0
  457. data/vendor/assets/components/highlightjs/styles/androidstudio.css +66 -0
  458. data/vendor/assets/components/highlightjs/styles/arduino-light.css +88 -0
  459. data/vendor/assets/components/highlightjs/styles/arta.css +73 -0
  460. data/vendor/assets/components/highlightjs/styles/ascetic.css +45 -0
  461. data/vendor/assets/components/highlightjs/styles/atelier-cave-dark.css +83 -0
  462. data/vendor/assets/components/highlightjs/styles/atelier-cave-light.css +85 -0
  463. data/vendor/assets/components/highlightjs/styles/atelier-cave.dark.css +113 -0
  464. data/vendor/assets/components/highlightjs/styles/atelier-cave.light.css +113 -0
  465. data/vendor/assets/components/highlightjs/styles/atelier-dune-dark.css +69 -0
  466. data/vendor/assets/components/highlightjs/styles/atelier-dune-light.css +69 -0
  467. data/vendor/assets/components/highlightjs/styles/atelier-dune.dark.css +94 -0
  468. data/vendor/assets/components/highlightjs/styles/atelier-dune.light.css +94 -0
  469. data/vendor/assets/components/highlightjs/styles/atelier-estuary-dark.css +84 -0
  470. data/vendor/assets/components/highlightjs/styles/atelier-estuary-light.css +84 -0
  471. data/vendor/assets/components/highlightjs/styles/atelier-estuary.dark.css +113 -0
  472. data/vendor/assets/components/highlightjs/styles/atelier-estuary.light.css +113 -0
  473. data/vendor/assets/components/highlightjs/styles/atelier-forest-dark.css +69 -0
  474. data/vendor/assets/components/highlightjs/styles/atelier-forest-light.css +69 -0
  475. data/vendor/assets/components/highlightjs/styles/atelier-forest.dark.css +94 -0
  476. data/vendor/assets/components/highlightjs/styles/atelier-forest.light.css +94 -0
  477. data/vendor/assets/components/highlightjs/styles/atelier-heath-dark.css +69 -0
  478. data/vendor/assets/components/highlightjs/styles/atelier-heath-light.css +69 -0
  479. data/vendor/assets/components/highlightjs/styles/atelier-heath.dark.css +94 -0
  480. data/vendor/assets/components/highlightjs/styles/atelier-heath.light.css +94 -0
  481. data/vendor/assets/components/highlightjs/styles/atelier-lakeside-dark.css +69 -0
  482. data/vendor/assets/components/highlightjs/styles/atelier-lakeside-light.css +69 -0
  483. data/vendor/assets/components/highlightjs/styles/atelier-lakeside.dark.css +94 -0
  484. data/vendor/assets/components/highlightjs/styles/atelier-lakeside.light.css +94 -0
  485. data/vendor/assets/components/highlightjs/styles/atelier-plateau-dark.css +84 -0
  486. data/vendor/assets/components/highlightjs/styles/atelier-plateau-light.css +84 -0
  487. data/vendor/assets/components/highlightjs/styles/atelier-plateau.dark.css +113 -0
  488. data/vendor/assets/components/highlightjs/styles/atelier-plateau.light.css +113 -0
  489. data/vendor/assets/components/highlightjs/styles/atelier-savanna-dark.css +84 -0
  490. data/vendor/assets/components/highlightjs/styles/atelier-savanna-light.css +84 -0
  491. data/vendor/assets/components/highlightjs/styles/atelier-savanna.dark.css +113 -0
  492. data/vendor/assets/components/highlightjs/styles/atelier-savanna.light.css +113 -0
  493. data/vendor/assets/components/highlightjs/styles/atelier-seaside-dark.css +69 -0
  494. data/vendor/assets/components/highlightjs/styles/atelier-seaside-light.css +69 -0
  495. data/vendor/assets/components/highlightjs/styles/atelier-seaside.dark.css +94 -0
  496. data/vendor/assets/components/highlightjs/styles/atelier-seaside.light.css +94 -0
  497. data/vendor/assets/components/highlightjs/styles/atelier-sulphurpool-dark.css +69 -0
  498. data/vendor/assets/components/highlightjs/styles/atelier-sulphurpool-light.css +69 -0
  499. data/vendor/assets/components/highlightjs/styles/atelier-sulphurpool.dark.css +94 -0
  500. data/vendor/assets/components/highlightjs/styles/atelier-sulphurpool.light.css +94 -0
  501. data/vendor/assets/components/highlightjs/styles/atom-one-dark.css +96 -0
  502. data/vendor/assets/components/highlightjs/styles/atom-one-light.css +96 -0
  503. data/vendor/assets/components/highlightjs/styles/brown-paper.css +64 -0
  504. data/vendor/assets/components/highlightjs/styles/brown-papersq.png +0 -0
  505. data/vendor/assets/components/highlightjs/styles/brown_paper.css +103 -0
  506. data/vendor/assets/components/highlightjs/styles/brown_papersq.png +0 -0
  507. data/vendor/assets/components/highlightjs/styles/codepen-embed.css +60 -0
  508. data/vendor/assets/components/highlightjs/styles/color-brewer.css +71 -0
  509. data/vendor/assets/components/highlightjs/styles/darcula.css +77 -0
  510. data/vendor/assets/components/highlightjs/styles/dark.css +63 -0
  511. data/vendor/assets/components/highlightjs/styles/darkula.css +6 -0
  512. data/vendor/assets/components/highlightjs/styles/default.css +99 -0
  513. data/vendor/assets/components/highlightjs/styles/docco.css +97 -0
  514. data/vendor/assets/components/highlightjs/styles/dracula.css +76 -0
  515. data/vendor/assets/components/highlightjs/styles/far.css +71 -0
  516. data/vendor/assets/components/highlightjs/styles/foundation.css +88 -0
  517. data/vendor/assets/components/highlightjs/styles/github-gist.css +71 -0
  518. data/vendor/assets/components/highlightjs/styles/github.css +99 -0
  519. data/vendor/assets/components/highlightjs/styles/googlecode.css +89 -0
  520. data/vendor/assets/components/highlightjs/styles/grayscale.css +101 -0
  521. data/vendor/assets/components/highlightjs/styles/gruvbox-dark.css +108 -0
  522. data/vendor/assets/components/highlightjs/styles/gruvbox-light.css +108 -0
  523. data/vendor/assets/components/highlightjs/styles/hopscotch.css +83 -0
  524. data/vendor/assets/components/highlightjs/styles/hybrid.css +102 -0
  525. data/vendor/assets/components/highlightjs/styles/idea.css +97 -0
  526. data/vendor/assets/components/highlightjs/styles/ir-black.css +73 -0
  527. data/vendor/assets/components/highlightjs/styles/ir_black.css +106 -0
  528. data/vendor/assets/components/highlightjs/styles/kimbie.dark.css +74 -0
  529. data/vendor/assets/components/highlightjs/styles/kimbie.light.css +74 -0
  530. data/vendor/assets/components/highlightjs/styles/magula.css +70 -0
  531. data/vendor/assets/components/highlightjs/styles/mono-blue.css +59 -0
  532. data/vendor/assets/components/highlightjs/styles/monokai-sublime.css +83 -0
  533. data/vendor/assets/components/highlightjs/styles/monokai.css +70 -0
  534. data/vendor/assets/components/highlightjs/styles/monokai_sublime.css +154 -0
  535. data/vendor/assets/components/highlightjs/styles/obsidian.css +88 -0
  536. data/vendor/assets/components/highlightjs/styles/ocean.css +74 -0
  537. data/vendor/assets/components/highlightjs/styles/paraiso-dark.css +72 -0
  538. data/vendor/assets/components/highlightjs/styles/paraiso-light.css +72 -0
  539. data/vendor/assets/components/highlightjs/styles/paraiso.dark.css +96 -0
  540. data/vendor/assets/components/highlightjs/styles/paraiso.light.css +96 -0
  541. data/vendor/assets/components/highlightjs/styles/pojoaque.css +83 -0
  542. data/vendor/assets/components/highlightjs/styles/pojoaque.jpg +0 -0
  543. data/vendor/assets/components/highlightjs/styles/purebasic.css +96 -0
  544. data/vendor/assets/components/highlightjs/styles/qtcreator_dark.css +83 -0
  545. data/vendor/assets/components/highlightjs/styles/qtcreator_light.css +83 -0
  546. data/vendor/assets/components/highlightjs/styles/railscasts.css +106 -0
  547. data/vendor/assets/components/highlightjs/styles/rainbow.css +85 -0
  548. data/vendor/assets/components/highlightjs/styles/routeros.css +108 -0
  549. data/vendor/assets/components/highlightjs/styles/school-book.css +72 -0
  550. data/vendor/assets/components/highlightjs/styles/school-book.png +0 -0
  551. data/vendor/assets/components/highlightjs/styles/school_book.css +111 -0
  552. data/vendor/assets/components/highlightjs/styles/school_book.png +0 -0
  553. data/vendor/assets/components/highlightjs/styles/solarized-dark.css +84 -0
  554. data/vendor/assets/components/highlightjs/styles/solarized-light.css +84 -0
  555. data/vendor/assets/components/highlightjs/styles/solarized_dark.css +107 -0
  556. data/vendor/assets/components/highlightjs/styles/solarized_light.css +107 -0
  557. data/vendor/assets/components/highlightjs/styles/sunburst.css +102 -0
  558. data/vendor/assets/components/highlightjs/styles/tomorrow-night-blue.css +75 -0
  559. data/vendor/assets/components/highlightjs/styles/tomorrow-night-bright.css +74 -0
  560. data/vendor/assets/components/highlightjs/styles/tomorrow-night-eighties.css +74 -0
  561. data/vendor/assets/components/highlightjs/styles/tomorrow-night.css +75 -0
  562. data/vendor/assets/components/highlightjs/styles/tomorrow.css +72 -0
  563. data/vendor/assets/components/highlightjs/styles/vs.css +68 -0
  564. data/vendor/assets/components/highlightjs/styles/vs2015.css +115 -0
  565. data/vendor/assets/components/highlightjs/styles/xcode.css +93 -0
  566. data/vendor/assets/components/highlightjs/styles/xt256.css +92 -0
  567. data/vendor/assets/components/highlightjs/styles/zenburn.css +80 -0
  568. data/vendor/assets/components/jquery/.bower.json +25 -0
  569. data/vendor/assets/components/jquery/AUTHORS.txt +313 -0
  570. data/vendor/assets/components/jquery/LICENSE.txt +36 -0
  571. data/vendor/assets/components/jquery/README.md +67 -0
  572. data/vendor/assets/components/jquery/bower.json +14 -0
  573. data/vendor/assets/components/jquery/dist/core.js +399 -0
  574. data/vendor/assets/components/jquery/dist/jquery.js +10364 -0
  575. data/vendor/assets/components/jquery/dist/jquery.min.js +2 -0
  576. data/vendor/assets/components/jquery/dist/jquery.min.map +1 -0
  577. data/vendor/assets/components/jquery/dist/jquery.slim.js +8269 -0
  578. data/vendor/assets/components/jquery/dist/jquery.slim.min.js +2 -0
  579. data/vendor/assets/components/jquery/dist/jquery.slim.min.map +1 -0
  580. data/vendor/assets/components/jquery/external/sizzle/LICENSE.txt +36 -0
  581. data/vendor/assets/components/jquery/external/sizzle/dist/sizzle.js +2272 -0
  582. data/vendor/assets/components/jquery/external/sizzle/dist/sizzle.min.js +3 -0
  583. data/vendor/assets/components/jquery/external/sizzle/dist/sizzle.min.map +1 -0
  584. data/vendor/assets/components/jquery/src/.eslintrc.json +5 -0
  585. data/vendor/assets/components/jquery/src/ajax.js +856 -0
  586. data/vendor/assets/components/jquery/src/ajax/jsonp.js +103 -0
  587. data/vendor/assets/components/jquery/src/ajax/load.js +77 -0
  588. data/vendor/assets/components/jquery/src/ajax/parseXML.js +30 -0
  589. data/vendor/assets/components/jquery/src/ajax/script.js +77 -0
  590. data/vendor/assets/components/jquery/src/ajax/var/location.js +5 -0
  591. data/vendor/assets/components/jquery/src/ajax/var/nonce.js +5 -0
  592. data/vendor/assets/components/jquery/src/ajax/var/rquery.js +5 -0
  593. data/vendor/assets/components/jquery/src/ajax/xhr.js +170 -0
  594. data/vendor/assets/components/jquery/src/attributes.js +13 -0
  595. data/vendor/assets/components/jquery/src/attributes/attr.js +141 -0
  596. data/vendor/assets/components/jquery/src/attributes/classes.js +186 -0
  597. data/vendor/assets/components/jquery/src/attributes/prop.js +143 -0
  598. data/vendor/assets/components/jquery/src/attributes/support.js +33 -0
  599. data/vendor/assets/components/jquery/src/attributes/val.js +191 -0
  600. data/vendor/assets/components/jquery/src/callbacks.js +236 -0
  601. data/vendor/assets/components/jquery/src/core.js +399 -0
  602. data/vendor/assets/components/jquery/src/core/DOMEval.js +30 -0
  603. data/vendor/assets/components/jquery/src/core/access.js +72 -0
  604. data/vendor/assets/components/jquery/src/core/camelCase.js +23 -0
  605. data/vendor/assets/components/jquery/src/core/init.js +129 -0
  606. data/vendor/assets/components/jquery/src/core/nodeName.js +13 -0
  607. data/vendor/assets/components/jquery/src/core/parseHTML.js +65 -0
  608. data/vendor/assets/components/jquery/src/core/ready-no-deferred.js +97 -0
  609. data/vendor/assets/components/jquery/src/core/ready.js +86 -0
  610. data/vendor/assets/components/jquery/src/core/readyException.js +13 -0
  611. data/vendor/assets/components/jquery/src/core/stripAndCollapse.js +14 -0
  612. data/vendor/assets/components/jquery/src/core/support.js +20 -0
  613. data/vendor/assets/components/jquery/src/core/toType.js +20 -0
  614. data/vendor/assets/components/jquery/src/core/var/rsingleTag.js +6 -0
  615. data/vendor/assets/components/jquery/src/css.js +481 -0
  616. data/vendor/assets/components/jquery/src/css/addGetHookIf.js +26 -0
  617. data/vendor/assets/components/jquery/src/css/adjustCSS.js +73 -0
  618. data/vendor/assets/components/jquery/src/css/curCSS.js +65 -0
  619. data/vendor/assets/components/jquery/src/css/hiddenVisibleSelectors.js +15 -0
  620. data/vendor/assets/components/jquery/src/css/showHide.js +105 -0
  621. data/vendor/assets/components/jquery/src/css/support.js +102 -0
  622. data/vendor/assets/components/jquery/src/css/var/cssExpand.js +5 -0
  623. data/vendor/assets/components/jquery/src/css/var/getStyles.js +17 -0
  624. data/vendor/assets/components/jquery/src/css/var/isHiddenWithinTree.js +34 -0
  625. data/vendor/assets/components/jquery/src/css/var/rboxStyle.js +7 -0
  626. data/vendor/assets/components/jquery/src/css/var/rnumnonpx.js +7 -0
  627. data/vendor/assets/components/jquery/src/css/var/swap.js +26 -0
  628. data/vendor/assets/components/jquery/src/data.js +180 -0
  629. data/vendor/assets/components/jquery/src/data/Data.js +162 -0
  630. data/vendor/assets/components/jquery/src/data/var/acceptData.js +19 -0
  631. data/vendor/assets/components/jquery/src/data/var/dataPriv.js +7 -0
  632. data/vendor/assets/components/jquery/src/data/var/dataUser.js +7 -0
  633. data/vendor/assets/components/jquery/src/deferred.js +399 -0
  634. data/vendor/assets/components/jquery/src/deferred/exceptionHook.js +21 -0
  635. data/vendor/assets/components/jquery/src/deprecated.js +98 -0
  636. data/vendor/assets/components/jquery/src/dimensions.js +57 -0
  637. data/vendor/assets/components/jquery/src/effects.js +702 -0
  638. data/vendor/assets/components/jquery/src/effects/Tween.js +123 -0
  639. data/vendor/assets/components/jquery/src/effects/animatedSelector.js +15 -0
  640. data/vendor/assets/components/jquery/src/event.js +748 -0
  641. data/vendor/assets/components/jquery/src/event/ajax.js +22 -0
  642. data/vendor/assets/components/jquery/src/event/alias.js +29 -0
  643. data/vendor/assets/components/jquery/src/event/focusin.js +55 -0
  644. data/vendor/assets/components/jquery/src/event/support.js +11 -0
  645. data/vendor/assets/components/jquery/src/event/trigger.js +199 -0
  646. data/vendor/assets/components/jquery/src/exports/amd.js +26 -0
  647. data/vendor/assets/components/jquery/src/exports/global.js +34 -0
  648. data/vendor/assets/components/jquery/src/jquery.js +40 -0
  649. data/vendor/assets/components/jquery/src/manipulation.js +486 -0
  650. data/vendor/assets/components/jquery/src/manipulation/_evalUrl.js +23 -0
  651. data/vendor/assets/components/jquery/src/manipulation/buildFragment.js +105 -0
  652. data/vendor/assets/components/jquery/src/manipulation/getAll.js +32 -0
  653. data/vendor/assets/components/jquery/src/manipulation/setGlobalEval.js +22 -0
  654. data/vendor/assets/components/jquery/src/manipulation/support.js +35 -0
  655. data/vendor/assets/components/jquery/src/manipulation/var/rcheckableType.js +5 -0
  656. data/vendor/assets/components/jquery/src/manipulation/var/rscriptType.js +5 -0
  657. data/vendor/assets/components/jquery/src/manipulation/var/rtagName.js +5 -0
  658. data/vendor/assets/components/jquery/src/manipulation/wrapMap.js +29 -0
  659. data/vendor/assets/components/jquery/src/offset.js +233 -0
  660. data/vendor/assets/components/jquery/src/queue.js +145 -0
  661. data/vendor/assets/components/jquery/src/queue/delay.js +24 -0
  662. data/vendor/assets/components/jquery/src/selector-native.js +237 -0
  663. data/vendor/assets/components/jquery/src/selector-sizzle.js +19 -0
  664. data/vendor/assets/components/jquery/src/selector.js +3 -0
  665. data/vendor/assets/components/jquery/src/serialize.js +132 -0
  666. data/vendor/assets/components/jquery/src/traversing.js +191 -0
  667. data/vendor/assets/components/jquery/src/traversing/findFilter.js +97 -0
  668. data/vendor/assets/components/jquery/src/traversing/var/dir.js +22 -0
  669. data/vendor/assets/components/jquery/src/traversing/var/rneedsContext.js +8 -0
  670. data/vendor/assets/components/jquery/src/traversing/var/siblings.js +17 -0
  671. data/vendor/assets/components/jquery/src/var/ObjectFunctionString.js +7 -0
  672. data/vendor/assets/components/jquery/src/var/arr.js +5 -0
  673. data/vendor/assets/components/jquery/src/var/class2type.js +6 -0
  674. data/vendor/assets/components/jquery/src/var/concat.js +7 -0
  675. data/vendor/assets/components/jquery/src/var/document.js +5 -0
  676. data/vendor/assets/components/jquery/src/var/documentElement.js +7 -0
  677. data/vendor/assets/components/jquery/src/var/fnToString.js +7 -0
  678. data/vendor/assets/components/jquery/src/var/getProto.js +5 -0
  679. data/vendor/assets/components/jquery/src/var/hasOwn.js +7 -0
  680. data/vendor/assets/components/jquery/src/var/indexOf.js +7 -0
  681. data/vendor/assets/components/jquery/src/var/isFunction.js +13 -0
  682. data/vendor/assets/components/jquery/src/var/isWindow.js +8 -0
  683. data/vendor/assets/components/jquery/src/var/pnum.js +5 -0
  684. data/vendor/assets/components/jquery/src/var/push.js +7 -0
  685. data/vendor/assets/components/jquery/src/var/rcssNum.js +9 -0
  686. data/vendor/assets/components/jquery/src/var/rnothtmlwhite.js +8 -0
  687. data/vendor/assets/components/jquery/src/var/slice.js +7 -0
  688. data/vendor/assets/components/jquery/src/var/support.js +6 -0
  689. data/vendor/assets/components/jquery/src/var/toString.js +7 -0
  690. data/vendor/assets/components/jquery/src/wrap.js +78 -0
  691. data/vendor/assets/components/markdown-it/.bower.json +38 -0
  692. data/vendor/assets/components/markdown-it/CHANGELOG.md +442 -0
  693. data/vendor/assets/components/markdown-it/CONTRIBUTING.md +15 -0
  694. data/vendor/assets/components/markdown-it/LICENSE +22 -0
  695. data/vendor/assets/components/markdown-it/Procfile +1 -0
  696. data/vendor/assets/components/markdown-it/README.md +294 -0
  697. data/vendor/assets/components/markdown-it/bin/markdown-it.js +113 -0
  698. data/vendor/assets/components/markdown-it/bower.json +28 -0
  699. data/vendor/assets/components/markdown-it/dist/markdown-it.js +7963 -0
  700. data/vendor/assets/components/markdown-it/dist/markdown-it.min.js +1 -0
  701. data/vendor/assets/components/markdown-it/package.json +64 -0
  702. data/vendor/assets/components/plantuml-encoder/.bower.json +29 -0
  703. data/vendor/assets/components/plantuml-encoder/LICENSE +19 -0
  704. data/vendor/assets/components/plantuml-encoder/README.md +38 -0
  705. data/vendor/assets/components/plantuml-encoder/bower.json +20 -0
  706. data/vendor/assets/components/plantuml-encoder/dist/plantuml-encoder.js +3994 -0
  707. data/vendor/assets/components/plantuml-encoder/dist/plantuml-encoder.min.js +1 -0
  708. data/vendor/assets/components/plantuml-encoder/package.json +33 -0
  709. data/vendor/assets/components/raphael/.bower.json +45 -0
  710. data/vendor/assets/components/raphael/bower.json +31 -0
  711. data/vendor/assets/components/raphael/dev/banner.txt +8 -0
  712. data/vendor/assets/components/raphael/dev/raphael.amd.js +14 -0
  713. data/vendor/assets/components/raphael/dev/raphael.core.js +5413 -0
  714. data/vendor/assets/components/raphael/dev/raphael.svg.js +1428 -0
  715. data/vendor/assets/components/raphael/dev/raphael.vml.js +1010 -0
  716. data/vendor/assets/components/raphael/dev/test/svg/dom.js +295 -0
  717. data/vendor/assets/components/raphael/dev/test/vml/dom.js +5 -0
  718. data/vendor/assets/components/raphael/license.txt +21 -0
  719. data/vendor/assets/components/raphael/raphael.js +8330 -0
  720. data/vendor/assets/components/raphael/raphael.min.js +3 -0
  721. data/vendor/assets/components/raphael/raphael.no-deps.js +7959 -0
  722. data/vendor/assets/components/raphael/raphael.no-deps.min.js +3 -0
  723. data/vendor/assets/components/raphael/webpack.config.js +62 -0
  724. data/vendor/assets/components/squire-rte/.bower.json +34 -0
  725. data/vendor/assets/components/squire-rte/Demo.html +143 -0
  726. data/vendor/assets/components/squire-rte/LICENSE +21 -0
  727. data/vendor/assets/components/squire-rte/Makefile +22 -0
  728. data/vendor/assets/components/squire-rte/README.md +473 -0
  729. data/vendor/assets/components/squire-rte/bower.json +24 -0
  730. data/vendor/assets/components/squire-rte/build/document.html +54 -0
  731. data/vendor/assets/components/squire-rte/build/squire-raw.js +4722 -0
  732. data/vendor/assets/components/squire-rte/build/squire.js +2 -0
  733. data/vendor/assets/components/squire-rte/package.json +31 -0
  734. data/vendor/assets/components/squire-rte/source/Clean.js +358 -0
  735. data/vendor/assets/components/squire-rte/source/Clipboard.js +331 -0
  736. data/vendor/assets/components/squire-rte/source/Constants.js +60 -0
  737. data/vendor/assets/components/squire-rte/source/Editor.js +2201 -0
  738. data/vendor/assets/components/squire-rte/source/KeyHandlers.js +502 -0
  739. data/vendor/assets/components/squire-rte/source/Node.js +553 -0
  740. data/vendor/assets/components/squire-rte/source/Range.js +540 -0
  741. data/vendor/assets/components/squire-rte/source/TreeWalker.js +118 -0
  742. data/vendor/assets/components/squire-rte/source/document.html +54 -0
  743. data/vendor/assets/components/squire-rte/source/exports.js +42 -0
  744. data/vendor/assets/components/squire-rte/source/intro.js +6 -0
  745. data/vendor/assets/components/squire-rte/source/outro.js +22 -0
  746. data/vendor/assets/components/to-mark/.bower.json +35 -0
  747. data/vendor/assets/components/to-mark/bower.json +22 -0
  748. data/vendor/assets/components/to-mark/demo/demo.html +24 -0
  749. data/vendor/assets/components/to-mark/demo/demo2.html +94 -0
  750. data/vendor/assets/components/to-mark/dist/to-mark.js +1283 -0
  751. data/vendor/assets/components/to-mark/dist/to-mark.min.js +1 -0
  752. data/vendor/assets/components/to-mark/gulpfile.js +112 -0
  753. data/vendor/assets/components/to-mark/karma.conf.js +260 -0
  754. data/vendor/assets/components/to-mark/package-lock.json +13061 -0
  755. data/vendor/assets/components/to-mark/package.json +53 -0
  756. data/vendor/assets/components/tui-chart/.bower.json +44 -0
  757. data/vendor/assets/components/tui-chart/CODE_OF_CONDUCT.md +73 -0
  758. data/vendor/assets/components/tui-chart/CONTRIBUTING.md +91 -0
  759. data/vendor/assets/components/tui-chart/LICENSE +21 -0
  760. data/vendor/assets/components/tui-chart/README.md +142 -0
  761. data/vendor/assets/components/tui-chart/bower.json +33 -0
  762. data/vendor/assets/components/tui-chart/dist/maps/china.js +10 -0
  763. data/vendor/assets/components/tui-chart/dist/maps/japan.js +10 -0
  764. data/vendor/assets/components/tui-chart/dist/maps/singapore.js +10 -0
  765. data/vendor/assets/components/tui-chart/dist/maps/south-korea.js +10 -0
  766. data/vendor/assets/components/tui-chart/dist/maps/taiwan.js +10 -0
  767. data/vendor/assets/components/tui-chart/dist/maps/thailand.js +10 -0
  768. data/vendor/assets/components/tui-chart/dist/maps/usa.js +10 -0
  769. data/vendor/assets/components/tui-chart/dist/maps/world.js +11 -0
  770. data/vendor/assets/components/tui-chart/dist/tui-chart.css +704 -0
  771. data/vendor/assets/components/tui-chart/dist/tui-chart.js +40567 -0
  772. data/vendor/assets/components/tui-chart/dist/tui-chart.min.css +10 -0
  773. data/vendor/assets/components/tui-chart/dist/tui-chart.min.js +20 -0
  774. data/vendor/assets/components/tui-chart/docs/COMMIT_MESSAGE_CONVENTION.md +49 -0
  775. data/vendor/assets/components/tui-chart/docs/ISSUE_TEMPLATE.md +24 -0
  776. data/vendor/assets/components/tui-chart/docs/PULL_REQUEST_TEMPLATE.md +42 -0
  777. data/vendor/assets/components/tui-chart/docs/README.md +11 -0
  778. data/vendor/assets/components/tui-chart/docs/wiki/README.md +27 -0
  779. data/vendor/assets/components/tui-chart/docs/wiki/_Sidebar.md +31 -0
  780. data/vendor/assets/components/tui-chart/docs/wiki/chart-export-menu.md +66 -0
  781. data/vendor/assets/components/tui-chart/docs/wiki/chart-type-radial.md +121 -0
  782. data/vendor/assets/components/tui-chart/docs/wiki/chart-types-bar,column.md +312 -0
  783. data/vendor/assets/components/tui-chart/docs/wiki/chart-types-bubble.md +63 -0
  784. data/vendor/assets/components/tui-chart/docs/wiki/chart-types-column-line-combo.md +104 -0
  785. data/vendor/assets/components/tui-chart/docs/wiki/chart-types-heatmap.md +39 -0
  786. data/vendor/assets/components/tui-chart/docs/wiki/chart-types-line,area.md +333 -0
  787. data/vendor/assets/components/tui-chart/docs/wiki/chart-types-line-area-combo.md +78 -0
  788. data/vendor/assets/components/tui-chart/docs/wiki/chart-types-line-scatter-combo.md +101 -0
  789. data/vendor/assets/components/tui-chart/docs/wiki/chart-types-map.md +153 -0
  790. data/vendor/assets/components/tui-chart/docs/wiki/chart-types-pie-donut-combo.md +98 -0
  791. data/vendor/assets/components/tui-chart/docs/wiki/chart-types-pie.md +186 -0
  792. data/vendor/assets/components/tui-chart/docs/wiki/chart-types-scatter.md +58 -0
  793. data/vendor/assets/components/tui-chart/docs/wiki/chart-types-treemap.md +158 -0
  794. data/vendor/assets/components/tui-chart/docs/wiki/code-table-of-china-map.md +38 -0
  795. data/vendor/assets/components/tui-chart/docs/wiki/code-table-of-japan-map.md +51 -0
  796. data/vendor/assets/components/tui-chart/docs/wiki/code-table-of-singapore-map.md +9 -0
  797. data/vendor/assets/components/tui-chart/docs/wiki/code-table-of-south-korea-map.md +21 -0
  798. data/vendor/assets/components/tui-chart/docs/wiki/code-table-of-taiwan-map.md +26 -0
  799. data/vendor/assets/components/tui-chart/docs/wiki/code-table-of-thailand-map.md +82 -0
  800. data/vendor/assets/components/tui-chart/docs/wiki/code-table-of-usa-map.md +55 -0
  801. data/vendor/assets/components/tui-chart/docs/wiki/code-table-of-world-map.md +180 -0
  802. data/vendor/assets/components/tui-chart/docs/wiki/features-axes.md +209 -0
  803. data/vendor/assets/components/tui-chart/docs/wiki/features-chart.md +157 -0
  804. data/vendor/assets/components/tui-chart/docs/wiki/features-circle-legend.md +20 -0
  805. data/vendor/assets/components/tui-chart/docs/wiki/features-legend.md +89 -0
  806. data/vendor/assets/components/tui-chart/docs/wiki/features-plot.md +141 -0
  807. data/vendor/assets/components/tui-chart/docs/wiki/features-series.md +240 -0
  808. data/vendor/assets/components/tui-chart/docs/wiki/features-tooltip.md +223 -0
  809. data/vendor/assets/components/tui-chart/docs/wiki/getting-started.md +74 -0
  810. data/vendor/assets/components/tui-chart/docs/wiki/import-chart-data-from-existing-table-element.md +150 -0
  811. data/vendor/assets/components/tui-chart/docs/wiki/table-of-supported-options.md +344 -0
  812. data/vendor/assets/components/tui-chart/docs/wiki/theme.md +338 -0
  813. data/vendor/assets/components/tui-chart/package-lock.json +8881 -0
  814. data/vendor/assets/components/tui-code-snippet/.bower.json +31 -0
  815. data/vendor/assets/components/tui-code-snippet/LICENSE +21 -0
  816. data/vendor/assets/components/tui-code-snippet/README.md +109 -0
  817. data/vendor/assets/components/tui-code-snippet/bower.json +20 -0
  818. data/vendor/assets/components/tui-code-snippet/demo/postBridge/README.md +26 -0
  819. data/vendor/assets/components/tui-code-snippet/demo/postBridge/public/popup.html +27 -0
  820. data/vendor/assets/components/tui-code-snippet/demo/postBridge/public/postBridge.html +31 -0
  821. data/vendor/assets/components/tui-code-snippet/demo/postBridge/server.js +28 -0
  822. data/vendor/assets/components/tui-code-snippet/dist/tui-code-snippet.js +4228 -0
  823. data/vendor/assets/components/tui-code-snippet/dist/tui-code-snippet.min.js +7 -0
  824. data/vendor/assets/components/tui-code-snippet/package-lock.json +6038 -0
  825. data/vendor/assets/components/tui-color-picker/.bower.json +37 -0
  826. data/vendor/assets/components/tui-color-picker/ISSUE_TEMPLATE.md +26 -0
  827. data/vendor/assets/components/tui-color-picker/LICENSE +34 -0
  828. data/vendor/assets/components/tui-color-picker/README.md +69 -0
  829. data/vendor/assets/components/tui-color-picker/bower.json +26 -0
  830. data/vendor/assets/components/tui-color-picker/dist/tui-color-picker.css +148 -0
  831. data/vendor/assets/components/tui-color-picker/dist/tui-color-picker.js +3146 -0
  832. data/vendor/assets/components/tui-color-picker/dist/tui-color-picker.min.css +7 -0
  833. data/vendor/assets/components/tui-color-picker/dist/tui-color-picker.min.js +9 -0
  834. data/vendor/assets/components/tui-color-picker/package-lock.json +8440 -0
  835. data/vendor/assets/components/tui-editor/.bower.json +71 -0
  836. data/vendor/assets/components/tui-editor/CODE_OF_CONDUCT.md +73 -0
  837. data/vendor/assets/components/tui-editor/CONTRIBUTING.md +92 -0
  838. data/vendor/assets/components/tui-editor/LICENSE +21 -0
  839. data/vendor/assets/components/tui-editor/README.md +204 -0
  840. data/vendor/assets/components/tui-editor/bower.json +59 -0
  841. data/vendor/assets/components/tui-editor/dist/tui-editor-Editor-all.js +36850 -0
  842. data/vendor/assets/components/tui-editor/dist/tui-editor-Editor-all.min.js +13 -0
  843. data/vendor/assets/components/tui-editor/dist/tui-editor-Editor.js +24646 -0
  844. data/vendor/assets/components/tui-editor/dist/tui-editor-Editor.min.js +7 -0
  845. data/vendor/assets/components/tui-editor/dist/tui-editor-Viewer-all.js +14768 -0
  846. data/vendor/assets/components/tui-editor/dist/tui-editor-Viewer-all.min.js +13 -0
  847. data/vendor/assets/components/tui-editor/dist/tui-editor-Viewer.js +3686 -0
  848. data/vendor/assets/components/tui-editor/dist/tui-editor-Viewer.min.js +7 -0
  849. data/vendor/assets/components/tui-editor/dist/tui-editor-contents.css +239 -0
  850. data/vendor/assets/components/tui-editor/dist/tui-editor-contents.min.css +1 -0
  851. data/vendor/assets/components/tui-editor/dist/tui-editor-extChart.js +7040 -0
  852. data/vendor/assets/components/tui-editor/dist/tui-editor-extChart.min.js +13 -0
  853. data/vendor/assets/components/tui-editor/dist/tui-editor-extColorSyntax.js +472 -0
  854. data/vendor/assets/components/tui-editor/dist/tui-editor-extColorSyntax.min.js +7 -0
  855. data/vendor/assets/components/tui-editor/dist/tui-editor-extScrollSync.js +1241 -0
  856. data/vendor/assets/components/tui-editor/dist/tui-editor-extScrollSync.min.js +7 -0
  857. data/vendor/assets/components/tui-editor/dist/tui-editor-extTable.js +3930 -0
  858. data/vendor/assets/components/tui-editor/dist/tui-editor-extTable.min.js +7 -0
  859. data/vendor/assets/components/tui-editor/dist/tui-editor-extUML.js +212 -0
  860. data/vendor/assets/components/tui-editor/dist/tui-editor-extUML.min.js +7 -0
  861. data/vendor/assets/components/tui-editor/dist/tui-editor.css +1166 -0
  862. data/vendor/assets/components/tui-editor/dist/tui-editor.min.css +1 -0
  863. data/vendor/assets/components/tui-editor/docs/COMMIT_MESSAGE_CONVENTION.md +49 -0
  864. data/vendor/assets/components/tui-editor/docs/PULL_REQUEST_TEMPLATE.md +41 -0
  865. data/vendor/assets/components/tui-editor/docs/README.md +13 -0
  866. data/vendor/assets/components/tui-editor/docs/getting-started-with-bower.md +93 -0
  867. data/vendor/assets/components/tui-editor/docs/getting-started.md +76 -0
  868. data/vendor/assets/components/tui-editor/docs/using-extensions.md +91 -0
  869. data/vendor/assets/components/tui-editor/docs/writing-your-own-extension.md +167 -0
  870. data/vendor/assets/components/tui-editor/examples/example00-demo.html +85 -0
  871. data/vendor/assets/components/tui-editor/examples/example01-basic.html +37 -0
  872. data/vendor/assets/components/tui-editor/examples/example02-viewer-basic.html +68 -0
  873. data/vendor/assets/components/tui-editor/examples/example03-jquery.html +36 -0
  874. data/vendor/assets/components/tui-editor/examples/example04-viewer-jquery.html +67 -0
  875. data/vendor/assets/components/tui-editor/examples/example05-scrollsync.html +77 -0
  876. data/vendor/assets/components/tui-editor/examples/example06-colorsyntax.html +44 -0
  877. data/vendor/assets/components/tui-editor/examples/example07-table.html +48 -0
  878. data/vendor/assets/components/tui-editor/examples/example08-uml.html +69 -0
  879. data/vendor/assets/components/tui-editor/examples/example09-multiple-extensions.html +85 -0
  880. data/vendor/assets/components/tui-editor/examples/example10-viewer-multiple-extensions.html +86 -0
  881. data/vendor/assets/components/tui-editor/examples/example11-chart.html +60 -0
  882. data/vendor/assets/components/tui-editor/examples/example12-writing-extension.html +66 -0
  883. data/vendor/assets/components/tui-editor/examples/examples.json +41 -0
  884. data/vendor/assets/components/tui-editor/examples/explain.css +7 -0
  885. data/vendor/assets/components/tui-editor/package-lock.json +13289 -0
  886. data/vendor/assets/components/tui-editor/package.json +90 -0
  887. metadata +956 -0
@@ -0,0 +1,60 @@
1
+ /*jshint strict:false, undef:false, unused:false */
2
+
3
+ var DOCUMENT_POSITION_PRECEDING = 2; // Node.DOCUMENT_POSITION_PRECEDING
4
+ var ELEMENT_NODE = 1; // Node.ELEMENT_NODE;
5
+ var TEXT_NODE = 3; // Node.TEXT_NODE;
6
+ var DOCUMENT_NODE = 9; // Node.DOCUMENT_NODE;
7
+ var DOCUMENT_FRAGMENT_NODE = 11; // Node.DOCUMENT_FRAGMENT_NODE;
8
+ var SHOW_ELEMENT = 1; // NodeFilter.SHOW_ELEMENT;
9
+ var SHOW_TEXT = 4; // NodeFilter.SHOW_TEXT;
10
+
11
+ var START_TO_START = 0; // Range.START_TO_START
12
+ var START_TO_END = 1; // Range.START_TO_END
13
+ var END_TO_END = 2; // Range.END_TO_END
14
+ var END_TO_START = 3; // Range.END_TO_START
15
+
16
+ var HIGHLIGHT_CLASS = 'highlight';
17
+ var COLOUR_CLASS = 'colour';
18
+ var FONT_FAMILY_CLASS = 'font';
19
+ var FONT_SIZE_CLASS = 'size';
20
+
21
+ var ZWS = '\u200B';
22
+
23
+ var win = doc.defaultView;
24
+
25
+ var ua = navigator.userAgent;
26
+
27
+ var isAndroid = /Android/.test( ua );
28
+ var isIOS = /iP(?:ad|hone|od)/.test( ua );
29
+ var isMac = /Mac OS X/.test( ua );
30
+ var isWin = /Windows NT/.test( ua );
31
+
32
+ var isGecko = /Gecko\//.test( ua );
33
+ var isIElt11 = /Trident\/[456]\./.test( ua );
34
+ var isPresto = !!win.opera;
35
+ var isEdge = /Edge\//.test( ua );
36
+ var isWebKit = !isEdge && /WebKit\//.test( ua );
37
+ var isIE = /Trident\/[4567]\./.test( ua );
38
+
39
+ var ctrlKey = isMac ? 'meta-' : 'ctrl-';
40
+
41
+ var useTextFixer = isIElt11 || isPresto;
42
+ var cantFocusEmptyTextNodes = isIElt11 || isWebKit;
43
+ var losesSelectionOnBlur = isIElt11;
44
+
45
+ var canObserveMutations = typeof MutationObserver !== 'undefined';
46
+ var canWeakMap = typeof WeakMap !== 'undefined';
47
+
48
+ // Use [^ \t\r\n] instead of \S so that nbsp does not count as white-space
49
+ var notWS = /[^ \t\r\n]/;
50
+
51
+ var indexOf = Array.prototype.indexOf;
52
+
53
+ // Polyfill for FF3.5
54
+ if ( !Object.create ) {
55
+ Object.create = function ( proto ) {
56
+ var F = function () {};
57
+ F.prototype = proto;
58
+ return new F();
59
+ };
60
+ }
@@ -0,0 +1,2201 @@
1
+ /*jshint strict:false, undef:false, unused:false */
2
+
3
+ function mergeObjects ( base, extras, mayOverride ) {
4
+ var prop, value;
5
+ if ( !base ) {
6
+ base = {};
7
+ }
8
+ if ( extras ) {
9
+ for ( prop in extras ) {
10
+ if ( mayOverride || !( prop in base ) ) {
11
+ value = extras[ prop ];
12
+ base[ prop ] = ( value && value.constructor === Object ) ?
13
+ mergeObjects( base[ prop ], value, mayOverride ) :
14
+ value;
15
+ }
16
+ }
17
+ }
18
+ return base;
19
+ }
20
+
21
+ function Squire ( root, config ) {
22
+ if ( root.nodeType === DOCUMENT_NODE ) {
23
+ root = root.body;
24
+ }
25
+ var doc = root.ownerDocument;
26
+ var win = doc.defaultView;
27
+ var mutation;
28
+
29
+ this._win = win;
30
+ this._doc = doc;
31
+ this._root = root;
32
+
33
+ this._events = {};
34
+
35
+ this._isFocused = false;
36
+ this._lastSelection = null;
37
+
38
+ // IE loses selection state of iframe on blur, so make sure we
39
+ // cache it just before it loses focus.
40
+ if ( losesSelectionOnBlur ) {
41
+ this.addEventListener( 'beforedeactivate', this.getSelection );
42
+ }
43
+
44
+ this._hasZWS = false;
45
+
46
+ this._lastAnchorNode = null;
47
+ this._lastFocusNode = null;
48
+ this._path = '';
49
+ this._willUpdatePath = false;
50
+
51
+ if ( 'onselectionchange' in doc ) {
52
+ this.addEventListener( 'selectionchange', this._updatePathOnEvent );
53
+ } else {
54
+ this.addEventListener( 'keyup', this._updatePathOnEvent );
55
+ this.addEventListener( 'mouseup', this._updatePathOnEvent );
56
+ }
57
+
58
+ this._undoIndex = -1;
59
+ this._undoStack = [];
60
+ this._undoStackLength = 0;
61
+ this._isInUndoState = false;
62
+ this._ignoreChange = false;
63
+ this._ignoreAllChanges = false;
64
+
65
+ if ( canObserveMutations ) {
66
+ mutation = new MutationObserver( this._docWasChanged.bind( this ) );
67
+ mutation.observe( root, {
68
+ childList: true,
69
+ attributes: true,
70
+ characterData: true,
71
+ subtree: true
72
+ });
73
+ this._mutation = mutation;
74
+ } else {
75
+ this.addEventListener( 'keyup', this._keyUpDetectChange );
76
+ }
77
+
78
+ // On blur, restore focus except if the user taps or clicks to focus a
79
+ // specific point. Can't actually use click event because focus happens
80
+ // before click, so use mousedown/touchstart
81
+ this._restoreSelection = false;
82
+ this.addEventListener( 'blur', enableRestoreSelection );
83
+ this.addEventListener( 'mousedown', disableRestoreSelection );
84
+ this.addEventListener( 'touchstart', disableRestoreSelection );
85
+ this.addEventListener( 'focus', restoreSelection );
86
+
87
+ // IE sometimes fires the beforepaste event twice; make sure it is not run
88
+ // again before our after paste function is called.
89
+ this._awaitingPaste = false;
90
+ this.addEventListener( isIElt11 ? 'beforecut' : 'cut', onCut );
91
+ this.addEventListener( 'copy', onCopy );
92
+ this.addEventListener( 'keydown', monitorShiftKey );
93
+ this.addEventListener( 'keyup', monitorShiftKey );
94
+ this.addEventListener( isIElt11 ? 'beforepaste' : 'paste', onPaste );
95
+ this.addEventListener( 'drop', onDrop );
96
+
97
+ // Opera does not fire keydown repeatedly.
98
+ this.addEventListener( isPresto ? 'keypress' : 'keydown', onKey );
99
+
100
+ // Add key handlers
101
+ this._keyHandlers = Object.create( keyHandlers );
102
+
103
+ // Override default properties
104
+ this.setConfig( config );
105
+
106
+ // Fix IE<10's buggy implementation of Text#splitText.
107
+ // If the split is at the end of the node, it doesn't insert the newly split
108
+ // node into the document, and sets its value to undefined rather than ''.
109
+ // And even if the split is not at the end, the original node is removed
110
+ // from the document and replaced by another, rather than just having its
111
+ // data shortened.
112
+ // We used to feature test for this, but then found the feature test would
113
+ // sometimes pass, but later on the buggy behaviour would still appear.
114
+ // I think IE10 does not have the same bug, but it doesn't hurt to replace
115
+ // its native fn too and then we don't need yet another UA category.
116
+ if ( isIElt11 ) {
117
+ win.Text.prototype.splitText = function ( offset ) {
118
+ var afterSplit = this.ownerDocument.createTextNode(
119
+ this.data.slice( offset ) ),
120
+ next = this.nextSibling,
121
+ parent = this.parentNode,
122
+ toDelete = this.length - offset;
123
+ if ( next ) {
124
+ parent.insertBefore( afterSplit, next );
125
+ } else {
126
+ parent.appendChild( afterSplit );
127
+ }
128
+ if ( toDelete ) {
129
+ this.deleteData( offset, toDelete );
130
+ }
131
+ return afterSplit;
132
+ };
133
+ }
134
+
135
+ root.setAttribute( 'contenteditable', 'true' );
136
+
137
+ // Remove Firefox's built-in controls
138
+ try {
139
+ doc.execCommand( 'enableObjectResizing', false, 'false' );
140
+ doc.execCommand( 'enableInlineTableEditing', false, 'false' );
141
+ } catch ( error ) {}
142
+
143
+ root.__squire__ = this;
144
+
145
+ // Need to register instance before calling setHTML, so that the fixCursor
146
+ // function can lookup any default block tag options set.
147
+ this.setHTML( '' );
148
+ }
149
+
150
+ var proto = Squire.prototype;
151
+
152
+ var sanitizeToDOMFragment = function ( html, isPaste, self ) {
153
+ var doc = self._doc;
154
+ var frag = html ? DOMPurify.sanitize( html, {
155
+ ALLOW_UNKNOWN_PROTOCOLS: true,
156
+ WHOLE_DOCUMENT: false,
157
+ RETURN_DOM: true,
158
+ RETURN_DOM_FRAGMENT: true
159
+ }) : null;
160
+ return frag ? doc.importNode( frag, true ) : doc.createDocumentFragment();
161
+ };
162
+
163
+ proto.setConfig = function ( config ) {
164
+ config = mergeObjects({
165
+ blockTag: 'DIV',
166
+ blockAttributes: null,
167
+ tagAttributes: {
168
+ blockquote: null,
169
+ ul: null,
170
+ ol: null,
171
+ li: null,
172
+ a: null
173
+ },
174
+ leafNodeNames: leafNodeNames,
175
+ undo: {
176
+ documentSizeThreshold: -1, // -1 means no threshold
177
+ undoLimit: -1 // -1 means no limit
178
+ },
179
+ isInsertedHTMLSanitized: true,
180
+ isSetHTMLSanitized: true,
181
+ sanitizeToDOMFragment:
182
+ typeof DOMPurify !== 'undefined' && DOMPurify.isSupported ?
183
+ sanitizeToDOMFragment : null
184
+
185
+ }, config, true );
186
+
187
+ // Users may specify block tag in lower case
188
+ config.blockTag = config.blockTag.toUpperCase();
189
+
190
+ this._config = config;
191
+
192
+ return this;
193
+ };
194
+
195
+ proto.createElement = function ( tag, props, children ) {
196
+ return createElement( this._doc, tag, props, children );
197
+ };
198
+
199
+ proto.createDefaultBlock = function ( children ) {
200
+ var config = this._config;
201
+ return fixCursor(
202
+ this.createElement( config.blockTag, config.blockAttributes, children ),
203
+ this._root
204
+ );
205
+ };
206
+
207
+ proto.didError = function ( error ) {
208
+ console.log( error );
209
+ };
210
+
211
+ proto.getDocument = function () {
212
+ return this._doc;
213
+ };
214
+ proto.getRoot = function () {
215
+ return this._root;
216
+ };
217
+
218
+ proto.modifyDocument = function ( modificationCallback ) {
219
+ var mutation = this._mutation;
220
+ if ( mutation ) {
221
+ if ( mutation.takeRecords().length ) {
222
+ this._docWasChanged();
223
+ }
224
+ mutation.disconnect();
225
+ }
226
+
227
+ this._ignoreAllChanges = true;
228
+ modificationCallback();
229
+ this._ignoreAllChanges = false;
230
+
231
+ if ( mutation ) {
232
+ mutation.observe( this._root, {
233
+ childList: true,
234
+ attributes: true,
235
+ characterData: true,
236
+ subtree: true
237
+ });
238
+ this._ignoreChange = false;
239
+ }
240
+ };
241
+
242
+ // --- Events ---
243
+
244
+ // Subscribing to these events won't automatically add a listener to the
245
+ // document node, since these events are fired in a custom manner by the
246
+ // editor code.
247
+ var customEvents = {
248
+ pathChange: 1, select: 1, input: 1, undoStateChange: 1
249
+ };
250
+
251
+ proto.fireEvent = function ( type, event ) {
252
+ var handlers = this._events[ type ];
253
+ var isFocused, l, obj;
254
+ // UI code, especially modal views, may be monitoring for focus events and
255
+ // immediately removing focus. In certain conditions, this can cause the
256
+ // focus event to fire after the blur event, which can cause an infinite
257
+ // loop. So we detect whether we're actually focused/blurred before firing.
258
+ if ( /^(?:focus|blur)/.test( type ) ) {
259
+ isFocused = this._root === this._doc.activeElement;
260
+ if ( type === 'focus' ) {
261
+ if ( !isFocused || this._isFocused ) {
262
+ return this;
263
+ }
264
+ this._isFocused = true;
265
+ } else {
266
+ if ( isFocused || !this._isFocused ) {
267
+ return this;
268
+ }
269
+ this._isFocused = false;
270
+ }
271
+ }
272
+ if ( handlers ) {
273
+ if ( !event ) {
274
+ event = {};
275
+ }
276
+ if ( event.type !== type ) {
277
+ event.type = type;
278
+ }
279
+ // Clone handlers array, so any handlers added/removed do not affect it.
280
+ handlers = handlers.slice();
281
+ l = handlers.length;
282
+ while ( l-- ) {
283
+ obj = handlers[l];
284
+ try {
285
+ if ( obj.handleEvent ) {
286
+ obj.handleEvent( event );
287
+ } else {
288
+ obj.call( this, event );
289
+ }
290
+ } catch ( error ) {
291
+ error.details = 'Squire: fireEvent error. Event type: ' + type;
292
+ this.didError( error );
293
+ }
294
+ }
295
+ }
296
+ return this;
297
+ };
298
+
299
+ proto.destroy = function () {
300
+ var events = this._events;
301
+ var type;
302
+
303
+ for ( type in events ) {
304
+ this.removeEventListener( type );
305
+ }
306
+ if ( this._mutation ) {
307
+ this._mutation.disconnect();
308
+ }
309
+ delete this._root.__squire__;
310
+
311
+ // Destroy undo stack
312
+ this._undoIndex = -1;
313
+ this._undoStack = [];
314
+ this._undoStackLength = 0;
315
+ };
316
+
317
+ proto.handleEvent = function ( event ) {
318
+ this.fireEvent( event.type, event );
319
+ };
320
+
321
+ proto.addEventListener = function ( type, fn ) {
322
+ var handlers = this._events[ type ];
323
+ var target = this._root;
324
+ if ( !fn ) {
325
+ this.didError({
326
+ name: 'Squire: addEventListener with null or undefined fn',
327
+ message: 'Event type: ' + type
328
+ });
329
+ return this;
330
+ }
331
+ if ( !handlers ) {
332
+ handlers = this._events[ type ] = [];
333
+ if ( !customEvents[ type ] ) {
334
+ if ( type === 'selectionchange' ) {
335
+ target = this._doc;
336
+ }
337
+ target.addEventListener( type, this, true );
338
+ }
339
+ }
340
+ handlers.push( fn );
341
+ return this;
342
+ };
343
+
344
+ proto.removeEventListener = function ( type, fn ) {
345
+ var handlers = this._events[ type ];
346
+ var target = this._root;
347
+ var l;
348
+ if ( handlers ) {
349
+ if ( fn ) {
350
+ l = handlers.length;
351
+ while ( l-- ) {
352
+ if ( handlers[l] === fn ) {
353
+ handlers.splice( l, 1 );
354
+ }
355
+ }
356
+ } else {
357
+ handlers.length = 0;
358
+ }
359
+ if ( !handlers.length ) {
360
+ delete this._events[ type ];
361
+ if ( !customEvents[ type ] ) {
362
+ if ( type === 'selectionchange' ) {
363
+ target = this._doc;
364
+ }
365
+ target.removeEventListener( type, this, true );
366
+ }
367
+ }
368
+ }
369
+ return this;
370
+ };
371
+
372
+ // --- Selection and Path ---
373
+
374
+ proto._createRange =
375
+ function ( range, startOffset, endContainer, endOffset ) {
376
+ if ( range instanceof this._win.Range ) {
377
+ return range.cloneRange();
378
+ }
379
+ var domRange = this._doc.createRange();
380
+ domRange.setStart( range, startOffset );
381
+ if ( endContainer ) {
382
+ domRange.setEnd( endContainer, endOffset );
383
+ } else {
384
+ domRange.setEnd( range, startOffset );
385
+ }
386
+ return domRange;
387
+ };
388
+
389
+ proto.getCursorPosition = function ( range ) {
390
+ if ( ( !range && !( range = this.getSelection() ) ) ||
391
+ !range.getBoundingClientRect ) {
392
+ return null;
393
+ }
394
+ // Get the bounding rect
395
+ var rect = range.getBoundingClientRect();
396
+ var node, parent;
397
+ if ( rect && !rect.top ) {
398
+ this._ignoreChange = true;
399
+ node = this._doc.createElement( 'SPAN' );
400
+ node.textContent = ZWS;
401
+ insertNodeInRange( range, node );
402
+ rect = node.getBoundingClientRect();
403
+ parent = node.parentNode;
404
+ parent.removeChild( node );
405
+ mergeInlines( parent, range );
406
+ }
407
+ return rect;
408
+ };
409
+
410
+ proto._moveCursorTo = function ( toStart ) {
411
+ var root = this._root,
412
+ range = this._createRange( root, toStart ? 0 : root.childNodes.length );
413
+ moveRangeBoundariesDownTree( range );
414
+ this.setSelection( range );
415
+ return this;
416
+ };
417
+ proto.moveCursorToStart = function () {
418
+ return this._moveCursorTo( true );
419
+ };
420
+ proto.moveCursorToEnd = function () {
421
+ return this._moveCursorTo( false );
422
+ };
423
+
424
+ var getWindowSelection = function ( self ) {
425
+ return self._win.getSelection() || null;
426
+ };
427
+
428
+ proto.setSelection = function ( range ) {
429
+ if ( range ) {
430
+ this._lastSelection = range;
431
+ // If we're setting selection, that automatically, and synchronously, // triggers a focus event. So just store the selection and mark it as
432
+ // needing restore on focus.
433
+ if ( !this._isFocused ) {
434
+ enableRestoreSelection.call( this );
435
+ } else if ( isAndroid && !this._restoreSelection ) {
436
+ // Android closes the keyboard on removeAllRanges() and doesn't
437
+ // open it again when addRange() is called, sigh.
438
+ // Since Android doesn't trigger a focus event in setSelection(),
439
+ // use a blur/focus dance to work around this by letting the
440
+ // selection be restored on focus.
441
+ // Need to check for !this._restoreSelection to avoid infinite loop
442
+ enableRestoreSelection.call( this );
443
+ this.blur();
444
+ this.focus();
445
+ } else {
446
+ // iOS bug: if you don't focus the iframe before setting the
447
+ // selection, you can end up in a state where you type but the input
448
+ // doesn't get directed into the contenteditable area but is instead
449
+ // lost in a black hole. Very strange.
450
+ if ( isIOS ) {
451
+ this._win.focus();
452
+ }
453
+ var sel = getWindowSelection( this );
454
+ if ( sel ) {
455
+ sel.removeAllRanges();
456
+ sel.addRange( range );
457
+ }
458
+ }
459
+ }
460
+ return this;
461
+ };
462
+
463
+ proto.getSelection = function () {
464
+ var sel = getWindowSelection( this );
465
+ var root = this._root;
466
+ var selection, startContainer, endContainer, node;
467
+ // If not focused, always rely on cached selection; another function may
468
+ // have set it but the DOM is not modified until focus again
469
+ if ( this._isFocused && sel && sel.rangeCount ) {
470
+ selection = sel.getRangeAt( 0 ).cloneRange();
471
+ startContainer = selection.startContainer;
472
+ endContainer = selection.endContainer;
473
+ // FF can return the selection as being inside an <img>. WTF?
474
+ if ( startContainer && isLeaf( startContainer ) ) {
475
+ selection.setStartBefore( startContainer );
476
+ }
477
+ if ( endContainer && isLeaf( endContainer ) ) {
478
+ selection.setEndBefore( endContainer );
479
+ }
480
+ }
481
+ if ( selection &&
482
+ isOrContains( root, selection.commonAncestorContainer ) ) {
483
+ this._lastSelection = selection;
484
+ } else {
485
+ selection = this._lastSelection;
486
+ node = selection.commonAncestorContainer;
487
+ // Check the editor is in the live document; if not, the range has
488
+ // probably been rewritten by the browser and is bogus
489
+ if ( !isOrContains( node.ownerDocument, node ) ) {
490
+ selection = null;
491
+ }
492
+ }
493
+ if ( !selection ) {
494
+ selection = this._createRange( root.firstChild, 0 );
495
+ }
496
+ return selection;
497
+ };
498
+
499
+ function enableRestoreSelection () {
500
+ this._restoreSelection = true;
501
+ }
502
+ function disableRestoreSelection () {
503
+ this._restoreSelection = false;
504
+ }
505
+ function restoreSelection () {
506
+ if ( this._restoreSelection ) {
507
+ this.setSelection( this._lastSelection );
508
+ }
509
+ }
510
+
511
+ proto.getSelectedText = function () {
512
+ var range = this.getSelection();
513
+ if ( !range || range.collapsed ) {
514
+ return '';
515
+ }
516
+ var walker = new TreeWalker(
517
+ range.commonAncestorContainer,
518
+ SHOW_TEXT|SHOW_ELEMENT,
519
+ function ( node ) {
520
+ return isNodeContainedInRange( range, node, true );
521
+ }
522
+ );
523
+ var startContainer = range.startContainer;
524
+ var endContainer = range.endContainer;
525
+ var node = walker.currentNode = startContainer;
526
+ var textContent = '';
527
+ var addedTextInBlock = false;
528
+ var value;
529
+
530
+ if ( !walker.filter( node ) ) {
531
+ node = walker.nextNode();
532
+ }
533
+
534
+ while ( node ) {
535
+ if ( node.nodeType === TEXT_NODE ) {
536
+ value = node.data;
537
+ if ( value && ( /\S/.test( value ) ) ) {
538
+ if ( node === endContainer ) {
539
+ value = value.slice( 0, range.endOffset );
540
+ }
541
+ if ( node === startContainer ) {
542
+ value = value.slice( range.startOffset );
543
+ }
544
+ textContent += value;
545
+ addedTextInBlock = true;
546
+ }
547
+ } else if ( node.nodeName === 'BR' ||
548
+ addedTextInBlock && !isInline( node ) ) {
549
+ textContent += '\n';
550
+ addedTextInBlock = false;
551
+ }
552
+ node = walker.nextNode();
553
+ }
554
+
555
+ return textContent;
556
+ };
557
+
558
+ proto.getPath = function () {
559
+ return this._path;
560
+ };
561
+
562
+ // --- Workaround for browsers that can't focus empty text nodes ---
563
+
564
+ // WebKit bug: https://bugs.webkit.org/show_bug.cgi?id=15256
565
+
566
+ // Walk down the tree starting at the root and remove any ZWS. If the node only
567
+ // contained ZWS space then remove it too. We may want to keep one ZWS node at
568
+ // the bottom of the tree so the block can be selected. Define that node as the
569
+ // keepNode.
570
+ var removeZWS = function ( root, keepNode ) {
571
+ var walker = new TreeWalker( root, SHOW_TEXT, function () {
572
+ return true;
573
+ }, false ),
574
+ parent, node, index;
575
+ while ( node = walker.nextNode() ) {
576
+ while ( ( index = node.data.indexOf( ZWS ) ) > -1 &&
577
+ ( !keepNode || node.parentNode !== keepNode ) ) {
578
+ if ( node.length === 1 ) {
579
+ do {
580
+ parent = node.parentNode;
581
+ parent.removeChild( node );
582
+ node = parent;
583
+ walker.currentNode = parent;
584
+ } while ( isInline( node ) && !getLength( node ) );
585
+ break;
586
+ } else {
587
+ node.deleteData( index, 1 );
588
+ }
589
+ }
590
+ }
591
+ };
592
+
593
+ proto._didAddZWS = function () {
594
+ this._hasZWS = true;
595
+ };
596
+ proto._removeZWS = function () {
597
+ if ( !this._hasZWS ) {
598
+ return;
599
+ }
600
+ removeZWS( this._root );
601
+ this._hasZWS = false;
602
+ };
603
+
604
+ // --- Path change events ---
605
+
606
+ proto._updatePath = function ( range, force ) {
607
+ if ( !range ) {
608
+ return;
609
+ }
610
+ var anchor = range.startContainer,
611
+ focus = range.endContainer,
612
+ newPath;
613
+ if ( force || anchor !== this._lastAnchorNode ||
614
+ focus !== this._lastFocusNode ) {
615
+ this._lastAnchorNode = anchor;
616
+ this._lastFocusNode = focus;
617
+ newPath = ( anchor && focus ) ? ( anchor === focus ) ?
618
+ getPath( focus, this._root ) : '(selection)' : '';
619
+ if ( this._path !== newPath ) {
620
+ this._path = newPath;
621
+ this.fireEvent( 'pathChange', { path: newPath } );
622
+ }
623
+ }
624
+ this.fireEvent( range.collapsed ? 'cursor' : 'select', {
625
+ range: range
626
+ });
627
+ };
628
+
629
+ // selectionchange is fired synchronously in IE when removing current selection
630
+ // and when setting new selection; keyup/mouseup may have processing we want
631
+ // to do first. Either way, send to next event loop.
632
+ proto._updatePathOnEvent = function ( event ) {
633
+ var self = this;
634
+ if ( self._isFocused && !self._willUpdatePath ) {
635
+ self._willUpdatePath = true;
636
+ setTimeout( function () {
637
+ self._willUpdatePath = false;
638
+ self._updatePath( self.getSelection() );
639
+ }, 0 );
640
+ }
641
+ };
642
+
643
+ // --- Focus ---
644
+
645
+ proto.focus = function () {
646
+ this._root.focus();
647
+
648
+ if ( isIE ) {
649
+ this.fireEvent( 'focus' );
650
+ }
651
+
652
+ return this;
653
+ };
654
+
655
+ proto.blur = function () {
656
+ this._root.blur();
657
+
658
+ if ( isIE ) {
659
+ this.fireEvent( 'blur' );
660
+ }
661
+
662
+ return this;
663
+ };
664
+
665
+ // --- Bookmarking ---
666
+
667
+ var startSelectionId = 'squire-selection-start';
668
+ var endSelectionId = 'squire-selection-end';
669
+
670
+ proto._saveRangeToBookmark = function ( range ) {
671
+ var startNode = this.createElement( 'INPUT', {
672
+ id: startSelectionId,
673
+ type: 'hidden'
674
+ }),
675
+ endNode = this.createElement( 'INPUT', {
676
+ id: endSelectionId,
677
+ type: 'hidden'
678
+ }),
679
+ temp;
680
+
681
+ insertNodeInRange( range, startNode );
682
+ range.collapse( false );
683
+ insertNodeInRange( range, endNode );
684
+
685
+ // In a collapsed range, the start is sometimes inserted after the end!
686
+ if ( startNode.compareDocumentPosition( endNode ) &
687
+ DOCUMENT_POSITION_PRECEDING ) {
688
+ startNode.id = endSelectionId;
689
+ endNode.id = startSelectionId;
690
+ temp = startNode;
691
+ startNode = endNode;
692
+ endNode = temp;
693
+ }
694
+
695
+ range.setStartAfter( startNode );
696
+ range.setEndBefore( endNode );
697
+ };
698
+
699
+ proto._getRangeAndRemoveBookmark = function ( range ) {
700
+ var root = this._root,
701
+ start = root.querySelector( '#' + startSelectionId ),
702
+ end = root.querySelector( '#' + endSelectionId );
703
+
704
+ if ( start && end ) {
705
+ var startContainer = start.parentNode,
706
+ endContainer = end.parentNode,
707
+ startOffset = indexOf.call( startContainer.childNodes, start ),
708
+ endOffset = indexOf.call( endContainer.childNodes, end );
709
+
710
+ if ( startContainer === endContainer ) {
711
+ endOffset -= 1;
712
+ }
713
+
714
+ detach( start );
715
+ detach( end );
716
+
717
+ if ( !range ) {
718
+ range = this._doc.createRange();
719
+ }
720
+ range.setStart( startContainer, startOffset );
721
+ range.setEnd( endContainer, endOffset );
722
+
723
+ // Merge any text nodes we split
724
+ mergeInlines( startContainer, range );
725
+ if ( startContainer !== endContainer ) {
726
+ mergeInlines( endContainer, range );
727
+ }
728
+
729
+ // If we didn't split a text node, we should move into any adjacent
730
+ // text node to current selection point
731
+ if ( range.collapsed ) {
732
+ startContainer = range.startContainer;
733
+ if ( startContainer.nodeType === TEXT_NODE ) {
734
+ endContainer = startContainer.childNodes[ range.startOffset ];
735
+ if ( !endContainer || endContainer.nodeType !== TEXT_NODE ) {
736
+ endContainer =
737
+ startContainer.childNodes[ range.startOffset - 1 ];
738
+ }
739
+ if ( endContainer && endContainer.nodeType === TEXT_NODE ) {
740
+ range.setStart( endContainer, 0 );
741
+ range.collapse( true );
742
+ }
743
+ }
744
+ }
745
+ }
746
+ return range || null;
747
+ };
748
+
749
+ // --- Undo ---
750
+
751
+ proto._keyUpDetectChange = function ( event ) {
752
+ var code = event.keyCode;
753
+ // Presume document was changed if:
754
+ // 1. A modifier key (other than shift) wasn't held down
755
+ // 2. The key pressed is not in range 16<=x<=20 (control keys)
756
+ // 3. The key pressed is not in range 33<=x<=45 (navigation keys)
757
+ if ( !event.ctrlKey && !event.metaKey && !event.altKey &&
758
+ ( code < 16 || code > 20 ) &&
759
+ ( code < 33 || code > 45 ) ) {
760
+ this._docWasChanged();
761
+ }
762
+ };
763
+
764
+ proto._docWasChanged = function () {
765
+ if ( canWeakMap ) {
766
+ nodeCategoryCache = new WeakMap();
767
+ }
768
+ if ( this._ignoreAllChanges ) {
769
+ return;
770
+ }
771
+
772
+ if ( canObserveMutations && this._ignoreChange ) {
773
+ this._ignoreChange = false;
774
+ return;
775
+ }
776
+ if ( this._isInUndoState ) {
777
+ this._isInUndoState = false;
778
+ this.fireEvent( 'undoStateChange', {
779
+ canUndo: true,
780
+ canRedo: false
781
+ });
782
+ }
783
+ this.fireEvent( 'input' );
784
+ };
785
+
786
+ // Leaves bookmark
787
+ proto._recordUndoState = function ( range, replace ) {
788
+ // Don't record if we're already in an undo state
789
+ if ( !this._isInUndoState|| replace ) {
790
+ // Advance pointer to new position
791
+ var undoIndex = this._undoIndex;
792
+ var undoStack = this._undoStack;
793
+ var undoConfig = this._config.undo;
794
+ var undoThreshold = undoConfig.documentSizeThreshold;
795
+ var undoLimit = undoConfig.undoLimit;
796
+ var html;
797
+
798
+ if ( !replace ) {
799
+ undoIndex += 1;
800
+ }
801
+
802
+ // Truncate stack if longer (i.e. if has been previously undone)
803
+ if ( undoIndex < this._undoStackLength ) {
804
+ undoStack.length = this._undoStackLength = undoIndex;
805
+ }
806
+
807
+ // Get data
808
+ if ( range ) {
809
+ this._saveRangeToBookmark( range );
810
+ }
811
+ html = this._getHTML();
812
+
813
+ // If this document is above the configured size threshold,
814
+ // limit the number of saved undo states.
815
+ // Threshold is in bytes, JS uses 2 bytes per character
816
+ if ( undoThreshold > -1 && html.length * 2 > undoThreshold ) {
817
+ if ( undoLimit > -1 && undoIndex > undoLimit ) {
818
+ undoStack.splice( 0, undoIndex - undoLimit );
819
+ undoIndex = undoLimit;
820
+ this._undoStackLength = undoLimit;
821
+ }
822
+ }
823
+
824
+ // Save data
825
+ undoStack[ undoIndex ] = html;
826
+ this._undoIndex = undoIndex;
827
+ this._undoStackLength += 1;
828
+ this._isInUndoState = true;
829
+ }
830
+ };
831
+
832
+ proto.saveUndoState = function ( range ) {
833
+ if ( range === undefined ) {
834
+ range = this.getSelection();
835
+ }
836
+ this._recordUndoState( range, this._isInUndoState );
837
+ this._getRangeAndRemoveBookmark( range );
838
+
839
+ return this;
840
+ };
841
+
842
+ proto.undo = function () {
843
+ // Sanity check: must not be at beginning of the history stack
844
+ if ( this._undoIndex !== 0 || !this._isInUndoState ) {
845
+ // Make sure any changes since last checkpoint are saved.
846
+ this._recordUndoState( this.getSelection(), false );
847
+
848
+ this._undoIndex -= 1;
849
+ this._setHTML( this._undoStack[ this._undoIndex ] );
850
+ var range = this._getRangeAndRemoveBookmark();
851
+ if ( range ) {
852
+ this.setSelection( range );
853
+ }
854
+ this._isInUndoState = true;
855
+ this.fireEvent( 'undoStateChange', {
856
+ canUndo: this._undoIndex !== 0,
857
+ canRedo: true
858
+ });
859
+ this.fireEvent( 'input' );
860
+ }
861
+ return this;
862
+ };
863
+
864
+ proto.redo = function () {
865
+ // Sanity check: must not be at end of stack and must be in an undo
866
+ // state.
867
+ var undoIndex = this._undoIndex,
868
+ undoStackLength = this._undoStackLength;
869
+ if ( undoIndex + 1 < undoStackLength && this._isInUndoState ) {
870
+ this._undoIndex += 1;
871
+ this._setHTML( this._undoStack[ this._undoIndex ] );
872
+ var range = this._getRangeAndRemoveBookmark();
873
+ if ( range ) {
874
+ this.setSelection( range );
875
+ }
876
+ this.fireEvent( 'undoStateChange', {
877
+ canUndo: true,
878
+ canRedo: undoIndex + 2 < undoStackLength
879
+ });
880
+ this.fireEvent( 'input' );
881
+ }
882
+ return this;
883
+ };
884
+
885
+ // --- Inline formatting ---
886
+
887
+ // Looks for matching tag and attributes, so won't work
888
+ // if <strong> instead of <b> etc.
889
+ proto.hasFormat = function ( tag, attributes, range ) {
890
+ // 1. Normalise the arguments and get selection
891
+ tag = tag.toUpperCase();
892
+ if ( !attributes ) { attributes = {}; }
893
+ if ( !range && !( range = this.getSelection() ) ) {
894
+ return false;
895
+ }
896
+
897
+ // Sanitize range to prevent weird IE artifacts
898
+ if ( !range.collapsed &&
899
+ range.startContainer.nodeType === TEXT_NODE &&
900
+ range.startOffset === range.startContainer.length &&
901
+ range.startContainer.nextSibling ) {
902
+ range.setStartBefore( range.startContainer.nextSibling );
903
+ }
904
+ if ( !range.collapsed &&
905
+ range.endContainer.nodeType === TEXT_NODE &&
906
+ range.endOffset === 0 &&
907
+ range.endContainer.previousSibling ) {
908
+ range.setEndAfter( range.endContainer.previousSibling );
909
+ }
910
+
911
+ // If the common ancestor is inside the tag we require, we definitely
912
+ // have the format.
913
+ var root = this._root;
914
+ var common = range.commonAncestorContainer;
915
+ var walker, node;
916
+ if ( getNearest( common, root, tag, attributes ) ) {
917
+ return true;
918
+ }
919
+
920
+ // If common ancestor is a text node and doesn't have the format, we
921
+ // definitely don't have it.
922
+ if ( common.nodeType === TEXT_NODE ) {
923
+ return false;
924
+ }
925
+
926
+ // Otherwise, check each text node at least partially contained within
927
+ // the selection and make sure all of them have the format we want.
928
+ walker = new TreeWalker( common, SHOW_TEXT, function ( node ) {
929
+ return isNodeContainedInRange( range, node, true );
930
+ }, false );
931
+
932
+ var seenNode = false;
933
+ while ( node = walker.nextNode() ) {
934
+ if ( !getNearest( node, root, tag, attributes ) ) {
935
+ return false;
936
+ }
937
+ seenNode = true;
938
+ }
939
+
940
+ return seenNode;
941
+ };
942
+
943
+ // Extracts the font-family and font-size (if any) of the element
944
+ // holding the cursor. If there's a selection, returns an empty object.
945
+ proto.getFontInfo = function ( range ) {
946
+ var fontInfo = {
947
+ color: undefined,
948
+ backgroundColor: undefined,
949
+ family: undefined,
950
+ size: undefined
951
+ };
952
+ var seenAttributes = 0;
953
+ var element, style, attr;
954
+
955
+ if ( !range && !( range = this.getSelection() ) ) {
956
+ return fontInfo;
957
+ }
958
+
959
+ element = range.commonAncestorContainer;
960
+ if ( range.collapsed || element.nodeType === TEXT_NODE ) {
961
+ if ( element.nodeType === TEXT_NODE ) {
962
+ element = element.parentNode;
963
+ }
964
+ while ( seenAttributes < 4 && element ) {
965
+ if ( style = element.style ) {
966
+ if ( !fontInfo.color && ( attr = style.color ) ) {
967
+ fontInfo.color = attr;
968
+ seenAttributes += 1;
969
+ }
970
+ if ( !fontInfo.backgroundColor &&
971
+ ( attr = style.backgroundColor ) ) {
972
+ fontInfo.backgroundColor = attr;
973
+ seenAttributes += 1;
974
+ }
975
+ if ( !fontInfo.family && ( attr = style.fontFamily ) ) {
976
+ fontInfo.family = attr;
977
+ seenAttributes += 1;
978
+ }
979
+ if ( !fontInfo.size && ( attr = style.fontSize ) ) {
980
+ fontInfo.size = attr;
981
+ seenAttributes += 1;
982
+ }
983
+ }
984
+ element = element.parentNode;
985
+ }
986
+ }
987
+ return fontInfo;
988
+ };
989
+
990
+ proto._addFormat = function ( tag, attributes, range ) {
991
+ // If the range is collapsed we simply insert the node by wrapping
992
+ // it round the range and focus it.
993
+ var root = this._root;
994
+ var el, walker, startContainer, endContainer, startOffset, endOffset,
995
+ node, needsFormat, block;
996
+
997
+ if ( range.collapsed ) {
998
+ el = fixCursor( this.createElement( tag, attributes ), root );
999
+ insertNodeInRange( range, el );
1000
+ range.setStart( el.firstChild, el.firstChild.length );
1001
+ range.collapse( true );
1002
+
1003
+ // Clean up any previous formats that may have been set on this block
1004
+ // that are unused.
1005
+ block = el;
1006
+ while ( isInline( block ) ) {
1007
+ block = block.parentNode;
1008
+ }
1009
+ removeZWS( block, el );
1010
+ }
1011
+ // Otherwise we find all the textnodes in the range (splitting
1012
+ // partially selected nodes) and if they're not already formatted
1013
+ // correctly we wrap them in the appropriate tag.
1014
+ else {
1015
+ // Create an iterator to walk over all the text nodes under this
1016
+ // ancestor which are in the range and not already formatted
1017
+ // correctly.
1018
+ //
1019
+ // In Blink/WebKit, empty blocks may have no text nodes, just a <br>.
1020
+ // Therefore we wrap this in the tag as well, as this will then cause it
1021
+ // to apply when the user types something in the block, which is
1022
+ // presumably what was intended.
1023
+ //
1024
+ // IMG tags are included because we may want to create a link around
1025
+ // them, and adding other styles is harmless.
1026
+ walker = new TreeWalker(
1027
+ range.commonAncestorContainer,
1028
+ SHOW_TEXT|SHOW_ELEMENT,
1029
+ function ( node ) {
1030
+ return ( node.nodeType === TEXT_NODE ||
1031
+ node.nodeName === 'BR' ||
1032
+ node.nodeName === 'IMG'
1033
+ ) && isNodeContainedInRange( range, node, true );
1034
+ },
1035
+ false
1036
+ );
1037
+
1038
+ // Start at the beginning node of the range and iterate through
1039
+ // all the nodes in the range that need formatting.
1040
+ startContainer = range.startContainer;
1041
+ startOffset = range.startOffset;
1042
+ endContainer = range.endContainer;
1043
+ endOffset = range.endOffset;
1044
+
1045
+ // Make sure we start with a valid node.
1046
+ walker.currentNode = startContainer;
1047
+ if ( !walker.filter( startContainer ) ) {
1048
+ startContainer = walker.nextNode();
1049
+ startOffset = 0;
1050
+ }
1051
+
1052
+ // If there are no interesting nodes in the selection, abort
1053
+ if ( !startContainer ) {
1054
+ return range;
1055
+ }
1056
+
1057
+ do {
1058
+ node = walker.currentNode;
1059
+ needsFormat = !getNearest( node, root, tag, attributes );
1060
+ if ( needsFormat ) {
1061
+ // <br> can never be a container node, so must have a text node
1062
+ // if node == (end|start)Container
1063
+ if ( node === endContainer && node.length > endOffset ) {
1064
+ node.splitText( endOffset );
1065
+ }
1066
+ if ( node === startContainer && startOffset ) {
1067
+ node = node.splitText( startOffset );
1068
+ if ( endContainer === startContainer ) {
1069
+ endContainer = node;
1070
+ endOffset -= startOffset;
1071
+ }
1072
+ startContainer = node;
1073
+ startOffset = 0;
1074
+ }
1075
+ el = this.createElement( tag, attributes );
1076
+ replaceWith( node, el );
1077
+ el.appendChild( node );
1078
+ }
1079
+ } while ( walker.nextNode() );
1080
+
1081
+ // If we don't finish inside a text node, offset may have changed.
1082
+ if ( endContainer.nodeType !== TEXT_NODE ) {
1083
+ if ( node.nodeType === TEXT_NODE ) {
1084
+ endContainer = node;
1085
+ endOffset = node.length;
1086
+ } else {
1087
+ // If <br>, we must have just wrapped it, so it must have only
1088
+ // one child
1089
+ endContainer = node.parentNode;
1090
+ endOffset = 1;
1091
+ }
1092
+ }
1093
+
1094
+ // Now set the selection to as it was before
1095
+ range = this._createRange(
1096
+ startContainer, startOffset, endContainer, endOffset );
1097
+ }
1098
+ return range;
1099
+ };
1100
+
1101
+ proto._removeFormat = function ( tag, attributes, range, partial ) {
1102
+ // Add bookmark
1103
+ this._saveRangeToBookmark( range );
1104
+
1105
+ // We need a node in the selection to break the surrounding
1106
+ // formatted text.
1107
+ var doc = this._doc,
1108
+ fixer;
1109
+ if ( range.collapsed ) {
1110
+ if ( cantFocusEmptyTextNodes ) {
1111
+ fixer = doc.createTextNode( ZWS );
1112
+ this._didAddZWS();
1113
+ } else {
1114
+ fixer = doc.createTextNode( '' );
1115
+ }
1116
+ insertNodeInRange( range, fixer );
1117
+ }
1118
+
1119
+ // Find block-level ancestor of selection
1120
+ var root = range.commonAncestorContainer;
1121
+ while ( isInline( root ) ) {
1122
+ root = root.parentNode;
1123
+ }
1124
+
1125
+ // Find text nodes inside formatTags that are not in selection and
1126
+ // add an extra tag with the same formatting.
1127
+ var startContainer = range.startContainer,
1128
+ startOffset = range.startOffset,
1129
+ endContainer = range.endContainer,
1130
+ endOffset = range.endOffset,
1131
+ toWrap = [],
1132
+ examineNode = function ( node, exemplar ) {
1133
+ // If the node is completely contained by the range then
1134
+ // we're going to remove all formatting so ignore it.
1135
+ if ( isNodeContainedInRange( range, node, false ) ) {
1136
+ return;
1137
+ }
1138
+
1139
+ var isText = ( node.nodeType === TEXT_NODE ),
1140
+ child, next;
1141
+
1142
+ // If not at least partially contained, wrap entire contents
1143
+ // in a clone of the tag we're removing and we're done.
1144
+ if ( !isNodeContainedInRange( range, node, true ) ) {
1145
+ // Ignore bookmarks and empty text nodes
1146
+ if ( node.nodeName !== 'INPUT' &&
1147
+ ( !isText || node.data ) ) {
1148
+ toWrap.push([ exemplar, node ]);
1149
+ }
1150
+ return;
1151
+ }
1152
+
1153
+ // Split any partially selected text nodes.
1154
+ if ( isText ) {
1155
+ if ( node === endContainer && endOffset !== node.length ) {
1156
+ toWrap.push([ exemplar, node.splitText( endOffset ) ]);
1157
+ }
1158
+ if ( node === startContainer && startOffset ) {
1159
+ node.splitText( startOffset );
1160
+ toWrap.push([ exemplar, node ]);
1161
+ }
1162
+ }
1163
+ // If not a text node, recurse onto all children.
1164
+ // Beware, the tree may be rewritten with each call
1165
+ // to examineNode, hence find the next sibling first.
1166
+ else {
1167
+ for ( child = node.firstChild; child; child = next ) {
1168
+ next = child.nextSibling;
1169
+ examineNode( child, exemplar );
1170
+ }
1171
+ }
1172
+ },
1173
+ formatTags = Array.prototype.filter.call(
1174
+ root.getElementsByTagName( tag ), function ( el ) {
1175
+ return isNodeContainedInRange( range, el, true ) &&
1176
+ hasTagAttributes( el, tag, attributes );
1177
+ }
1178
+ );
1179
+
1180
+ if ( !partial ) {
1181
+ formatTags.forEach( function ( node ) {
1182
+ examineNode( node, node );
1183
+ });
1184
+ }
1185
+
1186
+ // Now wrap unselected nodes in the tag
1187
+ toWrap.forEach( function ( item ) {
1188
+ // [ exemplar, node ] tuple
1189
+ var el = item[0].cloneNode( false ),
1190
+ node = item[1];
1191
+ replaceWith( node, el );
1192
+ el.appendChild( node );
1193
+ });
1194
+ // and remove old formatting tags.
1195
+ formatTags.forEach( function ( el ) {
1196
+ replaceWith( el, empty( el ) );
1197
+ });
1198
+
1199
+ // Merge adjacent inlines:
1200
+ this._getRangeAndRemoveBookmark( range );
1201
+ if ( fixer ) {
1202
+ range.collapse( false );
1203
+ }
1204
+ mergeInlines( root, range );
1205
+
1206
+ return range;
1207
+ };
1208
+
1209
+ proto.changeFormat = function ( add, remove, range, partial ) {
1210
+ // Normalise the arguments and get selection
1211
+ if ( !range && !( range = this.getSelection() ) ) {
1212
+ return this;
1213
+ }
1214
+
1215
+ // Save undo checkpoint
1216
+ this.saveUndoState( range );
1217
+
1218
+ if ( remove ) {
1219
+ range = this._removeFormat( remove.tag.toUpperCase(),
1220
+ remove.attributes || {}, range, partial );
1221
+ }
1222
+ if ( add ) {
1223
+ range = this._addFormat( add.tag.toUpperCase(),
1224
+ add.attributes || {}, range );
1225
+ }
1226
+
1227
+ this.setSelection( range );
1228
+ this._updatePath( range, true );
1229
+
1230
+ // We're not still in an undo state
1231
+ if ( !canObserveMutations ) {
1232
+ this._docWasChanged();
1233
+ }
1234
+
1235
+ return this;
1236
+ };
1237
+
1238
+ // --- Block formatting ---
1239
+
1240
+ var tagAfterSplit = {
1241
+ DT: 'DD',
1242
+ DD: 'DT',
1243
+ LI: 'LI',
1244
+ PRE: 'PRE'
1245
+ };
1246
+
1247
+ var splitBlock = function ( self, block, node, offset ) {
1248
+ var splitTag = tagAfterSplit[ block.nodeName ],
1249
+ splitProperties = null,
1250
+ nodeAfterSplit = split( node, offset, block.parentNode, self._root ),
1251
+ config = self._config;
1252
+
1253
+ if ( !splitTag ) {
1254
+ splitTag = config.blockTag;
1255
+ splitProperties = config.blockAttributes;
1256
+ }
1257
+
1258
+ // Make sure the new node is the correct type.
1259
+ if ( !hasTagAttributes( nodeAfterSplit, splitTag, splitProperties ) ) {
1260
+ block = createElement( nodeAfterSplit.ownerDocument,
1261
+ splitTag, splitProperties );
1262
+ if ( nodeAfterSplit.dir ) {
1263
+ block.dir = nodeAfterSplit.dir;
1264
+ }
1265
+ replaceWith( nodeAfterSplit, block );
1266
+ block.appendChild( empty( nodeAfterSplit ) );
1267
+ nodeAfterSplit = block;
1268
+ }
1269
+ return nodeAfterSplit;
1270
+ };
1271
+
1272
+ proto.forEachBlock = function ( fn, mutates, range ) {
1273
+ if ( !range && !( range = this.getSelection() ) ) {
1274
+ return this;
1275
+ }
1276
+
1277
+ // Save undo checkpoint
1278
+ if ( mutates ) {
1279
+ this.saveUndoState( range );
1280
+ }
1281
+
1282
+ var root = this._root;
1283
+ var start = getStartBlockOfRange( range, root );
1284
+ var end = getEndBlockOfRange( range, root );
1285
+ if ( start && end ) {
1286
+ do {
1287
+ if ( fn( start ) || start === end ) { break; }
1288
+ } while ( start = getNextBlock( start, root ) );
1289
+ }
1290
+
1291
+ if ( mutates ) {
1292
+ this.setSelection( range );
1293
+
1294
+ // Path may have changed
1295
+ this._updatePath( range, true );
1296
+
1297
+ // We're not still in an undo state
1298
+ if ( !canObserveMutations ) {
1299
+ this._docWasChanged();
1300
+ }
1301
+ }
1302
+ return this;
1303
+ };
1304
+
1305
+ proto.modifyBlocks = function ( modify, range ) {
1306
+ if ( !range && !( range = this.getSelection() ) ) {
1307
+ return this;
1308
+ }
1309
+
1310
+ // 1. Save undo checkpoint and bookmark selection
1311
+ this._recordUndoState( range, this._isInUndoState );
1312
+
1313
+ var root = this._root;
1314
+ var frag;
1315
+
1316
+ // 2. Expand range to block boundaries
1317
+ expandRangeToBlockBoundaries( range, root );
1318
+
1319
+ // 3. Remove range.
1320
+ moveRangeBoundariesUpTree( range, root, root, root );
1321
+ frag = extractContentsOfRange( range, root, root );
1322
+
1323
+ // 4. Modify tree of fragment and reinsert.
1324
+ insertNodeInRange( range, modify.call( this, frag ) );
1325
+
1326
+ // 5. Merge containers at edges
1327
+ if ( range.endOffset < range.endContainer.childNodes.length ) {
1328
+ mergeContainers( range.endContainer.childNodes[ range.endOffset ], root );
1329
+ }
1330
+ mergeContainers( range.startContainer.childNodes[ range.startOffset ], root );
1331
+
1332
+ // 6. Restore selection
1333
+ this._getRangeAndRemoveBookmark( range );
1334
+ this.setSelection( range );
1335
+ this._updatePath( range, true );
1336
+
1337
+ // 7. We're not still in an undo state
1338
+ if ( !canObserveMutations ) {
1339
+ this._docWasChanged();
1340
+ }
1341
+
1342
+ return this;
1343
+ };
1344
+
1345
+ var increaseBlockQuoteLevel = function ( frag ) {
1346
+ return this.createElement( 'BLOCKQUOTE',
1347
+ this._config.tagAttributes.blockquote, [
1348
+ frag
1349
+ ]);
1350
+ };
1351
+
1352
+ var decreaseBlockQuoteLevel = function ( frag ) {
1353
+ var root = this._root;
1354
+ var blockquotes = frag.querySelectorAll( 'blockquote' );
1355
+ Array.prototype.filter.call( blockquotes, function ( el ) {
1356
+ return !getNearest( el.parentNode, root, 'BLOCKQUOTE' );
1357
+ }).forEach( function ( el ) {
1358
+ replaceWith( el, empty( el ) );
1359
+ });
1360
+ return frag;
1361
+ };
1362
+
1363
+ var removeBlockQuote = function (/* frag */) {
1364
+ return this.createDefaultBlock([
1365
+ this.createElement( 'INPUT', {
1366
+ id: startSelectionId,
1367
+ type: 'hidden'
1368
+ }),
1369
+ this.createElement( 'INPUT', {
1370
+ id: endSelectionId,
1371
+ type: 'hidden'
1372
+ })
1373
+ ]);
1374
+ };
1375
+
1376
+ var makeList = function ( self, frag, type ) {
1377
+ var walker = getBlockWalker( frag, self._root ),
1378
+ node, tag, prev, newLi,
1379
+ tagAttributes = self._config.tagAttributes,
1380
+ listAttrs = tagAttributes[ type.toLowerCase() ],
1381
+ listItemAttrs = tagAttributes.li;
1382
+
1383
+ while ( node = walker.nextNode() ) {
1384
+ if ( node.parentNode.nodeName === 'LI' ) {
1385
+ node = node.parentNode;
1386
+ walker.currentNode = node.lastChild;
1387
+ }
1388
+ if ( node.nodeName !== 'LI' ) {
1389
+ newLi = self.createElement( 'LI', listItemAttrs );
1390
+ if ( node.dir ) {
1391
+ newLi.dir = node.dir;
1392
+ }
1393
+
1394
+ // Have we replaced the previous block with a new <ul>/<ol>?
1395
+ if ( ( prev = node.previousSibling ) && prev.nodeName === type ) {
1396
+ prev.appendChild( newLi );
1397
+ detach( node );
1398
+ }
1399
+ // Otherwise, replace this block with the <ul>/<ol>
1400
+ else {
1401
+ replaceWith(
1402
+ node,
1403
+ self.createElement( type, listAttrs, [
1404
+ newLi
1405
+ ])
1406
+ );
1407
+ }
1408
+ newLi.appendChild( empty( node ) );
1409
+ walker.currentNode = newLi;
1410
+ } else {
1411
+ node = node.parentNode;
1412
+ tag = node.nodeName;
1413
+ if ( tag !== type && ( /^[OU]L$/.test( tag ) ) ) {
1414
+ replaceWith( node,
1415
+ self.createElement( type, listAttrs, [ empty( node ) ] )
1416
+ );
1417
+ }
1418
+ }
1419
+ }
1420
+ };
1421
+
1422
+ var makeUnorderedList = function ( frag ) {
1423
+ makeList( this, frag, 'UL' );
1424
+ return frag;
1425
+ };
1426
+
1427
+ var makeOrderedList = function ( frag ) {
1428
+ makeList( this, frag, 'OL' );
1429
+ return frag;
1430
+ };
1431
+
1432
+ var removeList = function ( frag ) {
1433
+ var lists = frag.querySelectorAll( 'UL, OL' ),
1434
+ items = frag.querySelectorAll( 'LI' ),
1435
+ root = this._root,
1436
+ i, l, list, listFrag, item;
1437
+ for ( i = 0, l = lists.length; i < l; i += 1 ) {
1438
+ list = lists[i];
1439
+ listFrag = empty( list );
1440
+ fixContainer( listFrag, root );
1441
+ replaceWith( list, listFrag );
1442
+ }
1443
+
1444
+ for ( i = 0, l = items.length; i < l; i += 1 ) {
1445
+ item = items[i];
1446
+ if ( isBlock( item ) ) {
1447
+ replaceWith( item,
1448
+ this.createDefaultBlock([ empty( item ) ])
1449
+ );
1450
+ } else {
1451
+ fixContainer( item, root );
1452
+ replaceWith( item, empty( item ) );
1453
+ }
1454
+ }
1455
+ return frag;
1456
+ };
1457
+
1458
+ var getListSelection = function ( range, root ) {
1459
+ // Get start+end li in single common ancestor
1460
+ var list = range.commonAncestorContainer;
1461
+ var startLi = range.startContainer;
1462
+ var endLi = range.endContainer;
1463
+ while ( list && list !== root && !/^[OU]L$/.test( list.nodeName ) ) {
1464
+ list = list.parentNode;
1465
+ }
1466
+ if ( !list || list === root ) {
1467
+ return null;
1468
+ }
1469
+ if ( startLi === list ) {
1470
+ startLi = startLi.childNodes[ range.startOffset ];
1471
+ }
1472
+ if ( endLi === list ) {
1473
+ endLi = endLi.childNodes[ range.endOffset ];
1474
+ }
1475
+ while ( startLi && startLi.parentNode !== list ) {
1476
+ startLi = startLi.parentNode;
1477
+ }
1478
+ while ( endLi && endLi.parentNode !== list ) {
1479
+ endLi = endLi.parentNode;
1480
+ }
1481
+ return [ list, startLi, endLi ];
1482
+ };
1483
+
1484
+ proto.increaseListLevel = function ( range ) {
1485
+ if ( !range && !( range = this.getSelection() ) ) {
1486
+ return this.focus();
1487
+ }
1488
+
1489
+ var root = this._root;
1490
+ var listSelection = getListSelection( range, root );
1491
+ if ( !listSelection ) {
1492
+ return this.focus();
1493
+ }
1494
+
1495
+ var list = listSelection[0];
1496
+ var startLi = listSelection[1];
1497
+ var endLi = listSelection[2];
1498
+ if ( !startLi || startLi === list.firstChild ) {
1499
+ return this.focus();
1500
+ }
1501
+
1502
+ // Save undo checkpoint and bookmark selection
1503
+ this._recordUndoState( range, this._isInUndoState );
1504
+
1505
+ // Increase list depth
1506
+ var type = list.nodeName;
1507
+ var newParent = startLi.previousSibling;
1508
+ var listAttrs, next;
1509
+ if ( newParent.nodeName !== type ) {
1510
+ listAttrs = this._config.tagAttributes[ type.toLowerCase() ];
1511
+ newParent = this.createElement( type, listAttrs );
1512
+ list.insertBefore( newParent, startLi );
1513
+ }
1514
+ do {
1515
+ next = startLi === endLi ? null : startLi.nextSibling;
1516
+ newParent.appendChild( startLi );
1517
+ } while ( ( startLi = next ) );
1518
+ next = newParent.nextSibling;
1519
+ if ( next ) {
1520
+ mergeContainers( next, root );
1521
+ }
1522
+
1523
+ // Restore selection
1524
+ this._getRangeAndRemoveBookmark( range );
1525
+ this.setSelection( range );
1526
+ this._updatePath( range, true );
1527
+
1528
+ // We're not still in an undo state
1529
+ if ( !canObserveMutations ) {
1530
+ this._docWasChanged();
1531
+ }
1532
+
1533
+ return this.focus();
1534
+ };
1535
+
1536
+ proto.decreaseListLevel = function ( range ) {
1537
+ if ( !range && !( range = this.getSelection() ) ) {
1538
+ return this.focus();
1539
+ }
1540
+
1541
+ var root = this._root;
1542
+ var listSelection = getListSelection( range, root );
1543
+ if ( !listSelection ) {
1544
+ return this.focus();
1545
+ }
1546
+
1547
+ var list = listSelection[0];
1548
+ var startLi = listSelection[1];
1549
+ var endLi = listSelection[2];
1550
+ if ( !startLi ) {
1551
+ startLi = list.firstChild;
1552
+ }
1553
+ if ( !endLi ) {
1554
+ endLi = list.lastChild;
1555
+ }
1556
+
1557
+ // Save undo checkpoint and bookmark selection
1558
+ this._recordUndoState( range, this._isInUndoState );
1559
+
1560
+ // Find the new parent list node
1561
+ var newParent = list.parentNode;
1562
+ var next;
1563
+
1564
+ // Split list if necesary
1565
+ var insertBefore = !endLi.nextSibling ?
1566
+ list.nextSibling :
1567
+ split( list, endLi.nextSibling, newParent, root );
1568
+
1569
+ if ( newParent !== root && newParent.nodeName === 'LI' ) {
1570
+ newParent = newParent.parentNode;
1571
+ while ( insertBefore ) {
1572
+ next = insertBefore.nextSibling;
1573
+ endLi.appendChild( insertBefore );
1574
+ insertBefore = next;
1575
+ }
1576
+ insertBefore = list.parentNode.nextSibling;
1577
+ }
1578
+
1579
+ var makeNotList = !/^[OU]L$/.test( newParent.nodeName );
1580
+ do {
1581
+ next = startLi === endLi ? null : startLi.nextSibling;
1582
+ list.removeChild( startLi );
1583
+ if ( makeNotList && startLi.nodeName === 'LI' ) {
1584
+ startLi = this.createDefaultBlock([ empty( startLi ) ]);
1585
+ }
1586
+ newParent.insertBefore( startLi, insertBefore );
1587
+ } while ( ( startLi = next ) );
1588
+
1589
+ if ( !list.firstChild ) {
1590
+ detach( list );
1591
+ }
1592
+
1593
+ if ( insertBefore ) {
1594
+ mergeContainers( insertBefore, root );
1595
+ }
1596
+
1597
+ // Restore selection
1598
+ this._getRangeAndRemoveBookmark( range );
1599
+ this.setSelection( range );
1600
+ this._updatePath( range, true );
1601
+
1602
+ // We're not still in an undo state
1603
+ if ( !canObserveMutations ) {
1604
+ this._docWasChanged();
1605
+ }
1606
+
1607
+ return this.focus();
1608
+ };
1609
+
1610
+ proto._ensureBottomLine = function () {
1611
+ var root = this._root;
1612
+ var last = root.lastElementChild;
1613
+ if ( !last ||
1614
+ last.nodeName !== this._config.blockTag || !isBlock( last ) ) {
1615
+ root.appendChild( this.createDefaultBlock() );
1616
+ }
1617
+ };
1618
+
1619
+ // --- Keyboard interaction ---
1620
+
1621
+ proto.setKeyHandler = function ( key, fn ) {
1622
+ this._keyHandlers[ key ] = fn;
1623
+ return this;
1624
+ };
1625
+
1626
+ // --- Get/Set data ---
1627
+
1628
+ proto._getHTML = function () {
1629
+ return this._root.innerHTML;
1630
+ };
1631
+
1632
+ proto._setHTML = function ( html ) {
1633
+ var root = this._root;
1634
+ var node = root;
1635
+ node.innerHTML = html;
1636
+ do {
1637
+ fixCursor( node, root );
1638
+ } while ( node = getNextBlock( node, root ) );
1639
+ this._ignoreChange = true;
1640
+ };
1641
+
1642
+ proto.getHTML = function ( withBookMark ) {
1643
+ var brs = [],
1644
+ root, node, fixer, html, l, range;
1645
+ if ( withBookMark && ( range = this.getSelection() ) ) {
1646
+ this._saveRangeToBookmark( range );
1647
+ }
1648
+ if ( useTextFixer ) {
1649
+ root = this._root;
1650
+ node = root;
1651
+ while ( node = getNextBlock( node, root ) ) {
1652
+ if ( !node.textContent && !node.querySelector( 'BR' ) ) {
1653
+ fixer = this.createElement( 'BR' );
1654
+ node.appendChild( fixer );
1655
+ brs.push( fixer );
1656
+ }
1657
+ }
1658
+ }
1659
+ html = this._getHTML().replace( /\u200B/g, '' );
1660
+ if ( useTextFixer ) {
1661
+ l = brs.length;
1662
+ while ( l-- ) {
1663
+ detach( brs[l] );
1664
+ }
1665
+ }
1666
+ if ( range ) {
1667
+ this._getRangeAndRemoveBookmark( range );
1668
+ }
1669
+ return html;
1670
+ };
1671
+
1672
+ proto.setHTML = function ( html ) {
1673
+ var config = this._config;
1674
+ var sanitizeToDOMFragment = config.isSetHTMLSanitized ?
1675
+ config.sanitizeToDOMFragment : null;
1676
+ var root = this._root;
1677
+ var div, frag, child;
1678
+
1679
+ // Parse HTML into DOM tree
1680
+ if ( typeof sanitizeToDOMFragment === 'function' ) {
1681
+ frag = sanitizeToDOMFragment( html, false, this );
1682
+ } else {
1683
+ div = this.createElement( 'DIV' );
1684
+ div.innerHTML = html;
1685
+ frag = this._doc.createDocumentFragment();
1686
+ frag.appendChild( empty( div ) );
1687
+ }
1688
+
1689
+ cleanTree( frag );
1690
+ cleanupBRs( frag, root, false );
1691
+
1692
+ fixContainer( frag, root );
1693
+
1694
+ // Fix cursor
1695
+ var node = frag;
1696
+ while ( node = getNextBlock( node, root ) ) {
1697
+ fixCursor( node, root );
1698
+ }
1699
+
1700
+ // Don't fire an input event
1701
+ this._ignoreChange = true;
1702
+
1703
+ // Remove existing root children
1704
+ while ( child = root.lastChild ) {
1705
+ root.removeChild( child );
1706
+ }
1707
+
1708
+ // And insert new content
1709
+ root.appendChild( frag );
1710
+ fixCursor( root, root );
1711
+
1712
+ // Reset the undo stack
1713
+ this._undoIndex = -1;
1714
+ this._undoStack.length = 0;
1715
+ this._undoStackLength = 0;
1716
+ this._isInUndoState = false;
1717
+
1718
+ // Record undo state
1719
+ var range = this._getRangeAndRemoveBookmark() ||
1720
+ this._createRange( root.firstChild, 0 );
1721
+ this.saveUndoState( range );
1722
+ // IE will also set focus when selecting text so don't use
1723
+ // setSelection. Instead, just store it in lastSelection, so if
1724
+ // anything calls getSelection before first focus, we have a range
1725
+ // to return.
1726
+ this._lastSelection = range;
1727
+ enableRestoreSelection.call( this );
1728
+ this._updatePath( range, true );
1729
+
1730
+ return this;
1731
+ };
1732
+
1733
+ proto.insertElement = function ( el, range ) {
1734
+ if ( !range ) {
1735
+ range = this.getSelection();
1736
+ }
1737
+ range.collapse( true );
1738
+ if ( isInline( el ) ) {
1739
+ insertNodeInRange( range, el );
1740
+ range.setStartAfter( el );
1741
+ } else {
1742
+ // Get containing block node.
1743
+ var root = this._root;
1744
+ var splitNode = getStartBlockOfRange( range, root ) || root;
1745
+ var parent, nodeAfterSplit;
1746
+ // While at end of container node, move up DOM tree.
1747
+ while ( splitNode !== root && !splitNode.nextSibling ) {
1748
+ splitNode = splitNode.parentNode;
1749
+ }
1750
+ // If in the middle of a container node, split up to root.
1751
+ if ( splitNode !== root ) {
1752
+ parent = splitNode.parentNode;
1753
+ nodeAfterSplit = split( parent, splitNode.nextSibling, root, root );
1754
+ }
1755
+ if ( nodeAfterSplit ) {
1756
+ root.insertBefore( el, nodeAfterSplit );
1757
+ } else {
1758
+ root.appendChild( el );
1759
+ // Insert blank line below block.
1760
+ nodeAfterSplit = this.createDefaultBlock();
1761
+ root.appendChild( nodeAfterSplit );
1762
+ }
1763
+ range.setStart( nodeAfterSplit, 0 );
1764
+ range.setEnd( nodeAfterSplit, 0 );
1765
+ moveRangeBoundariesDownTree( range );
1766
+ }
1767
+ this.focus();
1768
+ this.setSelection( range );
1769
+ this._updatePath( range );
1770
+
1771
+ if ( !canObserveMutations ) {
1772
+ this._docWasChanged();
1773
+ }
1774
+
1775
+ return this;
1776
+ };
1777
+
1778
+ proto.insertImage = function ( src, attributes ) {
1779
+ var img = this.createElement( 'IMG', mergeObjects({
1780
+ src: src
1781
+ }, attributes, true ));
1782
+ this.insertElement( img );
1783
+ return img;
1784
+ };
1785
+
1786
+ var linkRegExp = /\b((?:(?:ht|f)tps?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,}\/)(?:[^\s()<>]+|\([^\s()<>]+\))+(?:\((?:[^\s()<>]+|(?:\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))|([\w\-.%+]+@(?:[\w\-]+\.)+[A-Z]{2,}\b)/i;
1787
+
1788
+ var addLinks = function ( frag, root, self ) {
1789
+ var doc = frag.ownerDocument,
1790
+ walker = new TreeWalker( frag, SHOW_TEXT,
1791
+ function ( node ) {
1792
+ return !getNearest( node, root, 'A' );
1793
+ }, false ),
1794
+ defaultAttributes = self._config.tagAttributes.a,
1795
+ node, data, parent, match, index, endIndex, child;
1796
+ while ( node = walker.nextNode() ) {
1797
+ data = node.data;
1798
+ parent = node.parentNode;
1799
+ while ( match = linkRegExp.exec( data ) ) {
1800
+ index = match.index;
1801
+ endIndex = index + match[0].length;
1802
+ if ( index ) {
1803
+ child = doc.createTextNode( data.slice( 0, index ) );
1804
+ parent.insertBefore( child, node );
1805
+ }
1806
+ child = self.createElement( 'A', mergeObjects({
1807
+ href: match[1] ?
1808
+ /^(?:ht|f)tps?:/.test( match[1] ) ?
1809
+ match[1] :
1810
+ 'http://' + match[1] :
1811
+ 'mailto:' + match[2]
1812
+ }, defaultAttributes, false ));
1813
+ child.textContent = data.slice( index, endIndex );
1814
+ parent.insertBefore( child, node );
1815
+ node.data = data = data.slice( endIndex );
1816
+ }
1817
+ }
1818
+ };
1819
+
1820
+ // Insert HTML at the cursor location. If the selection is not collapsed
1821
+ // insertTreeFragmentIntoRange will delete the selection so that it is replaced
1822
+ // by the html being inserted.
1823
+ proto.insertHTML = function ( html, isPaste ) {
1824
+ var config = this._config;
1825
+ var sanitizeToDOMFragment = config.isInsertedHTMLSanitized ?
1826
+ config.sanitizeToDOMFragment : null;
1827
+ var range = this.getSelection();
1828
+ var doc = this._doc;
1829
+ var startFragmentIndex, endFragmentIndex;
1830
+ var div, frag, root, node, event;
1831
+
1832
+ // Edge doesn't just copy the fragment, but includes the surrounding guff
1833
+ // including the full <head> of the page. Need to strip this out. If
1834
+ // available use DOMPurify to parse and sanitise.
1835
+ if ( typeof sanitizeToDOMFragment === 'function' ) {
1836
+ frag = sanitizeToDOMFragment( html, isPaste, this );
1837
+ } else {
1838
+ if ( isPaste ) {
1839
+ startFragmentIndex = html.indexOf( '<!--StartFragment-->' );
1840
+ endFragmentIndex = html.lastIndexOf( '<!--EndFragment-->' );
1841
+ if ( startFragmentIndex > -1 && endFragmentIndex > -1 ) {
1842
+ html = html.slice( startFragmentIndex + 20, endFragmentIndex );
1843
+ }
1844
+ }
1845
+ // Wrap with <tr> if html contains dangling <td> tags
1846
+ if ( /<\/td>((?!<\/tr>)[\s\S])*$/i.test( html ) ) {
1847
+ html = '<TR>' + html + '</TR>';
1848
+ }
1849
+ // Wrap with <table> if html contains dangling <tr> tags
1850
+ if ( /<\/tr>((?!<\/table>)[\s\S])*$/i.test( html ) ) {
1851
+ html = '<TABLE>' + html + '</TABLE>';
1852
+ }
1853
+ // Parse HTML into DOM tree
1854
+ div = this.createElement( 'DIV' );
1855
+ div.innerHTML = html;
1856
+ frag = doc.createDocumentFragment();
1857
+ frag.appendChild( empty( div ) );
1858
+ }
1859
+
1860
+ // Record undo checkpoint
1861
+ this.saveUndoState( range );
1862
+
1863
+ try {
1864
+ root = this._root;
1865
+ node = frag;
1866
+ event = {
1867
+ fragment: frag,
1868
+ preventDefault: function () {
1869
+ this.defaultPrevented = true;
1870
+ },
1871
+ defaultPrevented: false
1872
+ };
1873
+
1874
+ addLinks( frag, frag, this );
1875
+ cleanTree( frag );
1876
+ cleanupBRs( frag, root, false );
1877
+ removeEmptyInlines( frag );
1878
+ frag.normalize();
1879
+
1880
+ while ( node = getNextBlock( node, frag ) ) {
1881
+ fixCursor( node, root );
1882
+ }
1883
+
1884
+ if ( isPaste ) {
1885
+ this.fireEvent( 'willPaste', event );
1886
+ }
1887
+
1888
+ if ( !event.defaultPrevented ) {
1889
+ insertTreeFragmentIntoRange( range, event.fragment, root );
1890
+ if ( !canObserveMutations ) {
1891
+ this._docWasChanged();
1892
+ }
1893
+ range.collapse( false );
1894
+ this._ensureBottomLine();
1895
+ }
1896
+
1897
+ this.setSelection( range );
1898
+ this._updatePath( range, true );
1899
+ // Safari sometimes loses focus after paste. Weird.
1900
+ if ( isPaste ) {
1901
+ this.focus();
1902
+ }
1903
+ } catch ( error ) {
1904
+ this.didError( error );
1905
+ }
1906
+ return this;
1907
+ };
1908
+
1909
+ var escapeHTMLFragement = function ( text ) {
1910
+ return text.split( '&' ).join( '&amp;' )
1911
+ .split( '<' ).join( '&lt;' )
1912
+ .split( '>' ).join( '&gt;' )
1913
+ .split( '"' ).join( '&quot;' );
1914
+ };
1915
+
1916
+ proto.insertPlainText = function ( plainText, isPaste ) {
1917
+ var lines = plainText.split( '\n' );
1918
+ var config = this._config;
1919
+ var tag = config.blockTag;
1920
+ var attributes = config.blockAttributes;
1921
+ var closeBlock = '</' + tag + '>';
1922
+ var openBlock = '<' + tag;
1923
+ var attr, i, l, line;
1924
+
1925
+ for ( attr in attributes ) {
1926
+ openBlock += ' ' + attr + '="' +
1927
+ escapeHTMLFragement( attributes[ attr ] ) +
1928
+ '"';
1929
+ }
1930
+ openBlock += '>';
1931
+
1932
+ for ( i = 0, l = lines.length; i < l; i += 1 ) {
1933
+ line = lines[i];
1934
+ line = escapeHTMLFragement( line ).replace( / (?= )/g, '&nbsp;' );
1935
+ // Wrap each line in <div></div>
1936
+ lines[i] = openBlock + ( line || '<BR>' ) + closeBlock;
1937
+ }
1938
+ return this.insertHTML( lines.join( '' ), isPaste );
1939
+ };
1940
+
1941
+ // --- Formatting ---
1942
+
1943
+ var command = function ( method, arg, arg2 ) {
1944
+ return function () {
1945
+ this[ method ]( arg, arg2 );
1946
+ return this.focus();
1947
+ };
1948
+ };
1949
+
1950
+ proto.addStyles = function ( styles ) {
1951
+ if ( styles ) {
1952
+ var head = this._doc.documentElement.firstChild,
1953
+ style = this.createElement( 'STYLE', {
1954
+ type: 'text/css'
1955
+ });
1956
+ style.appendChild( this._doc.createTextNode( styles ) );
1957
+ head.appendChild( style );
1958
+ }
1959
+ return this;
1960
+ };
1961
+
1962
+ proto.bold = command( 'changeFormat', { tag: 'B' } );
1963
+ proto.italic = command( 'changeFormat', { tag: 'I' } );
1964
+ proto.underline = command( 'changeFormat', { tag: 'U' } );
1965
+ proto.strikethrough = command( 'changeFormat', { tag: 'S' } );
1966
+ proto.subscript = command( 'changeFormat', { tag: 'SUB' }, { tag: 'SUP' } );
1967
+ proto.superscript = command( 'changeFormat', { tag: 'SUP' }, { tag: 'SUB' } );
1968
+
1969
+ proto.removeBold = command( 'changeFormat', null, { tag: 'B' } );
1970
+ proto.removeItalic = command( 'changeFormat', null, { tag: 'I' } );
1971
+ proto.removeUnderline = command( 'changeFormat', null, { tag: 'U' } );
1972
+ proto.removeStrikethrough = command( 'changeFormat', null, { tag: 'S' } );
1973
+ proto.removeSubscript = command( 'changeFormat', null, { tag: 'SUB' } );
1974
+ proto.removeSuperscript = command( 'changeFormat', null, { tag: 'SUP' } );
1975
+
1976
+ proto.makeLink = function ( url, attributes ) {
1977
+ var range = this.getSelection();
1978
+ if ( range.collapsed ) {
1979
+ var protocolEnd = url.indexOf( ':' ) + 1;
1980
+ if ( protocolEnd ) {
1981
+ while ( url[ protocolEnd ] === '/' ) { protocolEnd += 1; }
1982
+ }
1983
+ insertNodeInRange(
1984
+ range,
1985
+ this._doc.createTextNode( url.slice( protocolEnd ) )
1986
+ );
1987
+ }
1988
+ attributes = mergeObjects(
1989
+ mergeObjects({
1990
+ href: url
1991
+ }, attributes, true ),
1992
+ this._config.tagAttributes.a,
1993
+ false
1994
+ );
1995
+
1996
+ this.changeFormat({
1997
+ tag: 'A',
1998
+ attributes: attributes
1999
+ }, {
2000
+ tag: 'A'
2001
+ }, range );
2002
+ return this.focus();
2003
+ };
2004
+ proto.removeLink = function () {
2005
+ this.changeFormat( null, {
2006
+ tag: 'A'
2007
+ }, this.getSelection(), true );
2008
+ return this.focus();
2009
+ };
2010
+
2011
+ proto.setFontFace = function ( name ) {
2012
+ this.changeFormat( name ? {
2013
+ tag: 'SPAN',
2014
+ attributes: {
2015
+ 'class': FONT_FAMILY_CLASS,
2016
+ style: 'font-family: ' + name + ', sans-serif;'
2017
+ }
2018
+ } : null, {
2019
+ tag: 'SPAN',
2020
+ attributes: { 'class': FONT_FAMILY_CLASS }
2021
+ });
2022
+ return this.focus();
2023
+ };
2024
+ proto.setFontSize = function ( size ) {
2025
+ this.changeFormat( size ? {
2026
+ tag: 'SPAN',
2027
+ attributes: {
2028
+ 'class': FONT_SIZE_CLASS,
2029
+ style: 'font-size: ' +
2030
+ ( typeof size === 'number' ? size + 'px' : size )
2031
+ }
2032
+ } : null, {
2033
+ tag: 'SPAN',
2034
+ attributes: { 'class': FONT_SIZE_CLASS }
2035
+ });
2036
+ return this.focus();
2037
+ };
2038
+
2039
+ proto.setTextColour = function ( colour ) {
2040
+ this.changeFormat( colour ? {
2041
+ tag: 'SPAN',
2042
+ attributes: {
2043
+ 'class': COLOUR_CLASS,
2044
+ style: 'color:' + colour
2045
+ }
2046
+ } : null, {
2047
+ tag: 'SPAN',
2048
+ attributes: { 'class': COLOUR_CLASS }
2049
+ });
2050
+ return this.focus();
2051
+ };
2052
+
2053
+ proto.setHighlightColour = function ( colour ) {
2054
+ this.changeFormat( colour ? {
2055
+ tag: 'SPAN',
2056
+ attributes: {
2057
+ 'class': HIGHLIGHT_CLASS,
2058
+ style: 'background-color:' + colour
2059
+ }
2060
+ } : colour, {
2061
+ tag: 'SPAN',
2062
+ attributes: { 'class': HIGHLIGHT_CLASS }
2063
+ });
2064
+ return this.focus();
2065
+ };
2066
+
2067
+ proto.setTextAlignment = function ( alignment ) {
2068
+ this.forEachBlock( function ( block ) {
2069
+ var className = block.className
2070
+ .split( /\s+/ )
2071
+ .filter( function ( klass ) {
2072
+ return !!klass && !/^align/.test( klass );
2073
+ })
2074
+ .join( ' ' );
2075
+ if ( alignment ) {
2076
+ block.className = className + ' align-' + alignment;
2077
+ block.style.textAlign = alignment;
2078
+ } else {
2079
+ block.className = className;
2080
+ block.style.textAlign = '';
2081
+ }
2082
+ }, true );
2083
+ return this.focus();
2084
+ };
2085
+
2086
+ proto.setTextDirection = function ( direction ) {
2087
+ this.forEachBlock( function ( block ) {
2088
+ if ( direction ) {
2089
+ block.dir = direction;
2090
+ } else {
2091
+ block.removeAttribute( 'dir' );
2092
+ }
2093
+ }, true );
2094
+ return this.focus();
2095
+ };
2096
+
2097
+ function removeFormatting ( self, root, clean ) {
2098
+ var node, next;
2099
+ for ( node = root.firstChild; node; node = next ) {
2100
+ next = node.nextSibling;
2101
+ if ( isInline( node ) ) {
2102
+ if ( node.nodeType === TEXT_NODE || node.nodeName === 'BR' || node.nodeName === 'IMG' ) {
2103
+ clean.appendChild( node );
2104
+ continue;
2105
+ }
2106
+ } else if ( isBlock( node ) ) {
2107
+ clean.appendChild( self.createDefaultBlock([
2108
+ removeFormatting(
2109
+ self, node, self._doc.createDocumentFragment() )
2110
+ ]));
2111
+ continue;
2112
+ }
2113
+ removeFormatting( self, node, clean );
2114
+ }
2115
+ return clean;
2116
+ }
2117
+
2118
+ proto.removeAllFormatting = function ( range ) {
2119
+ if ( !range && !( range = this.getSelection() ) || range.collapsed ) {
2120
+ return this;
2121
+ }
2122
+
2123
+ var root = this._root;
2124
+ var stopNode = range.commonAncestorContainer;
2125
+ while ( stopNode && !isBlock( stopNode ) ) {
2126
+ stopNode = stopNode.parentNode;
2127
+ }
2128
+ if ( !stopNode ) {
2129
+ expandRangeToBlockBoundaries( range, root );
2130
+ stopNode = root;
2131
+ }
2132
+ if ( stopNode.nodeType === TEXT_NODE ) {
2133
+ return this;
2134
+ }
2135
+
2136
+ // Record undo point
2137
+ this.saveUndoState( range );
2138
+
2139
+ // Avoid splitting where we're already at edges.
2140
+ moveRangeBoundariesUpTree( range, stopNode, stopNode, root );
2141
+
2142
+ // Split the selection up to the block, or if whole selection in same
2143
+ // block, expand range boundaries to ends of block and split up to root.
2144
+ var doc = stopNode.ownerDocument;
2145
+ var startContainer = range.startContainer;
2146
+ var startOffset = range.startOffset;
2147
+ var endContainer = range.endContainer;
2148
+ var endOffset = range.endOffset;
2149
+
2150
+ // Split end point first to avoid problems when end and start
2151
+ // in same container.
2152
+ var formattedNodes = doc.createDocumentFragment();
2153
+ var cleanNodes = doc.createDocumentFragment();
2154
+ var nodeAfterSplit = split( endContainer, endOffset, stopNode, root );
2155
+ var nodeInSplit = split( startContainer, startOffset, stopNode, root );
2156
+ var nextNode, childNodes;
2157
+
2158
+ // Then replace contents in split with a cleaned version of the same:
2159
+ // blocks become default blocks, text and leaf nodes survive, everything
2160
+ // else is obliterated.
2161
+ while ( nodeInSplit !== nodeAfterSplit ) {
2162
+ nextNode = nodeInSplit.nextSibling;
2163
+ formattedNodes.appendChild( nodeInSplit );
2164
+ nodeInSplit = nextNode;
2165
+ }
2166
+ removeFormatting( this, formattedNodes, cleanNodes );
2167
+ cleanNodes.normalize();
2168
+ nodeInSplit = cleanNodes.firstChild;
2169
+ nextNode = cleanNodes.lastChild;
2170
+
2171
+ // Restore selection
2172
+ childNodes = stopNode.childNodes;
2173
+ if ( nodeInSplit ) {
2174
+ stopNode.insertBefore( cleanNodes, nodeAfterSplit );
2175
+ startOffset = indexOf.call( childNodes, nodeInSplit );
2176
+ endOffset = indexOf.call( childNodes, nextNode ) + 1;
2177
+ } else {
2178
+ startOffset = indexOf.call( childNodes, nodeAfterSplit );
2179
+ endOffset = startOffset;
2180
+ }
2181
+
2182
+ // Merge text nodes at edges, if possible
2183
+ range.setStart( stopNode, startOffset );
2184
+ range.setEnd( stopNode, endOffset );
2185
+ mergeInlines( stopNode, range );
2186
+
2187
+ // And move back down the tree
2188
+ moveRangeBoundariesDownTree( range );
2189
+
2190
+ this.setSelection( range );
2191
+ this._updatePath( range, true );
2192
+
2193
+ return this.focus();
2194
+ };
2195
+
2196
+ proto.increaseQuoteLevel = command( 'modifyBlocks', increaseBlockQuoteLevel );
2197
+ proto.decreaseQuoteLevel = command( 'modifyBlocks', decreaseBlockQuoteLevel );
2198
+
2199
+ proto.makeUnorderedList = command( 'modifyBlocks', makeUnorderedList );
2200
+ proto.makeOrderedList = command( 'modifyBlocks', makeOrderedList );
2201
+ proto.removeList = command( 'modifyBlocks', removeList );