Ox.EditableContent = function(options, self) { self = self || {}; var that = Ox.Element({ element: options.type == 'div' ? '
' : '', tooltip: options.tooltip ? function(e) { return that.hasClass('OxEditableContentInput') ? '' : Ox.isString(options.tooltip) ? options.tooltip : options.tooltip(e); } : null }, self) .defaults({ clickLink: null, editable: true, editing: false, format: null, highlight: null, placeholder: '', replaceTags: {}, submitOnBlur: true, tags: null, tooltip: '', type: 'span', value: '' }) .options(options || {}) .update({ highlight: function() { !self.options.editing && self.$value.html(formatValue()); }, value: function() { !self.options.editing && self.$value.html(formatValue()); } }) .addClass('OxEditableContent') .on({ blur: self.options.submitOnBlur ? submit : blur, click: function(e) { var $target = $(e.target); if (!e.shiftKey && ($target.is('a') || ($target = $target.parents('a')).length)) { e.preventDefault(); if (self.options.clickLink) { e.target = $target[0]; self.options.clickLink(e); } else { document.location.href = $target.attr('href'); } } return false; }, keydown: function(e) { if (self.options.editing) { if (e.keyCode == 13 && self.options.type == 'span') { submit(); return false; } else if (e.keyCode == 27) { cancel(); return false; } setTimeout(function() { if (self.options.type == '') { that.css({padding: that.text() ? 0 : '0 2px'}); } else if (that.html().match(/

<\/div>$/)) { that.html( that.html().replace(/

<\/div>$/, '
') ) } //Ox.print('TEXT', that.text()) Ox.print('HTML', that.html()); }); } } }) .bindEvent({ doubleclick: edit }); self.options.value = self.options.value.toString(); that.html(formatValue()); function blur() { Ox.print('BLUR!') } function cancel() { if (self.options.editing) { Ox.print('CANCEL!') that.loseFocus(); self.options.editing = false; that.removeClass('OxEditableContentInput') .attr({contenteditable: false}) .html(formatValue()); that.triggerEvent('cancel', {value: self.options.value}); } } function edit() { if (self.options.editable && !self.options.editing) { var value = formatInputValue(); that.addClass('OxEditableContentInput') .removeClass('OxPlaceholder') .attr({contenteditable: true}); if (value) { that.text(value); } else { that.text(''); if (self.options.type == 'span') { that.css({padding: '0 2px'}); } } self.options.editing = true; that.gainFocus(); setTimeout(updateSelection, 50); } } function formatInputValue() { return Ox.decodeHTMLEntities( self.options.type == 'span' ? self.options.value : self.options.value.replace(//g, '\n\n') ); } function formatValue() { var value = self.options.value; that.removeClass('OxPlaceholder'); if (self.options.value === '' && self.options.placeholder) { value = self.options.placeholder; that.addClass('OxPlaceholder'); } else if (self.options.format) { value = self.options.format(self.options.value); } if (self.options.highlight) { value = Ox.highlight( value, self.options.highlight, 'OxHighlight', true ); } return value; } function parseValue() { var value = Ox.clean( that.text().replace(/\n\n+/g, '\0') ).replace(/\0/g, '\n\n').trim(); return ( self.options.type == 'span' ? Ox.encodeHTMLEntities(value) : Ox.sanitizeHTML(value, self.options.tags, self.options.replaceTags) ); } function setCSS() { } function submit() { if (self.options.editing) { Ox.print('SUBMIT!') that.loseFocus(); self.options.editing = false; self.options.value = that.text(); that.removeClass('OxEditableContentInput') .attr({contenteditable: false}) .html(formatValue()); if (self.options.type == 'span') { that.css({padding: 0}); } that.triggerEvent('submit', {value: self.options.value}); } } function updateSelection() { var range, selection; that.$element[0].focus(); selection = window.getSelection(); selection.removeAllRanges(); range = document.createRange(); range.selectNodeContents(that.$element[0]); selection.addRange(range); if (self.options.type == 'div') { setTimeout(function() { selection.collapseToEnd(); }, 0); } } return that; };