JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
f4b78451b15478c7f49c5e9725b490ad0f533514
[peach-html5-editor.git] / editor.coffee
1 # Copyright 2015 Jason Woofenden
2 # This file implements an WYSIWYG editor in the browser (no contenteditable)
3 #
4 # This program is free software: you can redistribute it and/or modify it under
5 # the terms of the GNU Affero General Public License as published by the Free
6 # Software Foundation, either version 3 of the License, or (at your option) any
7 # later version.
8 #
9 # This program is distributed in the hope that it will be useful, but WITHOUT
10 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 # FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
12 # details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 # encode text so it can be safely placed inside an html attribute
18 enc_attr_regex = new RegExp '(&)|(")|(\u00A0)', 'g'
19 enc_attr = (txt) ->
20         return txt.replace enc_attr_regex, (match, amp, quote) ->
21                 return '&amp;' if (amp)
22                 return '&quot;' if (quote)
23                 return '&nbsp;'
24
25 void_elements = {
26         area: true
27         base: true
28         br: true
29         col: true
30         embed: true
31         hr: true
32         img: true
33         input: true
34         keygen: true
35         link: true
36         meta: true
37         param: true
38         source: true
39         track: true
40         wbr: true
41 }
42 dom_to_html = (dom) ->
43         ret = ''
44         for el in dom
45                 switch el.type
46                         when wheic_parser.TYPE_TAG
47                                 ret += '<' + el.name
48                                 attr_keys = []
49                                 for k of el.attrs
50                                         attr_keys.unshift k
51                                 #attr_keys.sort()
52                                 for k in attr_keys
53                                         ret += " #{k}"
54                                         if el.attrs[k].length > 0
55                                                 ret += "=\"#{enc_attr el.attrs[k]}\""
56                                 ret += '>'
57                                 unless void_elements[el.name]
58                                         if el.children.length
59                                                 ret += dom_to_html el.children
60                                         ret += "</#{el.name}>"
61                         when wheic_parser.TYPE_TEXT
62                                 ret += el.text
63                         when wheic_parser.TYPE_COMMENT
64                                 ret += "<!--#{el.text}-->"
65                         when wheic_parser.TYPE_DOCTYPE
66                                 ret += "<!DOCTYPE #{el.name}"
67                                 if el.public_identifier? and el.public_identifier.length > 0
68                                         ret += " \"#{el.public_identifier}\""
69                                 if el.system_identifier? and el.system_identifier.length > 0
70                                         ret += " \"#{el.system_identifier}\""
71                                 ret += ">\n"
72         return ret
73
74 wysiwyg = (el, options = {}) ->
75         opt_fragment = options.fragment ? true
76         parser_opts = {}
77         if opt_fragment
78                 parser_opts.fragment = 'body'
79         editor_instance = dom: wheic_parser.parse(el.value, parser_opts)
80         # el.value = dom_to_html dom
81         return editor_instance
82
83 window.wheic = {
84         wysiwyg: wysiwyg
85         dom_to_html: dom_to_html
86 }
87
88 # test in browser: wheic(document.getElementsByTagName('textarea')[0])