|
25 | 25 | if(window._pen_debug_mode_on || force) console.log('%cPEN DEBUGGER: %c' + message, 'font-family:arial,sans-serif;color:#1abf89;line-height:2em;', 'font-family:cursor,monospace;color:#333;'); |
26 | 26 | }; |
27 | 27 |
|
| 28 | + // shift a function |
| 29 | + utils.shift = function(key, fn, time) { |
| 30 | + time = time || 50; |
| 31 | + var queue = this['_shift_fn' + key], timeout = 'shift_timeout' + key, current; |
| 32 | + queue ? queue.concat([fn, time]) : (queue = [[fn, time]]); |
| 33 | + current = queue.pop(); |
| 34 | + clearTimeout(this[timeout]); |
| 35 | + this[timeout] = setTimeout(function() { |
| 36 | + current[0](); |
| 37 | + }, time); |
| 38 | + }; |
| 39 | + |
28 | 40 | // merge: make it easy to have a fallback |
29 | 41 | utils.merge = function(config) { |
30 | 42 |
|
31 | 43 | // default settings |
32 | 44 | var defaults = { |
33 | 45 | class: 'pen', |
34 | 46 | debug: false, |
35 | | - stay: true, |
| 47 | + stay: config.stay || !config.debug, |
36 | 48 | textarea: '<textarea name="content"></textarea>', |
37 | 49 | list: [ |
38 | 50 | 'blockquote', 'h2', 'h3', 'p', 'insertorderedlist', 'insertunorderedlist', 'inserthorizontalrule', |
|
65 | 77 | var editor = defaults.editor; |
66 | 78 |
|
67 | 79 | // set default class |
68 | | - var klass = editor.getAttribute('class'); |
69 | | - klass = /\bpen\b/.test(klass) ? klass : (klass ? (klass + ' ' + defaults.class) : defaults.class); |
70 | | - editor.setAttribute('class', klass); |
| 80 | + editor.classList.add(defaults.class); |
71 | 81 |
|
72 | 82 | // set contenteditable |
73 | 83 | var editable = editor.getAttribute('contenteditable'); |
|
115 | 125 |
|
116 | 126 | Pen.prototype.toolbar = function() { |
117 | 127 |
|
118 | | - var menu, that = this, icons = '', setpos; |
| 128 | + var that = this, icons = ''; |
119 | 129 |
|
120 | 130 | for(var i = 0, list = this.config.list; i < list.length; i++) { |
121 | 131 | var name = list[i], klass = 'pen-icon icon-' + name; |
122 | 132 | icons += '<i class="' + klass + '" data-action="' + name + '">' + (name.match(/^h[1-6]|p$/i) ? name.toUpperCase() : '') + '</i>'; |
123 | 133 | if((name === 'createlink')) icons += '<input class="pen-input" placeholder="http://" />'; |
124 | 134 | } |
125 | 135 |
|
126 | | - menu = doc.createElement('div'); |
| 136 | + var menu = doc.createElement('div'); |
127 | 137 | menu.setAttribute('class', this.config.class + '-menu pen-menu'); |
128 | 138 | menu.innerHTML = icons; |
129 | 139 | menu.style.display = 'none'; |
130 | 140 |
|
131 | 141 | doc.body.appendChild((this._menu = menu)); |
132 | 142 |
|
133 | | - setpos = function() { |
| 143 | + var setpos = function() { |
134 | 144 | if(menu.style.display === 'block') that.menu(); |
135 | | - } |
| 145 | + }; |
136 | 146 |
|
137 | 147 | // change menu offset when window resize / scroll |
138 | 148 | window.addEventListener('resize', setpos); |
139 | 149 | window.addEventListener('scroll', setpos); |
140 | 150 |
|
141 | | - // show toolbar on select |
142 | | - this.config.editor.addEventListener('mouseup', function(){ |
143 | | - var range = that._sel; |
144 | | - if(!range.isCollapsed) { |
145 | | - that._range = range.getRangeAt(0); |
146 | | - that.menu().highlight(); |
147 | | - } |
| 151 | + var editor = this.config.editor; |
| 152 | + var show = function() { |
| 153 | + var range = that._sel; |
| 154 | + if(!range.isCollapsed) { |
| 155 | + that._range = range.getRangeAt(0); |
| 156 | + that.menu().highlight(); |
| 157 | + } |
| 158 | + }; |
| 159 | + |
| 160 | + // show toolbar on mouse select |
| 161 | + editor.addEventListener('mouseup', show); |
| 162 | + |
| 163 | + // show toolbar on arrow key select |
| 164 | + editor.addEventListener('keyup', function(e) { |
| 165 | + var code = e.keyCode || e.which; |
| 166 | + if(code > 36 && code < 41) utils.shift('select_text', show, 200); |
148 | 167 | }); |
149 | 168 |
|
150 | 169 | // when to hide |
151 | | - this.config.editor.addEventListener('click', function() { |
| 170 | + editor.addEventListener('click', function() { |
152 | 171 | setTimeout(function() { |
153 | | - that._sel.isCollapsed ? |
154 | | - (that._menu.style.display = 'none') : |
155 | | - (that._menu.getElementsByTagName('input')[0].style.display = 'none'); |
| 172 | + that._sel.isCollapsed && (that._menu.style.display = 'none'); |
156 | 173 | }, 0); |
157 | 174 | }); |
158 | 175 |
|
|
207 | 224 | el.classList.remove('active'); |
208 | 225 | }); |
209 | 226 |
|
| 227 | + // display link input |
| 228 | + menu.querySelector('input').style.display = 'none'; |
| 229 | + |
210 | 230 | highlight = function(str) { |
211 | 231 | var selector = '.icon-' + str |
212 | 232 | , el = menu.querySelector(selector); |
|
215 | 235 |
|
216 | 236 | effects.forEach(function(item) { |
217 | 237 | var tag = item.nodeName.toLowerCase(); |
218 | | - if(tag === 'a') { |
219 | | - menu.querySelector('input').value = item.href; |
220 | | - return highlight('createlink'); |
| 238 | + switch(tag) { |
| 239 | + case 'a': return (menu.querySelector('input').value = item.href), highlight('createlink'); |
| 240 | + case 'i': return highlight('italic'); |
| 241 | + case 'u': return highlight('underline'); |
| 242 | + case 'b': return highlight('bold'); |
| 243 | + case 'ul': return highlight('insertunorderedlist'); |
| 244 | + case 'ol': return highlight('insertorderedlist'); |
| 245 | + case 'ol': return highlight('insertorderedlist'); |
| 246 | + case 'li': return highlight('indent'); |
| 247 | + default : highlight(tag); |
221 | 248 | } |
222 | | - if(tag === 'i') return highlight('italic'); |
223 | | - if(tag === 'u') return highlight('underline'); |
224 | | - if(tag === 'b') return highlight('bold'); |
225 | | - if(tag === 'ul') return highlight('insertunorderedlist'); |
226 | | - if(tag === 'ol') return highlight('insertorderedlist'); |
227 | | - if(tag === 'ol') return highlight('insertorderedlist'); |
228 | | - if(tag === 'li') return highlight('indent'); |
229 | | - return highlight(tag); |
230 | 249 | }); |
231 | 250 |
|
232 | 251 | return this; |
|
267 | 286 | } else { |
268 | 287 | if(this.config.debug) utils.log('can not find command function for name: ' + name + (value ? (', value: ' + value) : '')); |
269 | 288 | } |
270 | | - } |
| 289 | + }; |
271 | 290 |
|
272 | 291 | return this; |
273 | | - } |
| 292 | + }; |
274 | 293 |
|
275 | 294 | // show menu |
276 | 295 | Pen.prototype.menu = function() { |
|
291 | 310 | Pen.prototype.stay = function() { |
292 | 311 | !window.onbeforeunload && (window.onbeforeunload = function() { |
293 | 312 | return 'Are you going to leave here?'; |
294 | | - }) |
| 313 | + }); |
295 | 314 | }; |
296 | 315 |
|
297 | 316 | // a fallback for old browers |
|
0 commit comments