tui_editor-rails 1.0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 );