4561,5023c4561 < dom.setStyle(b, 'width', t.getStyle('width', 1)); < dom.setStyle(b, 'height', t.getStyle('height', 1)); < dom.setStyle(b, 'display', t.getStyle('display', 1)); < dom.setStyle(b, 'zIndex', parseInt(t.getStyle('zIndex', 1) || 0) - 1); < } < } < < }); < })(tinymce); < (function(tinymce) { < function trimNl(s) { < return s.replace(/[\n\r]+/g, ''); < }; < < // Shorten names < var is = tinymce.is, isIE = tinymce.isIE, each = tinymce.each; < < tinymce.create('tinymce.dom.Selection', { < Selection : function(dom, win, serializer) { < var t = this; < < t.dom = dom; < t.win = win; < t.serializer = serializer; < < // Add events < each([ < 'onBeforeSetContent', < 'onBeforeGetContent', < 'onSetContent', < 'onGetContent' < ], function(e) { < t[e] = new tinymce.util.Dispatcher(t); < }); < < // No W3C Range support < if (!t.win.getSelection) < t.tridentSel = new tinymce.dom.TridentSelection(t); < < // Prevent leaks < tinymce.addUnload(t.destroy, t); < }, < < getContent : function(s) { < var t = this, r = t.getRng(), e = t.dom.create("body"), se = t.getSel(), wb, wa, n; < < s = s || {}; < wb = wa = ''; < s.get = true; < s.format = s.format || 'html'; < t.onBeforeGetContent.dispatch(t, s); < < if (s.format == 'text') < return t.isCollapsed() ? '' : (r.text || (se.toString ? se.toString() : '')); < < if (r.cloneContents) { < n = r.cloneContents(); < < if (n) < e.appendChild(n); < } else if (is(r.item) || is(r.htmlText)) < e.innerHTML = r.item ? r.item(0).outerHTML : r.htmlText; < else < e.innerHTML = r.toString(); < < // Keep whitespace before and after < if (/^\s/.test(e.innerHTML)) < wb = ' '; < < if (/\s+$/.test(e.innerHTML)) < wa = ' '; < < s.getInner = true; < < s.content = t.isCollapsed() ? '' : wb + t.serializer.serialize(e, s) + wa; < t.onGetContent.dispatch(t, s); < < return s.content; < }, < < setContent : function(h, s) { < var t = this, r = t.getRng(), c, d = t.win.document; < < s = s || {format : 'html'}; < s.set = true; < h = s.content = t.dom.processHTML(h); < < // Dispatch before set content event < t.onBeforeSetContent.dispatch(t, s); < h = s.content; < < if (r.insertNode) { < // Make caret marker since insertNode places the caret in the beginning of text after insert < h += '_'; < < // Delete and insert new node < r.deleteContents(); < r.insertNode(t.getRng().createContextualFragment(h)); < < // Move to caret marker < c = t.dom.get('__caret'); < < // Make sure we wrap it compleatly, Opera fails with a simple select call < r = d.createRange(); < r.setStartBefore(c); < r.setEndAfter(c); < t.setRng(r); < < // Delete the marker, and hopefully the caret gets placed in the right location < // Removed this since it seems to remove   in FF and simply deleting it < // doesn't seem to affect the caret position in any browser < //d.execCommand('Delete', false, null); < < // Remove the caret position < t.dom.remove('__caret'); < } else { < if (r.item) { < // Delete content and get caret text selection < d.execCommand('Delete', false, null); < r = t.getRng(); < } < < r.pasteHTML(h); < } < < // Dispatch set content event < t.onSetContent.dispatch(t, s); < }, < < getStart : function() { < var t = this, r = t.getRng(), e; < < if (isIE) { < if (r.item) < return r.item(0); < < r = r.duplicate(); < r.collapse(1); < e = r.parentElement(); < < if (e && e.nodeName == 'BODY') < return e.firstChild; < < return e; < } else { < e = r.startContainer; < < if (e.nodeName == 'BODY') < return e.firstChild; < < return t.dom.getParent(e, '*'); < } < }, < < getEnd : function() { < var t = this, r = t.getRng(), e; < < if (isIE) { < if (r.item) < return r.item(0); < < r = r.duplicate(); < r.collapse(0); < e = r.parentElement(); < < if (e && e.nodeName == 'BODY') < return e.lastChild; < < return e; < } else { < e = r.endContainer; < < if (e.nodeName == 'BODY') < return e.lastChild; < < return t.dom.getParent(e, '*'); < } < }, < < getBookmark : function(si) { < var t = this, r = t.getRng(), tr, sx, sy, vp = t.dom.getViewPort(t.win), e, sp, bp, le, c = -0xFFFFFF, s, ro = t.dom.getRoot(), wb = 0, wa = 0, nv; < sx = vp.x; < sy = vp.y; < < // Simple bookmark fast but not as persistent < if (si == 'simple') < return {rng : r, scrollX : sx, scrollY : sy}; < < // Handle IE < if (isIE) { < // Control selection < if (r.item) { < e = r.item(0); < < each(t.dom.select(e.nodeName), function(n, i) { < if (e == n) { < sp = i; < return false; < } < }); < < return { < tag : e.nodeName, < index : sp, < scrollX : sx, < scrollY : sy < }; < } < < // Text selection < tr = t.dom.doc.body.createTextRange(); < tr.moveToElementText(ro); < tr.collapse(true); < bp = Math.abs(tr.move('character', c)); < < tr = r.duplicate(); < tr.collapse(true); < sp = Math.abs(tr.move('character', c)); < < tr = r.duplicate(); < tr.collapse(false); < le = Math.abs(tr.move('character', c)) - sp; < < return { < start : sp - bp, < length : le, < scrollX : sx, < scrollY : sy < }; < } < < // Handle W3C < e = t.getNode(); < s = t.getSel(); < < if (!s) < return null; < < // Image selection < if (e && e.nodeName == 'IMG') { < return { < scrollX : sx, < scrollY : sy < }; < } < < // Text selection < < function getPos(r, sn, en) { < var w = t.dom.doc.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {}; < < while ((n = w.nextNode()) != null) { < if (n == sn) < d.start = p; < < if (n == en) { < d.end = p; < return d; < } < < p += trimNl(n.nodeValue || '').length; < } < < return null; < }; < < // Caret or selection < if (s.anchorNode == s.focusNode && s.anchorOffset == s.focusOffset) { < e = getPos(ro, s.anchorNode, s.focusNode); < < if (!e) < return {scrollX : sx, scrollY : sy}; < < // Count whitespace before < trimNl(s.anchorNode.nodeValue || '').replace(/^\s+/, function(a) {wb = a.length;}); < < return { < start : Math.max(e.start + s.anchorOffset - wb, 0), < end : Math.max(e.end + s.focusOffset - wb, 0), < scrollX : sx, < scrollY : sy, < beg : s.anchorOffset - wb == 0 < }; < } else { < e = getPos(ro, r.startContainer, r.endContainer); < < // Count whitespace before start and end container < //(r.startContainer.nodeValue || '').replace(/^\s+/, function(a) {wb = a.length;}); < //(r.endContainer.nodeValue || '').replace(/^\s+/, function(a) {wa = a.length;}); < < if (!e) < return {scrollX : sx, scrollY : sy}; < < return { < start : Math.max(e.start + r.startOffset - wb, 0), < end : Math.max(e.end + r.endOffset - wa, 0), < scrollX : sx, < scrollY : sy, < beg : r.startOffset - wb == 0 < }; < } < }, < < moveToBookmark : function(b) { < var t = this, r = t.getRng(), s = t.getSel(), ro = t.dom.getRoot(), sd, nvl, nv; < < function getPos(r, sp, ep) { < var w = t.dom.doc.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {}, o, v, wa, wb; < < while ((n = w.nextNode()) != null) { < wa = wb = 0; < < nv = n.nodeValue || ''; < //nv.replace(/^\s+[^\s]/, function(a) {wb = a.length - 1;}); < //nv.replace(/[^\s]\s+$/, function(a) {wa = a.length - 1;}); < < nvl = trimNl(nv).length; < p += nvl; < < if (p >= sp && !d.startNode) { < o = sp - (p - nvl); < < // Fix for odd quirk in FF < if (b.beg && o >= nvl) < continue; < < d.startNode = n; < d.startOffset = o + wb; < } < < if (p >= ep) { < d.endNode = n; < d.endOffset = ep - (p - nvl) + wb; < return d; < } < } < < return null; < }; < < if (!b) < return false; < < t.win.scrollTo(b.scrollX, b.scrollY); < < // Handle explorer < if (isIE) { < // Handle simple < if (r = b.rng) { < try { < r.select(); < } catch (ex) { < // Ignore < } < < return true; < } < < t.win.focus(); < < // Handle control bookmark < if (b.tag) { < r = ro.createControlRange(); < < each(t.dom.select(b.tag), function(n, i) { < if (i == b.index) < r.addElement(n); < }); < } else { < // Try/catch needed since this operation breaks when TinyMCE is placed in hidden divs/tabs < try { < // Incorrect bookmark < if (b.start < 0) < return true; < < r = s.createRange(); < r.moveToElementText(ro); < r.collapse(true); < r.moveStart('character', b.start); < r.moveEnd('character', b.length); < } catch (ex2) { < return true; < } < } < < try { < r.select(); < } catch (ex) { < // Needed for some odd IE bug #1843306 < } < < return true; < } < < // Handle W3C < if (!s) < return false; < < // Handle simple < if (b.rng) { < s.removeAllRanges(); < s.addRange(b.rng); < } else { < if (is(b.start) && is(b.end)) { < try { < sd = getPos(ro, b.start, b.end); < < if (sd) { < r = t.dom.doc.createRange(); < r.setStart(sd.startNode, sd.startOffset); < r.setEnd(sd.endNode, sd.endOffset); < s.removeAllRanges(); < s.addRange(r); < } < < if (!tinymce.isOpera) < t.win.focus(); < } catch (ex) { < // Ignore < } < } < } < }, < < select : function(n, c) { < var t = this, r = t.getRng(), s = t.getSel(), b, fn, ln, d = t.win.document; < < function find(n, start) { < var walker, o; < < if (n) { < walker = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false); < < // Find first/last non empty text node < while (n = walker.nextNode()) { < o = n; < < if (tinymce.trim(n.nodeValue).length != 0) { < if (start) < return n; < else < o = n; < } < } < } < < return o; < }; < < if (isIE) { < try { < b = d.body; < < if (/^(IMG|TABLE)$/.test(n.nodeName)) { < r = b.createControlRange(); < r.addElement(n); < } else { < r = b.createTextRange(); < r.moveToElementText(n); < } < < r.select(); < } catch (ex) { --- > dom.setSh (ex) { 5326,5328c4864 < this.inAttr = true; < this.count++; < this.elementCount = this.count; --- > this.inAttr = true;rn this.editors[id]; 5331,5334c4867,4868 < writeAttribute : function(n, v) { < var t = this; < < t.writeRaw(" " + t.encode(n) + '="' + t.encode(v) + '"'); --- > getInstanceById : function(id) { > return this.get(id); 5337,5344c4871,4873 < writeEndElement : function() { < var n; < < if (this.tags.length > 0) { < n = this.tags.pop(); < < if (this._writeAttributesEnd(1)) < this.writeRaw(''); --- > add : function(e) { > this.editors[e.id] = e; > this._setActive(e); 5346,5348c4875 < if (this.settings.indentation > 0) < this.writeRaw('\n'); < } --- > return e; 5351,5357c4878,4881 < writeFullEndElement : function() { < if (this.tags.length > 0) { < this._writeAttributesEnd(); < this.writeRaw(''); < < if (this.settings.indentation > 0) < this.writeRaw('\n'); --- > remove : function(e) { > var t = this @ @`?`@+ etActive(e); > return false; // Break > }); 5359d4882 < }, 5361,5365c4884 < writeText : function(v) { < this._writeAttributesEnd(); < this.writeRaw(this.encode(v)); < this.count++; < }, --- > e.destroy(); 5367,5370c4886 < writeCDATA : function(v) { < this._writeAttributesEnd(); < this.writeRaw(''); < this.count++; --- > return e; 5373,5377c4889,4890 < writeComment : function(v) { < this._writeAttributesEnd(); < this.writeRaw(''); < this.count++; < }, --- > execCommand : function(c, u, v) { > var t = this, ed = t.get(v), w; 5379,5381c4892,4896 < writeRaw : function(v) { < this.str += v; < }, --- > // Manager commands > switch (c) { > case "mceFocus": > ed.focus(); > return true; 5383,5387c4898,4901 < encode : function(s) { < return s.replace(/[<>&"]/g, function(v) { < switch (v) { < case '<': < return '<'; --- > case "mceAddEditor": > case "mceAddControl": > if (!t.get(v)) > new tinymce.Editor(v, t.settings).render(); 5389,5390c4903,5369 < case '>': < return '>'; --- > return true; > > case "mceAddFrameControl": > w = v.window; > > // Add tinyMCE global instance and tinymce namespace to specified window > w.tinyMCE = tinyMCE; > w.tinymce = tinymce; > > tinymce.DOM.doc = w.document; > tinymce.DOM.win = w; > > ed = new tinymce.Editor(v.element_id, v); > ed.render(); > > // Fix IE memory leaks > if (tinymce.isIE) { > function clr() { > ed.destroy(); > w.detachEvent('onunload', clr); > w = w.tinyMCE = w.tinymce = null; // IE leak > }; > > w.attachEvent('onunload', clr); > } > > v.page_window = null; > > return true; > > case "mceRemoveEditor": > case "mceRemoveControl": > if (ed) > ed.remove(); > > return true; > > case 'mceToggleEditor': > if (!ed) { > t.execCommand('mceAddControl', 0, v); > return true; > } > > if (ed.isHidden()) > ed.show(); > else > ed.hide(); > > return true; > } > > // Run command on active editor > if (t.activeEditor) > return t.activeEditor.execCommand(c, u, v); > > return false; > }, > > execInstanceCommand : function(id, c, u, v) { > var ed = this.get(id); > > if (ed) > return ed.execCommand(c, u, v); > > return false; > }, > > triggerSave : function() { > each(this.editors, function(e) { > e.save(); > }); > }, > > addI18n : function(p, o) { > var lo, i18n = this.i18n; > > if (!tinymce.is(p, 'string')) { > each(p, function(o, lc) { > each(o, function(o, g) { > each(o, function(o, k) { > if (g === 'common') > i18n[lc + '.' + k] = o; > else > i18n[lc + '.' + g + '.' + k] = o; > }); > }); > }); > } else { > each(o, function(o, k) { > i18n[p + '.' + k] = o; > }); > } > }, > > // Private methods > > _setActive : function(e) { > this.selectedInstance = this.activeEditor = e; > } > > }); > > tinymce.EditorManager.preInit(); > })(tinymce); > > // Short for editor manager window.tinyMCE is needed when TinyMCE gets loaded though a XHR call > var tinyMCE = window.tinyMCE = tinymce.EditorManager; > (function(tinymce) { > var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, Dispatcher = tinymce.util.Dispatcher; > var each = tinymce.each, isGecko = tinymce.isGecko, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit; > var is = tinymce.is, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, EditorManager = tinymce.EditorManager; > var inArray = tinymce.inArray, grep = tinymce.grep, explode = tinymce.explode; > > tinymce.create('tinymce.Editor', { > Editor : function(id, s) { > var t = this; > > t.id = t.editorId = id; > t.execCommands = {}; > t.queryStateCommands = {}; > t.queryValueCommands = {}; > t.plugins = {}; > > // Add events to the editor > each([ > 'onPreInit', > 'onBeforeRenderUI', > 'onPostRender', > 'onInit', > 'onRemove', > 'onActivate', > 'onDeactivate', > 'onClick', > 'onEvent', > 'onMouseUp', > 'onMouseDown', > 'onDblClick', > 'onKeyDown', > 'onKeyUp', > 'onKeyPress', > 'onContextMenu', > 'onSubmit', > 'onReset', > 'onPaste', > 'onPreProcess', > 'onPostProcess', > 'onBeforeSetContent', > 'onBeforeGetContent', > 'onSetContent', > 'onGetContent', > 'onLoadContent', > 'onSaveContent', > 'onNodeChange', > 'onChange', > 'onBeforeExecCommand', > 'onExecCommand', > 'onUndo', > 'onRedo', > 'onVisualAid', > 'onSetProgressState' > ], function(e) { > t[e] = new Dispatcher(t); > }); > > // Default editor config > t.settings = s = extend({ > id : id, > language : 'en', > docs_language : 'en', > theme : 'simple', > skin : 'default', > delta_width : 0, > delta_height : 0, > popup_css : '', > plugins : '', > document_base_url : tinymce.documentBaseURL, > add_form_submit_trigger : 1, > submit_patch : 1, > add_unload_trigger : 1, > convert_urls : 1, > relative_urls : 1, > remove_script_host : 1, > table_inline_editing : 0, > object_resizing : 1, > cleanup : 1, > accessibility_focus : 1, > custom_shortcuts : 1, > custom_undo_redo_keyboard_shortcuts : 1, > custom_undo_redo_restore_selection : 1, > custom_undo_redo : 1, > doctype : '', > visual_table_class : 'mceItemTable', > visual : 1, > inline_styles : true, > convert_fonts_to_spans : true, > font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large', > apply_source_formatting : 1, > directionality : 'ltr', > forced_root_block : 'p', > valid_elements : '@[id|class|style|title|dir try { > r.select(); > } catch (ex) { > // Needed for some odd IE bug #1843306 > } > } > }, > > setNode : function(n) { > var t = this; > > t.setContent(t.dom.getOuterHTML(n)); > > return n; > }, > > getNode : function() { > var t = this, r = t.getRng(), s = t.getSel(), e; > > if (!isIE) { > // Range maybe lost after the editor is made visible again > if (!r) > return t.dom.getRoot(); > > e = r.commonAncestorContainer; > > // Handle selection a image or other control like element such as anchors > if (!r.collapsed) { > // If the anchor node is a element instead of a text node then return this element > if (tinymce.isWebKit && s.anchorNode && s.anchorNode.nodeType == 1) > return s.anchorNode.childNodes[s.anchorOffset]; > > if (r.startContainer == r.endContainer) { > if (r.startOffset - r.endOffset < 2) { > if (r.startContainer.hasChildNodes()) > e = r.startContainer.childNodes[r.startOffset]; > } > } > } > > return t.dom.getParent(e, '*'); > } > > return r.item ? r.item(0) : r.parentElement(); > }, > > getSelectedBlocks : function(st, en) { > var t = this, dom = t.dom, sb, eb, n, bl = []; > > sb = dom.getParent(st || t.getStart(), dom.isBlock); > eb = dom.getParent(en || t.getEnd(), dom.isBlock); > > if (sb) > bl.push(sb); > > if (sb && eb && sb != eb) { > n = sb; > > while ((n = n.nextSibling) && n != eb) { > if (dom.isBlock(n)) > bl.push(n); > } > } > > if (eb && sb != eb) > bl.push(eb); > > return bl; > }, > > destroy : function(s) { > var t = this; > > t.win = null; > > // Manual destroy then remove unload handler > if (!s) > tinymce.removeUnload(t.destroy); > } > > }); > })(tinymce); > (function(tinymce) { > tinymce.create('tinymce.dom.XMLWriter', { > node : null, > > XMLWriter : function(s) { > // Get XML document > function getXML() { > var i = document.implementation; > > if (!i || !i.createDocument) { > // Try IE objects > try {return new ActiveXObject('MSXML2.DOMDocument');} catch (ex) {} > try {return new ActiveXObject('Microsoft.XmlDom');} catch (ex) {} > } else > return i.createDocument('', '', null); > }; > > this.doc = getXML(); > > // Since Opera and WebKit doesn't escape > into > we need to do it our self to normalize the output for all browsers > this.valid = tinymce.isOpera || tinymce.isWebKit; > > this.reset(); > }, > > reset : function() { > var t = this, d = t.doc; > > if (d.firstChild) > d.removeChild(d.firstChild); > > t.node = d.appendChild(d.createElement("html")); > }, > > writeStartElement : function(n) { > var t = this; > > t.node = t.node.appendChild(t.doc.createElement(n)); > }, > > writeAttribute : function(n, v) { > if (this.valid) > v = v.replace(/>/g, '%MCGT%'); > > this.node.setAttribute(n, v); > }, > > writeEndElement : function() { > this.node = this.node.parentNode; > }, > > writeFullEndElement : function() { > var t = this, n = t.node; > > n.appendChild(t.doc.createTextNode("")); > t.node = n.parentNode; > }, > > writeText : function(v) { > if (this.valid) > v = v.replace(/>/g, '%MCGT%'); > > this.node.appendChild(this.doc.createTextNode(v)); > }, > > writeCDATA : function(v) { > this.node.appendChild(this.doc.createCDATA(v)); > }, > > writeComment : function(v) { > // Fix for bug #2035694 > if (tinymce.isIE) > v = v.replace(/^\-|\-$/g, ' '); > > this.node.appendChild(this.doc.createComment(v.replace(/\-\-/g, ' '))); > }, > > getContent : function() { > var h; > > h = this.doc.xml || new XMLSerializer().serializeToString(this.doc); > h = h.replace(/<\?[^?]+\?>||<\/html>||]+>/g, ''); > h = h.replace(/ ?\/>/g, ' />'); > > if (this.valid) > h = h.replace(/\%MCGT%/g, '>'); > > return h; > } > > }); > })(tinymce); > (function(tinymce) { > tinymce.create('tinymce.dom.StringWriter', { > str : null, > tags : null, > count : 0, > settings : null, > indent : null, > > StringWriter : function(s) { > this.settings = tinymce.extend({ > indent_char : ' ', > indentation : 1 > }, s); > > this.reset(); > }, > > reset : function() { > this.indent = ''; > this.str = ""; > this.tags = []; > this.count = 0; > }, > > writeStartElement : function(n) { > this._writeAttributesEnd(); > this.writeRaw('<' + n); > this.tags.push(n); > this.inAttr = true; > this.count++; > this.elementCount = this.count; > }, > > writeAttribute : function(n, v) { > var t = this; > > t.writeRaw(" " + t.encode(n) + '="' + t.encode(v) + '"'); > }, > > writeEndElement : function() { > var n; > > if (this.tags.length > 0) { > n = this.tags.pop(); > > if (this._writeAttributesEnd(1)) > this.writeRaw(''); > > if (this.settings.indentation > 0) > this.writeRaw('\n'); > } > }, > > writeFullEndElement : function() { > if (this.tags.length > 0) { > this._writeAttributesEnd(); > this.writeRaw(''); > > if (this.settings.indentation > 0) > this.writeRaw('\n'); > } > }, > > writeText : function(v) { > this._writeAttributesEnd(); > this.writeRaw(this.encode(v)); > this.count++; > }, > > writeCDATA : function(v) { > this._writeAttributesEnd(); > this.writeRaw(''); > this.count++; > }, > > writeComment : function(v) { > this._writeAttributesEnd(); > this.writeRaw(''); > this.count++; > }, > > writeRaw : function(v) { > this.str += v; > }, > > encode : function(s) { > return s.replace(/[<>&"]/g, function(v) { > switch (v) { > case '<': > return '<'; > > case '>': > return '>'; 10344,10348c10323,10328 < var ed = this.editor, d = ed.dom, s = ); < return; < } else < ed.getDoc().execCommand('ForeColor', false, v); < }, --- > var ed = this.editor, d = ed.dom, s = ed.selection, e, v, iv, iu; > > // Setup indent level > iv = ed.settings.indentation; > iu = /[a-z%]+$/i.exec(iv); > iv = parseInt(iv); 10350,10351c10330,10334 < HiliteColor : function(ui, val) { < var t = this, ed = t.editor, d = ed.getDoc(); --- > if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) { > each(s.getSelectedBlocks(), function(e) { > v = Math.max(0, parseInt(e.style.paddingLeft || 0) - iv); > d.setStyle(e, 'paddingLeft', v ? v + iu : ''); > }); 10353,10354d10335 < if (ed.settings.convert_fonts_to_spans) { < this._applyInlineStyle('span', {style : {backgroundColor : val}}); 10358,10360c10339,10340 < function set(s) { < if (!isGecko) < return; --- > ed.getDoc().execCommand('Outdent', false, null); > }, 10362,10369c10342,10344 < try { < // Try new Gecko method < d.execCommand("styleWithCSS", 0, s); < } catch (ex) { < // Use old < d.execCommand("useCSS", 0, !s); < } < }; --- > /* > mceSetAttribute : function(u, v) { > var ed = this.editor, d = ed.dom, e; 10371,10376c10346,10351 < if (isGecko || isOpera) { < set(true); < d.execCommand('hilitecolor', false, val); < set(false); < } else < d.execCommand('BackColor', false, val); --- > if (e = d.getParent(ed.selection.getNode(), d.isBlock)) > d.setAttrib(e, v.name, v.value); > }, > */ > mceSetContent : function(u, v) { > this.editor.setContent(v); 10379,10380c10354,10355 < FormatBlock : function(ui, val) { < var t = this, ed = t.editor, s = ed.selection, dom = ed.dom, bl, nb, b; --- > mceToggleVisualAid : function() { > var ed = this.editor; 10382,10384c10357,10359 < function isBlock(n) { < return /^(P|DIV|H[1-6]|ADDRESS|BLOCKQUOTE|PRE)$/.test(n.nodeName); < }; --- > ed.hasVisual = !ed.hasVisual; > ed.addVisual(); > }, 10386,10388c10361,10362 < bl = dom.getParent(s.getNode(), function(n) { < return isBlock(n); < }); --- > mceReplaceContent : function(u, v) { > var s = this.editor.selection; 10390,10395c10364,10365 < // IE has an issue where it removes the parent div if you change format on the paragrah in

Content

< // FF and Opera doesn't change parent DIV elements if you switch format < if (bl) { < if ((isIE && isBlock(bl.parentNode)) || bl.nodeName == 'DIV') { < // Rename block element < nb = ed.dom.create(val); --- > s.setContent(v.replace(/\{\$selection\}/g, s.getContent({format : 'text'}))); > }, 10397,10399c10367,10368 < each(dom.getAttribs(bl), function(v) { < dom.setAttrib(nb, v.nodeName, dom.getAttrib(bl, v.nodeName)); < }); --- > mceInsertLink : function(u, v) { > var ed = this.editor, s = ed.selection, e = ed.dom.getParent(s.getNode(), 'A'); 10401,10407c10370,10371 < b = s.getBookmark(); < dom.replace(nb, bl, 1); < s.moveToBookmark(b); < ed.nodeChanged(); < return; < } < } --- > if (tinymce.is(v, 'string')) > v = {href : v}; 10409c10373,10377 < val = ed.settings.forced_root_block ? (val || '

') : val; --- > function set(e) { > each(v, function(v, k) { > ed.dom.setAttrib(e, k, v); > }); > }; 10411,10412c10379,10390 < if (val.indexOf('<') == -1) < val = '<' + val + '>'; --- > if (!e) { > ed.execCommand('CreateLink', false, 'javascript:mctmp(0);'); > each(ed.dom.select('a[href=javascript:mctmp(0);]'), function(e) { > set(e); > }); > } else { > if (v.href) > set(e); > else > ed.dom.remove(e, 1); > } > }, 10414,10415c10392,10393 < if (tinymce.isGecko) < val = val.replace(/<(div|blockquote|code|dt|dd|dl|samp)>/gi, '$1'); --- > UnLink : function() { > var ed = this.editor, s = ed.selection; 10417,10418c10395,10396 < ed.getDoc().execCommand('FormatBlock', false, val); < }, --- > if (s.isCollapsed()) > s.select(s.getNode()); 10420,10423c10398,10399 < mceCleanup : function() { < var ed = this.editor, s = ed.selection, b = s.getBookmark(); < ed.setContent(ed.getContent()); < s.moveToBookmark(b); --- > ed.getDoc().execCommand('unlink', false, null); > s.collapse(0); 10426,10431c10402,10403 < mceRemoveNode : function(ui, val) { < var ed = this.editor, s = ed.selection, b, n = val || s.getNode(); < < // Make sure that the body node isn't removed < if (n == ed.getBody()) < return; --- > FontName : function(u, v) { > var t = this, ed = t.editor, s = ed.selection, e; 10433,10436c10405,10413 < b = s.getBookmark(); < ed.dom.remove(n, 1); < s.moveToBookmark(b); < ed.nodeChanged(); --- > if (!v) { > if (s.isCollapsed()) > s.select(s.getNode()); > } else { > if (ed.settings.convert_fonts_to_spans) > t._applyInlineStyle('span', {style : {fontFamily : v}}); > else > ed.getDoc().execCommand('FontName', false, v); > } 10439,10440c10416,10417 < mceSelectNodeDepth : function(ui, val) { < var ed = this.editor, s = ed.selection, c = 0; --- > FontSize : function(u, v) { > var ed = this.editor, s = ed.settings, fc, fs; 10442,10449c10419,10428 < ed.dom.getParent(s.getNode(), function(n) { < if (n.nodeType == 1 && c++ == val) { < s.select(n); < ed.nodeChanged(); < return false; < } < }, ed.getBody()); < }, --- > // Use style options instead > if (s.convert_fonts_to_spans && v >= 1 && v <= 7) { > fs = tinymce.explode(s.font_size_style_values); > fc = tinymce.explode(s.font_size_classes); > > if (fc) > v = fc[v - 1] || v; > else > v = fs[v - 1] || v; > } 10451,10452c10430,10433 < mceSelectNode : function(u, v) { < this.editor.selection.select(v); --- > if (v >= 1 && v <= 7) > ed.getDoc().execCommand('FontSize', false, v); > else > this._applyInlineStyle('span', {style : {fontSize : v}}); 10455,10456c10436,10442 < mceInsertContent : function(ui, val) { < this.editor.selection.setContent(val); --- > queryCommandValue : function(c) { > var f = this['queryValue' + c]; > > if (f) > return f.call(this, c); > > return false; 10459,10460c10445,10446 < mceInsertRawHTML : function(ui, val) { < var ed = this.editor; --- > queryCommandState : function(cmd) { > var f; 10462,10463c10448,10452 < ed.selection.setContent('tiny_mce_marker'); < ed.setContent(ed.getContent().replace(/tiny_mce_marker/g, val)); --- > switch (cmd) { > // Bundle these together > case 'JustifyLeft': > case 'JustifyCenter': > etContent().replace(/tiny_mce_marker/g, val)); 10501,10502c10490,10619 < if ((n = ed.dom.getParent(ed.selection.getEnd(), ed.dom.isBlock)) && parseInt(n.style.paddingLeft) > 0) < return true; --- > if ((n = ed.dom.getParent(ed.selection.getEnd(), ed.dom.isBlock)) && parseInt(n.style.paddingLeft) > 0) > return true; > } > > return this.queryStateInsertUnorderedList() || this.queryStateInsertOrderedList() || (!ed.settings.inline_styles && !!ed.dom.getParent(ed.selection.getNode(), 'BLOCKQUOTE')); > }, > > queryStateInsertUnorderedList : function() { > return this.editor.dom.getParent(this.editor.selection.getNode(), 'UL'); > }, > > queryStateInsertOrderedList : function() { > return this.editor.dom.getParent(this.editor.selection.getNode(), 'OL'); > }, > > queryStatemceBlockQuote : function() { > return !!this.editor.dom.getParent(this.editor.selection.getStart(), function(n) {return n.nodeName === 'BLOCKQUOTE';}); > }, > > _applyInlineStyle : function(na, at, op) { > var t = this, ed = t.editor, dom = ed.dom, bm, lo = {}, kh, found; > > na = na.toUpperCase(); > > if (op && op.check_classes && at['class']) > op.check_classes.push(at['class']); > > function removeEmpty() { > each(dom.select(na).reverse(), function(n) { > var c = 0; > > // Check if there is any attributes > each(dom.getAttribs(n), function(an) { > if (an.nodeName.substring(0, 1) != '_' && dom.getAttrib(n, an.nodeName) != '') { > //console.log(dom.getOuterHTML(n), dom.getAttrib(n, an.nodeName)); > c++; > } > }); > > // No attributes then remove the element and keep the children > if (c == 0) > dom.remove(n, 1); > }); > }; > > function replaceFonts() { > var bm; > > each(dom.select('span,font'), function(n) { > if (n.style.fontFamily == 'mceinline' || n.face == 'mceinline') { > if (!bm) > bm = ed.selection.getBookmark(); > > at._mce_new = '1'; > dom.replace(dom.create(na, at), n, 1); > } > }); > > // Remove redundant elements > each(dom.select(na + '[_mce_new]'), function(n) { > function removeStyle(n) { > if (n.nodeType == 1) { > each(at.style, function(v, k) { > dom.setStyle(n, k, ''); > }); > > // Remove spans with the same class or marked classes > if (at['class'] && n.className && op) { > each(op.check_classes, function(c) { > if (dom.hasClass(n, c)) > dom.removeClass(n, c); > }); > } > } > }; > > // Remove specified style information from child elements > each(dom.select(na, n), removeStyle); > > // Remove the specified style information on parent if current node is only child (IE) > if (n.parentNode && n.parentNode.nodeType == 1 && n.parentNode.childNodes.length == 1) > removeStyle(n.parentNode); > > // Remove the child elements style info if a parent already has it > dom.getParent(n.parentNode, function(pn) { > if (pn.nodeType == 1) { > if (at.style) { > each(at.style, function(v, k) { > var sv; > > if (!lo[k] && (sv = dom.getStyle(pn, k))) { > if (sv === v) > dom.setStyle(n, k, ''); > > lo[k] = 1; > } > }); > } > > // Remove spans with the same class or marked classes > if (at['class'] && pn.className && op) { > each(op.check_classes, function(c) { > if (dom.hasClass(pn, c)) > dom.removeClass(n, c); > }); > } > } > > return false; > }); > > n.removeAttribute('_mce_new'); > }); > > removeEmpty(); > ed.selection.moveToBookmark(bm); > > return !!bm; > }; > > // Create inline elements > ed.focus(); > ed.getDoc().execCommand('FontName', false, 'mceinline'); > replaceFonts(); > > if (kh = t._applyInlineStyle.keyhandler) { > ed.onKeyUp.remove(kh); > ed.onKeyPress.remove(kh); > ed.onKeyDown.remove(kh); > ed.onSetContent.remove(t._applyInlineStyle.chandler); 10505,10506c10622,10627 < return this.queryStateInsertUnorderedList() || this.queryStateInsertOrderedList() || (!ed.settings.inline_styles && !!ed.dom.getParent(ed.selection.getNode(), 'BLOCKQUOTE')); < }, --- > if (ed.selection.isCollapsed()) { > // IE will format the current word so this code can't be executed on that browser > if (!isIE) { > each(dom.getParents(ed.selection.getNode(), 'span'), function(n) { > each(at.style, function(v, k) { > var kv; 10508,10510c10629,10634 < queryStateInsertUnorderedList : function() { < return this.editor.dom.getParent(this.editor.selection.getNode(), 'UL'); < }, --- > if (kv = dom.getStyle(n, k)) { > if (kv == v) { > dom.setStyle(n, k, ''); > found = 2; > return false; > } 10512,10514c10636,10639 < queryStateInsertOrderedList : function() { < return this.editor.dom.getParent(this.editor.selection.getNode(), 'OL'); < }, --- > found = 1; > return false; > } > }); 10516,10517c10641,10642 < queryStatemceBlockQuote : function() { < return !!this.editor.dom.getParent(this.editor.selection.getStart(), function(n) {return n.nodeName === 'BLOCKQUOTE';}); --- > if (found) > entNode; 10520,10530c10645,10646 < _applyInlineStyle : function(na, at, op) { < var t = this, ed = t.editor, dom = ed.dom, bm, lo = {}, kh, found; < < na = na.toUpperCase(); < < if (op && op.check_classes && at['class']) < op.check_classes.push(at['class']); < < function removeEmpty() { < each(dom.select(na).reverse(), function(n) { < var c = 0; --- > writeFullEndElement : function() { > var t = this, n = t.node; 10532,10536c10648,10650 < // Check if there is any attributes < each(dom.getAttribs(n), function(an) { < if (an.nodeName.substring(0, 1) != '_' && dom.getAttrib(n, an.nodeName) != '') { < //console.log(dom.getOuterHTML(n), dom.getAttrib(n, an.nodeName)); < c++ DOM.setAttrib(e, 'id', v); --- > n.appendChild(t.doc.createTextNode("")); > )@``@W`@createCDATA(v)); > }, 10538,10541c10652,10655 < ed = new tinymce.Editor(v, s); < el.push(ed); < ed.rendei@`` : DOM.hasClass(n, c); < }; --- > writeComment : function(v) { > // Fix for bug #2035694 > if (tinymce.isIE) > v = v.replace(/^\-|\-$/g, ' '); 10543,10545c10657,10658 < each(DOM.select('textarea'), function(v) { < if (s.editor_deselector && hasClass(v, s.editor_deselector)) < return; --- > this.node.appendChild(this.doc.createComment(v.replace(/\-\-/g, ' '))); > }, 10547,10551c10660,10661 < if (!s.editor_selector || hasClass(v, s.editor_selector)) { < // Can we use the name < e = DOM.get(v.name); < if (!v.id && !e) < v.id = v.name; --- > getContent : function() { > var h; 10553,10555c10663,10665 < // Generate unique name if missing or already exists < if (!v.id || t.get(v.id)) < v.id = DOM.uniqueId(); --- > h = this.doc.xml || new XMLSerializer().serializeToString(this.doc); > h = h.replace(/<\?[^?]+\?>||<\/html>||]+>/g, ''); > h = h.replace(/ ?\/>/g, ' />'); 10557,10563c10667,10668 < ed = new tinymce.Editor(v.id, s); < el.push(ed); < ed.render(1); < } < }); < break; < } --- > if (this.valid) > h = h.replace(/\%MCGT%/g, '>'); 10565,10567c10670,10671 < // Call onInit when all editors are initialized < if (s.oninit) { < l = co = 0; --- > return h; > } 10569,10570c10673,10681 < each (el, function(ed) { < co++; --- > }); > })(tinymce); > (function(tinymce) { > tinymce.create('tinymce.dom.StringWriter', { > str : null, > tags : null, > count : 0, > settings : null, > indent : null, 10572,10575c10683,10687 < if (!ed.initialized) { < // Wait for it < ed.onInit.add(function() { < l++; --- > StringWriter : function(s) { > this.settings = tinymce.extend({ > indent_char : ' ', > indentation : 1 > }, s); 10577,10582c10689,10690 < // All done < if (l == co) < execCallback(s, 'oninit'); < }); < } else < l++; --- > this.reset(); > }, 10584,10589c10692,10696 < // All done < if (l == co) < execCallback(s, 'oninit'); < }); < } < }); --- > reset : function() { > this.indent = ''; > this.str = ""; > this.tags = []; > this.count = 0; 10592,10593c10699,10703 < get : function(id) { < return this.editors[id]; --- > writeStartElement : function(n) { > this._writeAttributesEnd(); > this.writeRaw('<' + n); > this.tags.push(n); > this.inAttr = true;rn this.editors[id]; 10608,10619c10718 < var t = this; < < // Not in the collection < if (!t.editors[e.id]) < return null; < < delete t.editors[e.id]; < < // Select another editor since the active one was removed < if (t.activeEditor == e) { < each(t.editors, function(e) { < t._setActive(e); --- > var t = this @ @`?`@+ etActive(e); 10810,10964c10909,10941 < language : 'en', < docs_language : 'en', < theme : 'simple', < skin : 'default', < delta_width : 0, < delta_height : 0, < popup_css : '', < plugins : '', < document_base_url : tinymce.documentBaseURL, < add_form_submit_trigger : 1, < submit_patch : 1, < add_unload_trigger : 1, < convert_urls : 1, < relative_urls : 1, < remove_script_host : 1, < table_inline_editing : 0, < object_resizing : 1, < cleanup : 1, < accessibility_focus : 1, < custom_shortcuts : 1, < custom_undo_redo_keyboard_shortcuts : 1, < custom_undo_redo_restore_selection : 1, < custom_undo_redo : 1, < doctype : '', < visual_table_class : 'mceItemTable', < visual : 1, < inline_styles : true, < convert_fonts_to_spans : true, < font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large', < apply_source_formatting : 1, < directionality : 'ltr', < forced_root_block : 'p', < valid_elements : '@[id|class|style|title|dir

Content

< // FF and Opera doesn't change parent DIV elements if you switch format < if (bl) { < if ((isIE && isBlock(bl.parentNode)) || bl.nodeName == 'DIV') { < // Rename block element < nb = ed.dom.create(val); < < each(dom.getAttribs(bl), function(v) { < dom.setAttrib(nb, v.nodeName, dom.getAttrib(bl, v.nodeName)); < }); < < b = s.getBookmark(); < dom.replace(nb, bl, 1); < s.moveToBookmark(b); < ed.nodeChanged(); < return; < } < } < < val = ed.settings.forced_root_block ? (val || '

') : val; < < if (val.indexOf('<') == -1) < val = '<' + val + '>'; < < if (tinymce.isGecko) < val = val.replace(/<(div|blockquote|code|dt|dd|dl|samp)>/gi, '$1'); < < ed.getDoc().execCommand('FormatBlock', false, val); < }, < < mceCleanup : function() { < var ed = this.editor, s = ed.selection, b = s.getBookmark(); < ed.setContent(ed.getContent()); < s.moveToBookmark(b); < }, < < mceRemoveNode : function(ui, val) { < var ed = this.editor, s = ed.selection, b, n = val || s.getNode(); < < // Make sure that the body node isn't removed < if (n == ed.getBody()) < return; < < b = s.getBookmark(); < ed.dom.remove(n, 1); < s.moveToBookmark(b); < ed.nodeChanged(); < }, < < mceSelectNodeDepth : function(ui, val) { < var ed = this.editor, s = ed.selection, c = 0; < < ed.dom.getParent(s.getNode(), function(n) { < if (n.nodeType == 1 && c++ == val) { < s.select(n); < ed.nodeChanged(); < return false; < } < }, ed.getBody()); < }, < < mceSelectNode : function(u, v) { < this.editor.selection.select(v); < }, < < mceInsertContent : function(ui, val) { < this.editor.selection.setContent(val); < }, < < mceInsertRawHTML : function(ui, val) { < var ed = this.editor; < < ed.selection.setContent('tiny_mce_marker'); < ed.setContent(ed.getContent().replace(/tiny_mce_marker/g, val)); < }, < < mceRepaint : function() { < var s, b, e = this.editor; < < if (tinymce.isGecko) { < try { < s = e.selection; < b = s.getBookmark(true); < < if (s.getSel()) < s.getSel().selectAllChildren(e.getBody()); < < s.collapse(true); < s.moveToBookmark(b); < } catch (ex) { < // Ignore < } < } < }, < < queryStateUnderline : function() { < var ed = this.editor, n = ed.selection.getNode(); < < if (n && n.nodeName == 'A') < return false; < < return this._queryState('Underline'); < }, < < queryStateOutdent : function() { < var ed = this.editor, n; < < if (ed.settings.inline_styles) { < if ((n = ed.dom.getParent(ed.selection.getStart(), ed.dom.isBlock)) && parseInt(n.style.paddingLeft) > 0) --- > language : 'en', > docs_language : 'en', > theme : 'simple', > skin : 'default', > delta_width : 0, > delta_height : 0, > popup_css : '', > plugins : '', > document_base_url : tinymce.documentBaseURL, > add_form_submit_trigger : 1, > submit_patch : 1, > add_unload_trigger : 1, > convert_urls : 1, > relative_urls : 1, > remove_script_host : 1, > table_inline_editing : 0, > object_resizing : 1, > cleanup : 1, > accessibility_focus : 1, > custom_shortcuts : 1, > custom_undo_redo_keyboard_shortcuts : 1, > custom_undo_redo_restore_selection : 1, > custom_undo_redo : 1, > doctype : '', > visual_table_class : 'mceItemTable', > visual : 1, > inline_styles : true, > convert_fonts_to_spans : true, > font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large', > apply_source_formatting : 1, > directionality : 'ltr', > forced_root_block : 'p', > valid_elements : '@[id|class|style|title|dir 0) 11285,11289c11262,11265 < t.data = []; < t.index = 0; < t.typing = 0; < t.add({initial : true}); < }, --- > t.data = [];test(dom.getStyle(sb, 'position', 1)))) { > bn = se.element; > sb = null; > } 11291,11293c11267,11271 < hasUndo : function() { < return this.index != 0 || this.typing; < }, --- > // If caption or absolute layers then always generate new blocks within > if (eb && (eb.nodeName == 'CAPTION' || /absolute|relative|fixed/gi.test(dom.getStyle(sb, 'position', 1)))) { > bn = se.element; > eb = null; > } 11295,11297c11273,11277 < hasRedo : function() { < return this.index < this.data.length - 1; < } --- > // Use P instead > if (/(TD|TABLE|TH|CAPTION)/.test(bn) || (sb && bn == "DIV" && /left|right/gi.test(dom.getStyle(sb, 'float', 1)))) { > bn = se.element; > sb = eb = null; > } 11299,11303c11279,11281 < }); < })(tinymce); < (function(tinymce) { < // Shorten names < var Event, isIE, isGecko, isOpera, each, extend; --- > // Setup new before and after blocks > bef = (sb && sb.nodeName == bn) ? sb.cloneNode(0) : ed.dom.create(bn); > aft = (eb && eb.nodeName == bn) ? eb.cloneNode(0) : ed.dom.create(bn); 11305,11314c11283,11284 < Event = tinymce.dom.Event; < isIE = tinymce.isIE; < isGecko = tinymce.isGecko; < isOpera = tinymce.isOpera; < each = tinymce.each; < extend = tinymce.extend; < < tinymce.create('tinymce.ForceBlocks', { < ForceBlocks : function(ed) { < var t = this, s = ed.settings, elm; --- > // Remove id from after clone > aft.removeAttribute('id'); 11316,11344c11286,11303 < t.editor = ed; < t.dom = ed.dom; < elm = (s.forced_root_block || 'p').toLowerCase(); < s.element = elm.toUpperCase(); < < ed.onPreInit.add(t.setup, t); < < t.reOpera = new RegExp('(\\u00a0| | )<\/' + elm + '>', 'gi'); < t.rePadd = new RegExp(']+)><\\\/p>|]+)\\\/>|]+)>\\s+<\\\/p>|

<\\\/p>||

\\s+<\\\/p>'.replace(/p/g, elm), 'gi'); < t.reNbsp2BR1 = new RegExp(']+)>[\\s\\u00a0]+<\\\/p>|

[\\s\\u00a0]+<\\\/p>'.replace(/p/g, elm), 'gi'); < t.reNbsp2BR2 = new RegExp('<%p()([^>]+)>( | )<\\\/%p>|<%p>( | )<\\\/%p>'.replace(/%p/g, elm), 'gi'); < t.reBR2Nbsp = new RegExp(']+)>\\s*
\\s*<\\\/p>|

\\s*
\\s*<\\\/p>'.replace(/p/g, elm), 'gi'); < t.reTrailBr = new RegExp('\\s*
\\s*<\\\/p>'.replace(/p/g, elm), 'gi'); < < function padd(ed, o) { < if (isOpera) < o.content = o.content.replace(t.reOpera, ''); < < o.content = o.content.replace(t.rePadd, '<' + elm + '$1$2$3$4$5$6>\u00a0'); < < if (!isIE && !isOpera && o.set) { < // Use   instead of BR in padded paragraphs < o.content = o.content.replace(t.reNbsp2BR1, '<' + elm + '$1$2>
'); < o.content = o.content.replace(t.reNbsp2BR2, '<' + elm + '$1$2>
'); < } else { < o.content = o.content.replace(t.reBR2Nbsp, '<' + elm + '$1$2>\u00a0'); < o.content = o.content.replace(t.reTrailBr, ''); < } < }; --- > // Is header and cursor is at the end, then force paragraph under > if (/^(H[1-6])$/.test(bn) && sn.nodeValue && so == sn.nodeValue.length) > aft = ed.dom.create(se.element); > > // Find start chop node > n = sc = sn; > do { > if (n == b || n.nodeType == 9 || t.dom.isBlock(n) || /(TD|TABLE|TH|CAPTION)/.test(n.nodeName)) > break; > > sc = n; > } while ((n = n.previousSibling ? n.previousSibling : n.parentNode)); > > // Find end chop node > n = ec = en; > do { > if (n == b || n.nodeType == 9 || t.dom.isBlock(n) || /(TD|TABLE|TH|CAPTION)/.test(n.nodeName)) > break; 11346,11347c11305,11312 < ed.onBeforeSetContent.add(padd); < ed.onPostProcess.add(padd); --- > ec = n; > } while ((n = n.nextSibling ? n.nextSibling : n.parentNode)); > > // Place first chop part into before block element > if (sc.nodeName == bn) > rb.setStart(sc, 0); > else > rb.setStartBefore(sc); 11349,11352c11314,11321 < if (s.forced_root_block) { < ed.onInit.add(t.forceRoots, t); < ed.onSetContent.add(t.forceRoots, t); < ed.onBeforeGetContent.add(t.forceRoots, t); --- > rb.setEnd(sn, so); > bef.appendChild(rb.cloneContents() || d.createTextNode('')); // Empty text node needed for Safari > > // Place secnd chop part within new block element > try { > ra.setEndAfter(ec); > } catch(ex) { > //console.debug(s.focusNode, s.focusOffset); 11354d11322 < }, 11356,11357c11324,11325 < setup : function() { < var t = this, ed = t.editor, s = ed.settings; --- > ra.setStart(en, eo); > aft.appendChild(ra.cloneContents() || d.createTextNode('')); // Empty text node needed for Safari 11359,11362c11327,11335 < // Force root blocks when typing and when getting output < if (s.forced_root_block) { < ed.onKeyUp.add(t.forceRoots, t); < ed.onPreProcess.add(t.forceRoots, t); --- > // Create range around everything > r = d.createRange(); > if (!sc.previousSibling && sc.parentNode.nodeName == bn) { > r.setStartBefore(sc.parentNode); > } else { > if (rb.startContainer.nodeName == bn && rb.startOffset == 0) > r.setStartBefore(rb.startContainer); > else > r.setStart(rb.startContainer, rb.startOffset); 11365,11369c11338,11341 < if (s.force_br_newlines) { < // Force IE to produce BRs on enter < if (isIE) { < ed.onKeyPress.add(function(ed, e) { < var n, s = ed.selection; --- > if (!ec.nextSibling && ec.parentNode.nodeName == bn) > r.setEndAfter(ec.parentNode); > else > r.setEnd(ra.endContainer, ra.endOffset); 11371,11377c11343,11373 < if (e.keyCode == 13 && s.getNode().nodeName != 'LI') { < s.setContent('
', {format : 'raw'}); < n = ed.dom.get('__'); < n.removeAttribute('id'); < s.select(n); < s.collapse(); < return Event.cancel(e); --- > // Delete and replace it with new block elements > r.deleteContents(); > > if (isOpera) > ed.getWin().scrollTo(0, vp.y); > > // Never wrap blocks in blocks > if (bef.firstChild && bef.firstChild.nodeName == bn) > bef.innerHTML = bef.firstChild.innerHTML; > > if (aft.firstChild && aft.firstChild.nodeName == bn) > aft.innerHTML = aft.firstChild.innerHTML; > > // Padd empty blocks > if (isEmpty(bef)) > bef.innerHTML = '
'; > > function appendStyles(e, en) { > var nl = [], nn, n, i; > > e.innerHTML = ''; > > // Make clones of style elements > if (se.keep_styles) { > n = en; > do { > // We only want style specific elements > if (/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(n.nodeName)) { > nn = n.cloneNode(false); > dom.setAttrib(nn, 'id', ''); // Remove ID since it needs to be unique > nl.push(nn); 11379c11375 < }); --- > } while (n = n.parentNode); 11382,11383c11378,11495 < return; < } --- > // Append style elements to aft > if (nl.length > 0) { > for (i = nl.length - 1, nn = e; i >= 0; i--) > nn = nn.appendChild(nl[i]); > > // Padd most inner style element > nl[0].innerHTML = isOpera ? ' ' : '
'; // Extra space for Opera so that the caret can move there > return nl[0]; // Move caret to most inner element > } else > e.innerHTML = isOpera ? ' ' : '
'; // Extra space for Opera so that the caret can move there > }; > > // Fill empty afterblook with current style > if (isEmpty(aft)) > car = appendStyles(aft, en); > > // Opera needs this one backwards for older versions > if (isOpera && parseFloat(opera.version()) < 9.5) { > r.insertNode(bef); > r.insertNode(aft); > } else { > r.insertNode(aft); > r.insertNode(bef); > } > > // Normalize > aft.normalize(); > bef.normalize(); > > function first(n) { > return d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false).nextNode() || n; > }; > > // Move cursor and scroll into view > r = d.createRange(); > r.selectNodeContents(isGecko ? first(car || aft) : car || aft); > r.collapse(1); > s.removeAllRanges(); > s.addRange(r); > > // scrollIntoView seems to scroll the parent window in most browsers now including FF 3.0b4 so it's time to stop using it and do it our selfs > y = ed.dom.getPos(aft).y; > ch = aft.clientHeight; > > // Is element within viewport > if (y < vp.y || y + ch > vp.y + vp.h) { > ed.getWin().scrollTo(0, y < vp.y ? y : y - vp.h + 25); // Needs to be hardcoded to roughly one line of text if a huge text block is broken into two blocks > //console.debug('SCROLentNode; > }, > > writeFullEndElement : function() { > var t = this, n = t.node; > > n.appendChild(t.doc.createTextNode("")); > @iU``q@*^@og@o@j,createCDATA(v)); > }, > > writeComment : function(v) { > // Fix for bug #2035694 > if (tinymce.isIE) > v = v.replace(/^\-|\-$/g, ' '); > > this.node.appendChild(this.doc.createComment(v.replace(/\-\-/g, ' '))); > }, > > getContent : function() { > var h; > > h = this.doc.xml || new XMLSerializer().serializeToString(this.doc); > h = h.replace(/<\?[^?]+\?>||<\/html>||]+>/g, ''); > h = h.replace(/ ?\/>/g, ' />'); > > if (this.valid) > h = h.replace(/\%MCGT%/g, '>'); > > return h; > } > > }); > })(tinymce); > (function(tinymce) { > tinymce.create('tinymce.dom.StringWriter', { > str : null, > tags : null, > count : 0, > settings : null, > indent : null, > > StringWriter : function(s) { > this.settings = tinymce.extend({ > indent_char : ' ', > indentation : 1 > }, s); > > this.reset(); > }, > > reset : function() { > this.indent = ''; > this.str = ""; > this.tags = []; > this.count = 0; > }, > > writeStartElement : function(n) { > this._writeAttributesEnd(); > this.writeRaw('<' + n); > this.tags.push(n); > this.inAttr = true;rn this.editors[id]; > }, > > getInstanceById : function(id) { > return this.get(id); > }, > > add : function(e) { > this.editors[e.id] = e; > this._setActive(e); 11385,11395c11497,11498 < if (!isIE && s.force_p_newlines) { < /* ed.onPreProcess.add(function(ed, o) { < each(ed.dom.select('br', o.node), function(n) { < var p = n.parentNode; < < // Replace


with

 

< if (p && p.nodeName == 'p' && (p.childNodes.length == 1 || p.lastChild == n)) { < p.replaceChild(ed.getDoc().createTextNode('\u00a0'), n); < } < }); < });*/ --- > return e; > }, 11397,11401c11500,11502 < ed.onKeyPress.add(function(ed, e) { < if (e.keyCode == 13 && !e.shiftKey) { < if (!t.insertPara(e)) < Event.cancel(e); < } --- > remove : function(e) { > var t = this @ @`?`@+ etActive(e); > return false; // Break 11403,11409d11503 < < if (isGecko) { < ed.onKeyDown.add(function(ed, e) { < if ((e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) < t.backspaceDelete(e, e.keyCode == 8); < }); < } 11412,11418c11506 < function ren(rn, na) { < var ne = ed.dom.create(na); < < each(rn.attributes, function(a) { < if (a.specified && a.nodeValue) < ne.setAttribute(a.nodeName.toLowerCase(), a.nodeValue); < }); --- > e.destroy(); 11420,11422c11508,11509 < each(rn.childNodes, function(n) { < ne.appendChild(n.cloneNode(true)); < }); --- > return e; > }, 11424c11511,11512 < rn.parentNode.replaceChild(ne, rn); --- > execCommand : function(c, u, v) { > var t = this, ed = t.get(v), w; 11426,11427c11514,11518 < return ne; < }; --- > // Manager commands > switch (c) { > case "mceFocus": > ed.focus(); > return true; 11429,11444c11520,11523 < // Replaces IE:s auto generated paragraphs with the specified element name < if (isIE && s.element != 'P') { < ed.onKeyPress.add(function(ed, e) { < t.lastElm = ed.selection.getNode().nodeName; < }); < < ed.onKeyUp.add(function(ed, e) { < var bl, sel = ed.selection, n = sel.getNode(), b = ed.getBody(); < < if (b.childNodes.length === 1 && n.nodeName == 'P') { < n = ren(n, s.element); < sel.select(n); < sel.collapse(); < ed.nodeChanged(); < } else if (e.keyCode == 13 && !e.shiftKey && t.lastElm != 'P') { < bl = ed.dom.getParent(n, 'P'); --- > case "mceAddEditor": > case "mceAddControl": > if (!t.get(v)) > new tinymce.Editor(v, t.settings).render(); 11446,11453c11525 < if (bl) { < ren(bl, s.element); < ed.nodeChanged(); < } < } < }); < } < }, --- > return true; 11455,11456c11527,11528 < find : function(n, t, s) { < var ed = this.editor, w = ed.getDoc().createTreeWalker(n, 4, null, false), c = -1; --- > case "mceAddFrameControl": > w = v.window; 11458,11459c11530,11532 < while (n = w.nextNode()) { < c++; --- > // Add tinyMCE global instance and tinymce namespace to specified window > w.tinyMCE = tinyMCE; > w.tinymce = tinymce; 11461,11463c11534,11535 < // Index by node < if (t == 0 && n == s) < return c; --- > tinymce.DOM.doc = w.document; > tinymce.DOM.win = w; 11465,11468c11537,11538 < // Node by index < if (t == 1 && c == s) < return n; < } --- > ed = new tinymce.Editor(v.element_id, v); > ed.render(); 11470,11471c11540,11546 < return -1; < }, --- > // Fix IE memory leaks > if (tinymce.isIE) { > function clr() { > ed.destroy(); > w.detachEvent('onunload', clr); > w = w.tinyMCE = w.tinymce = null; // IE leak > }; 11473,11475c11548,11549 < forceRoots : function(ed, e) { < var t = this, ed = t.editor, b = ed.getBody(), d = ed.getDoc(), se = ed.selection, s = se.getSel(), r = se.getRng(), si = -2, ei, so, eo, tr, c = -0xFFFFFF; < var nx, bl, bp, sp, le, nl = b.childNodes, i, n, eid; --- > w.attachEvent('onunload', clr); > } 11477,11479c11551 < // Fix for bug #1863847 < //if (e && e.keyCode == 13) < // return true; --- > v.page_window = null; 11481,11483c11553 < // Wrap non blocks into blocks < for (i = nl.length - 1; i >= 0; i--) { < nx = nl[i]; --- > return true; 11485,11519c11555,11558 < // Is text or non block element < if (nx.nodeType == 3 || (!t.dom.isBlock(nx) && nx.nodeType != 8)) { < if (!bl) { < // Create new block but ignore whitespace < if (nx.nodeType != 3 || /[^\s]/g.test(nx.nodeValue)) { < // Store selection < if (si == -2 && r) { < if (!isIE) { < // If selection is element then mark it < if (r.startContainer.nodeType == 1 && (n = r.startContainer.childNodes[r.startOffset]) && n.nodeType == 1) { < // Save the id of the selected element < eid = n.getAttribute("id"); < n.setAttribute("id", "__mce"); < } else { < // If element is inside body, might not be the case in contentEdiable mode < if (ed.dom.getParent(r.startContainer, function(e) {return e === b;})) { < so = r.startOffset; < eo = r.endOffset; < si = t.find(b, 0, r.startContainer); < ei = t.find(b, 0, r.endContainer); < } < } < } else { < tr = d.body.createTextRange(); < tr.moveToElementText(b); < tr.collapse(1); < bp = tr.move('character', c) * -1; < < tr = r.duplicate(); < tr.collapse(1); < sp = tr.move('character', c) * -1; < < tr = r.duplicate(); < tr.collapse(0); < le = (tr.move('character', c) * -1) - sp; --- > case "mceRemoveEditor": > case "mceRemoveControl": > if (ed) > ed.remove(); 11521,11524c11560 < si = sp - bp; < ei = le; < } < } --- > return true; 11526,11534c11562,11565 < bl = ed.dom.create(ed.settings.forced_root_block); < bl.appendChild(nx.cloneNode(1)); < nx.parentNode.replaceChild(bl, nx); < } < } else { < if (bl.hasChildNodes()) < bl.insertBefore(nx, bl.firstChild); < else < bl.appendChild(nx); --- > case 'mceToggleEditor': > if (!ed) { > t.execCommand('mceAddControl', 0, v); > return true; 11536,11544d11566 < } else < bl = null; // Time to create new block < } < < // Restore selection < if (si != -2) { < if (!isIE) { < bl = b.getElementsByTagName(ed.settings.element)[0]; < r = d.createRange(); 11546,11548c11568,11569 < // Select last location or generated block < if (si != -1) < r.setStart(t.find(b, 1, si), so); --- > if (ed.isHidden()) > ed.show(); 11550c11571 < r.setStart(bl, 0); --- > ed.hide(); 11552,11556c11573,11574 < // Select last location or generated block < if (ei != -1) < r.setEnd(t.find(b, 1, ei), eo); < else < r.setEnd(bl, 0); --- > return true; > } 11558,11579c11576,11578 < if (s) { < s.removeAllRanges(); < s.addRange(r); < } < } else { < try { < r = s.createRange(); < r.moveToElementText(b); < r.collapse(1); < r.moveStart('character', si); < r.moveEnd('character', ei); < r.select(); < } catch (ex) { < // Ignore < } < } < } else if (!isIE && (n = ed.dom.get('__mce'))) { < // Restore the id of the selected element < if (eid) < n.setAttribute('id', eid); < else < n.removeAttribute('id'); --- > // Run command on active editor > if (t.activeEditor) > return t.activeEditor.execCommand(c, u, v); 11581,11586c11580 < // Move caret before selected element < r = d.createRange(); < r.setStartBefore(n); < r.setEndBefore(n); < se.setRng(r); < } --- > return false; 11589,11590c11583,11587 < getParentBlock : function(n) { < var d = this.dom; --- > execInstanceCommand : function(id, c, u, v) { > var ed = this.get(id); > > if (ed) > return ed.execCommand(c, u, v); 11592c11589 < return d.getParent(n, d.isBlock); --- > return false; 11595,11597c11592,11596 < insertPara : function(e) { < var t = this, ed = t.editor, dom = ed.dom, d = ed.getDoc(), se = ed.settings, s = ed.selection.getSel(), r = s.getRangeAt(0), b = d.body; < var rb, ra, dir, sn, so, en, eo, sb, eb, bn, bef, aft, sc, ec, n, vp = dom.getViewPort(ed.getWin()), y, ch, car; --- > triggerSave : function() { > each(this.editors, function(e) { > e.save(); > }); > }, 11599,11602c11598,11599 < function isEmpty(n) { < n = n.innerHTML; < n = n.replace(/<(img|hr|table)/gi, '-'); // Keep these convert them to - chars < n = n.replace(/<[^>]+>/g, ''); // Remove all tags --- > addI18n : function(p, o) { > var lo, i18n = this.i18n; 11604,11605c11601,11617 < return n.replace(/[ \t\r\n]+/g, '') == ''; < }; --- > if (!tinymce.is(p, 'string')) { > each(p, function(o, lc) { > each(o, function(o, g) { > each(o, function(o, k) { > if (g === 'common') > i18n[lc + '.' + k] = o; > else > i18n[lc + '.' + g + '.' + k] = o; > }); > }); > }); > } else { > each(o, function(o, k) { > i18n[p + '.' + k] = o; > }); > } > }, 11607,11645c11619 < // If root blocks are forced then use Operas default behavior since it's really good < // Removed due to bug: #1853816 < // if (se.forced_root_block && isOpera) < // return true; < < // Setup before range < rb = d.createRange(); < < // If is before the first block element and in body, then move it into first block element < rb.setStart(s.anchorNode, s.anchorOffset); < rb.collapse(true); < < // Setup after range < ra = d.createRange(); < < // If is before the first block element and in body, then move it into first block element < ra.setStart(s.focusNode, s.focusOffset); < ra.collapse(true); < < // Setup start/end points < dir = rb.compareBoundaryPoints(rb.START_TO_END, ra) < 0; < sn = dir ? s.anchorNode : s.focusNode; < so = dir ? s.anchorOffset : s.focusOffset; < en = dir ? s.focusNode : s.anchorNode; < eo = dir ? s.focusOffset : s.anchorOffset; < < // If selection is in empty table cell < if (sn === en && /^(TD|TH)$/.test(sn.nodeName)) { < dom.remove(sn.firstChild); // Remove BR < < // Create two new block elements < ed.dom.add(sn, se.element, null, '
'); < aft = ed.dom.add(sn, se.element, null, '
'); < < // Move caret into the last one < r = d.createRange(); < r.selectNodeContents(aft); < r.collapse(1); < ed.selection.setRng(r); --- > // Private methods 11647,11648c11621,11623 < return false; < } --- > _setActive : function(e) { > this.selectedInstance = this.activeEditor = e; > } 11650,11669c11625 < // If the caret is in an invalid location in FF we need to move it into the first block < if (sn == b && en == b && b.firstChild && ed.dom.isBlock(b.firstChild)) { < sn = en = sn.firstChild; < so = eo = 0; < rb = d.createRange(); < rb.setStart(sn, 0); < ra = d.createRange(); < ra.setStart(en, 0); < } < < // Never use body as start or end node < sn = sn.nodeName == "HTML" ? d.body : sn; // Fix for Opera bug: https://bugs.opera.com/show_bug.cgi?id=273224&comments=yes < sn = sn.nodeName == "BODY" ? sn.firstChild : sn; < en = en.nodeName == "HTML" ? d.body : en; // Fix for Opera bug: https://bugs.opera.com/show_bug.cgi?id=273224&comments=yes < en = en.nodeName == "BODY" ? en.firstChild : en; < < // Get start and end blocks < sb = t.getParentBlock(sn); < eb = t.getParentBlock(en); < bn = sb ? sb.nodeName : se.element; // Get block name to create --- > }); 11671,11673c11627,11628 < // Return inside list use default browser behavior < if (t.dom.getParent(sb, 'OL,UL,PRE')) < return true; --- > tinymce.EditorManager.preInit(); > })(tinymce); 11675,11679c11630,11636 < // If caption or absolute layers then always generate new blocks within < if (sb && (sb.nodeName == 'CAPTION' || /absolute|relative|fixed/gi.test(dom.getStyle(sb, 'position', 1)))) { < bn = se.element; < sb = null; < } --- > // Short for editor manager window.tinyMCE is needed when TinyMCE gets loaded though a XHR call > var tinyMCE = window.tinyMCE = tinymce.EditorManager; > (function(tinymce) { > var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, Dispatcher = tinymce.util.Dispatcher; > var each = tinymce.each, isGecko = tinymce.isGecko, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit; > var is = tinymce.is, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, EditorManager = tinymce.EditorManager; > var inArray = tinymce.inArray, grep = tinymce.grep, explode = tinymce.explode; 11681,11685c11638,11640 < // If caption or absolute layers then always generate new blocks within < if (eb && (eb.nodeName == 'CAPTION' || /absolute|relative|fixed/gi.test(dom.getStyle(sb, 'position', 1)))) { < bn = se.element; < eb = null; < } --- > tinymce.create('tinymce.Editor', { > Editor : function(id, s) { > var t = this; 11687,11691c11642,11646 < // Use P instead < if (/(TD|TABLE|TH|CAPTION)/.test(bn) || (sb && bn == "DIV" && /left|right/gi.test(dom.getStyle(sb, 'float', 1)))) { < bn = se.element; < sb = eb = null; < } --- > t.id = t.editorId = id; > t.execCommands = {}; > t.queryStateCommands = {}; > t.queryValueCommands = {}; > t.plugins = {}; 11693,11695c11648,11724 < // Setup new before and after blocks < bef = (sb && sb.nodeName == bn) ? sb.cloneNode(0) : ed.dom.create(bn); < aft = (eb && eb.nodeName == bn) ? eb.cloneNode(0) : ed.dom.create(bn); --- > // Add events to the editor > each([ > 'onPreInit', > 'onBeforeRenderUI', > 'onPostRender', > 'onInit', > 'onRemove', > 'onActivate', > 'onDeactivate', > 'onClick', > 'onEvent', > 'onMouseUp', > 'onMouseDown', > 'onDblClick', > 'onKeyDown', > 'onKeyUp', > 'onKeyPress', > 'onContextMenu', > 'onSubmit', > 'onReset', > 'onPaste', > 'onPreProcess', > 'onPostProcess', > 'onBeforeSetContent', > 'onBeforeGetContent', > 'onSetContent', > 'onGetContent', > 'onLoadContent', > 'onSaveContent', > 'onNodeChange', > 'onChange', > 'onBeforeExecCommand', > 'onExecCommand', > 'onUndo', > 'onRedo', > 'onVisualAid', > 'onSetProgressState' > ], function(e) { > t[e] = new Dispatcher(t); > }); > > // Default editor config > t.settings = s = extend({ > id : id, > language : 'en', > docs_language : 'en', > theme : 'simple', > skin : 'default', > delta_width : 0, > delta_height : 0, > popup_css : '', > plugins : '', > document_base_url : tinymce.documentBaseURL, > add_form_submit_trigger : 1, > submit_patch : 1, > add_unload_trigger : 1, > convert_urls : 1, > relative_urls : 1, > remove_script_host : 1, > table_inline_editing : 0, > object_resizing : 1, > cleanup : 1, > accessibility_focus : 1, > custom_shortcuts : 1, > custom_undo_redo_keyboard_shortcuts : 1, > custom_undo_redo_restore_selection : 1, > custom_undo_redo : 1, > doctype : '', > visual_table_class : 'mceItemTable', > visual : 1, > inline_styles : true, > convert_fonts_to_spans : true, > font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large', > apply_source_formatting : 1, > directionality : 'ltr', > forced_root_block : 'p', > valid_elements : '@[id|class|style|title|dir