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
|
|||
22 | if ( |
||
23 | typeof window.getSelection().anchorNode === 'undefined' || |
||
24 | window.getSelection().anchorNode === null |
||
25 | ) |
||
26 | return |
||
0 ignored issues
–
show
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 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
|
|||
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
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 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
|
|||
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
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 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
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 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
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 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
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 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 |
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.