| | |
| | | var tinymce = {
|
| | | majorVersion : '3',
|
| | | minorVersion : '2.3',
|
| | | releaseDate : '2009-04-23',
|
| | | minorVersion : '2.7',
|
| | | releaseDate : '2009-09-22',
|
| | |
|
| | | _init : function() {
|
| | | var t = this, d = document, w = window, na = navigator, ua = na.userAgent, i, nl, n, base, p, v;
|
| | |
|
| | | // Browser checks
|
| | | t.isOpera = w.opera && opera.buildNumber;
|
| | |
|
| | | t.isWebKit = /WebKit/.test(ua);
|
| | |
|
| | | t.isIE = !t.isWebKit && !t.isOpera && (/MSIE/gi).test(ua) && (/Explorer/gi).test(na.appName);
|
| | |
|
| | | t.isIE6 = t.isIE && /MSIE [56]/.test(ua);
|
| | |
|
| | | t.isGecko = !t.isWebKit && /Gecko/.test(ua);
|
| | |
|
| | | t.isMac = ua.indexOf('Mac') != -1;
|
| | |
|
| | | t.isAir = /adobeair/i.test(ua);
|
| | |
|
| | | // TinyMCE .NET webcontrol might be setting the values for TinyMCE
|
| | |
| | | }
|
| | |
|
| | | function getBase(n) {
|
| | | if (n.src && /tiny_mce(|_dev|_src|_gzip|_jquery|_prototype).js/.test(n.src)) {
|
| | | if (n.src && /tiny_mce(|_gzip|_jquery|_prototype)(_dev|_src)?.js/.test(n.src)) {
|
| | | if (/_(src|dev)\.js/g.test(n.src))
|
| | | t.suffix = '_src';
|
| | |
|
| | |
| | | t.baseURL = n.src.substring(0, n.src.lastIndexOf('/'));
|
| | |
|
| | | // If path to script is relative and a base href was found add that one infront
|
| | | if (base && t.baseURL.indexOf('://') == -1)
|
| | | // the src property will always be an absolute one on non IE browsers and IE 8
|
| | | // so this logic will basically only be executed on older IE versions
|
| | | if (base && t.baseURL.indexOf('://') == -1 && t.baseURL.indexOf('/') !== 0)
|
| | | t.baseURL = base + t.baseURL;
|
| | |
|
| | | return t.baseURL;
|
| | |
| | | return n == t;
|
| | | },
|
| | |
|
| | |
|
| | | each : function(o, cb, s) {
|
| | | var n, l;
|
| | |
|
| | |
| | |
|
| | | return 1;
|
| | | },
|
| | |
|
| | |
|
| | | map : function(a, f) {
|
| | | var o = [];
|
| | |
| | | return o;
|
| | | },
|
| | |
|
| | |
|
| | | trim : function(s) {
|
| | | return (s ? '' + s : '').replace(/^\s*|\s*$/g, '');
|
| | | },
|
| | |
|
| | |
|
| | | create : function(s, p) {
|
| | | var t = this, sp, ns, cn, scn, c, de = 0;
|
| | |
| | | o = o || window;
|
| | |
|
| | | n = n.split('.');
|
| | | for (i=0, l = n.length; i<l; i++) {
|
| | | for (i = 0, l = n.length; i < l; i++) {
|
| | | o = o[n[i]];
|
| | |
|
| | | if (!o)
|
| | |
| | | URI : function(u, s) {
|
| | | var t = this, o, a, b;
|
| | |
|
| | | // Trim whitespace
|
| | | u = tinymce.trim(u);
|
| | |
|
| | | // Default settings
|
| | | s = t.settings = s || {};
|
| | |
|
| | | // Strange app protocol or local anchor
|
| | | if (/^(mailto|tel|news|javascript|about):/i.test(u) || /^\s*#/.test(u)) {
|
| | | if (/^(mailto|tel|news|javascript|about|data):/i.test(u) || /^\s*#/.test(u)) {
|
| | | t.source = u;
|
| | | return;
|
| | | }
|
| | |
| | | if (u.indexOf('/') === 0 && u.indexOf('//') !== 0)
|
| | | u = (s.base_uri ? s.base_uri.protocol || 'http' : 'http') + '://mce_host' + u;
|
| | |
|
| | | // Relative path
|
| | | if (u.indexOf(':/') === -1 && u.indexOf('//') !== 0)
|
| | | // Relative path http:// or protocol relative //path
|
| | | if (!/^\w*:?\/\//.test(u))
|
| | | u = (s.base_uri.protocol || 'http') + '://mce_host' + t.toAbsPath(s.base_uri.path, u);
|
| | |
|
| | | // Parse URL (Credits goes to Steave, http://blog.stevenlevithan.com/archives/parseuri)
|
| | |
| | | toAbsolute : function(u, nh) {
|
| | | var u = new tinymce.util.URI(u, {base_uri : this});
|
| | |
|
| | | return u.getURI(this.host == u.host ? nh : 0);
|
| | | return u.getURI(this.host == u.host && this.protocol == u.protocol ? nh : 0);
|
| | | },
|
| | |
|
| | | toRelPath : function(base, path) {
|
| | |
| | | },
|
| | |
|
| | | toAbsPath : function(base, path) {
|
| | | var i, nb = 0, o = [], tr;
|
| | | var i, nb = 0, o = [], tr, outPath;
|
| | |
|
| | | // Split paths
|
| | | tr = /\/$/.test(path) ? '/' : '';
|
| | |
| | |
|
| | | // If /a/b/c or /
|
| | | if (i <= 0)
|
| | | return '/' + o.reverse().join('/') + tr;
|
| | | outPath = o.reverse().join('/');
|
| | | else
|
| | | outPath = base.slice(0, i).join('/') + '/' + o.reverse().join('/');
|
| | |
|
| | | return '/' + base.slice(0, i).join('/') + '/' + o.reverse().join('/') + tr;
|
| | | // Add front / if it's needed
|
| | | if (outPath.indexOf('/') !== 0)
|
| | | outPath = '/' + outPath;
|
| | |
|
| | | // Add traling / if it's needed
|
| | | if (tr && outPath.lastIndexOf('/') !== outPath.length - 1)
|
| | | outPath += tr;
|
| | |
|
| | | return outPath;
|
| | | },
|
| | |
|
| | | getURI : function(nh) {
|
| | |
| | |
|
| | | return t.source;
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | })();
|
| | | (function() {
|
| | | var each = tinymce.each;
|
| | |
| | |
|
| | | this.set(n, '', d, p, d);
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | })();
|
| | | tinymce.create('static tinymce.util.JSON', {
|
| | | serialize : function(o) {
|
| | |
| | | if (o.content_type)
|
| | | x.setRequestHeader('Content-Type', o.content_type);
|
| | |
|
| | | x.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
| | |
|
| | | x.send(o.data);
|
| | |
|
| | | function ready() {
|
| | |
| | | // Wait for response, onReadyStateChange can not be used since it leaks memory in IE
|
| | | t = w.setTimeout(ready, 10);
|
| | | }
|
| | |
|
| | | }
|
| | | }
|
| | | });
|
| | | (function() {
|
| | | var extend = tinymce.extend, JSON = tinymce.util.JSON, XHR = tinymce.util.XHR;
|
| | |
| | | return new tinymce.util.JSONRequest().send(o);
|
| | | }
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | }());(function(tinymce) {
|
| | | // Shorten names
|
| | | var each = tinymce.each, is = tinymce.is;
|
| | |
| | | t.boxModel = !tinymce.isIE || d.compatMode == "CSS1Compat";
|
| | | t.stdMode = d.documentMode === 8;
|
| | |
|
| | | this.settings = s = tinymce.extend({
|
| | | t.settings = s = tinymce.extend({
|
| | | keep_values : false,
|
| | | hex_colors : 1,
|
| | | process_html : 1
|
| | |
| | | };
|
| | | },
|
| | |
|
| | | is : function(n, patt) {
|
| | | return tinymce.dom.Sizzle.matches(patt, n.nodeType ? [n] : n).length > 0;
|
| | | },
|
| | |
|
| | | getParent : function(n, f, r) {
|
| | | return this.getParents(n, f, r, false);
|
| | | },
|
| | |
| | | return e;
|
| | | },
|
| | |
|
| | | getNext : function(node, selector) {
|
| | | return this._findSib(node, selector, 'nextSibling');
|
| | | },
|
| | |
|
| | | getPrev : function(node, selector) {
|
| | | return this._findSib(node, selector, 'previousSibling');
|
| | | },
|
| | |
|
| | |
|
| | | select : function(pa, s) {
|
| | | var t = this;
|
| | |
|
| | | return tinymce.dom.Sizzle(pa, t.get(s) || t.get(t.settings.root_element) || t.doc, []);
|
| | | },
|
| | |
|
| | | is : function(n, patt) {
|
| | | return tinymce.dom.Sizzle.matches(patt, n.nodeType ? [n] : n).length > 0;
|
| | | },
|
| | |
|
| | |
|
| | |
| | | return p.removeChild(n);
|
| | | });
|
| | | },
|
| | |
|
| | |
|
| | | setStyle : function(n, na, v) {
|
| | | var t = this;
|
| | |
| | | });
|
| | | },
|
| | |
|
| | |
|
| | | getAttrib : function(e, n, dv) {
|
| | | var v, t = this;
|
| | |
|
| | |
| | |
|
| | | if (!v)
|
| | | v = e.getAttribute(n, 2);
|
| | |
|
| | | // Check boolean attribs
|
| | | if (/^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)$/.test(n)) {
|
| | | if (e[t.props[n]] === true && v === '')
|
| | | return n;
|
| | |
|
| | | return v ? n : '';
|
| | | }
|
| | |
|
| | | // Inner input elements will override attributes on form elements
|
| | | if (e.nodeName === "FORM" && e.getAttributeNode(n))
|
| | | return e.getAttributeNode(n).nodeValue;
|
| | |
|
| | | if (n === 'style') {
|
| | | v = v || e.style.cssText;
|
| | |
| | | default:
|
| | | // IE has odd anonymous function for event attributes
|
| | | if (n.indexOf('on') === 0 && v)
|
| | | v = ('' + v).replace(/^function\s+anonymous\(\)\s+\{\s+(.*)\s+\}$/, '$1');
|
| | | v = ('' + v).replace(/^function\s+\w+\(\)\s+\{\s+(.*)\s+\}$/, '$1');
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | },
|
| | |
|
| | | loadCSS : function(u) {
|
| | | var t = this, d = t.doc;
|
| | | var t = this, d = t.doc, head;
|
| | |
|
| | | if (!u)
|
| | | u = '';
|
| | |
|
| | | head = t.select('head')[0];
|
| | |
|
| | | each(u.split(','), function(u) {
|
| | | var link;
|
| | |
|
| | | if (t.files[u])
|
| | | return;
|
| | |
|
| | | t.files[u] = true;
|
| | | t.add(t.select('head')[0], 'link', {rel : 'stylesheet', href : tinymce._addVer(u)});
|
| | | link = t.create('link', {rel : 'stylesheet', href : tinymce._addVer(u)});
|
| | |
|
| | | // IE 8 has a bug where dynamically loading stylesheets would produce a 1 item remaining bug
|
| | | // This fix seems to resolve that issue by realcing the document ones a stylesheet finishes loading
|
| | | // It's ugly but it seems to work fine.
|
| | | if (isIE && d.documentMode) {
|
| | | link.onload = function() {
|
| | | d.recalc();
|
| | | link.onload = null;
|
| | | };
|
| | | }
|
| | |
|
| | | head.appendChild(link);
|
| | | });
|
| | | },
|
| | |
|
| | |
|
| | | addClass : function(e, c) {
|
| | | return this.run(e, function(e) {
|
| | |
| | |
|
| | | return !e || e.style.display == 'none' || this.getStyle(e, 'display') == 'none';
|
| | | },
|
| | |
|
| | |
|
| | | uniqueId : function(p) {
|
| | | return (!p ? 'mce_' : p) + (this.counter++);
|
| | |
| | | if (x) {
|
| | | // So if we replace the p elements with divs and mark them and then replace them back to paragraphs
|
| | | // after we use innerHTML we can fix the DOM tree
|
| | | h = h.replace(/<p ([^>]+)>|<p>/g, '<div $1 mce_tmp="1">');
|
| | | h = h.replace(/<p ([^>]+)>|<p>/ig, '<div $1 mce_tmp="1">');
|
| | | h = h.replace(/<\/p>/g, '</div>');
|
| | |
|
| | | // Set the new HTML with DIVs
|
| | |
| | | },
|
| | |
|
| | | processHTML : function(h) {
|
| | | var t = this, s = t.settings;
|
| | | var t = this, s = t.settings, codeBlocks = [];
|
| | |
|
| | | if (!s.process_html)
|
| | | return h;
|
| | |
| | | // Store away src and href in mce_src and mce_href since browsers mess them up
|
| | | if (s.keep_values) {
|
| | | // Wrap scripts and styles in comments for serialization purposes
|
| | | if (/<script|style/.test(h)) {
|
| | | if (/<script|noscript|style/i.test(h)) {
|
| | | function trim(s) {
|
| | | // Remove prefix and suffix code for element
|
| | | s = s.replace(/(<!--\[CDATA\[|\]\]-->)/g, '\n');
|
| | |
| | | return s;
|
| | | };
|
| | |
|
| | | // Preserve script elements
|
| | | h = h.replace(/<script([^>]+|)>([\s\S]*?)<\/script>/g, function(v, a, b) {
|
| | | // Remove prefix and suffix code for script element
|
| | | b = trim(b);
|
| | |
|
| | | // Wrap the script contents in CDATA and keep them from executing
|
| | | h = h.replace(/<script([^>]+|)>([\s\S]*?)<\/script>/gi, function(v, attribs, text) {
|
| | | // Force type attribute
|
| | | if (!a)
|
| | | a = ' type="text/javascript"';
|
| | | if (!attribs)
|
| | | attribs = ' type="text/javascript"';
|
| | |
|
| | | // Wrap contents in a comment
|
| | | if (b)
|
| | | b = '<!--\n' + b + '\n// -->';
|
| | | // Convert the src attribute of the scripts
|
| | | attribs = attribs.replace(/src=\"([^\"]+)\"?/i, function(a, url) {
|
| | | if (s.url_converter)
|
| | | url = t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(url), 'src', 'script'));
|
| | |
|
| | | // Output fake element
|
| | | return '<mce:script' + a + '>' + b + '</mce:script>';
|
| | | return 'mce_src="' + url + '"';
|
| | | });
|
| | |
|
| | | // Wrap text contents
|
| | | if (tinymce.trim(text)) {
|
| | | codeBlocks.push(trim(text));
|
| | | text = '<!--\nMCE_SCRIPT:' + (codeBlocks.length - 1) + '\n// -->';
|
| | | }
|
| | |
|
| | | return '<mce:script' + attribs + '>' + text + '</mce:script>';
|
| | | });
|
| | |
|
| | | // Preserve style elements
|
| | | h = h.replace(/<style([^>]+|)>([\s\S]*?)<\/style>/g, function(v, a, b) {
|
| | | b = trim(b);
|
| | | return '<mce:style' + a + '><!--\n' + b + '\n--></mce:style><style' + a + ' mce_bogus="1">' + b + '</style>';
|
| | | // Wrap style elements
|
| | | h = h.replace(/<style([^>]+|)>([\s\S]*?)<\/style>/gi, function(v, attribs, text) {
|
| | | // Wrap text contents
|
| | | if (text) {
|
| | | codeBlocks.push(trim(text));
|
| | | text = '<!--\nMCE_SCRIPT:' + (codeBlocks.length - 1) + '\n-->';
|
| | | }
|
| | |
|
| | | return '<mce:style' + attribs + '>' + text + '</mce:style><style ' + attribs + ' mce_bogus="1">' + text + '</style>';
|
| | | });
|
| | |
|
| | | // Wrap noscript elements
|
| | | h = h.replace(/<noscript([^>]+|)>([\s\S]*?)<\/noscript>/g, function(v, attribs, text) {
|
| | | return '<mce:noscript' + attribs + '><!--' + t.encode(text).replace(/--/g, '--') + '--></mce:noscript>';
|
| | | });
|
| | | }
|
| | |
|
| | | h = h.replace(/<!\[CDATA\[([\s\S]+)\]\]>/g, '<!--[CDATA[$1]]-->');
|
| | |
|
| | | // Remove false bool attributes and force attributes into xhtml style attr="attr"
|
| | | h = h.replace(/<([\w:]+) [^>]*(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)[^>]*>/gi, function(val) {
|
| | | function handle(val, name, value) {
|
| | | // Remove false/0 attribs
|
| | | if (value === 'false' || value === '0')
|
| | | return '';
|
| | |
|
| | | return ' ' + name + '="' + name + '"';
|
| | | };
|
| | |
|
| | | val = val.replace(/ (checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)=[\"]([^\"]+)[\"]/gi, handle); // W3C
|
| | | val = val.replace(/ (checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)=[\']([^\']+)[\']/gi, handle); // W3C
|
| | | val = val.replace(/ (checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)=([^\s\"\'>]+)/gi, handle); // IE
|
| | | val = val.replace(/ (checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)([\s>])/gi, ' $1="$1"$2'); // Force attr="attr"
|
| | |
|
| | | return val;
|
| | | });
|
| | |
|
| | | // Process all tags with src, href or style
|
| | | h = h.replace(/<([\w:]+) [^>]*(src|href|style|shape|coords)[^>]*>/gi, function(a, n) {
|
| | |
| | | if (t._isRes(c))
|
| | | return m;
|
| | |
|
| | | if (s.hex_colors) {
|
| | | u = u.replace(/rgb\([^\)]+\)/g, function(v) {
|
| | | return t.toHex(v);
|
| | | });
|
| | | }
|
| | |
|
| | | if (s.url_converter) {
|
| | | u = u.replace(/url\([\'\"]?([^\)\'\"]+)\)/g, function(x, c) {
|
| | | return 'url(' + t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n)) + ')';
|
| | | });
|
| | | }
|
| | | // Parse and serialize the style to convert for example uppercase styles like "BORDER: 1px"
|
| | | u = t.encode(t.serializeStyle(t.parseStyle(u)));
|
| | | } else if (b != 'coords' && b != 'shape') {
|
| | | if (s.url_converter)
|
| | | u = t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n));
|
| | |
| | | a = a.replace(/ (src|href|style|coords|shape)=[\']([^\']+)[\']/gi, handle); // W3C
|
| | |
|
| | | return a.replace(/ (src|href|style|coords|shape)=([^\s\"\'>]+)/gi, handle); // IE
|
| | | });
|
| | |
|
| | | // Restore script blocks
|
| | | h = h.replace(/MCE_SCRIPT:([0-9]+)/g, function(val, idx) {
|
| | | return codeBlocks[idx];
|
| | | });
|
| | | }
|
| | |
|
| | |
| | | setOuterHTML : function(e, h, d) {
|
| | | var t = this;
|
| | |
|
| | | return this.run(e, function(e) {
|
| | | function setHTML(e, h, d) {
|
| | | var n, tp;
|
| | | |
| | | tp = d.createElement("body");
|
| | | tp.innerHTML = h;
|
| | |
|
| | | n = tp.lastChild;
|
| | | while (n) {
|
| | | t.insertAfter(n.cloneNode(true), e);
|
| | | n = n.previousSibling;
|
| | | }
|
| | |
|
| | | t.remove(e);
|
| | | };
|
| | |
|
| | | return this.run(e, function(e) {
|
| | | e = t.get(e);
|
| | | d = d || e.ownerDocument || t.doc;
|
| | |
|
| | | if (isIE && e.nodeType == 1)
|
| | | e.outerHTML = h;
|
| | | else {
|
| | | tp = d.createElement("body");
|
| | | tp.innerHTML = h;
|
| | | // Only set HTML on elements
|
| | | if (e.nodeType == 1) {
|
| | | d = d || e.ownerDocument || t.doc;
|
| | |
|
| | | n = tp.lastChild;
|
| | | while (n) {
|
| | | t.insertAfter(n.cloneNode(true), e);
|
| | | n = n.previousSibling;
|
| | | }
|
| | |
|
| | | t.remove(e);
|
| | | if (isIE) {
|
| | | try {
|
| | | // Try outerHTML for IE it sometimes produces an unknown runtime error
|
| | | if (isIE && e.nodeType == 1)
|
| | | e.outerHTML = h;
|
| | | else
|
| | | setHTML(e, h, d);
|
| | | } catch (ex) {
|
| | | // Fix for unknown runtime error
|
| | | setHTML(e, h, d);
|
| | | }
|
| | | } else
|
| | | setHTML(e, h, d);
|
| | | }
|
| | | });
|
| | | },
|
| | |
| | | }) : s;
|
| | | },
|
| | |
|
| | |
|
| | | insertAfter : function(n, r) {
|
| | | var t = this;
|
| | |
|
| | |
| | | });
|
| | | },
|
| | |
|
| | |
|
| | | isBlock : function(n) {
|
| | | if (n.nodeType && n.nodeType !== 1)
|
| | | return false;
|
| | |
|
| | | n = n.nodeName || n;
|
| | |
|
| | | return /^(H[1-6]|HR|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TR|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP)$/.test(n);
|
| | | return /^(H[1-6]|HR|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TH|TBODY|TR|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP)$/.test(n);
|
| | | },
|
| | |
|
| | |
|
| | | replace : function(n, o, k) {
|
| | | var t = this;
|
| | |
| | | return o.parentNode.replaceChild(n, o);
|
| | | });
|
| | | },
|
| | |
|
| | |
|
| | | findCommonAncestor : function(a, b) {
|
| | | var ps = a, pe;
|
| | |
| | | if (n.nodeName == 'OBJECT')
|
| | | return n.attributes;
|
| | |
|
| | | // IE doesn't keep the selected attribute if you clone option elements
|
| | | if (n.nodeName === 'OPTION' && this.getAttrib(n, 'selected'))
|
| | | o.push({specified : 1, nodeName : 'selected'});
|
| | |
|
| | | // It's crazy that this is faster in IE but it's because it returns all attributes all the time
|
| | | n.cloneNode(false).outerHTML.replace(/([a-z0-9\:\-_]+)=/gi, function(a, b) {
|
| | | o.push({specified : 1, nodeName : b});
|
| | | n.cloneNode(false).outerHTML.replace(/<\/?[\w:]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=\w+|>/gi, '').replace(/[\w:]+/gi, function(a) {
|
| | | o.push({specified : 1, nodeName : a});
|
| | | });
|
| | |
|
| | | return o;
|
| | |
| | | destroy : function(s) {
|
| | | var t = this;
|
| | |
|
| | | t.win = t.doc = t.root = null;
|
| | | if (t.events)
|
| | | t.events.destroy();
|
| | |
|
| | | t.win = t.doc = t.root = t.events = null;
|
| | |
|
| | | // Manual destroy then remove unload handler
|
| | | if (!s)
|
| | |
| | | return n.replace(/[ \t\r\n]+| | /g, '') == '';
|
| | | };
|
| | |
|
| | | // Added until Gecko can create real HTML documents using implementation.createHTMLDocument
|
| | | // this is to future proof it if Gecko decides to implement the error checking for range methods.
|
| | | function nodeIndex(n) {
|
| | | var i = 0;
|
| | |
|
| | | while (n.previousSibling) {
|
| | | i++;
|
| | | n = n.previousSibling;
|
| | | }
|
| | |
|
| | | return i;
|
| | | };
|
| | |
|
| | | if (pe && e) {
|
| | | // Get before chunk
|
| | | r.setStartBefore(pe);
|
| | | r.setEndBefore(e);
|
| | | r.setStart(pe.parentNode, nodeIndex(pe));
|
| | | r.setEnd(e.parentNode, nodeIndex(e));
|
| | | bef = r.extractContents();
|
| | |
|
| | | // Get after chunk
|
| | | r = t.createRng();
|
| | | r.setStartAfter(e);
|
| | | r.setEndAfter(pe);
|
| | | r.setStart(e.parentNode, nodeIndex(e) + 1);
|
| | | r.setEnd(pe.parentNode, nodeIndex(pe) + 1);
|
| | | aft = r.extractContents();
|
| | |
|
| | | // Insert chunks and remove parent
|
| | |
| | | }
|
| | | },
|
| | |
|
| | | bind : function(target, name, func, scope) {
|
| | | var t = this;
|
| | |
|
| | | if (!t.events)
|
| | | t.events = new tinymce.dom.EventUtils();
|
| | |
|
| | | return t.events.add(target, name, func, scope || this);
|
| | | },
|
| | |
|
| | | unbind : function(target, name, func) {
|
| | | var t = this;
|
| | |
|
| | | if (!t.events)
|
| | | t.events = new tinymce.dom.EventUtils();
|
| | |
|
| | | return t.events.remove(target, name, func);
|
| | | },
|
| | |
|
| | |
|
| | | _findSib : function(node, selector, name) {
|
| | | var t = this, f = selector;
|
| | |
|
| | | if (node) {
|
| | | // If expression make a function of it using is
|
| | | if (is(f, 'string')) {
|
| | | f = function(node) {
|
| | | return t.is(node, selector);
|
| | | };
|
| | | }
|
| | |
|
| | | // Loop all siblings
|
| | | for (node = node[name]; node; node = node[name]) {
|
| | | if (f(node))
|
| | | return node;
|
| | | }
|
| | | }
|
| | |
|
| | | return null;
|
| | | },
|
| | |
|
| | | _isRes : function(c) {
|
| | | // Is live resizble element
|
| | |
| | | return s;
|
| | | }
|
| | | */
|
| | | });
|
| | |
|
| | | });
|
| | |
|
| | | // Setup page DOM
|
| | | tinymce.DOM = new tinymce.dom.DOMUtils(document, {process_html : 0});
|
| | | })(tinymce);
|
| | | (function(ns) {
|
| | |
| | | if (sc == ec && sc.nodeType == 3) {
|
| | | startPos = getCharPos(sc, so);
|
| | |
|
| | | ieRng = body.createTextRange();
|
| | | ieRng.move('character', startPos);
|
| | | ieRng.moveEnd('character', eo - so);
|
| | | ieRng.select();
|
| | |
| | | // Shorten names
|
| | | var each = tinymce.each, DOM = tinymce.DOM, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit, Event;
|
| | |
|
| | | tinymce.create('static tinymce.dom.Event', {
|
| | | inits : [],
|
| | | events : [],
|
| | |
|
| | | tinymce.create('tinymce.dom.EventUtils', {
|
| | | EventUtils : function() {
|
| | | this.inits = [];
|
| | | this.events = [];
|
| | | },
|
| | |
|
| | | add : function(o, n, f, s) {
|
| | | var cb, t = this, el = t.events, r;
|
| | |
|
| | | if (n instanceof Array) {
|
| | | r = [];
|
| | |
|
| | | each(n, function(n) {
|
| | | r.push(t.add(o, n, f, s));
|
| | | });
|
| | |
|
| | | return r;
|
| | | }
|
| | |
|
| | | // Handle array
|
| | | if (o && o.hasOwnProperty && o instanceof Array) {
|
| | |
| | |
|
| | | // Setup event callback
|
| | | cb = function(e) {
|
| | | // Is all events disabled
|
| | | if (t.disabled)
|
| | | return;
|
| | |
|
| | | e = e || window.event;
|
| | |
|
| | | // Patch in target in IE it's W3C valid
|
| | | if (e && !e.target && isIE)
|
| | | e.target = e.srcElement;
|
| | | // Patch in target, preventDefault and stopPropagation in IE it's W3C valid
|
| | | if (e && isIE) {
|
| | | if (!e.target)
|
| | | e.target = e.srcElement;
|
| | |
|
| | | // Patch in preventDefault, stopPropagation methods for W3C compatibility
|
| | | tinymce.extend(e, t._stoppers);
|
| | | }
|
| | |
|
| | | if (!s)
|
| | | return f(e);
|
| | |
| | | }
|
| | | },
|
| | |
|
| | |
|
| | | cancel : function(e) {
|
| | | if (!e)
|
| | | return false;
|
| | |
|
| | | this.stop(e);
|
| | |
|
| | | return this.prevent(e);
|
| | | },
|
| | |
|
| | |
| | | return false;
|
| | | },
|
| | |
|
| | | _unload : function() {
|
| | | var t = Event;
|
| | | destroy : function() {
|
| | | var t = this;
|
| | |
|
| | | each(t.events, function(e, i) {
|
| | | t._remove(e.obj, e.name, e.cfunc);
|
| | |
| | | }
|
| | | },
|
| | |
|
| | | _pageInit : function() {
|
| | | var e = Event;
|
| | | _pageInit : function(win) {
|
| | | var t = this;
|
| | |
|
| | | // Keep it from running more than once
|
| | | if (e.domLoaded)
|
| | | if (t.domLoaded)
|
| | | return;
|
| | |
|
| | | e._remove(window, 'DOMContentLoaded', e._pageInit);
|
| | | e.domLoaded = true;
|
| | | t.domLoaded = true;
|
| | |
|
| | | each(e.inits, function(c) {
|
| | | each(t.inits, function(c) {
|
| | | c();
|
| | | });
|
| | |
|
| | | e.inits = [];
|
| | | t.inits = [];
|
| | | },
|
| | |
|
| | | _wait : function() {
|
| | | _wait : function(win) {
|
| | | var t = this, doc = win.document;
|
| | |
|
| | | // No need since the document is already loaded
|
| | | if (window.tinyMCE_GZ && tinyMCE_GZ.loaded) {
|
| | | Event.domLoaded = 1;
|
| | | if (win.tinyMCE_GZ && tinyMCE_GZ.loaded) {
|
| | | t.domLoaded = 1;
|
| | | return;
|
| | | }
|
| | |
|
| | | // Use IE method
|
| | | if (document.attachEvent) {
|
| | | document.attachEvent("onreadystatechange", function() {
|
| | | if (document.readyState === "complete") {
|
| | | document.detachEvent("onreadystatechange", arguments.callee);
|
| | | Event._pageInit();
|
| | | if (doc.attachEvent) {
|
| | | doc.attachEvent("onreadystatechange", function() {
|
| | | if (doc.readyState === "complete") {
|
| | | doc.detachEvent("onreadystatechange", arguments.callee);
|
| | | t._pageInit(win);
|
| | | }
|
| | | });
|
| | |
|
| | | if (document.documentElement.doScroll && window == window.top) {
|
| | | if (doc.documentElement.doScroll && win == win.top) {
|
| | | (function() {
|
| | | if (Event.domLoaded)
|
| | | if (t.domLoaded)
|
| | | return;
|
| | |
|
| | | try {
|
| | | // If IE is used, use the trick by Diego Perini
|
| | | // http://javascript.nwbox.com/IEContentLoaded/
|
| | | document.documentElement.doScroll("left");
|
| | | doc.documentElement.doScroll("left");
|
| | | } catch (ex) {
|
| | | setTimeout(arguments.callee, 0);
|
| | | return;
|
| | | }
|
| | |
|
| | | Event._pageInit();
|
| | | t._pageInit(win);
|
| | | })();
|
| | | }
|
| | | } else if (document.addEventListener)
|
| | | Event._add(window, 'DOMContentLoaded', Event._pageInit, Event);
|
| | | } else if (doc.addEventListener) {
|
| | | t._add(win, 'DOMContentLoaded', function() {
|
| | | t._pageInit(win);
|
| | | });
|
| | | }
|
| | |
|
| | | Event._add(window, 'load', Event._pageInit, Event);
|
| | | t._add(win, 'load', function() {
|
| | | t._pageInit(win);
|
| | | });
|
| | | },
|
| | |
|
| | | _stoppers : {
|
| | | preventDefault : function() {
|
| | | this.returnValue = false;
|
| | | },
|
| | |
|
| | | stopPropagation : function() {
|
| | | this.cancelBubble = true;
|
| | | }
|
| | | }
|
| | | });
|
| | |
|
| | | });
|
| | |
|
| | | // Shorten name
|
| | | Event = tinymce.dom.Event;
|
| | | Event = tinymce.dom.Event = new tinymce.dom.EventUtils();
|
| | |
|
| | | // Dispatch DOM content loaded event for IE and Safari
|
| | | Event._wait();
|
| | | tinymce.addUnload(Event._unload);
|
| | | Event._wait(window);
|
| | |
|
| | | tinymce.addUnload(function() {
|
| | | Event.destroy();
|
| | | });
|
| | | })(tinymce);
|
| | | (function(tinymce) {
|
| | | var each = tinymce.each;
|
| | |
| | | dom.setStyle(b, 'zIndex', parseInt(t.getStyle('zIndex', 1) || 0) - 1);
|
| | | }
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | })(tinymce);
|
| | | (function(tinymce) {
|
| | | function trimNl(s) {
|
| | |
| | | sy = vp.y;
|
| | |
|
| | | // Simple bookmark fast but not as persistent
|
| | | if (si == 'simple')
|
| | | if (si)
|
| | | return {rng : r, scrollX : sx, scrollY : sy};
|
| | |
|
| | | // Handle IE
|
| | |
| | |
|
| | | // Handle explorer
|
| | | if (isIE) {
|
| | | t.tridentSel.destroy();
|
| | |
|
| | | // Handle simple
|
| | | if (r = b.rng) {
|
| | | try {
|
| | |
| | | if (!s)
|
| | | tinymce.removeUnload(t.destroy);
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | })(tinymce);
|
| | | (function(tinymce) {
|
| | | tinymce.create('tinymce.dom.XMLWriter', {
|
| | |
| | | },
|
| | |
|
| | | writeCDATA : function(v) {
|
| | | this.node.appendChild(this.doc.createCDATA(v));
|
| | | this.node.appendChild(this.doc.createCDATASection(v));
|
| | | },
|
| | |
|
| | | writeComment : function(v) {
|
| | |
| | |
|
| | | return h;
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | })(tinymce);
|
| | | (function(tinymce) {
|
| | | tinymce.create('tinymce.dom.StringWriter', {
|
| | |
| | | StringWriter : function(s) {
|
| | | this.settings = tinymce.extend({
|
| | | indent_char : ' ',
|
| | | indentation : 1
|
| | | indentation : 0
|
| | | }, s);
|
| | |
|
| | | this.reset();
|
| | |
| | |
|
| | | return true;
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | })(tinymce);
|
| | | (function(tinymce) {
|
| | | // Shorten names
|
| | |
| | | valid_nodes : 0,
|
| | | node_filter : 0,
|
| | | attr_filter : 0,
|
| | | invalid_attrs : /^(mce_|_moz_)/,
|
| | | invalid_attrs : /^(mce_|_moz_|sizset|sizcache)/,
|
| | | closed : /^(br|hr|input|meta|img|link|param|area)$/,
|
| | | entity_encoding : 'named',
|
| | | entities : '160,nbsp,161,iexcl,162,cent,163,pound,164,curren,165,yen,166,brvbar,167,sect,168,uml,169,copy,170,ordf,171,laquo,172,not,173,shy,174,reg,175,macr,176,deg,177,plusmn,178,sup2,179,sup3,180,acute,181,micro,182,para,183,middot,184,cedil,185,sup1,186,ordm,187,raquo,188,frac14,189,frac12,190,frac34,191,iquest,192,Agrave,193,Aacute,194,Acirc,195,Atilde,196,Auml,197,Aring,198,AElig,199,Ccedil,200,Egrave,201,Eacute,202,Ecirc,203,Euml,204,Igrave,205,Iacute,206,Icirc,207,Iuml,208,ETH,209,Ntilde,210,Ograve,211,Oacute,212,Ocirc,213,Otilde,214,Ouml,215,times,216,Oslash,217,Ugrave,218,Uacute,219,Ucirc,220,Uuml,221,Yacute,222,THORN,223,szlig,224,agrave,225,aacute,226,acirc,227,atilde,228,auml,229,aring,230,aelig,231,ccedil,232,egrave,233,eacute,234,ecirc,235,euml,236,igrave,237,iacute,238,icirc,239,iuml,240,eth,241,ntilde,242,ograve,243,oacute,244,ocirc,245,otilde,246,ouml,247,divide,248,oslash,249,ugrave,250,uacute,251,ucirc,252,uuml,253,yacute,254,thorn,255,yuml,402,fnof,913,Alpha,914,Beta,915,Gamma,916,Delta,917,Epsilon,918,Zeta,919,Eta,920,Theta,921,Iota,922,Kappa,923,Lambda,924,Mu,925,Nu,926,Xi,927,Omicron,928,Pi,929,Rho,931,Sigma,932,Tau,933,Upsilon,934,Phi,935,Chi,936,Psi,937,Omega,945,alpha,946,beta,947,gamma,948,delta,949,epsilon,950,zeta,951,eta,952,theta,953,iota,954,kappa,955,lambda,956,mu,957,nu,958,xi,959,omicron,960,pi,961,rho,962,sigmaf,963,sigma,964,tau,965,upsilon,966,phi,967,chi,968,psi,969,omega,977,thetasym,978,upsih,982,piv,8226,bull,8230,hellip,8242,prime,8243,Prime,8254,oline,8260,frasl,8472,weierp,8465,image,8476,real,8482,trade,8501,alefsym,8592,larr,8593,uarr,8594,rarr,8595,darr,8596,harr,8629,crarr,8656,lArr,8657,uArr,8658,rArr,8659,dArr,8660,hArr,8704,forall,8706,part,8707,exist,8709,empty,8711,nabla,8712,isin,8713,notin,8715,ni,8719,prod,8721,sum,8722,minus,8727,lowast,8730,radic,8733,prop,8734,infin,8736,ang,8743,and,8744,or,8745,cap,8746,cup,8747,int,8756,there4,8764,sim,8773,cong,8776,asymp,8800,ne,8801,equiv,8804,le,8805,ge,8834,sub,8835,sup,8836,nsub,8838,sube,8839,supe,8853,oplus,8855,otimes,8869,perp,8901,sdot,8968,lceil,8969,rceil,8970,lfloor,8971,rfloor,9001,lang,9002,rang,9674,loz,9824,spades,9827,clubs,9829,hearts,9830,diams,338,OElig,339,oelig,352,Scaron,353,scaron,376,Yuml,710,circ,732,tilde,8194,ensp,8195,emsp,8201,thinsp,8204,zwnj,8205,zwj,8206,lrm,8207,rlm,8211,ndash,8212,mdash,8216,lsquo,8217,rsquo,8218,sbquo,8220,ldquo,8221,rdquo,8222,bdquo,8224,dagger,8225,Dagger,8240,permil,8249,lsaquo,8250,rsaquo,8364,euro',
|
| | | bool_attrs : /(checked|disabled|readonly|selected|nowrap)/,
|
| | | valid_elements : '*[*]',
|
| | | extended_valid_elements : 0,
|
| | | valid_child_elements : 0,
|
| | |
| | |
|
| | | if (s.fix_table_elements) {
|
| | | t.onPreProcess.add(function(se, o) {
|
| | | each(t.dom.select('p table', o.node), function(n) {
|
| | | t.dom.split(t.dom.getParent(n, 'p'), n);
|
| | | });
|
| | | // Since Opera will crash if you attach the node to a dynamic document we need to brrowser sniff a specific build
|
| | | // so Opera users with an older version will have to live with less compaible output not much we can do here
|
| | | if (!tinymce.isOpera || opera.buildNumber() >= 1767) {
|
| | | each(t.dom.select('p table', o.node).reverse(), function(n) {
|
| | | var parent = t.dom.getParent(n.parentNode, 'table,p');
|
| | |
|
| | | if (parent.nodeName != 'TABLE') {
|
| | | try {
|
| | | t.dom.split(parent, n);
|
| | | } catch (ex) {
|
| | | // IE can sometimes fire an unknown runtime error so we just ignore it
|
| | | }
|
| | | }
|
| | | });
|
| | | }
|
| | | });
|
| | | }
|
| | | },
|
| | |
| | | },
|
| | |
|
| | | serialize : function(n, o) {
|
| | | var h, t = this;
|
| | | var h, t = this, doc, oldDoc, impl, selected;
|
| | |
|
| | | t._setup();
|
| | | o = o || {};
|
| | | o.format = o.format || 'html';
|
| | | t.processObj = o;
|
| | |
|
| | | // IE looses the selected attribute on option elements so we need to store it
|
| | | // See: http://support.microsoft.com/kb/829907
|
| | | if (isIE) {
|
| | | selected = [];
|
| | | each(n.getElementsByTagName('option'), function(n) {
|
| | | var v = t.dom.getAttrib(n, 'selected');
|
| | |
|
| | | selected.push(v ? v : null);
|
| | | });
|
| | | }
|
| | |
|
| | | n = n.cloneNode(true);
|
| | |
|
| | | // IE looses the selected attribute on option elements so we need to restore it
|
| | | if (isIE) {
|
| | | each(n.getElementsByTagName('option'), function(n, i) {
|
| | | t.dom.setAttrib(n, 'selected', selected[i]);
|
| | | });
|
| | | }
|
| | |
|
| | | // Nodes needs to be attached to something in WebKit/Opera
|
| | | // Older builds of Opera crashes if you attach the node to an document created dynamically
|
| | | // and since we can't feature detect a crash we need to sniff the acutal build number
|
| | | // This fix will make DOM ranges and make Sizzle happy!
|
| | | impl = n.ownerDocument.implementation;
|
| | | if (impl.createHTMLDocument && (tinymce.isOpera && opera.buildNumber() >= 1767)) {
|
| | | // Create an empty HTML document
|
| | | doc = impl.createHTMLDocument("");
|
| | |
|
| | | // Add the element or it's children if it's a body element to the new document
|
| | | each(n.nodeName == 'BODY' ? n.childNodes : [n], function(node) {
|
| | | doc.body.appendChild(doc.importNode(node, true));
|
| | | });
|
| | |
|
| | | // Grab first child or body element for serialization
|
| | | if (n.nodeName != 'BODY')
|
| | | n = doc.body.firstChild;
|
| | | else
|
| | | n = doc.body;
|
| | |
|
| | | // set the new document in DOMUtils so createElement etc works
|
| | | oldDoc = t.dom.doc;
|
| | | t.dom.doc = doc;
|
| | | }
|
| | |
|
| | | t.key = '' + (parseInt(t.key) + 1);
|
| | |
|
| | | // Pre process
|
| | |
| | |
|
| | | // Post process
|
| | | o.content = t.writer.getContent();
|
| | |
|
| | | // Restore the old document if it was changed
|
| | | if (oldDoc)
|
| | | t.dom.doc = oldDoc;
|
| | |
|
| | | if (!o.no_events)
|
| | | t.onPostProcess.dispatch(t, o);
|
| | |
| | | content : h,
|
| | | patterns : [
|
| | | {pattern : /(<script[^>]*>)(.*?)(<\/script>)/g},
|
| | | {pattern : /(<noscript[^>]*>)(.*?)(<\/noscript>)/g},
|
| | | {pattern : /(<style[^>]*>)(.*?)(<\/style>)/g},
|
| | | {pattern : /(<pre[^>]*>)(.*?)(<\/pre>)/g, encode : 1},
|
| | | {pattern : /(<!--\[CDATA\[)(.*?)(\]\]-->)/g}
|
| | |
| | | // Restore the \u00a0 character if raw mode is enabled
|
| | | if (s.entity_encoding == 'raw')
|
| | | h = h.replace(/<p> <\/p>|<p([^>]+)> <\/p>/g, '<p$1>\u00a0</p>');
|
| | |
|
| | | // Restore noscript elements
|
| | | h = h.replace(/<noscript([^>]+|)>([\s\S]*?)<\/noscript>/g, function(v, attribs, text) {
|
| | | return '<noscript' + attribs + '>' + t.dom.decode(text.replace(/<!--|-->/g, '')) + '</noscript>';
|
| | | });
|
| | | }
|
| | |
|
| | | o.content = h;
|
| | | },
|
| | |
|
| | | _serializeNode : function(n, inn) {
|
| | | var t = this, s = t.settings, w = t.writer, hc, el, cn, i, l, a, at, no, v, nn, ru, ar, iv;
|
| | | var t = this, s = t.settings, w = t.writer, hc, el, cn, i, l, a, at, no, v, nn, ru, ar, iv, closed;
|
| | |
|
| | | if (!s.node_filter || s.node_filter(n)) {
|
| | | switch (n.nodeType) {
|
| | |
| | | nn = nn.substring(4);
|
| | |
|
| | | // Check if valid
|
| | | if (!t.validElementsRE.test(nn) || (t.invalidElementsRE && t.invalidElementsRE.test(nn)) || inn) {
|
| | | if (!t.validElementsRE || !t.validElementsRE.test(nn) || (t.invalidElementsRE && t.invalidElementsRE.test(nn)) || inn) {
|
| | | iv = true;
|
| | | break;
|
| | | }
|
| | |
| | |
|
| | | ru = t.findRule(nn);
|
| | | nn = ru.name || nn;
|
| | | closed = s.closed.test(nn);
|
| | |
|
| | | // Skip empty nodes or empty node name in IE
|
| | | if ((!hc && ru.noEmpty) || (isIE && !nn)) {
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | // Write text from script
|
| | | if (nn === 'script' && tinymce.trim(n.innerHTML)) {
|
| | | w.writeText('// '); // Padd it with a comment so it will parse on older browsers
|
| | | w.writeCDATA(n.innerHTML.replace(/<!--|-->|<\[CDATA\[|\]\]>/g, '')); // Remove comments and cdata stuctures
|
| | | hc = false;
|
| | | break;
|
| | | }
|
| | |
|
| | | // Padd empty nodes with a
|
| | | if (ru.padd) {
|
| | | // If it has only one bogus child, padd it anyway workaround for <td><br /></td> bug
|
| | |
| | | } else if (n.nodeType == 1)
|
| | | hc = n.hasChildNodes();
|
| | |
|
| | | if (hc) {
|
| | | if (hc && !closed) {
|
| | | cn = n.firstChild;
|
| | |
|
| | | while (cn) {
|
| | |
| | |
|
| | | // Write element end
|
| | | if (!iv) {
|
| | | if (hc || !s.closed.test(nn))
|
| | | if (!closed)
|
| | | w.writeFullEndElement();
|
| | | else
|
| | | w.writeEndElement();
|
| | |
| | |
|
| | | v = this.dom.getAttrib(n, na);
|
| | |
|
| | | // Bool attr
|
| | | if (this.settings.bool_attrs.test(na) && v) {
|
| | | v = ('' + v).toLowerCase();
|
| | |
|
| | | if (v === 'false' || v === '0')
|
| | | return null;
|
| | |
|
| | | v = na;
|
| | | }
|
| | |
|
| | | switch (na) {
|
| | | case 'rowspan':
|
| | | case 'colspan':
|
| | |
| | |
|
| | | return v;
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | })(tinymce);
|
| | | (function(tinymce) {
|
| | | var each = tinymce.each, Event = tinymce.dom.Event;
|
| | |
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | |
|
| | | // Global script loader
|
| | | tinymce.ScriptLoader = new tinymce.dom.ScriptLoader();
|
| | |
| | | destroy : function() {
|
| | | tinymce.dom.Event.clear(this.id);
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | })(tinymce);tinymce.create('tinymce.ui.Container:tinymce.ui.Control', {
|
| | | Container : function(id, s) {
|
| | | this.parent(id, s);
|
| | |
|
| | | this.controls = [];
|
| | |
|
| | | this.lookup = {};
|
| | | },
|
| | |
|
| | |
| | | get : function(n) {
|
| | | return this.lookup[n];
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | |
|
| | | tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
|
| | | Separator : function(id, s) {
|
| | |
| | | renderHTML : function() {
|
| | | return tinymce.DOM.createHTML('span', {'class' : this.classPrefix});
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | (function(tinymce) {
|
| | | var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk;
|
| | |
|
| | |
| | | if (is(t.selected))
|
| | | t.setSelected(t.selected);
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | })(tinymce);
|
| | | (function(tinymce) {
|
| | | var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk;
|
| | |
| | |
|
| | | return m;
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | })(tinymce);(function(tinymce) {
|
| | | var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, Event = tinymce.dom.Event, Element = tinymce.dom.Element;
|
| | |
|
| | |
| | |
|
| | | DOM.addClass(ro, 'mceLast');
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | })(tinymce);(function(tinymce) {
|
| | | var DOM = tinymce.DOM;
|
| | |
|
| | |
| | | return s.onclick.call(s.scope, e);
|
| | | });
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | })(tinymce);
|
| | | (function(tinymce) {
|
| | | var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher;
|
| | |
| | | var t = this;
|
| | |
|
| | | t.parent(id, s);
|
| | |
|
| | | t.items = [];
|
| | |
|
| | | t.onChange = new Dispatcher(t);
|
| | |
|
| | | t.onPostRender = new Dispatcher(t);
|
| | |
|
| | | t.onAdd = new Dispatcher(t);
|
| | |
|
| | | t.onRenderMenu = new tinymce.util.Dispatcher(this);
|
| | |
|
| | | t.classPrefix = 'mceListBox';
|
| | | },
|
| | |
|
| | |
| | | this.parent();
|
| | |
|
| | | Event.clear(this.id + '_text');
|
| | | Event.clear(this.id + '_open');
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | })(tinymce);(function(tinymce) {
|
| | | var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher;
|
| | |
|
| | |
| | |
|
| | | t.onPostRender.dispatch(t, DOM.get(t.id));
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | })(tinymce);(function(tinymce) {
|
| | | var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each;
|
| | |
|
| | | tinymce.create('tinymce.ui.MenuButton:tinymce.ui.Button', {
|
| | | MenuButton : function(id, s) {
|
| | | this.parent(id, s);
|
| | |
|
| | | this.onRenderMenu = new tinymce.util.Dispatcher(this);
|
| | |
|
| | | s.menu_container = s.menu_container || DOM.doc.body;
|
| | | },
|
| | |
|
| | |
| | | }
|
| | | });
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | })(tinymce);
|
| | | (function(tinymce) {
|
| | | var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each;
|
| | |
| | | Event.clear(this.id + '_action');
|
| | | Event.clear(this.id + '_open');
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | })(tinymce);
|
| | | (function(tinymce) {
|
| | | var DOM = tinymce.DOM, Event = tinymce.dom.Event, is = tinymce.is, each = tinymce.each;
|
| | |
| | | }, t.settings);
|
| | |
|
| | | t.onShowMenu = new tinymce.util.Dispatcher(t);
|
| | |
|
| | | t.onHideMenu = new tinymce.util.Dispatcher(t);
|
| | |
|
| | | t.value = s.default_color;
|
| | |
| | | e = 0;
|
| | |
|
| | | Event.add(DOM.doc, 'mousedown', t.hideMenu, t);
|
| | | t.onShowMenu.dispatch(t);
|
| | |
|
| | | if (t._focused) {
|
| | | t._keyHandler = Event.add(t.id + '_menu', 'keydown', function(e) {
|
| | |
| | |
|
| | | DOM.select('a', t.id + '_menu')[0].focus(); // Select first link
|
| | | }
|
| | |
|
| | | t.onShowMenu.dispatch(t);
|
| | |
|
| | | t.isMenuVisible = 1;
|
| | | },
|
| | |
| | | Event.clear(this.id + '_more');
|
| | | DOM.remove(this.id + '_menu');
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | })(tinymce);
|
| | | tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
| | | renderHTML : function() {
|
| | |
| | |
|
| | | return dom.createHTML('table', {id : t.id, 'class' : 'mceToolbar' + (s['class'] ? ' ' + s['class'] : ''), cellpadding : '0', cellspacing : '0', align : t.settings.align || ''}, '<tbody><tr>' + h + '</tr></tbody>');
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | (function(tinymce) {
|
| | | var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each;
|
| | |
|
| | |
| | | items : [],
|
| | | urls : {},
|
| | | lookup : {},
|
| | |
|
| | | onAdd : new Dispatcher(this),
|
| | |
|
| | | get : function(n) {
|
| | |
| | | t.urls[n] = u.substring(0, u.lastIndexOf('/'));
|
| | | tinymce.ScriptLoader.add(u, cb, s);
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | |
|
| | | // Create plugin and theme managers
|
| | | tinymce.PluginManager = new tinymce.AddOnManager();
|
| | | tinymce.ThemeManager = new tinymce.AddOnManager();
|
| | | }(tinymce));(function(tinymce) {
|
| | | }(tinymce));
|
| | |
|
| | | (function(tinymce) {
|
| | | // Shorten names
|
| | | var each = tinymce.each, extend = tinymce.extend, DOM = tinymce.DOM, Event = tinymce.dom.Event, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, explode = tinymce.explode;
|
| | |
|
| | | tinymce.create('static tinymce.EditorManager', {
|
| | | editors : {},
|
| | |
|
| | | i18n : {},
|
| | | |
| | | activeEditor : null,
|
| | |
|
| | | preInit : function() {
|
| | |
| | |
|
| | | tinymce.baseURL = new tinymce.util.URI(tinymce.documentBaseURL).toAbsolute(tinymce.baseURL);
|
| | | tinymce.EditorManager.baseURI = new tinymce.util.URI(tinymce.baseURL);
|
| | |
|
| | | // User specified a document.domain value
|
| | | if (document.domain && lo.hostname != document.domain)
|
| | | tinymce.relaxedDomain = document.domain;
|
| | |
|
| | | // Add before unload listener
|
| | | // This was required since IE was leaking memory if you added and removed beforeunload listeners
|
| | |
| | | // Load plugins
|
| | | if (s.plugins) {
|
| | | pl = explode(s.plugins);
|
| | |
|
| | | // Load compat2x first
|
| | | if (tinymce.inArray(pl, 'compat2x') != -1)
|
| | | PluginManager.load('compat2x', 'plugins/compat2x/editor_plugin' + tinymce.suffix + '.js');
|
| | |
|
| | | // Load rest if plugins
|
| | | each(pl, function(v) {
|
| | |
| | |
|
| | | // Select another editor since the active one was removed
|
| | | if (t.activeEditor == e) {
|
| | | t._setActive(null);
|
| | |
|
| | | each(t.editors, function(e) {
|
| | | t._setActive(e);
|
| | | return false; // Break
|
| | |
| | | _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 t = this;
|
| | |
|
| | | t.id = t.editorId = id;
|
| | |
|
| | | t.execCommands = {};
|
| | | t.queryStateCommands = {};
|
| | | t.queryValueCommands = {};
|
| | |
|
| | | t.isNotDirty = false;
|
| | |
|
| | | 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',
|
| | |
| | | apply_source_formatting : 1,
|
| | | directionality : 'ltr',
|
| | | forced_root_block : 'p',
|
| | | valid_elements : '@[id|class|style|title|dir<ltr?rtl|lang|xml::lang|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],a[rel|rev|charset|hreflang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur],strong/b,em/i,strike,u,#p[align],-ol[type|compact],-ul[type|compact],-li,br,img[longdesc|usemap|src|border|alt=|title|hspace|vspace|width|height|align],-sub,-sup,-blockquote[cite],-table[border=0|cellspacing|cellpadding|width|frame|rules|height|align|summary|bgcolor|background|bordercolor],-tr[rowspan|width|height|align|valign|bgcolor|background|bordercolor],tbody,thead,tfoot,#td[colspan|rowspan|width|height|align|valign|bgcolor|background|bordercolor|scope],#th[colspan|rowspan|width|height|align|valign|scope],caption,-div,-span,-code,-pre,address,-h1,-h2,-h3,-h4,-h5,-h6,hr[size|noshade],-font[face|size|color],dd,dl,dt,cite,abbr,acronym,del[datetime|cite],ins[datetime|cite],object[classid|width|height|codebase|*],param[name|value],embed[type|width|height|src|*],script[src|type],map[name],area[shape|coords|href|alt|target],bdo,button,col[align|char|charoff|span|valign|width],colgroup[align|char|charoff|span|valign|width],dfn,fieldset,form[action|accept|accept-charset|enctype|method],input[accept|alt|checked|disabled|maxlength|name|readonly|size|src|type|value|tabindex|accesskey],kbd,label[for],legend,noscript,optgroup[label|disabled],option[disabled|label|selected|value],q[cite],samp,select[disabled|multiple|name|size],small,textarea[cols|rows|disabled|name|readonly],tt,var,big',
|
| | | valid_elements : '@[id|class|style|title|dir<ltr?rtl|lang|xml::lang|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],a[rel|rev|charset|hreflang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur],strong/b,em/i,strike,u,#p,-ol[type|compact],-ul[type|compact],-li,br,img[longdesc|usemap|src|border|alt=|title|hspace|vspace|width|height|align],-sub,-sup,-blockquote[cite],-table[border|cellspacing|cellpadding|width|frame|rules|height|align|summary|bgcolor|background|bordercolor],-tr[rowspan|width|height|align|valign|bgcolor|background|bordercolor],tbody,thead,tfoot,#td[colspan|rowspan|width|height|align|valign|bgcolor|background|bordercolor|scope],#th[colspan|rowspan|width|height|align|valign|scope],caption,-div,-span,-code,-pre,address,-h1,-h2,-h3,-h4,-h5,-h6,hr[size|noshade],-font[face|size|color],dd,dl,dt,cite,abbr,acronym,del[datetime|cite],ins[datetime|cite],object[classid|width|height|codebase|*],param[name|value],embed[type|width|height|src|*],script[src|type],map[name],area[shape|coords|href|alt|target],bdo,button,col[align|char|charoff|span|valign|width],colgroup[align|char|charoff|span|valign|width],dfn,fieldset,form[action|accept|accept-charset|enctype|method],input[accept|alt|checked|disabled|maxlength|name|readonly|size|src|type|value|tabindex|accesskey],kbd,label[for],legend,noscript,optgroup[label|disabled],option[disabled|label|selected|value],q[cite],samp,select[disabled|multiple|name|size],small,textarea[cols|rows|disabled|name|readonly],tt,var,big',
|
| | | hidden_input : 1,
|
| | | padd_empty_editor : 1,
|
| | | render_ui : 1,
|
| | |
| | | removeformat_selector : 'span,b,strong,em,i,font,u,strike'
|
| | | }, s);
|
| | |
|
| | | // Setup URIs
|
| | | t.documentBaseURI = new tinymce.util.URI(s.document_base_url || tinymce.documentBaseURL, {
|
| | | base_uri : tinyMCE.baseURI
|
| | | });
|
| | |
|
| | | t.baseURI = EditorManager.baseURI;
|
| | |
|
| | | // Call setup
|
| | |
| | | });
|
| | | };
|
| | |
|
| | | // Load compat2x first
|
| | | if (s.plugins.indexOf('compat2x') != -1) {
|
| | | PluginManager.load('compat2x', 'plugins/compat2x/editor_plugin' + tinymce.suffix + '.js');
|
| | | sl.loadQueue(loadScripts);
|
| | | } else
|
| | | loadScripts();
|
| | | loadScripts();
|
| | | },
|
| | |
|
| | | init : function() {
|
| | |
| | |
|
| | | EditorManager.add(t);
|
| | |
|
| | | // Create theme
|
| | | if (s.theme) {
|
| | | s.theme = s.theme.replace(/-/, '');
|
| | | o = ThemeManager.get(s.theme);
|
| | |
| | | if (s.popup_css_add)
|
| | | s.popup_css += ',' + t.documentBaseURI.toAbsolute(s.popup_css_add);
|
| | |
|
| | | // Setup control factory
|
| | | t.controlManager = new tinymce.ControlManager(t);
|
| | |
|
| | | t.undoManager = new tinymce.UndoManager(t);
|
| | |
|
| | | // Pass through
|
| | |
| | | }
|
| | |
|
| | |
|
| | | // User specified a document.domain value
|
| | | if (document.domain && location.hostname != document.domain)
|
| | | tinymce.relaxedDomain = document.domain;
|
| | |
|
| | | // Resize editor
|
| | | DOM.setStyles(o.sizeContainer || o.editorContainer, {
|
| | | width : w,
|
| | |
| | | if (h < 100)
|
| | | h = 100;
|
| | |
|
| | | t.iframeHTML = s.doctype + '<html><head xmlns="http://www.w3.org/1999/xhtml"><base href="' + t.documentBaseURI.getURI() + '" />';
|
| | | t.iframeHTML = s.doctype + '<html><head xmlns="http://www.w3.org/1999/xhtml">';
|
| | |
|
| | | // We only need to override paths if we have to
|
| | | // IE has a bug where it remove site absolute urls to relative ones if this is specified
|
| | | if (s.document_base_url != tinymce.documentBaseURL)
|
| | | t.iframeHTML += '<base href="' + t.documentBaseURI.getURI() + '" />';
|
| | |
|
| | | t.iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';
|
| | |
|
| | | if (tinymce.relaxedDomain)
|
| | |
| | | DOM.show(b);
|
| | | }
|
| | |
|
| | | // Setup objects
|
| | | t.dom = new tinymce.DOM.DOMUtils(t.getDoc(), {
|
| | | t.dom = new tinymce.dom.DOMUtils(t.getDoc(), {
|
| | | keep_values : true,
|
| | | url_converter : t.convertURL,
|
| | | url_converter_scope : t,
|
| | |
| | | fix_ie_paragraphs : 1
|
| | | });
|
| | |
|
| | | t.serializer = new tinymce.dom.Serializer({
|
| | | entity_encoding : s.entity_encoding,
|
| | | entities : s.entities,
|
| | | t.serializer = new tinymce.dom.Serializer(extend(s, {
|
| | | valid_elements : s.verify_html === false ? '*[*]' : s.valid_elements,
|
| | | extended_valid_elements : s.extended_valid_elements,
|
| | | valid_child_elements : s.valid_child_elements,
|
| | | invalid_elements : s.invalid_elements,
|
| | | fix_table_elements : s.fix_table_elements,
|
| | | fix_list_elements : s.fix_list_elements,
|
| | | fix_content_duplication : s.fix_content_duplication,
|
| | | convert_fonts_to_spans : s.convert_fonts_to_spans,
|
| | | font_size_classes : s.font_size_classes,
|
| | | font_size_style_values : s.font_size_style_values,
|
| | | apply_source_formatting : s.apply_source_formatting,
|
| | | remove_linebreaks : s.remove_linebreaks,
|
| | | element_format : s.element_format,
|
| | | dom : t.dom
|
| | | });
|
| | | }));
|
| | |
|
| | | t.selection = new tinymce.dom.Selection(t.dom, t.getWin(), t.serializer);
|
| | |
|
| | | t.forceBlocks = new tinymce.ForceBlocks(t, {
|
| | | forced_root_block : s.forced_root_block
|
| | | });
|
| | |
| | | if (s.nowrap)
|
| | | t.getBody().style.whiteSpace = "nowrap";
|
| | |
|
| | | if (s.auto_resize)
|
| | | t.onNodeChange.add(t.resizeToContent, t);
|
| | |
|
| | | if (s.custom_elements) {
|
| | | function handleCustom(ed, o) {
|
| | | each(explode(s.custom_elements), function(v) {
|
| | |
| | | t.onBeforeSetContent.add(handleCustom);
|
| | | t.onPostProcess.add(function(ed, o) {
|
| | | if (o.set)
|
| | | handleCustom(ed, o)
|
| | | handleCustom(ed, o);
|
| | | });
|
| | | }
|
| | |
|
| | |
| | | return b;
|
| | | },
|
| | |
|
| | | resizeToContent : function() {
|
| | | var t = this;
|
| | |
|
| | | DOM.setStyle(t.id + "_ifr", 'height', t.getBody().scrollHeight);
|
| | | },
|
| | |
|
| | | load : function(o) {
|
| | | var t = this, e = t.getElement(), h;
|
| | |
|
| | |
| | | case 'contextmenu':
|
| | | if (tinymce.isOpera) {
|
| | | // Fake contextmenu on Opera
|
| | | Event.add(t.getBody(), 'mousedown', function(e) {
|
| | | t.dom.bind(t.getBody(), 'mousedown', function(e) {
|
| | | if (e.ctrlKey) {
|
| | | e.fakeType = 'contextmenu';
|
| | | eventHandler(e);
|
| | | }
|
| | | });
|
| | | } else
|
| | | Event.add(t.getBody(), k, eventHandler);
|
| | | t.dom.bind(t.getBody(), k, eventHandler);
|
| | | break;
|
| | |
|
| | | case 'paste':
|
| | | Event.add(t.getBody(), k, function(e) {
|
| | | t.dom.bind(t.getBody(), k, function(e) {
|
| | | eventHandler(e);
|
| | | });
|
| | | break;
|
| | |
|
| | | case 'submit':
|
| | | case 'reset':
|
| | | Event.add(t.getElement().form || DOM.getParent(t.id, 'form'), k, eventHandler);
|
| | | t.dom.bind(t.getElement().form || DOM.getParent(t.id, 'form'), k, eventHandler);
|
| | | break;
|
| | |
|
| | | default:
|
| | | Event.add(s.content_editable ? t.getBody() : t.getDoc(), k, eventHandler);
|
| | | t.dom.bind(s.content_editable ? t.getBody() : t.getDoc(), k, eventHandler);
|
| | | }
|
| | | });
|
| | |
|
| | | Event.add(s.content_editable ? t.getBody() : (isGecko ? t.getDoc() : t.getWin()), 'focus', function(e) {
|
| | | t.dom.bind(s.content_editable ? t.getBody() : (isGecko ? t.getDoc() : t.getWin()), 'focus', function(e) {
|
| | | t.focus(true);
|
| | | });
|
| | |
|
| | |
| | | })
|
| | | });*/
|
| | |
|
| | | Event.add(t.getDoc(), 'DOMNodeInserted', function(e) {
|
| | | t.dom.bind(t.getDoc(), 'DOMNodeInserted', function(e) {
|
| | | var v;
|
| | |
|
| | | e = e.target;
|
| | |
| | | if (tinymce.isIE) {
|
| | | // Fix so resize will only update the width and height attributes not the styles of an image
|
| | | // It will also block mceItemNoResize items
|
| | | Event.add(t.getDoc(), 'controlselect', function(e) {
|
| | | t.dom.bind(t.getDoc(), 'controlselect', function(e) {
|
| | | var re = t.resizeInfo, cb;
|
| | |
|
| | | e = e.target;
|
| | |
| | | return;
|
| | |
|
| | | if (re)
|
| | | Event.remove(re.node, re.ev, re.cb);
|
| | | t.dom.unbind(re.node, re.ev, re.cb);
|
| | |
|
| | | if (!t.dom.hasClass(e, 'mceItemNoResize')) {
|
| | | ev = 'resizeend';
|
| | | cb = Event.add(e, ev, function(e) {
|
| | | cb = t.dom.bind(e, ev, function(e) {
|
| | | var v;
|
| | |
|
| | | e = e.target;
|
| | |
| | | });
|
| | | } else {
|
| | | ev = 'resizestart';
|
| | | cb = Event.add(e, 'resizestart', Event.cancel, Event);
|
| | | cb = t.dom.bind(e, 'resizestart', Event.cancel, Event);
|
| | | }
|
| | |
|
| | | re = t.resizeInfo = {
|
| | |
| | |
|
| | | // Add undo level on editor blur
|
| | | if (tinymce.isIE) {
|
| | | Event.add(t.getWin(), 'blur', function(e) {
|
| | | t.dom.bind(t.getWin(), 'blur', function(e) {
|
| | | var n;
|
| | |
|
| | | // Check added for fullscreen bug
|
| | |
| | | }
|
| | | });
|
| | | } else {
|
| | | Event.add(t.getDoc(), 'blur', function() {
|
| | | t.dom.bind(t.getDoc(), 'blur', function() {
|
| | | if (t.selection && !t.removed)
|
| | | addUndo();
|
| | | });
|
| | |
| | |
|
| | | return s;
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | })(tinymce);
|
| | | (function(tinymce) {
|
| | | var each = tinymce.each, isIE = tinymce.isIE, isGecko = tinymce.isGecko, isOpera = tinymce.isOpera, isWebKit = tinymce.isWebKit;
|
| | |
| | | hasRedo : function() {
|
| | | return this.index < this.data.length - 1;
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | })(tinymce);
|
| | | (function(tinymce) {
|
| | | // Shorten names
|
| | |
| | | each = tinymce.each;
|
| | | extend = tinymce.extend;
|
| | |
|
| | | // Checks if the selection/caret is at the end of the specified block element
|
| | | function isAtEnd(rng, par) {
|
| | | var rng2 = par.ownerDocument.createRange();
|
| | |
|
| | | rng2.setStart(rng.endContainer, rng.endOffset);
|
| | | rng2.setEndAfter(par);
|
| | |
|
| | | // Get number of characters to the right of the cursor if it's zero then we are at the end and need to merge the next block element
|
| | | return rng2.cloneContents().textContent.length == 0;
|
| | | };
|
| | |
|
| | | function isEmpty(n) {
|
| | | n = n.innerHTML;
|
| | | n = n.replace(/<\w+ .*?mce_\w+\"?=.*?>/gi, '-'); // Keep tags with mce_ attribs
|
| | | n = n.replace(/<(img|hr|table)/gi, '-'); // Keep these convert them to - chars
|
| | |
|
| | | n = n.replace(/<(img|hr|table|input|select|textarea)[ \>]/gi, '-'); // Keep these convert them to - chars
|
| | | n = n.replace(/<[^>]+>/g, ''); // Remove all tags
|
| | |
|
| | | return n.replace(/[ \t\r\n]+/g, '') == '';
|
| | |
| | | return ne;
|
| | | };
|
| | |
|
| | | // Padd empty inline elements within block elements
|
| | | // For example: <p><strong><em></em></strong></p> becomes <p><strong><em> </em></strong></p>
|
| | | ed.onPreProcess.add(function(ed, o) {
|
| | | each(ed.dom.select('p,h1,h2,h3,h4,h5,h6,div', o.node), function(p) {
|
| | | if (isEmpty(p)) {
|
| | | each(ed.dom.select('span,em,strong,b,i', o.node), function(n) {
|
| | | if (!n.hasChildNodes()) {
|
| | | n.appendChild(ed.getDoc().createTextNode('\u00a0'));
|
| | | return false; // Break the loop one padding is enough
|
| | | }
|
| | | });
|
| | | }
|
| | | });
|
| | | });
|
| | |
|
| | | // IE specific fixes
|
| | | if (isIE) {
|
| | | // Remove empty inline elements within block elements
|
| | | // For example: <p><strong><em></em></strong></p>
|
| | | ed.onPreProcess.add(function(ed, o) {
|
| | | each(ed.dom.select('p,h1,h2,h3,h4,h5,h6,div', o.node), function(p) {
|
| | | if (isEmpty(p))
|
| | | p.innerHTML = '';
|
| | | });
|
| | | });
|
| | |
|
| | | // Replaces IE:s auto generated paragraphs with the specified element name
|
| | | if (s.element != 'P') {
|
| | | ed.onKeyPress.add(function(ed, e) {
|
| | |
| | | nx = nl[i];
|
| | |
|
| | | // Is text or non block element
|
| | | if (nx.nodeType == 3 || (!t.dom.isBlock(nx) && nx.nodeType != 8)) {
|
| | | if (nx.nodeType === 3 || (!t.dom.isBlock(nx) && nx.nodeType !== 8 && !/^(script|mce:script|style|mce:style)$/i.test(nx.nodeName))) {
|
| | | if (!bl) {
|
| | | // Create new block but ignore whitespace
|
| | | if (nx.nodeType != 3 || /[^\s]/g.test(nx.nodeValue)) {
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | // Uses replaceChild instead of cloneNode since it removes selected attribute from option elements on IE
|
| | | // See: http://support.microsoft.com/kb/829907
|
| | | bl = ed.dom.create(ed.settings.forced_root_block);
|
| | | bl.appendChild(nx.cloneNode(1));
|
| | | nx.parentNode.replaceChild(bl, nx);
|
| | | bl.appendChild(nx);
|
| | | }
|
| | | } else {
|
| | | if (bl.hasChildNodes())
|
| | |
| | |
|
| | | // If selection is in empty table cell
|
| | | if (sn === en && /^(TD|TH)$/.test(sn.nodeName)) {
|
| | | dom.remove(sn.firstChild); // Remove BR
|
| | | if (sn.firstChild.nodeName == 'BR')
|
| | | dom.remove(sn.firstChild); // Remove BR
|
| | |
|
| | | // Create two new block elements
|
| | | ed.dom.add(sn, se.element, null, '<br />');
|
| | | aft = ed.dom.add(sn, se.element, null, '<br />');
|
| | | if (sn.childNodes.length == 0) {
|
| | | ed.dom.add(sn, se.element, null, '<br />');
|
| | | aft = ed.dom.add(sn, se.element, null, '<br />');
|
| | | } else {
|
| | | n = sn.innerHTML;
|
| | | sn.innerHTML = '';
|
| | | ed.dom.add(sn, se.element, null, n);
|
| | | aft = ed.dom.add(sn, se.element, null, '<br />');
|
| | | }
|
| | |
|
| | | // Move caret into the last one
|
| | | r = d.createRange();
|
| | |
| | | aft.removeAttribute('id');
|
| | |
|
| | | // Is header and cursor is at the end, then force paragraph under
|
| | | if (/^(H[1-6])$/.test(bn) && sn.nodeValue && so == sn.nodeValue.length)
|
| | | if (/^(H[1-6])$/.test(bn) && isAtEnd(r, sb))
|
| | | aft = ed.dom.create(se.element);
|
| | |
|
| | | // Find start chop node
|
| | |
| | | },
|
| | |
|
| | | backspaceDelete : function(e, bs) {
|
| | | var t = this, ed = t.editor, b = ed.getBody(), n, se = ed.selection, r = se.getRng(), sc = r.startContainer, n, w, tn;
|
| | | var t = this, ed = t.editor, b = ed.getBody(), dom = ed.dom, n, se = ed.selection, r = se.getRng(), sc = r.startContainer, n, w, tn;
|
| | |
|
| | | /*
|
| | | var par, rng, nextBlock;
|
| | |
|
| | | // Delete key will not merge paragraphs on Gecko so we need to do this manually
|
| | | // Hitting the delete key at the following caret position doesn't merge the elements <p>A|</p><p>B</p>
|
| | | // This logic will merge them into this: <p>A|B</p>
|
| | | if (e.keyCode == 46) {
|
| | | if (r.collapsed) {
|
| | | par = dom.getParent(sc, 'p,h1,h2,h3,h4,h5,h6,div');
|
| | |
|
| | | if (par) {
|
| | | rng = dom.createRng();
|
| | |
|
| | | rng.setStart(sc, r.startOffset);
|
| | | rng.setEndAfter(par);
|
| | |
|
| | | // Get number of characters to the right of the cursor if it's zero then we are at the end and need to merge the next block element
|
| | | if (dom.getOuterHTML(rng.cloneContents()).replace(/<[^>]+>/g, '').length == 0) {
|
| | | nextBlock = dom.getNext(par, 'p,h1,h2,h3,h4,h5,h6,div');
|
| | |
|
| | | // Copy all children from next sibling block and remove it
|
| | | if (nextBlock) {
|
| | | each(nextBlock.childNodes, function(node) {
|
| | | par.appendChild(node.cloneNode(true));
|
| | | });
|
| | |
|
| | | dom.remove(nextBlock);
|
| | | }
|
| | |
|
| | | // Block the default even since the Gecko team might eventually fix this
|
| | | // We will remove this logic once they do we can't feature detect this one
|
| | | e.preventDefault();
|
| | | return;
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | */
|
| | |
|
| | | // The caret sometimes gets stuck in Gecko if you delete empty paragraphs
|
| | | // This workaround removes the element by hand and moves the caret to the previous element
|
| | |
| | | c.onPostRender.add(function(c, n) {
|
| | | // Store bookmark on mousedown
|
| | | Event.add(n, 'mousedown', function() {
|
| | | ed.bookmark = ed.selection.getBookmark('simple');
|
| | | ed.bookmark = ed.selection.getBookmark(1);
|
| | | });
|
| | |
|
| | | // Restore on focus, since it might be lost
|
| | |
| | | s.onclick = function(v) {
|
| | | if (tinymce.isIE)
|
| | | bm = ed.selection.getBookmark(1);
|
| | | |
| | |
|
| | | ed.execCommand(s.cmd, s.ui || false, v || s.value);
|
| | | };
|
| | | }
|
| | |
| | |
|
| | | // Fix for bug #1897785, #1898007
|
| | | if (tinymce.isIE) {
|
| | | c.onShowMenu.add(function() {
|
| | | // IE 8 needs focus in order to store away a range with the current collapsed caret location
|
| | | ed.focus();
|
| | | bm = ed.selection.getBookmark(1);
|
| | | });
|
| | |
|
| | | c.onHideMenu.add(function() {
|
| | | if (bm) {
|
| | | ed.selection.moveToBookmark(bm);
|
| | |
| | | setControlType : function(n, c) {
|
| | | return this._cls[n.toLowerCase()] = c;
|
| | | },
|
| | |
|
| | | |
| | | destroy : function() {
|
| | | each(this.controls, function(c) {
|
| | | c.destroy();
|
| | |
| | |
|
| | | this.controls = null;
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | })(tinymce);
|
| | | (function(tinymce) {
|
| | | var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each, isIE = tinymce.isIE, isOpera = tinymce.isOpera;
|
| | |
| | | _decode : function(s) {
|
| | | return tinymce.DOM.decode(s).replace(/\\n/g, '\n');
|
| | | }
|
| | |
|
| | | });
|
| | | });
|
| | | }(tinymce));(function(tinymce) {
|
| | | tinymce.CommandManager = function() {
|
| | | var execCommands = {}, queryStateCommands = {}, queryValueCommands = {};
|
| | |
| | | doc.execCommand(cmd, false, null);
|
| | |
|
| | | // On WebKit the command will just be ignored if it's not enabled
|
| | | if (!doc.queryCommandSupported(cmd))
|
| | | if (!doc.queryCommandEnabled(cmd))
|
| | | throw 'Error';
|
| | | } catch (ex) {
|
| | | ed.windowManager.alert(ed.getLang('clipboard_no_support'));
|
| | | if (tinymce.isGecko) {
|
| | | ed.windowManager.confirm(ed.getLang('clipboard_msg'), function(s) {
|
| | | if (s)
|
| | | open('http://www.mozilla.org/editor/midasdemo/securityprefs.html', '_blank');
|
| | | });
|
| | | } else
|
| | | ed.windowManager.alert(ed.getLang('clipboard_no_support'));
|
| | | }
|
| | | });
|
| | | });
|