Skip to content

Commit 0719e3e

Browse files
committed
2 parents 5c5d5fb + 9bcf05b commit 0719e3e

File tree

1 file changed

+198
-0
lines changed

1 file changed

+198
-0
lines changed

modules/CodeSelector.js

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
/**
2+
* update by IWANABETHATGUY
3+
* this is a easy finish for the codeSelector you need to register before use it..
4+
* 这是第一次pullrequest ,如果做得不好的地方请多多指教,做了一个代码选择模块,
5+
* 什么代码规范也不太会写,写的不好的地方请多多包涵,后面的样例会慢慢更新,readme 明天更新吧,
6+
* 今天刚把git配置好
7+
*/
8+
export class CodeSelector {
9+
constructor(quill, options) {
10+
this.quill = quill
11+
this.options = options
12+
this.container = quill.options.container
13+
this.codeBlockList = this.container.getElementsByClassName('ql-syntax')
14+
this.codeSelectList = []
15+
this.languages = ['asp', 'javascript', 'html', 'css', 'scss', 'sass', 'less', 'python', 'c++', 'java'].sort()
16+
this.quill.on('text-change', function (delta, olddelta, source) {
17+
for (let d in delta.ops) {
18+
if (delta['ops'][d].hasOwnProperty('attributes')) {
19+
if (delta['ops'][d]['attributes'].hasOwnProperty('code-block')) {
20+
if (delta['ops'][d]['attributes']['code-block']) {
21+
this.onAddCodeBlock()
22+
} else {
23+
this.onAddCodeBlock()
24+
this.onEnter()
25+
}
26+
}
27+
} else if (delta['ops'][d].hasOwnProperty('insert')) {
28+
if (delta['ops'][d]['insert'] === "\n") {
29+
this.onAddCodeBlock()
30+
}
31+
} else if (delta['ops'][d].hasOwnProperty('delete') && delta['ops'][d]['delete'] === 1) {
32+
this.onAddCodeBlock()
33+
}
34+
}
35+
36+
}.bind(this))
37+
}
38+
onEnter() {
39+
for (let i = 0, len = Math.min(this.codeBlockList.length, this.codeSelectList.length); i < len; i++) {
40+
this.codeSelectList[i].style.top = this.codeBlockList[i].offsetTop + 'px'
41+
}
42+
43+
}
44+
onRemoveCodeBlock() {
45+
let i = 0
46+
while (i < this.codeSelectList.length) {
47+
if (!this.codeBlockList[i] || this.codeBlockList[i].offsetTop !== parseInt(this.codeSelectList[i].style.top, 10)) {
48+
this.container.removeChild(this.codeSelectList[i])
49+
this.codeSelectList.splice(i, 1)
50+
}
51+
i++
52+
}
53+
}
54+
onAddCodeBlock() {
55+
if (this.codeBlockList.length > this.codeSelectList.length) {
56+
for (let i = 0, len = this.codeBlockList.length; i < len; i++) {
57+
if (!this.codeSelectList[i] || this.codeBlockList[i].offsetTop !== parseInt(this.codeSelectList[i].style.top, 10)) {
58+
let item = this.codeBlockList[i],
59+
cur = new CodeSelectBlock(item.offsetTop, item.offsetLeft, item.offsetWidth, this.languages)
60+
this.codeSelectList.splice(i, 0, cur)
61+
this.container.appendChild(cur)
62+
break
63+
}
64+
}
65+
} else if (this.codeBlockList.length < this.codeSelectList.length) {
66+
this.onRemoveCodeBlock()
67+
}
68+
this.onEnter()
69+
}
70+
}
71+
class CodeSelectBlock {
72+
constructor(top, left, width, languages) {
73+
this.init(top, left, width, languages)
74+
this.initEvent()
75+
return this.container
76+
}
77+
init(top, left, width, languages) {
78+
//init style
79+
this.container = this.itemConstructor("div", {
80+
'position': 'absolute',
81+
'background-color': '#fff',
82+
'height': '30px',
83+
'width': '130px',
84+
'border': '1px solid #ccc',
85+
'box-sizing': 'border-box',
86+
'border-radius': '5px',
87+
'opacity': '1'
88+
}, 'code-type-container')
89+
this.list = this.itemConstructor('ul', {
90+
'width': '120px',
91+
'max-height': '200px',
92+
'position': 'absolute',
93+
'padding': '0',
94+
'text-align': 'center',
95+
'margin': '0',
96+
'box-sizing': 'border-box',
97+
'top': '30px',
98+
'overflow-y': 'scroll',
99+
'visibility': 'hidden'
100+
}, 'code-type-list')
101+
this.input = this.itemConstructor('input', {
102+
'height': '23px',
103+
'outline': 'none',
104+
'position': 'absolute',
105+
'top': '2.5px',
106+
'left': '0',
107+
'width': '100px',
108+
'border': 'none',
109+
})
110+
this.button = this.itemConstructor('button', {
111+
'position': 'absolute',
112+
'outline': 'none',
113+
'box-sizing': 'border-box',
114+
'background': 'none',
115+
'height': '30px',
116+
'top': '-1px',
117+
'width': '30px',
118+
'right': '-1px',
119+
'border': '1px solid #ccc',
120+
'border-radius': '5px'
121+
})
122+
this.button.innerHTML = "<span class=\"label\">▼</span>"
123+
this.container.appendChild(this.list)
124+
this.container.appendChild(this.input)
125+
this.container.appendChild(this.button)
126+
//130px is the width of this container
127+
this.extendStyle(this.container, {
128+
top: top + 'px',
129+
left: width + left - 130 + 'px'
130+
})
131+
//initData
132+
this.languages = languages
133+
for (let i = 0; i < this.languages.length; i++) {
134+
this.list.appendChild(this.itemConstructor('li', {
135+
'list-style': 'none',
136+
'height': '30px',
137+
'user-select': 'none',
138+
'cursor': 'pointer',
139+
'font-size': '13px'
140+
}, 'code-type-item', this.languages[i]))
141+
}
142+
}
143+
itemConstructor(tagName, style, className = "", innerHTML = "") {
144+
let item = document.createElement(tagName)
145+
item.className = className
146+
item.innerHTML = innerHTML
147+
this.extendStyle(item, style)
148+
return item
149+
}
150+
extendStyle(element, style) {
151+
for (let s in style) {
152+
element.style[s] = style[s]
153+
}
154+
}
155+
getValue() {
156+
return this.input.value
157+
}
158+
initEvent() {
159+
//input event
160+
this.input.addEventListener("blur", () => {
161+
this.list.style.visibility = "hidden"
162+
})
163+
164+
this.input.addEventListener("keyup", (e) => {
165+
if (e.keyCode === 13) {
166+
let filter_list = Array.prototype.filter.call(this.list.children, (item) => {
167+
return item.style.display === "block"
168+
})
169+
if (filter_list.length > 0 && filter_list[0].innerText.length > 0) {
170+
this.input.value = filter_list[0].innerText
171+
this.list.style.visibility = "hidden"
172+
}
173+
} else {
174+
this.list.style.visibility = "initial"
175+
Array.prototype.forEach.call(this.list.children, (item, index) => {
176+
if (new RegExp('^' + this.input.value + '.*').test(item.innerText)) {
177+
item.style.display = "block"
178+
} else {
179+
item.style.display = "none"
180+
}
181+
})
182+
}
183+
})
184+
this.button.onclick = () => {
185+
if (this.list.style.visibility === "hidden") {
186+
this.list.style.visibility = "initial"
187+
} else if (this.list.style.visibility === "initial") {
188+
this.list.style.visibility = "hidden"
189+
}
190+
}
191+
Array.prototype.forEach.call(this.list.children, (item) => {
192+
item.addEventListener("mousedown", () => {
193+
this.input.value = item.innerText
194+
this.list.style.visibility = "hidden"
195+
})
196+
})
197+
}
198+
}

0 commit comments

Comments
 (0)