Completed
Push — master ( 976119...75ac8d )
by greg
17s
created

public/abecms/scripts/utils/rich-textarea.js (7 issues)

1
/*global window, document, wysiwyg */
2
3
export default class RichTextarea {
4
  constructor(wrapper, color, link, image, smiley) {
5
    this.color = color
6
    this.link = link
7
    this.image = image
8
    this.smiley = smiley
9
    this.wrapper = wrapper
10
    this.textarea = wrapper.querySelector('.form-rich')
11
    this.btns = this.wrapper.querySelectorAll('.wysiwyg-toolbar-icon')
12
    this.selects = this.wrapper.querySelectorAll('.wysiwyg-dropdown-option')
13
14
    if (this.textarea.getAttribute('disabled') !== 'disabled') {
15
      this.textEditor = wysiwyg({
16
        element: this.textarea,
17
        onKeyUp: () => {
18
          this.setHTML()
19
        },
20
        hijackContextmenu: false,
21
        onSelection: (collapsed, rect, nodes, rightclick) => {
22
          if (
23
            typeof window.getSelection().anchorNode === 'undefined' ||
24
            window.getSelection().anchorNode === null
25
          )
26
            return
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
27
          var node = window.getSelection().anchorNode.parentNode
28
          if (node.tagName === 'A') {
29
            var parentTextarea = node.parentNode
30
            var i = 10
31
            while (!parentTextarea.classList.contains('wysiwyg-container')) {
32
              parentTextarea = parentTextarea.parentNode
33
            }
34
            this._action(
35
              {target: parentTextarea.querySelector('[data-popup="link"]')},
36
              node
37
            )
38
          }
39
        }
40
      })
41
42
      this._action = this.action.bind(this)
43
      Array.prototype.forEach.call(this.btns, btn => {
44
        btn.addEventListener('click', this._action)
45
      })
46
47
      Array.prototype.forEach.call(this.selects, select => {
48
        select.addEventListener('click', this.dropdownAction.bind(this))
49
      })
50
    }
51
  }
52
53
  setHTML() {
54
    this.textarea.innerHTML = this.textEditor.getHTML()
55
    var evt = document.createEvent('KeyboardEvent')
56
    evt.initKeyboardEvent(
57
      'keyup',
58
      true,
59
      true,
60
      window,
61
      0,
62
      0,
63
      0,
64
      0,
65
      0,
66
      'e'.charCodeAt(0)
67
    )
68
    this.textarea.dispatchEvent(evt)
69
  }
70
71
  _replaceSelectionWithHtml(html) {
72
    if (document.activeElement.getAttribute('contenteditable') != null) {
73
      var range
74
      if (window.getSelection && window.getSelection().getRangeAt) {
75
        range = window.getSelection().getRangeAt(0)
76
        range.deleteContents()
77
        var div = document.createElement('div')
78
        div.innerHTML = html
79
        var frag = document.createDocumentFragment(),
80
          child
81
        while ((child = div.firstChild)) {
82
          frag.appendChild(child)
83
        }
84
        range.insertNode(frag)
85
      } else if (document.selection && document.selection.createRange) {
86
        range = document.selection.createRange()
87
        html = node.nodeType == 3 ? node.data : node.outerHTML
88
        range.pasteHTML(html)
89
      }
90
    } else {
91
      this.wrapper.querySelector('[contenteditable]').focus()
92
      this._replaceSelectionWithHtml(html)
93
    }
94
  }
95
96
  dropdownAction(e) {
97
    var newValue = e.target
98
      .getAttribute('data-regexp')
99
      .replace('$1', window.getSelection().toString())
100
    this._replaceSelectionWithHtml(newValue)
101
    this.setHTML()
102
  }
103
104
  action(e, selection = null) {
105
    this.el = e.target
106
    if (this.el.tagName.toLowerCase() === 'span') this.el = this.el.parentNode
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
107
108
    this.action = this.el.getAttribute('data-action')
109
    this.popup = this.el.getAttribute('data-popup')
110
    this.param = this.el.getAttribute('data-param')
111
    if (typeof this.popup !== 'undefined' && this.popup !== null) {
112
      var off
113
      switch (this.popup) {
0 ignored issues
show
As per coding-style, switch statements should have a default case.
Loading history...
114
        case 'color':
115
          off = this.color.onColor(color => {
116
            if (color !== null) {
117
              this.textEditor[this.action](color)
118
              this.setHTML()
119
            }
120
            off()
121
          })
122
          this.color.show(this.el)
123
          break
124
        case 'link':
125
          var html = this.textEditor.getHTML()
126
          var currentSelection = null
127
          if (selection != null) currentSelection = selection.outerHTML
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
128
          else
129
            this._replaceSelectionWithHtml(
130
              `<a href="[LINK]" target="[TARGET]" rel="[REL]">${window
131
                .getSelection()
132
                .toString()}</a>`
133
            )
134
          off = this.link.onLink(obj => {
135
            if (obj.link !== null) {
136
              if (currentSelection != null) {
137
                this.textEditor.setHTML(
138
                  this.textEditor
139
                    .getHTML()
140
                    .replace(
141
                      currentSelection,
142
                      `<a href="[LINK]" target="[TARGET]" rel="[REL]">${selection.innerHTML}</a>`
143
                    )
144
                )
145
              }
146
              html = this.textEditor.getHTML().replace('[LINK]', obj.link)
147
              if (obj.target) html = html.replace(/\[TARGET\]/, '_blank')
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
148
              else html = html.replace(/target=\"\[TARGET\]\"/, '')
149
              if (obj.noFollow) html = html.replace(/\[REL\]/, 'nofollow')
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
150
              else html = html.replace(/rel=\"\[REL\]\"/, '')
151
              this.textEditor.setHTML(html)
152
            } else this.textEditor.setHTML(html)
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
153
            this.setHTML()
154
            off()
155
          })
156
          this.link.show(this.el)
157
          break
158
        case 'image':
159
          var html = this.textEditor.getHTML()
160
          this._replaceSelectionWithHtml(
161
            `${window.getSelection().toString()}[MEDIA]`
162
          )
163
          off = this.image.onImg(obj => {
164
            if (obj.image.indexOf('.mp4') > 0) {
165
              html = this.textEditor
166
                .getHTML()
167
                .replace(
168
                  '[MEDIA]',
169
                  `<video controls><source src="${obj.image}" type="video/mp4"></source></video>`
170
                )
171
            } else {
172
              html = this.textEditor
173
                .getHTML()
174
                .replace('[MEDIA]', `<img src="${obj.image}" >`)
175
            }
176
            this.textEditor.setHTML(html)
177
            this.setHTML()
178
            off()
179
          })
180
          this.image.show(this.el)
181
          break
182
        case 'smiley':
183
          var html = this.textEditor.getHTML()
184
          off = this.smiley.onSmiley(obj => {
185
            this._replaceSelectionWithHtml(obj)
186
            this.textEditor.setHTML(this.textEditor.getHTML())
187
            this.setHTML()
188
            off()
189
          })
190
          this.smiley.show(this.el)
191
          break
192
      }
193
    } else if (this.action === 'code') {
194
      this._replaceSelectionWithHtml(
195
        `<pre><code>${window.getSelection().toString()}</code></pre>`
196
      )
197
      this.textEditor.setHTML(this.textEditor.getHTML())
198
      this.setHTML()
199
    } else {
200
      this.textEditor[this.action](this.param)
201
      this.setHTML()
202
    }
203
  }
204
}
205