Passed
Branch master (c2f34b)
by greg
02:22
created

EditorStructures.js ➔ ???   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 9
Bugs 9 Features 0
Metric Value
c 9
b 9
f 0
nc 2
nop 0
dl 0
loc 14
cc 2
rs 9.4285
1
/*global document */
2
3
import Nanoajax from 'nanoajax'
4
import qs from 'qs'
5
6
export default class EditorStructures {
7
  constructor() {
8
    var struc = document.querySelector('.structure-json')
9
    if(!(struc != null)) 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...
10
    this._ajax = Nanoajax.ajax
11
    this.datas = JSON.parse(struc.value)
12
    this.structureWrapper = document.querySelector('.structure-wrapper')
13
    this.folderName = document.querySelector('input.folder-name')
14
15
    var lvl_0 = this.createFolder('structure/', 0, '', 'structure', '')
16
17
    this.createStructure(lvl_0, this.datas)
18
    this.structureWrapper.appendChild(lvl_0)
19
    this.rebind()
20
  }
21
22
  createFolder(path, level, daddy, folderName, hidden = 'hidden') {
23
    var folder = document.createElement('div')
24
    if(hidden && hidden !== '') folder.classList.add(hidden)
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...
25
    folder.classList.add('structure-folder')
26
    folder.setAttribute('data-path', path.replace(/\/+$/, '') + '/')
27
    folder.setAttribute('data-level', level)
28
    folder.setAttribute('data-daddy', daddy)
29
30
    var span = document.createElement('span')
31
    var html = `<span class="glyphicon glyphicon-chevron-right arrow" aria-hidden="true"></span>
32
                ${folderName} 
33
                <div class="structure-tool">
34
                  <span class="glyphicon glyphicon-plus folder-action" data-init="0" data-action="add" aria-hidden="true"></span>`
35
    if(level !== 0) html += '<span class="glyphicon glyphicon-minus folder-action" data-init="0" data-action="remove" aria-hidden="true"></span>'
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...
36
    html += '</div>'
37
    span.innerHTML = html
38
    folder.appendChild(span)
39
40
    this.bindArrow(span.querySelector('.arrow'))
41
42
    return folder
43
  }
44
45
  toggleFolder(daddy, forceState = ''){
46
    var folders = daddy.querySelectorAll('[data-level="' + (parseInt(daddy.getAttribute('data-level')) + 1) + '"]')
47
    if(folders) {
48
      if(!daddy.classList.contains('open') || forceState === 'open'){
49
        daddy.classList.add('open')
50
        Array.prototype.forEach.call(folders, (folder) => {
51
          folder.classList.remove('hidden')
52
        })
53
      }
54
      else{
55
        daddy.classList.remove('open')
56
        Array.prototype.forEach.call(folders, (folder) => {
57
          folder.classList.add('hidden')
58
        })
59
      }
60
    }
61
  }
62
63
  bindArrow(arrow) {
64
    arrow.addEventListener('click', () => {
65
      this.toggleFolder(arrow.parentNode.parentNode)
66
    })
67
  }
68
69
  createStructure(daddy, datas) {
70
    Array.prototype.forEach.call(datas, (data) => {
71
      var folderName = data['path'].split('/')
72
      var folder = this.createFolder(
73
        data['path'],
74
        (parseInt(daddy.getAttribute('data-level')) + 1),
75
        daddy.getAttribute('data-daddy'),
76
        folderName[folderName.length - 1]
77
      )
78
      daddy.appendChild(folder)
79
80
      if(data.folders && data.folders.length > 0) this.createStructure(folder, data.folders)
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...
81
    })
82
  }
83
84
  add(element){
85
    this.toggleFolder(element, 'open')
86
    this.folderName.removeAttribute('disabled')
87
    this.folderName.focus()
88
    this.folderName.setAttribute('data-folder', `[data-path="${element.getAttribute('data-path')}"]`)
89
90
    var writeFolderName = (e) => {
91
      var value = this.folderName.value
92
      if(/^[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*$/.test(value)) this.folderName.classList.remove('error')
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...
93
      else this.folderName.classList.add('error')
94
      if(e.keyCode === 13) {
95
        if(/^[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*$/.test(value)){
96
          this.folderName.removeEventListener('keyup', writeFolderName)
97
          this.folderName.setAttribute('disabled', 1)
98
          var newFolderDaddy = document.querySelector(this.folderName.getAttribute('data-folder'))
99
          var path = newFolderDaddy.getAttribute('data-path').split('/')
100
          path.pop()
101
          path = path.concat(value).join('/')
0 ignored issues
show
Unused Code introduced by
The assignment to variable path seems to be never used. Consider removing it.
Loading history...
102
          var folder = this.createFolder(
103
            newFolderDaddy.getAttribute('data-path') + value,
104
            (parseInt(newFolderDaddy.getAttribute('data-level')) + 1),
105
            newFolderDaddy.getAttribute('data-daddy'),
106
            value,
107
            ''
108
          )
109
          newFolderDaddy.appendChild(folder)
110
          this.rebind()
111
          this.save(qs.stringify({type: 'add', folderPath: (newFolderDaddy.getAttribute('data-path') + value)}))
112
          this.folderName.value = ''
113
        }
114
      }
115
    }
116
117
    this.folderName.removeEventListener('keyup', writeFolderName)
118
    this.folderName.addEventListener('keyup', writeFolderName)
119
  }
120
121
  remove(element){
122
    this.save(qs.stringify({type: 'remove', folderPath: element.getAttribute('data-path')}))
123
    element.parentNode.removeChild(element)
124
  }
125
126
  save(body){
127
    this._ajax({url: '/abe/structure/', body: body, cors: true, method: 'post'}, () => {
128
129
    })
130
  }
131
132
  rebind(){
133
    var folderActions = document.querySelectorAll('.folder-action')
134
    Array.prototype.forEach.call(folderActions, (folderAction) => {
135
      if(parseInt(folderAction.getAttribute('data-init')) === 0){
136
        folderAction.setAttribute('data-init', 1)
137
        folderAction.addEventListener('click', (e) => {
138
          var target = e.target
139
          this[target.getAttribute('data-action')](target.parentNode.parentNode.parentNode)
140
        })
141
      }
142
    })  
143
  }
144
145
}
146