/** nicImageUploadGT (Image + Upload + Lightbox support) -- example image uploads integrated with wiki-like site CMS */ /* START CONFIG */ var nicImageUploadGTOptions = { buttons: { 'image': {name: __('Add Image'), type: 'nicImageUploadGTButton', tags: ['IMG']} } }; /* END CONFIG */ var nicImageUploadGTButton = nicEditorAdvancedButton.extend({ addPane: function() { this.im = (this.selElm || this.ne.selectedInstance.selElm()).parentTag('IMG'); var s, params = this.parseParams(this.im); this.addForm({ '': {type: 'title', txt: __('Add/Edit Image')}, 'src': {type: 'text', txt: __('URL or Name'), style: {width: '150px'}}, 'upload': {type: 'container', txt: __('Or upload')}, 'href': {type: 'text', txt: __('Hyperlink'), style: {width: '150px'}}, 'size': {type: 'container', txt: __('Max Size')}, 'align': {type: 'select', txt: __('Align'), options: {'': __('Inline'), floatleft: __('Left'), floatright: __('Right')}}, 'alt': {type: 'text', txt: __('Popup text'), style: {width: '150px'}} }, params); this.hinter = new SimpleAutocomplete(this.inputs['src'], this.gtLoadData.closure(this), { emptyText: false, allowHTML: true }); s = this.inputs['href'].parentNode; new bkElement('br').appendTo(s); this.inputs['newwindow'] = new bkElement('input').setAttributes({type: 'checkbox', id: 'newwindow', checked: 1 && params.newwindow}).appendTo(s); new bkElement('label').setAttributes({htmlFor: 'newwindow'}).setContent(__('Open in new window')).appendTo(s); var self = this; s = this.inputs['upload']; this.inputs['fileName'] = new bkElement('input').setStyle({width: '150px', height: '20px'}).setAttributes({type: 'button', value: __('Select file')}).appendTo(s); this.inputs['fileName'].addEvent('click', function() { self.inputs['file'].click(); }); this.inputs['file'] = new bkElement('input').setStyle({ width: '150px', position: 'absolute', left: '0', top: '-100px' }).setAttributes({type: 'file', size: 5}).appendTo(s); this.inputs['file'].addEvent('change', this.onFileChange.closure(this)); new bkElement('br').appendTo(s); this.inputs['progress'] = new bkElement('progress') .setStyle({ width: '100%', display: 'none' }) .setAttributes('max', 100) .appendTo(s); s = this.inputs['size']; this.inputs['width'] = new bkElement('input').setAttributes({type: 'text', size: 5, value: params.width||''}).appendTo(s); s.appendChild(document.createTextNode(' x ')); this.inputs['height'] = new bkElement('input').setAttributes({type: 'text', size: 5, value: params.height||''}).appendTo(s); }, onFileChange: function() { this.inputs['src'].value = ''; this.inputs['fileName'].value = this.inputs['file'].files[0].name; }, checkNodes: function(e) { var r = nicEditorAdvancedButton.prototype.checkNodes.apply(this, [e]); this.selElm = r ? e : null; return r; }, parseParams: function(elm) { var r = { getAttribute: function(n) { return this[n]; } }; if (!elm) return r; if (elm.parentNode.nodeName == 'A') { r.href = elm.parentNode.href; if (r.href.substr(0, GT.domain.length+10) == GT.domain+'/file.php?' || r.href.substr(0, 9) == 'file.php?') { // Clear lightbox link r.href = ''; } if (elm.parentNode.target == '_blank') { r.newwindow = true; } } else { r.href = '-'; } r.align = elm.className; var abs = elm.src.substr(0, GT.domain.length+10) == GT.domain+'/file.php?'; if (abs || elm.src.substr(0, 9) == 'file.php?') { var id, p, m = elm.src.substr(abs ? GT.domain.length+10 : 9).split('&'); for (var i = 0; i < m.length; i++) { p = m[i].split('=', 2); if (p[0] == 'id') { id = p[1]; } else if (p[0] == 'w') { r.width = p[1]; } else if (p[0] == 'h') { r.height = p[1]; } } r.src = '#'+id+' - '+elm.title; } else { r.src = elm.src; r.width = elm.style.maxWidth.replace('px', ''); r.height = elm.style.maxHeight.replace('px', ''); } r.alt = elm.alt; return r; }, removePane: function() { if (this.hinter) { this.hinter.remove(); this.hinter = null; } nicEditorAdvancedButton.prototype.removePane.apply(this); }, gtLoadData: function(hint, value, more) { POST(GT.domain+'/api.php?action=listimgs&format=json', {value: value, more: more}, function(r){ try { hint.replaceItems(JSON.parse(r.responseText), more > 0); } catch(e) {} }); }, submit: function(e) { if (!this.inputs['src'].value && this.inputs['file'].files[0]) { // Upload the file, then continue from a callback this.uploadFile(); return false; } var src = this.inputs['src'].value; var gtId = /^#(\d+)(\s*-\s*)?(.*)/.exec(src); var alt = this.inputs['alt'].value; var style = {}; var w = this.inputs['width'].value; var h = this.inputs['height'].value; if (!/^[1-9]\d*$/.exec(w)) w = ''; if (!/^[1-9]\d*$/.exec(h)) h = ''; if (gtId && gtId[1]) { if (!alt) { alt = gtId[3]; } // Save relative path to the page text // FIXME This will work only for the same level pages, but OK src = 'file.php?action=thumb&id='+gtId[1]+'&w='+w+'&h='+h; } else if (/^https?:\/\/./.exec(src)) { if (w) style.maxWidth = w+'px'; if (h) style.maxHeight = h+'px'; } else { alert(__('To insert an image you must select uploaded file ID or enter the image URL!')); return false; } this.removePane(); if (!this.im) { var tmp = 'javascript:nicImTemp();'; this.ne.nicCommand("insertImage",tmp); this.im = this.findElm('IMG','src',tmp); } if (this.im) { var lnk = { href: this.inputs['href'].value, target: this.inputs['newwindow'].checked ? '_blank' : '', title: alt }; if (lnk.href.substr(0, GT.domain.length) == GT.domain) { var l = lnk.href.substr(GT.domain.length+1).replace(/^\/+/, ''); if (/^[a-z_]/.exec(l)) { lnk.href = l; } } if (!lnk.href.length) { if (gtId && gtId[1] && (w || h)) { // If link URL is not '-', add lightbox (relative path) lnk.href = 'file.php?action=thumb&id='+gtId[1]; lnk.target = '_blank'; lnk.rel = 'lightbox'; } else { lnk.href = '-'; } } var p = $BK(this.im.parentNode); if (p.nodeName != 'A' && lnk.href != '-') { p = $BK(document.createElement('A')); this.im.parentNode.insertBefore(p, this.im); p.appendChild(this.im); } if (p && p.nodeName == 'A') { if (lnk.href != '-') { p.setAttributes(lnk); } else { p.parentNode.appendChild(this.im); p.removeChild(parentNode); } } this.im.setStyle(style).setAttributes({ src: src, alt: alt, title: alt }) .className = this.inputs['align'].value; } }, uploadFile: function() { var file = this.inputs['file'].files[0]; if (!file || !file.type.match(/image.*/)) { alert(__("Only image files can be uploaded")); return; } this.inputs['file'].setStyle({display: 'none'}); this.setProgress(0); var fd = new FormData(); // https://hacks.mozilla.org/2011/01/how-to-develop-a-html5-image-uploader/ fd.append("e_file", file); fd.append("e_title", file.name); var self = this; var xhr = new XMLHttpRequest(); xhr.open("POST", GT.domain+'/file.php?action=save&format=json'); xhr.onload = function() { try { var res = JSON.parse(xhr.responseText); } catch(e) {} if (res && (res.file || res.duplicate)) { self.onUploaded(res); } else { alert(__('Failed to upload image') + (res && (res.exception || res.error) ? ': '+(res.exception || res.error) : '')); } }; xhr.onerror = function(e) { alert(__('Error uploading file')+': '+e); }; xhr.upload.onprogress = function(e) { self.setProgress(e.loaded / e.total); }; xhr.send(fd); }, onUploaded: function(r) { var f = r.file||r.duplicate; this.inputs['src'].value = '#'+f.id+' - '+f.title; this.submit(); }, setProgress: function(percent) { var p = this.inputs['progress']; p.setStyle({display: 'block'}); if(percent < .98) { p.value = percent; } else { p.removeAttribute('value'); } }, }); nicEditors.registerPlugin(nicPlugin,nicImageUploadGTOptions);