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

public/abecms/scripts/utils/rich-textarea.js (15 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) => {
0 ignored issues
show
The parameter rect is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
The parameter rightclick is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
The parameter nodes is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
The parameter collapsed is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
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
0 ignored issues
show
The variable i seems to be never used. Consider removing it.
Loading history...
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
0 ignored issues
show
The variable node seems to be never declared. If this is a global, consider adding a /** global: node */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
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()
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable html already seems to be declared on line 125. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
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()
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable html already seems to be declared on line 125. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
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