function _iframeDoc(iframe) { iframe = _get(iframe); return iframe.contentDocument || iframe.contentWindow.document; } var html, _direction = ''; if ((html = document.getElementsByTagName('html'))) { _direction = html[0].dir; } function _getInitHtml(options) { var themesPath = _undef(options.themesPath, ''), bodyClass = options.bodyClass, cssPath = options.cssPath, jsPath = options.jsPath, cssData = options.cssData; var arr = [ (_direction === '' ? '' : ''), '', //'', ''); if (!_isArray(cssPath)) { cssPath = [cssPath]; } if (_inArray(K.basePath+'themes/app.css', cssPath) < 0) { cssPath.push(K.basePath+'themes/app.css'); } _each(cssPath, function(i, path) { if (path) { arr.push(''); } }); if (cssData) { arr.push(''); } arr.push(''); if (!_isArray(jsPath)) { jsPath = [jsPath]; } _each(jsPath, function(i, path) { if (path) { arr.push(''); } }); arr.push(''); return arr.join('\n'); } function _elementVal(knode, val) { if (knode.hasVal()) { if (val === undefined) { var html = knode.val(); // 去除内容为空的p标签 // https://github.com/kindsoft/kindeditor/pull/52 html = html.replace(/(<(?:p|p\s[^>]*)>) *(<\/p>)/ig, ''); return html; } return knode.val(val); } return knode.html(val); } // create KEdit class function KEdit(options) { this.init(options); } _extend(KEdit, KWidget, { init : function(options) { var self = this; KEdit.parent.init.call(self, options); self.srcElement = K(options.srcElement); self.div.addClass('ke-edit'); self.designMode = _undef(options.designMode, true); self.beforeGetHtml = options.beforeGetHtml; self.beforeSetHtml = options.beforeSetHtml; self.afterSetHtml = options.afterSetHtml; var isDocumentDomain = location.protocol != 'res:' && location.host.replace(/:\d+/, '') !== document.domain, srcScript = ('document.open();' + (isDocumentDomain ? 'document.domain="' + document.domain + '";' : '') + 'document.close();'), iframeSrc = _IE ? ' src="javascript:void(function(){' + encodeURIComponent(srcScript) + '}())"' : ''; self.iframe = K('').css('width', '100%'); self.textarea = K('').css('width', '100%'); self.tabIndex = isNaN(parseInt(options.tabIndex, 10)) ? self.srcElement.attr('tabindex') : parseInt(options.tabIndex, 10); self.iframe.attr('tabindex', self.tabIndex); self.textarea.attr('tabindex', self.tabIndex); if (self.width) { self.setWidth(self.width); } if (self.height) { self.setHeight(self.height); } if (self.designMode) { self.textarea.hide(); } else { self.iframe.hide(); } function ready() { var doc = _iframeDoc(self.iframe); doc.open(); if (isDocumentDomain) { doc.domain = document.domain; } doc.write(_getInitHtml(self.options)); doc.close(); self.win = self.iframe[0].contentWindow; self.doc = doc; var cmd = _cmd(doc); // add events self.afterChange(function(e) { cmd.selection(); }); // [WEBKIT] select an image after click the image if (_WEBKIT) { K(doc).click(function(e) { if (K(e.target).name === 'img') { cmd.selection(true); cmd.range.selectNode(e.target); cmd.select(); } }); } if (_IE) { // Fix bug: https://github.com/kindsoft/kindeditor/issues/53 self._mousedownHandler = function() { var newRange = cmd.range.cloneRange(); newRange.shrink(); if (newRange.isControl()) { self.blur(); } }; K(document).mousedown(self._mousedownHandler); // [IE] bug: clear iframe when press backspase key K(doc).keydown(function(e) { if (e.which == 8) { cmd.selection(); var rng = cmd.range; if (rng.isControl()) { rng.collapse(true); K(rng.startContainer.childNodes[rng.startOffset]).remove(); e.preventDefault(); } } }); } self.cmd = cmd; self.html(_elementVal(self.srcElement)); if (_IE) { doc.body.disabled = true; doc.body.contentEditable = true; doc.body.removeAttribute('disabled'); } else { doc.designMode = 'on'; } if (options.afterCreate) { options.afterCreate.call(self); } } if (isDocumentDomain) { self.iframe.bind('load', function(e) { self.iframe.unbind('load'); if (_IE) { ready(); } else { setTimeout(ready, 0); } }); } self.div.append(self.iframe); self.div.append(self.textarea); self.srcElement.hide(); !isDocumentDomain && ready(); }, setWidth : function(val) { var self = this; val = _addUnit(val); self.width = val; self.div.css('width', val); return self; }, setHeight : function(val) { var self = this; val = _addUnit(val); self.height = val; self.div.css('height', val); self.iframe.css('height', val); // 校正IE6和IE7的textarea高度 if ((_IE && _V < 8) || _QUIRKS) { val = _addUnit(_removeUnit(val) - 2); } self.textarea.css('height', val); return self; }, remove : function() { var self = this, doc = self.doc; // remove events K(doc.body).unbind(); K(doc).unbind(); K(self.win).unbind(); if (self._mousedownHandler) { K(document).unbind('mousedown', self._mousedownHandler); } // remove elements _elementVal(self.srcElement, self.html()); self.srcElement.show(); // doc.write(''); self.iframe.unbind(); self.textarea.unbind(); KEdit.parent.remove.call(self); }, html : function(val, isFull) { var self = this, doc = self.doc; // design mode if (self.designMode) { var body = doc.body; // get if (val === undefined) { if (isFull) { val = '' + body.parentNode.innerHTML + ''; } else { val = body.innerHTML; } if (self.beforeGetHtml) { val = self.beforeGetHtml(val); } // bugfix: Firefox自动生成一个br标签 if (_GECKO && val == '
') { val = ''; } return val; } // set if (self.beforeSetHtml) { val = self.beforeSetHtml(val); } // IE9 Bugfix: https://github.com/kindsoft/kindeditor/issues/62 if (_IE && _V >= 9) { val = val.replace(/(<.*?checked=")checked(".*>)/ig, '$1$2'); } K(body).html(val); if (self.afterSetHtml) { self.afterSetHtml(); } return self; } // source mode if (val === undefined) { return self.textarea.val(); } self.textarea.val(val); return self; }, design : function(bool) { var self = this, val; if (bool === undefined ? !self.designMode : bool) { if (!self.designMode) { val = self.html(); self.designMode = true; self.textarea.hide(); self.html(val); // cache var iframe = self.iframe; var height = _removeUnit(self.height); iframe.height(height - 2); iframe.show(); // safari iframe scrollbar hack setTimeout(function() { iframe.height(height); }, 0); } } else { if (self.designMode) { val = self.html(); self.designMode = false; self.html(val); self.iframe.hide(); self.textarea.show(); } } return self.focus(); }, focus : function() { var self = this; self.designMode ? self.win.focus() : self.textarea[0].focus(); return self; }, blur : function() { var self = this; if (_IE) { var input = K('', self.div); self.div.append(input); input[0].focus(); input.remove(); } else { self.designMode ? self.win.blur() : self.textarea[0].blur(); } return self; }, afterChange : function(fn) { var self = this, doc = self.doc, body = doc.body; K(doc).keyup(function(e) { if (!e.ctrlKey && !e.altKey && _CHANGE_KEY_MAP[e.which]) { fn(e); } }); K(doc).mouseup(fn).contextmenu(fn); K(self.win).blur(fn); function timeoutHandler(e) { setTimeout(function() { fn(e); }, 1); } K(body).bind('paste', timeoutHandler); K(body).bind('cut', timeoutHandler); return self; } }); function _edit(options) { return new KEdit(options); } K.EditClass = KEdit; K.edit = _edit; K.iframeDoc = _iframeDoc;