changeset 588 | 20484deb89cd |
parent 543 | dffcbfbc4e59 |
child 778 | 57ce13805b6f |
587:705ed7162315 | 588:20484deb89cd |
---|---|
1 |
1 |
2 /* file:jscripts/tiny_mce/classes/tinymce.js */ |
2 /* file:jscripts/tiny_mce/classes/tinymce.js */ |
3 |
3 |
4 var tinymce = { |
4 var tinymce = { |
5 majorVersion : '3', |
5 majorVersion : '3', |
6 minorVersion : '0.8', |
6 minorVersion : '1.0.1', |
7 releaseDate : '2008-04-30', |
7 releaseDate : '2008-06-18', |
8 |
8 |
9 _init : function() { |
9 _init : function() { |
10 var t = this, d = document, w = window, na = navigator, ua = na.userAgent, i, nl, n, base, p; |
10 var t = this, d = document, w = window, na = navigator, ua = na.userAgent, i, nl, n, base, p, v; |
11 |
11 |
12 // Browser checks |
12 // Browser checks |
13 t.isOpera = w.opera && opera.buildNumber; |
13 t.isOpera = w.opera && opera.buildNumber; |
14 t.isWebKit = /WebKit/.test(ua); |
14 t.isWebKit = /WebKit/.test(ua); |
15 t.isOldWebKit = t.isWebKit && !w.getSelection().getRangeAt; |
15 t.isOldWebKit = t.isWebKit && !w.getSelection().getRangeAt; |
30 t.suffix = ''; |
30 t.suffix = ''; |
31 |
31 |
32 // If base element found, add that infront of baseURL |
32 // If base element found, add that infront of baseURL |
33 nl = d.getElementsByTagName('base'); |
33 nl = d.getElementsByTagName('base'); |
34 for (i=0; i<nl.length; i++) { |
34 for (i=0; i<nl.length; i++) { |
35 if (nl[i].href) |
35 if (v = nl[i].href) { |
36 base = nl[i].href; |
36 // Host only value like http://site.com or http://site.com:8008 |
37 if (/^https?:\/\/[^\/]+$/.test(v)) |
|
38 v += '/'; |
|
39 |
|
40 base = v ? v.match(/.*\//)[0] : ''; // Get only directory |
|
41 } |
|
37 } |
42 } |
38 |
43 |
39 function getBase(n) { |
44 function getBase(n) { |
40 if (n.src && /tiny_mce(|_dev|_src|_gzip|_jquery|_prototype).js/.test(n.src)) { |
45 if (n.src && /tiny_mce(|_dev|_src|_gzip|_jquery|_prototype).js/.test(n.src)) { |
41 if (/_(src|dev)\.js/g.test(n.src)) |
46 if (/_(src|dev)\.js/g.test(n.src)) |
874 if (o.content_type) |
879 if (o.content_type) |
875 x.setRequestHeader('Content-Type', o.content_type); |
880 x.setRequestHeader('Content-Type', o.content_type); |
876 |
881 |
877 x.send(o.data); |
882 x.send(o.data); |
878 |
883 |
879 // Wait for response, onReadyStateChange can not be used since it leaks memory in IE |
884 function ready() { |
880 t = w.setInterval(function() { |
885 if (!o.async || x.readyState == 4 || c++ > 10000) { |
881 if (x.readyState == 4 || c++ > 10000) { |
|
882 w.clearInterval(t); |
|
883 |
|
884 if (o.success && c < 10000 && x.status == 200) |
886 if (o.success && c < 10000 && x.status == 200) |
885 o.success.call(o.success_scope, '' + x.responseText, x, o); |
887 o.success.call(o.success_scope, '' + x.responseText, x, o); |
886 else if (o.error) |
888 else if (o.error) |
887 o.error.call(o.error_scope, c > 10000 ? 'TIMED_OUT' : 'GENERAL', x, o); |
889 o.error.call(o.error_scope, c > 10000 ? 'TIMED_OUT' : 'GENERAL', x, o); |
888 |
890 |
889 x = null; |
891 x = null; |
890 } |
892 } else |
891 }, 10); |
893 w.setTimeout(ready, 10); |
894 }; |
|
895 |
|
896 // Syncronous request |
|
897 if (!o.async) |
|
898 return ready(); |
|
899 |
|
900 // Wait for response, onReadyStateChange can not be used since it leaks memory in IE |
|
901 t = w.setTimeout(ready, 10); |
|
892 } |
902 } |
893 |
903 |
894 } |
904 } |
895 }); |
905 }); |
896 |
906 |
1063 s = true; |
1073 s = true; |
1064 return false; |
1074 return false; |
1065 } |
1075 } |
1066 |
1076 |
1067 each(na.split(','), function(v) { |
1077 each(na.split(','), function(v) { |
1068 if (n.nodeType == 1 && ((se.strict && n.nodeName.toUpperCase() == v) || n.nodeName == v)) { |
1078 if (n.nodeType == 1 && ((se.strict && n.nodeName.toUpperCase() == v) || n.nodeName.toUpperCase() == v)) { |
1069 s = true; |
1079 s = true; |
1070 return false; // Break loop |
1080 return false; // Break loop |
1071 } |
1081 } |
1072 }); |
1082 }); |
1073 |
1083 |
1480 |
1490 |
1481 t.setAttrib(e, 'mce_' + n, v, 2); |
1491 t.setAttrib(e, 'mce_' + n, v, 2); |
1482 } |
1492 } |
1483 |
1493 |
1484 break; |
1494 break; |
1495 |
|
1496 case "shape": |
|
1497 e.setAttribute('mce_style', v); |
|
1498 break; |
|
1485 } |
1499 } |
1486 |
1500 |
1487 if (is(v) && v !== null && v.length !== 0) |
1501 if (is(v) && v !== null && v.length !== 0) |
1488 e.setAttribute(n, '' + v, 2); |
1502 e.setAttribute(n, '' + v, 2); |
1489 else |
1503 else |
1513 |
1527 |
1514 if (!is(dv)) |
1528 if (!is(dv)) |
1515 dv = ""; |
1529 dv = ""; |
1516 |
1530 |
1517 // Try the mce variant for these |
1531 // Try the mce variant for these |
1518 if (/^(src|href|style|coords)$/.test(n)) { |
1532 if (/^(src|href|style|coords|shape)$/.test(n)) { |
1519 v = e.getAttribute("mce_" + n); |
1533 v = e.getAttribute("mce_" + n); |
1520 |
1534 |
1521 if (v) |
1535 if (v) |
1522 return v; |
1536 return v; |
1523 } |
1537 } |
1584 v = ''; |
1598 v = ''; |
1585 |
1599 |
1586 break; |
1600 break; |
1587 |
1601 |
1588 case 'tabindex': |
1602 case 'tabindex': |
1589 // IE returns 32768 as default value |
1603 // IE returns default value |
1590 if (v === 32768) |
1604 if (v === 32768) |
1605 v = ''; |
|
1606 |
|
1607 break; |
|
1608 |
|
1609 case 'maxlength': |
|
1610 // IE returns default value |
|
1611 if (v === 2147483647) |
|
1591 v = ''; |
1612 v = ''; |
1592 |
1613 |
1593 break; |
1614 break; |
1594 |
1615 |
1595 case 'shape': |
1616 case 'shape': |
1700 delete o[a]; |
1721 delete o[a]; |
1701 delete o[b]; |
1722 delete o[b]; |
1702 delete o[c]; |
1723 delete o[c]; |
1703 }; |
1724 }; |
1704 |
1725 |
1726 st = st.replace(/&(#?[a-z0-9]+);/g, '&$1_MCE_SEMI_'); // Protect entities |
|
1727 |
|
1705 each(st.split(';'), function(v) { |
1728 each(st.split(';'), function(v) { |
1706 var sv, ur = []; |
1729 var sv, ur = []; |
1707 |
1730 |
1708 if (v) { |
1731 if (v) { |
1732 v = v.replace(/_MCE_SEMI_/g, ';'); // Restore entities |
|
1709 v = v.replace(/url\([^\)]+\)/g, function(v) {ur.push(v);return 'url(' + ur.length + ')';}); |
1733 v = v.replace(/url\([^\)]+\)/g, function(v) {ur.push(v);return 'url(' + ur.length + ')';}); |
1710 v = v.split(':'); |
1734 v = v.split(':'); |
1711 sv = tinymce.trim(v[1]); |
1735 sv = tinymce.trim(v[1]); |
1712 sv = sv.replace(/url\(([^\)]+)\)/g, function(a, b) {return ur[parseInt(b) - 1];}); |
1736 sv = sv.replace(/url\(([^\)]+)\)/g, function(a, b) {return ur[parseInt(b) - 1];}); |
1713 |
1737 |
1715 return t.toHex(v); |
1739 return t.toHex(v); |
1716 }); |
1740 }); |
1717 |
1741 |
1718 if (s.url_converter) { |
1742 if (s.url_converter) { |
1719 sv = sv.replace(/url\([\'\"]?([^\)\'\"]+)[\'\"]?\)/g, function(x, c) { |
1743 sv = sv.replace(/url\([\'\"]?([^\)\'\"]+)[\'\"]?\)/g, function(x, c) { |
1720 return 'url(' + t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), 'style', null)) + ')'; |
1744 return 'url(' + s.url_converter.call(s.url_converter_scope || t, t.decode(c), 'style', null) + ')'; |
1721 }); |
1745 }); |
1722 } |
1746 } |
1723 |
1747 |
1724 o[tinymce.trim(v[0]).toLowerCase()] = sv; |
1748 o[tinymce.trim(v[0]).toLowerCase()] = sv; |
1725 } |
1749 } |
1745 serializeStyle : function(o) { |
1769 serializeStyle : function(o) { |
1746 var s = ''; |
1770 var s = ''; |
1747 |
1771 |
1748 each(o, function(v, k) { |
1772 each(o, function(v, k) { |
1749 if (k && v) { |
1773 if (k && v) { |
1774 if (tinymce.isGecko && k.indexOf('-moz-') === 0) |
|
1775 return; |
|
1776 |
|
1750 switch (k) { |
1777 switch (k) { |
1751 case 'color': |
1778 case 'color': |
1752 case 'background-color': |
1779 case 'background-color': |
1753 v = v.toLowerCase(); |
1780 v = v.toLowerCase(); |
1754 break; |
1781 break; |
1973 // Fix some issues |
2000 // Fix some issues |
1974 h = h.replace(/<a( )([^>]+)\/>|<a\/>/gi, '<a$1$2></a>'); // Force open |
2001 h = h.replace(/<a( )([^>]+)\/>|<a\/>/gi, '<a$1$2></a>'); // Force open |
1975 |
2002 |
1976 // Store away src and href in mce_src and mce_href since browsers mess them up |
2003 // Store away src and href in mce_src and mce_href since browsers mess them up |
1977 if (s.keep_values) { |
2004 if (s.keep_values) { |
1978 // Wrap scripts in comments for serialization purposes |
2005 // Wrap scripts and styles in comments for serialization purposes |
1979 if (h.indexOf('<script') !== -1) { |
2006 if (/<script|style/.test(h)) { |
1980 h = h.replace(/<script>/g, '<script type="text/javascript">'); |
2007 function trim(s) { |
1981 h = h.replace(/<script(|[^>]+)>(\s*<!--|\/\/\s*<\[CDATA\[)?[\r\n]*/g, '<mce:script$1><!--\n'); |
2008 // Remove prefix and suffix code for element |
1982 h = h.replace(/\s*(\/\/\s*-->|\/\/\s*]]>)?<\/script>/g, '\n// --></mce:script>'); |
2009 s = s.replace(/^[\r\n]*|[\r\n]*$/g, ''); |
1983 h = h.replace(/<mce:script(|[^>]+)><!--\n\/\/ --><\/mce:script>/g, '<mce:script$1></mce:script>'); |
2010 s = s.replace(/^\s*(\/\/\s*<!--|\/\/\s*<\[CDATA\[|<!--|<\[CDATA\[)[\r\n]*/g, ''); |
2011 s = s.replace(/\s*(\/\/\s*\]\]>|\/\/\s*-->|\]\]>|-->)\s*$/g, ''); |
|
2012 |
|
2013 return s; |
|
2014 }; |
|
2015 |
|
2016 // Preserve script elements |
|
2017 h = h.replace(/<script([^>]+|)>([\s\S]*?)<\/script>/g, function(v, a, b) { |
|
2018 // Remove prefix and suffix code for script element |
|
2019 b = trim(b); |
|
2020 |
|
2021 // Force type attribute |
|
2022 if (!a) |
|
2023 a = ' type="text/javascript"'; |
|
2024 |
|
2025 // Wrap contents in a comment |
|
2026 if (b) |
|
2027 b = '<!--\n' + b + '\n// -->'; |
|
2028 |
|
2029 // Output fake element |
|
2030 return '<mce:script' + a + '>' + b + '</mce:script>'; |
|
2031 }); |
|
2032 |
|
2033 // Preserve style elements |
|
2034 h = h.replace(/<style([^>]+|)>([\s\S]*?)<\/style>/g, function(v, a, b) { |
|
2035 b = trim(b); |
|
2036 return '<mce:style' + a + '><!--\n' + b + '\n--></mce:style><style' + a + ' mce_bogus="1">' + b + '</style>'; |
|
2037 }); |
|
1984 } |
2038 } |
1985 |
2039 |
1986 // Process all tags with src, href or style |
2040 // Process all tags with src, href or style |
1987 h = h.replace(/<([\w:]+) [^>]*(src|href|style|coords)[^>]*>/gi, function(a, n) { |
2041 h = h.replace(/<([\w:]+) [^>]*(src|href|style|shape|coords)[^>]*>/gi, function(a, n) { |
1988 function handle(m, b, c) { |
2042 function handle(m, b, c) { |
1989 var u = c; |
2043 var u = c; |
1990 |
2044 |
1991 // Tag already got a mce_ version |
2045 // Tag already got a mce_ version |
1992 if (a.indexOf('mce_' + b) != -1) |
2046 if (a.indexOf('mce_' + b) != -1) |
2010 if (s.url_converter) { |
2064 if (s.url_converter) { |
2011 u = u.replace(/url\([\'\"]?([^\)\'\"]+)\)/g, function(x, c) { |
2065 u = u.replace(/url\([\'\"]?([^\)\'\"]+)\)/g, function(x, c) { |
2012 return 'url(' + t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n)) + ')'; |
2066 return 'url(' + t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n)) + ')'; |
2013 }); |
2067 }); |
2014 } |
2068 } |
2015 } else if (b != 'coords') { |
2069 } else if (b != 'coords' && b != 'shape') { |
2016 if (s.url_converter) |
2070 if (s.url_converter) |
2017 u = t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n)); |
2071 u = t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(c), b, n)); |
2018 } |
2072 } |
2019 |
2073 |
2020 return ' ' + b + '="' + c + '" mce_' + b + '="' + u + '"'; |
2074 return ' ' + b + '="' + c + '" mce_' + b + '="' + u + '"'; |
2021 }; |
2075 }; |
2022 |
2076 |
2023 a = a.replace(/ (src|href|style|coords)=[\"]([^\"]+)[\"]/gi, handle); // W3C |
2077 a = a.replace(/ (src|href|style|coords|shape)=[\"]([^\"]+)[\"]/gi, handle); // W3C |
2024 a = a.replace(/ (src|href|style|coords)=[\']([^\']+)[\']/gi, handle); // W3C |
2078 a = a.replace(/ (src|href|style|coords|shape)=[\']([^\']+)[\']/gi, handle); // W3C |
2025 |
2079 |
2026 return a.replace(/ (src|href|style|coords)=([^\s\"\'>]+)/gi, handle); // IE |
2080 return a.replace(/ (src|href|style|coords|shape)=([^\s\"\'>]+)/gi, handle); // IE |
2027 }); |
2081 }); |
2028 } |
2082 } |
2029 |
2083 |
2030 return h; |
2084 return h; |
2031 }, |
2085 }, |
2136 if (n.nodeType && n.nodeType !== 1) |
2190 if (n.nodeType && n.nodeType !== 1) |
2137 return false; |
2191 return false; |
2138 |
2192 |
2139 n = n.nodeName || n; |
2193 n = n.nodeName || n; |
2140 |
2194 |
2141 return /^(H[1-6]|HR|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|FORM|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP)$/.test(n); |
2195 return /^(H[1-6]|HR|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP)$/.test(n); |
2142 }, |
2196 }, |
2143 |
2197 |
2144 // #if !jquery |
2198 // #if !jquery |
2145 |
2199 |
2146 replace : function(n, o, k) { |
2200 replace : function(n, o, k) { |
2311 tinymce.removeUnload(t.destroy); |
2365 tinymce.removeUnload(t.destroy); |
2312 }, |
2366 }, |
2313 |
2367 |
2314 _isRes : function(c) { |
2368 _isRes : function(c) { |
2315 // Is live resizble element |
2369 // Is live resizble element |
2316 |
2370 return /^(top|left|bottom|right|width|height)/i.test(c) || /;\s*(top|left|bottom|right|width|height)/i.test(c); |
2317 return /^(top|left|bottom|right|width|height)/i.test(c) || /^[;\s](top|left|bottom|right|width|height)/i.test(c); |
|
2318 } |
2371 } |
2319 |
2372 |
2320 /* |
2373 /* |
2321 walk : function(n, f, s) { |
2374 walk : function(n, f, s) { |
2322 var d = this.doc, w; |
2375 var d = this.doc, w; |
2553 |
2606 |
2554 _wait : function() { |
2607 _wait : function() { |
2555 var t; |
2608 var t; |
2556 |
2609 |
2557 // No need since the document is already loaded |
2610 // No need since the document is already loaded |
2558 if (window.tinyMCE_GZ && tinyMCE_GZ.loaded) |
2611 if (window.tinyMCE_GZ && tinyMCE_GZ.loaded) { |
2612 Event.domLoaded = 1; |
|
2559 return; |
2613 return; |
2614 } |
|
2560 |
2615 |
2561 if (isIE && document.location.protocol != 'https:') { |
2616 if (isIE && document.location.protocol != 'https:') { |
2562 // Fake DOMContentLoaded on IE |
2617 // Fake DOMContentLoaded on IE |
2563 document.write('<script id=__ie_onload defer src=\'javascript:""\';><\/script>'); |
2618 document.write('<script id=__ie_onload defer src=\'javascript:""\';><\/script>'); |
2564 DOM.get("__ie_onload").onreadystatechange = function() { |
2619 DOM.get("__ie_onload").onreadystatechange = function() { |
2782 |
2837 |
2783 return t.isCollapsed() ? '' : wb + t.serializer.serialize(e, s) + wa; |
2838 return t.isCollapsed() ? '' : wb + t.serializer.serialize(e, s) + wa; |
2784 }, |
2839 }, |
2785 |
2840 |
2786 setContent : function(h, s) { |
2841 setContent : function(h, s) { |
2787 var t = this, r = t.getRng(), d; |
2842 var t = this, r = t.getRng(), d = t.win.document; |
2788 |
2843 |
2789 s = s || {format : 'html'}; |
2844 s = s || {format : 'html'}; |
2790 s.set = true; |
2845 s.set = true; |
2791 h = t.dom.processHTML(h); |
2846 h = t.dom.processHTML(h); |
2792 |
2847 |
2793 if (r.insertNode) { |
2848 if (r.insertNode) { |
2794 d = t.win.document; |
|
2795 |
|
2796 // Gecko has a bug where if you insert using InsertHTML it will insert a space instead |
2849 // Gecko has a bug where if you insert using InsertHTML it will insert a space instead |
2797 // So we simply check if the input is HTML or text and then insert text using the insertNode method |
2850 // So we simply check if the input is HTML or text and then insert text using the insertNode method |
2798 if (tinymce.isGecko && h.indexOf('<') == -1) { |
2851 if (tinymce.isGecko && h.indexOf('<') == -1) { |
2799 r.deleteContents(); |
2852 r.deleteContents(); |
2800 r.insertNode(t.getRng().createContextualFragment(h + '<span id="__caret">_</span>')); |
2853 r.insertNode(t.getRng().createContextualFragment(h + '<span id="__caret">_</span>')); |
2812 // Use old school method |
2865 // Use old school method |
2813 r.deleteContents(); |
2866 r.deleteContents(); |
2814 r.insertNode(t.getRng().createContextualFragment(h)); |
2867 r.insertNode(t.getRng().createContextualFragment(h)); |
2815 } |
2868 } |
2816 } else { |
2869 } else { |
2817 if (r.item) |
2870 if (r.item) { |
2818 r.item(0).outerHTML = h; |
2871 // Delete content and get caret text selection |
2819 else |
2872 d.execCommand('Delete', false, null); |
2820 r.pasteHTML(h); |
2873 r = t.getRng(); |
2874 } |
|
2875 |
|
2876 r.pasteHTML(h); |
|
2821 } |
2877 } |
2822 }, |
2878 }, |
2823 |
2879 |
2824 getStart : function() { |
2880 getStart : function() { |
2825 var t = this, r = t.getRng(), e; |
2881 var t = this, r = t.getRng(), e; |
2950 if (n == en) { |
3006 if (n == en) { |
2951 d.end = p; |
3007 d.end = p; |
2952 return d; |
3008 return d; |
2953 } |
3009 } |
2954 |
3010 |
2955 p += (n.nodeValue || '').length; |
3011 p += trimNl(n.nodeValue || '').length; |
2956 } |
3012 } |
2957 |
3013 |
2958 return null; |
3014 return null; |
2959 }; |
3015 }; |
2960 |
3016 |
4325 t.setRules(s.valid_elements); |
4381 t.setRules(s.valid_elements); |
4326 t.addRules(s.extended_valid_elements); |
4382 t.addRules(s.extended_valid_elements); |
4327 t.addValidChildRules(s.valid_child_elements); |
4383 t.addValidChildRules(s.valid_child_elements); |
4328 |
4384 |
4329 if (s.invalid_elements) |
4385 if (s.invalid_elements) |
4330 t.invalidElementsRE = new RegExp('^(' + wildcardToRE(s.invalid_elements.replace(',', '|').toLowerCase()) + ')$'); |
4386 t.invalidElementsRE = new RegExp('^(' + wildcardToRE(s.invalid_elements.replace(/,/g, '|').toLowerCase()) + ')$'); |
4331 |
4387 |
4332 if (s.attrib_value_filter) |
4388 if (s.attrib_value_filter) |
4333 t.attribValueFilter = s.attribValueFilter; |
4389 t.attribValueFilter = s.attribValueFilter; |
4334 }, |
4390 }, |
4335 |
4391 |
4923 |
4979 |
4924 this.parent(id, s); |
4980 this.parent(id, s); |
4925 this.onShowMenu = new tinymce.util.Dispatcher(this); |
4981 this.onShowMenu = new tinymce.util.Dispatcher(this); |
4926 this.onHideMenu = new tinymce.util.Dispatcher(this); |
4982 this.onHideMenu = new tinymce.util.Dispatcher(this); |
4927 this.classPrefix = 'mceMenu'; |
4983 this.classPrefix = 'mceMenu'; |
4928 |
|
4929 // Fix for odd IE bug: #1903622 (Frames selection) |
|
4930 this.fixIE = tinymce.isIE && (DOM.win.top != DOM.win); |
|
4931 }, |
4984 }, |
4932 |
4985 |
4933 createMenu : function(s) { |
4986 createMenu : function(s) { |
4934 var t = this, cs = t.settings, m; |
4987 var t = this, cs = t.settings, m; |
4935 |
4988 |
5015 |
5068 |
5016 DOM.setStyles(co, {left : x , top : y}); |
5069 DOM.setStyles(co, {left : x , top : y}); |
5017 t.element.update(); |
5070 t.element.update(); |
5018 |
5071 |
5019 t.isMenuVisible = 1; |
5072 t.isMenuVisible = 1; |
5020 t.mouseClickFunc = Event.add(co, t.fixIE ? 'mousedown' : 'click', function(e) { |
5073 t.mouseClickFunc = Event.add(co, 'click', function(e) { |
5021 var m; |
5074 var m; |
5022 |
5075 |
5023 e = e.target; |
5076 e = e.target; |
5024 |
5077 |
5025 if (e && (e = DOM.getParent(e, 'TR')) && !DOM.hasClass(e, cp + 'ItemSub')) { |
5078 if (e && (e = DOM.getParent(e, 'TR')) && !DOM.hasClass(e, cp + 'ItemSub')) { |
5028 if (m.isDisabled()) |
5081 if (m.isDisabled()) |
5029 return; |
5082 return; |
5030 |
5083 |
5031 dm = t; |
5084 dm = t; |
5032 |
5085 |
5033 // Wait a while to fix IE bug where it looses the selection if the user clicks on a menu |
5086 while (dm) { |
5034 // item when the editor is placed within an frame or iframe |
5087 if (dm.hideMenu) |
5035 DOM.win.setTimeout(function() { |
5088 dm.hideMenu(); |
5036 while (dm) { |
5089 |
5037 if (dm.hideMenu) |
5090 dm = dm.settings.parent; |
5038 dm.hideMenu(); |
5091 } |
5039 |
5092 |
5040 dm = dm.settings.parent; |
5093 if (m.settings.onclick) |
5041 } |
5094 m.settings.onclick(e); |
5042 }, 0); |
|
5043 |
|
5044 // Yield on IE to prevent loosing image focus when context menu is used |
|
5045 window.setTimeout(function() { |
|
5046 if (m.settings.onclick) |
|
5047 m.settings.onclick(e); |
|
5048 }, 0); |
|
5049 |
5095 |
5050 return Event.cancel(e); // Cancel to fix onbeforeunload problem |
5096 return Event.cancel(e); // Cancel to fix onbeforeunload problem |
5051 } |
5097 } |
5052 }); |
5098 }); |
5053 |
5099 |
5079 t.onShowMenu.dispatch(t); |
5125 t.onShowMenu.dispatch(t); |
5080 |
5126 |
5081 if (s.keyboard_focus) { |
5127 if (s.keyboard_focus) { |
5082 Event.add(co, 'keydown', t._keyHandler, t); |
5128 Event.add(co, 'keydown', t._keyHandler, t); |
5083 DOM.select('a', 'menu_' + t.id)[0].focus(); // Select first link |
5129 DOM.select('a', 'menu_' + t.id)[0].focus(); // Select first link |
5130 t._focusIdx = 0; |
|
5084 } |
5131 } |
5085 }, |
5132 }, |
5086 |
5133 |
5087 hideMenu : function(c) { |
5134 hideMenu : function(c) { |
5088 var t = this, co = DOM.get('menu_' + t.id), e; |
5135 var t = this, co = DOM.get('menu_' + t.id), e; |
5089 |
5136 |
5090 if (!t.isMenuVisible) |
5137 if (!t.isMenuVisible) |
5091 return; |
5138 return; |
5092 |
5139 |
5093 Event.remove(co, 'mouseover', t.mouseOverFunc); |
5140 Event.remove(co, 'mouseover', t.mouseOverFunc); |
5094 Event.remove(co, t.fixIE ? 'mousedown' : 'click', t.mouseClickFunc); |
5141 Event.remove(co, 'click', t.mouseClickFunc); |
5095 Event.remove(co, 'keydown', t._keyHandler); |
5142 Event.remove(co, 'keydown', t._keyHandler); |
5096 DOM.hide(co); |
5143 DOM.hide(co); |
5097 t.isMenuVisible = 0; |
5144 t.isMenuVisible = 0; |
5098 |
5145 |
5099 if (!c) |
5146 if (!c) |
5167 }, |
5214 }, |
5168 |
5215 |
5169 // Internal functions |
5216 // Internal functions |
5170 |
5217 |
5171 _keyHandler : function(e) { |
5218 _keyHandler : function(e) { |
5172 // Accessibility feature |
5219 var t = this, kc = e.keyCode; |
5173 if (e.keyCode == 27) |
5220 |
5174 this.hideMenu(); |
5221 function focus(d) { |
5222 var i = t._focusIdx + d, e = DOM.select('a', 'menu_' + t.id)[i]; |
|
5223 |
|
5224 if (e) { |
|
5225 t._focusIdx = i; |
|
5226 e.focus(); |
|
5227 } |
|
5228 }; |
|
5229 |
|
5230 switch (kc) { |
|
5231 case 38: |
|
5232 focus(-1); // Select first link |
|
5233 return; |
|
5234 |
|
5235 case 40: |
|
5236 focus(1); |
|
5237 return; |
|
5238 |
|
5239 case 13: |
|
5240 return; |
|
5241 |
|
5242 case 27: |
|
5243 return this.hideMenu(); |
|
5244 } |
|
5175 }, |
5245 }, |
5176 |
5246 |
5177 _add : function(tb, o) { |
5247 _add : function(tb, o) { |
5178 var n, s = o.settings, a, ro, it, cp = this.classPrefix; |
5248 var n, s = o.settings, a, ro, it, cp = this.classPrefix; |
5179 |
5249 |
5347 p2 = DOM.getPos(e); |
5417 p2 = DOM.getPos(e); |
5348 |
5418 |
5349 m = t.menu; |
5419 m = t.menu; |
5350 m.settings.offset_x = p2.x; |
5420 m.settings.offset_x = p2.x; |
5351 m.settings.offset_y = p2.y; |
5421 m.settings.offset_y = p2.y; |
5352 m.settings.keyboard_focus = t._focused; |
5422 m.settings.keyboard_focus = !tinymce.isOpera; // Opera is buggy when it comes to auto focus |
5353 |
5423 |
5354 // Select in menu |
5424 // Select in menu |
5355 if (t.oldID) |
5425 if (t.oldID) |
5356 m.items[t.oldID].setSelected(0); |
5426 m.items[t.oldID].setSelected(0); |
5357 |
5427 |
5364 |
5434 |
5365 m.showMenu(0, e.clientHeight); |
5435 m.showMenu(0, e.clientHeight); |
5366 |
5436 |
5367 Event.add(DOM.doc, 'mousedown', t.hideMenu, t); |
5437 Event.add(DOM.doc, 'mousedown', t.hideMenu, t); |
5368 DOM.addClass(t.id, t.classPrefix + 'Selected'); |
5438 DOM.addClass(t.id, t.classPrefix + 'Selected'); |
5439 |
|
5440 //DOM.get(t.id + '_text').focus(); |
|
5369 }, |
5441 }, |
5370 |
5442 |
5371 hideMenu : function(e) { |
5443 hideMenu : function(e) { |
5372 var t = this; |
5444 var t = this; |
5373 |
5445 |
5396 |
5468 |
5397 m.onHideMenu.add(t.hideMenu, t); |
5469 m.onHideMenu.add(t.hideMenu, t); |
5398 |
5470 |
5399 m.add({ |
5471 m.add({ |
5400 title : t.settings.title, |
5472 title : t.settings.title, |
5401 'class' : 'mceMenuItemTitle' |
5473 'class' : 'mceMenuItemTitle', |
5402 }).setDisabled(1); |
5474 onclick : function() { |
5475 if (t.settings.onselect('') !== false) |
|
5476 t.select(''); // Must be runned after |
|
5477 } |
|
5478 }); |
|
5403 |
5479 |
5404 each(t.items, function(o) { |
5480 each(t.items, function(o) { |
5405 o.id = DOM.uniqueId(); |
5481 o.id = DOM.uniqueId(); |
5406 o.onclick = function() { |
5482 o.onclick = function() { |
5407 if (t.settings.onselect(o.value) !== false) |
5483 if (t.settings.onselect(o.value) !== false) |
5417 |
5493 |
5418 postRender : function() { |
5494 postRender : function() { |
5419 var t = this, cp = t.classPrefix; |
5495 var t = this, cp = t.classPrefix; |
5420 |
5496 |
5421 Event.add(t.id, 'click', t.showMenu, t); |
5497 Event.add(t.id, 'click', t.showMenu, t); |
5422 Event.add(t.id + '_text', 'focus', function() {t._focused = 1;}); |
5498 Event.add(t.id + '_text', 'focus', function(e) { |
5423 Event.add(t.id + '_text', 'blur', function() {t._focused = 0;}); |
5499 if (!t._focused) { |
5500 t.keyDownHandler = Event.add(t.id + '_text', 'keydown', function(e) { |
|
5501 var idx = -1, v, kc = e.keyCode; |
|
5502 |
|
5503 // Find current index |
|
5504 each(t.items, function(v, i) { |
|
5505 if (t.selectedValue == v.value) |
|
5506 idx = i; |
|
5507 }); |
|
5508 |
|
5509 // Move up/down |
|
5510 if (kc == 38) |
|
5511 v = t.items[idx - 1]; |
|
5512 else if (kc == 40) |
|
5513 v = t.items[idx + 1]; |
|
5514 else if (kc == 13) { |
|
5515 // Fake select on enter |
|
5516 v = t.selectedValue; |
|
5517 t.selectedValue = null; // Needs to be null to fake change |
|
5518 t.settings.onselect(v); |
|
5519 return Event.cancel(e); |
|
5520 } |
|
5521 |
|
5522 if (v) { |
|
5523 t.hideMenu(); |
|
5524 t.select(v.value); |
|
5525 } |
|
5526 }); |
|
5527 } |
|
5528 |
|
5529 t._focused = 1; |
|
5530 }); |
|
5531 Event.add(t.id + '_text', 'blur', function() {Event.remove(t.id + '_text', 'keydown', t.keyDownHandler); t._focused = 0;}); |
|
5424 |
5532 |
5425 // Old IE doesn't have hover on all elements |
5533 // Old IE doesn't have hover on all elements |
5426 if (tinymce.isIE6 || !DOM.boxModel) { |
5534 if (tinymce.isIE6 || !DOM.boxModel) { |
5427 Event.add(t.id, 'mouseover', function() { |
5535 Event.add(t.id, 'mouseover', function() { |
5428 if (!DOM.hasClass(t.id, cp + 'Disabled')) |
5536 if (!DOM.hasClass(t.id, cp + 'Disabled')) |
5728 t.settings = s = tinymce.extend({ |
5836 t.settings = s = tinymce.extend({ |
5729 colors : '000000,993300,333300,003300,003366,000080,333399,333333,800000,FF6600,808000,008000,008080,0000FF,666699,808080,FF0000,FF9900,99CC00,339966,33CCCC,3366FF,800080,999999,FF00FF,FFCC00,FFFF00,00FF00,00FFFF,00CCFF,993366,C0C0C0,FF99CC,FFCC99,FFFF99,CCFFCC,CCFFFF,99CCFF,CC99FF,FFFFFF', |
5837 colors : '000000,993300,333300,003300,003366,000080,333399,333333,800000,FF6600,808000,008000,008080,0000FF,666699,808080,FF0000,FF9900,99CC00,339966,33CCCC,3366FF,800080,999999,FF00FF,FFCC00,FFFF00,00FF00,00FFFF,00CCFF,993366,C0C0C0,FF99CC,FFCC99,FFFF99,CCFFCC,CCFFFF,99CCFF,CC99FF,FFFFFF', |
5730 grid_width : 8, |
5838 grid_width : 8, |
5731 default_color : '#888888' |
5839 default_color : '#888888' |
5732 }, t.settings); |
5840 }, t.settings); |
5841 |
|
5842 t.onShowMenu = new tinymce.util.Dispatcher(t); |
|
5843 t.onHideMenu = new tinymce.util.Dispatcher(t); |
|
5733 |
5844 |
5734 t.value = s.default_color; |
5845 t.value = s.default_color; |
5735 }, |
5846 }, |
5736 |
5847 |
5737 showMenu : function() { |
5848 showMenu : function() { |
5768 }); |
5879 }); |
5769 |
5880 |
5770 DOM.select('a', t.id + '_menu')[0].focus(); // Select first link |
5881 DOM.select('a', t.id + '_menu')[0].focus(); // Select first link |
5771 } |
5882 } |
5772 |
5883 |
5884 t.onShowMenu.dispatch(t); |
|
5885 |
|
5773 t.isMenuVisible = 1; |
5886 t.isMenuVisible = 1; |
5774 }, |
5887 }, |
5775 |
5888 |
5776 hideMenu : function(e) { |
5889 hideMenu : function(e) { |
5777 var t = this; |
5890 var t = this; |
5784 DOM.removeClass(t.id, 'mceSplitButtonSelected'); |
5897 DOM.removeClass(t.id, 'mceSplitButtonSelected'); |
5785 Event.remove(DOM.doc, 'mousedown', t.hideMenu, t); |
5898 Event.remove(DOM.doc, 'mousedown', t.hideMenu, t); |
5786 Event.remove(t.id + '_menu', 'keydown', t._keyHandler); |
5899 Event.remove(t.id + '_menu', 'keydown', t._keyHandler); |
5787 DOM.hide(t.id + '_menu'); |
5900 DOM.hide(t.id + '_menu'); |
5788 } |
5901 } |
5902 |
|
5903 t.onHideMenu.dispatch(t); |
|
5789 |
5904 |
5790 t.isMenuVisible = 0; |
5905 t.isMenuVisible = 0; |
5791 }, |
5906 }, |
5792 |
5907 |
5793 renderMenu : function() { |
5908 renderMenu : function() { |
6465 convert_fonts_to_spans : true, |
6580 convert_fonts_to_spans : true, |
6466 font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large', |
6581 font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large', |
6467 apply_source_formatting : 1, |
6582 apply_source_formatting : 1, |
6468 directionality : 'ltr', |
6583 directionality : 'ltr', |
6469 forced_root_block : 'p', |
6584 forced_root_block : 'p', |
6470 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,-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|_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],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', |
6585 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],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', |
6471 hidden_input : 1, |
6586 hidden_input : 1, |
6472 padd_empty_editor : 1, |
6587 padd_empty_editor : 1, |
6473 render_ui : 1, |
6588 render_ui : 1, |
6474 init_theme : 1, |
6589 init_theme : 1, |
6475 force_p_newlines : 1, |
6590 force_p_newlines : 1, |
6518 |
6633 |
6519 t.windowManager = new tinymce.WindowManager(t); |
6634 t.windowManager = new tinymce.WindowManager(t); |
6520 |
6635 |
6521 if (s.encoding == 'xml') { |
6636 if (s.encoding == 'xml') { |
6522 t.onGetContent.add(function(ed, o) { |
6637 t.onGetContent.add(function(ed, o) { |
6523 if (o.get) |
6638 if (o.save) |
6524 o.content = DOM.encode(o.content); |
6639 o.content = DOM.encode(o.content); |
6525 }); |
6640 }); |
6526 } |
6641 } |
6527 |
6642 |
6528 if (s.add_form_submit_trigger) { |
6643 if (s.add_form_submit_trigger) { |
6532 t.isNotDirty = 1; |
6647 t.isNotDirty = 1; |
6533 } |
6648 } |
6534 }); |
6649 }); |
6535 } |
6650 } |
6536 |
6651 |
6537 if (s.add_unload_trigger) { |
6652 if (s.add_unload_trigger && !s.ask) { |
6538 t._beforeUnload = tinyMCE.onBeforeUnload.add(function() { |
6653 t._beforeUnload = tinyMCE.onBeforeUnload.add(function() { |
6539 if (t.initialized && !t.destroyed && !t.isHidden()) |
6654 if (t.initialized && !t.destroyed && !t.isHidden()) |
6540 t.save({format : 'raw', no_events : true}); |
6655 t.save({format : 'raw', no_events : true}); |
6541 }); |
6656 }); |
6542 } |
6657 } |
6591 |
6706 |
6592 // Init when que is loaded |
6707 // Init when que is loaded |
6593 sl.loadQueue(function() { |
6708 sl.loadQueue(function() { |
6594 if (s.ask) { |
6709 if (s.ask) { |
6595 function ask() { |
6710 function ask() { |
6596 t.windowManager.confirm(t.getLang('edit_confirm'), function(s) { |
6711 // Yield for awhile to avoid focus bug on FF 3 when cancel is pressed |
6597 if (s) |
6712 window.setTimeout(function() { |
6598 t.init(); |
6713 Event.remove(t.id, 'focus', ask); |
6599 else |
6714 |
6600 Event.remove(t.id, 'focus', ask); |
6715 t.windowManager.confirm(t.getLang('edit_confirm'), function(s) { |
6601 }); |
6716 if (s) |
6717 t.init(); |
|
6718 }); |
|
6719 }, 0); |
|
6602 }; |
6720 }; |
6603 |
6721 |
6604 Event.add(t.id, 'focus', ask); |
6722 Event.add(t.id, 'focus', ask); |
6605 return; |
6723 return; |
6606 } |
6724 } |
6734 |
6852 |
6735 h = (o.iframeHeight || h) + ((h + '').indexOf('%') == -1 ? (o.deltaHeight || 0) : ''); |
6853 h = (o.iframeHeight || h) + ((h + '').indexOf('%') == -1 ? (o.deltaHeight || 0) : ''); |
6736 if (h < 100) |
6854 if (h < 100) |
6737 h = 100; |
6855 h = 100; |
6738 |
6856 |
6739 t.iframeHTML = s.doctype + '<html><head xmlns="http://www.w3.org/1999/xhtml"><base href="' + t.documentBaseURI.getURI() + '"></base>'; |
6857 t.iframeHTML = s.doctype + '<html><head xmlns="http://www.w3.org/1999/xhtml"><base href="' + t.documentBaseURI.getURI() + '" />'; |
6740 t.iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />'; |
6858 t.iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />'; |
6741 |
6859 |
6742 if (tinymce.relaxedDomain) |
6860 if (tinymce.relaxedDomain) |
6743 t.iframeHTML += '<script type="text/javascript">document.domain = "' + tinymce.relaxedDomain + '";</script>'; |
6861 t.iframeHTML += '<script type="text/javascript">document.domain = "' + tinymce.relaxedDomain + '";</script>'; |
6744 |
6862 |
7085 e = null; |
7203 e = null; |
7086 }, |
7204 }, |
7087 |
7205 |
7088 |
7206 |
7089 focus : function(sf) { |
7207 focus : function(sf) { |
7090 var oed, t = this; |
7208 var oed, t = this, ce = t.settings.content_editable; |
7091 |
7209 |
7092 if (!sf) { |
7210 if (!sf) { |
7093 t.getWin().focus(); |
7211 // Is not content editable or the selection is outside the area in IE |
7212 // the IE statement is needed to avoid bluring if element selections inside layers since |
|
7213 // the layer is like it's own document in IE |
|
7214 if (!ce && (!isIE || t.selection.getNode().ownerDocument != t.getDoc())) |
|
7215 t.getWin().focus(); |
|
7094 |
7216 |
7095 } |
7217 } |
7096 |
7218 |
7097 if (EditorManager.activeEditor != t) { |
7219 if (EditorManager.activeEditor != t) { |
7098 if ((oed = EditorManager.activeEditor) != null) |
7220 if ((oed = EditorManager.activeEditor) != null) |
7263 o = {}; |
7385 o = {}; |
7264 t.onBeforeExecCommand.dispatch(t, cmd, ui, val, o); |
7386 t.onBeforeExecCommand.dispatch(t, cmd, ui, val, o); |
7265 if (o.terminate) |
7387 if (o.terminate) |
7266 return false; |
7388 return false; |
7267 |
7389 |
7268 // Comamnd callback |
7390 // Command callback |
7269 if (t.execCallback('execcommand_callback', t.id, t.selection.getNode(), cmd, ui, val)) { |
7391 if (t.execCallback('execcommand_callback', t.id, t.selection.getNode(), cmd, ui, val)) { |
7270 t.onExecCommand.dispatch(t, cmd, ui, val, a); |
7392 t.onExecCommand.dispatch(t, cmd, ui, val, a); |
7271 return true; |
7393 return true; |
7272 } |
7394 } |
7273 |
7395 |
7429 if (!t.initialized) |
7551 if (!t.initialized) |
7430 return; |
7552 return; |
7431 |
7553 |
7432 o = o || {}; |
7554 o = o || {}; |
7433 o.save = true; |
7555 o.save = true; |
7556 |
|
7557 // Add undo level will trigger onchange event |
|
7558 if (!o.no_events) { |
|
7559 t.undoManager.typing = 0; |
|
7560 t.undoManager.add(); |
|
7561 } |
|
7434 |
7562 |
7435 o.element = e; |
7563 o.element = e; |
7436 h = o.content = t.getContent(o); |
7564 h = o.content = t.getContent(o); |
7437 |
7565 |
7438 if (!o.no_events) |
7566 if (!o.no_events) |
7472 t.onBeforeSetContent.dispatch(t, o); |
7600 t.onBeforeSetContent.dispatch(t, o); |
7473 |
7601 |
7474 // Padd empty content in Gecko and Safari. Commands will otherwise fail on the content |
7602 // Padd empty content in Gecko and Safari. Commands will otherwise fail on the content |
7475 // It will also be impossible to place the caret in the editor unless there is a BR element present |
7603 // It will also be impossible to place the caret in the editor unless there is a BR element present |
7476 if (!tinymce.isIE && (h.length === 0 || /^\s+$/.test(h))) { |
7604 if (!tinymce.isIE && (h.length === 0 || /^\s+$/.test(h))) { |
7477 o.content = t.dom.setHTML(t.getBody(), '<br mce_bogus="1" />', 1); |
7605 o.content = t.dom.setHTML(t.getBody(), '<br mce_bogus="1" />'); |
7478 o.format = 'raw'; |
7606 o.format = 'raw'; |
7479 } |
7607 } |
7480 |
7608 |
7481 o.content = t.dom.setHTML(t.getBody(), tinymce.trim(o.content)); |
7609 o.content = t.dom.setHTML(t.getBody(), tinymce.trim(o.content)); |
7482 |
7610 |
7506 h = t.serializer.serialize(t.getBody(), o); |
7634 h = t.serializer.serialize(t.getBody(), o); |
7507 } else |
7635 } else |
7508 h = t.getBody().innerHTML; |
7636 h = t.getBody().innerHTML; |
7509 |
7637 |
7510 h = h.replace(/^\s*|\s*$/g, ''); |
7638 h = h.replace(/^\s*|\s*$/g, ''); |
7511 o = {content : h}; |
7639 o.content = h; |
7512 t.onGetContent.dispatch(t, o); |
7640 |
7641 if (!o.no_events) |
|
7642 t.onGetContent.dispatch(t, o); |
|
7513 |
7643 |
7514 return o.content; |
7644 return o.content; |
7515 }, |
7645 }, |
7516 |
7646 |
7517 isDirty : function() { |
7647 isDirty : function() { |
7727 each(lo, function(v, k) { |
7857 each(lo, function(v, k) { |
7728 switch (k) { |
7858 switch (k) { |
7729 case 'contextmenu': |
7859 case 'contextmenu': |
7730 if (tinymce.isOpera) { |
7860 if (tinymce.isOpera) { |
7731 // Fake contextmenu on Opera |
7861 // Fake contextmenu on Opera |
7732 Event.add(t.getDoc(), 'mousedown', function(e) { |
7862 Event.add(t.getBody(), 'mousedown', function(e) { |
7733 if (e.ctrlKey) { |
7863 if (e.ctrlKey) { |
7734 e.fakeType = 'contextmenu'; |
7864 e.fakeType = 'contextmenu'; |
7735 eventHandler(e); |
7865 eventHandler(e); |
7736 } |
7866 } |
7737 }); |
7867 }); |
7738 } else |
7868 } else |
7739 Event.add(t.getDoc(), k, eventHandler); |
7869 Event.add(t.getBody(), k, eventHandler); |
7740 break; |
7870 break; |
7741 |
7871 |
7742 case 'paste': |
7872 case 'paste': |
7743 Event.add(t.getBody(), k, function(e) { |
7873 Event.add(t.getBody(), k, function(e) { |
7744 var tx, h, el, r; |
7874 var tx, h, el, r; |
7820 // Try new Gecko method |
7950 // Try new Gecko method |
7821 d.execCommand("styleWithCSS", 0, false); |
7951 d.execCommand("styleWithCSS", 0, false); |
7822 } catch (ex) { |
7952 } catch (ex) { |
7823 // Use old method |
7953 // Use old method |
7824 if (!t._isHidden()) |
7954 if (!t._isHidden()) |
7825 d.execCommand("useCSS", 0, true); |
7955 try {d.execCommand("useCSS", 0, true);} catch (ex) {} |
7826 } |
7956 } |
7827 |
7957 |
7828 if (!s.table_inline_editing) |
7958 if (!s.table_inline_editing) |
7829 try {d.execCommand('enableInlineTableEditing', false, false);} catch (ex) {} |
7959 try {d.execCommand('enableInlineTableEditing', false, false);} catch (ex) {} |
7830 |
7960 |
8549 } else |
8679 } else |
8550 ed.getDoc().execCommand('FontName', false, v); |
8680 ed.getDoc().execCommand('FontName', false, v); |
8551 }, |
8681 }, |
8552 |
8682 |
8553 FontSize : function(u, v) { |
8683 FontSize : function(u, v) { |
8554 var ed = this.editor, s = ed.settings, fz = tinymce.explode(s.font_size_style_values), fzc = tinymce.explode(s.font_size_classes); |
8684 var ed = this.editor, s = ed.settings, fz = tinymce.explode(s.font_size_style_values), fzc = tinymce.explode(s.font_size_classes), h, bm; |
8555 |
8685 |
8686 // Remove style sizes |
|
8687 each(ed.dom.select('font'), function(e) { |
|
8688 e.style.fontSize = ''; |
|
8689 }); |
|
8690 |
|
8691 // Let the browser add new size it will remove unneded ones in some browsers |
|
8556 ed.getDoc().execCommand('FontSize', false, v); |
8692 ed.getDoc().execCommand('FontSize', false, v); |
8557 |
8693 |
8558 // Add style values |
8694 // Add style values |
8559 if (s.inline_styles) { |
8695 if (s.inline_styles) { |
8560 each(ed.dom.select('font'), function(e) { |
8696 each(ed.dom.select('font'), function(e) { |
8561 if (e.size === v) { |
8697 // Try remove redundant font elements |
8698 if (e.parentNode.nodeName == 'FONT' && e.size == e.parentNode.size) { |
|
8699 if (!bm) |
|
8700 bm = ed.selection.getBookmark(); |
|
8701 |
|
8702 ed.dom.remove(e, 1); |
|
8703 return; |
|
8704 } |
|
8705 |
|
8706 // Setup font size based on font size value |
|
8707 if (v = e.size) { |
|
8562 if (fzc && fzc.length > 0) |
8708 if (fzc && fzc.length > 0) |
8563 ed.dom.setAttrib(e, 'class', fzc[parseInt(v) - 1]); |
8709 ed.dom.setAttrib(e, 'class', fzc[parseInt(v) - 1]); |
8564 else |
8710 else |
8565 ed.dom.setStyle(e, 'fontSize', fz[parseInt(v) - 1]); |
8711 ed.dom.setStyle(e, 'fontSize', fz[parseInt(v) - 1]); |
8566 } |
8712 } |
8567 }); |
8713 }); |
8568 } |
8714 } |
8715 |
|
8716 ed.selection.moveToBookmark(bm); |
|
8569 }, |
8717 }, |
8570 |
8718 |
8571 queryCommandValue : function(c) { |
8719 queryCommandValue : function(c) { |
8572 var f = this['queryValue' + c]; |
8720 var f = this['queryValue' + c]; |
8573 |
8721 |
9002 } else |
9150 } else |
9003 ed.getDoc().execCommand('Redo', false, null); |
9151 ed.getDoc().execCommand('Redo', false, null); |
9004 }, |
9152 }, |
9005 |
9153 |
9006 FormatBlock : function(ui, val) { |
9154 FormatBlock : function(ui, val) { |
9007 var t = this, ed = t.editor; |
9155 var t = this, ed = t.editor, s = ed.selection, dom = ed.dom, bl, nb, b; |
9156 |
|
9157 function isBlock(n) { |
|
9158 return /^(P|DIV|H[1-6]|ADDRESS|BLOCKQUOTE|PRE)$/.test(n.nodeName); |
|
9159 }; |
|
9160 |
|
9161 bl = dom.getParent(s.getNode(), function(n) { |
|
9162 return isBlock(n); |
|
9163 }); |
|
9164 |
|
9165 // IE has an issue where it removes the parent div if you change format on the paragrah in <div><p>Content</p></div> |
|
9166 // FF and Opera doesn't change parent DIV elements if you switch format |
|
9167 if (bl) { |
|
9168 if ((isIE && isBlock(bl.parentNode)) || bl.nodeName == 'DIV') { |
|
9169 // Rename block element |
|
9170 nb = ed.dom.create(val); |
|
9171 |
|
9172 each(dom.getAttribs(bl), function(v) { |
|
9173 dom.setAttrib(nb, v.nodeName, dom.getAttrib(bl, v.nodeName)); |
|
9174 }); |
|
9175 |
|
9176 b = s.getBookmark(); |
|
9177 dom.replace(nb, bl, 1); |
|
9178 s.moveToBookmark(b); |
|
9179 ed.nodeChanged(); |
|
9180 return; |
|
9181 } |
|
9182 } |
|
9008 |
9183 |
9009 val = ed.settings.forced_root_block ? (val || '<p>') : val; |
9184 val = ed.settings.forced_root_block ? (val || '<p>') : val; |
9010 |
|
9011 if (/^(P|DIV|H[1-6]|ADDRESS|BLOCKQUOTE|PRE)$/.test(ed.selection.getNode().nodeName)) |
|
9012 t.mceRemoveNode(); |
|
9013 |
9185 |
9014 if (val.indexOf('<') == -1) |
9186 if (val.indexOf('<') == -1) |
9015 val = '<' + val + '>'; |
9187 val = '<' + val + '>'; |
9016 |
9188 |
9017 if (tinymce.isGecko) |
9189 if (tinymce.isGecko) |
9654 // Create new block but ignore whitespace |
9826 // Create new block but ignore whitespace |
9655 if (nx.nodeType != 3 || /[^\s]/g.test(nx.nodeValue)) { |
9827 if (nx.nodeType != 3 || /[^\s]/g.test(nx.nodeValue)) { |
9656 // Store selection |
9828 // Store selection |
9657 if (si == -2 && r) { |
9829 if (si == -2 && r) { |
9658 if (!isIE) { |
9830 if (!isIE) { |
9659 so = r.startOffset; |
9831 // If element is inside body, might not be the case in contentEdiable mode |
9660 eo = r.endOffset; |
9832 if (ed.dom.getParent(r.startContainer, function(e) {return e === b;})) { |
9661 si = t.find(b, 0, r.startContainer); |
9833 so = r.startOffset; |
9662 ei = t.find(b, 0, r.endContainer); |
9834 eo = r.endOffset; |
9835 si = t.find(b, 0, r.startContainer); |
|
9836 ei = t.find(b, 0, r.endContainer); |
|
9837 } |
|
9663 } else { |
9838 } else { |
9664 tr = d.body.createTextRange(); |
9839 tr = d.body.createTextRange(); |
9665 tr.moveToElementText(b); |
9840 tr.moveToElementText(b); |
9666 tr.collapse(1); |
9841 tr.collapse(1); |
9667 bp = tr.move('character', c) * -1; |
9842 bp = tr.move('character', c) * -1; |
9694 } |
9869 } |
9695 |
9870 |
9696 // Restore selection |
9871 // Restore selection |
9697 if (si != -2) { |
9872 if (si != -2) { |
9698 if (!isIE) { |
9873 if (!isIE) { |
9699 bl = d.getElementsByTagName(ed.settings.element)[0]; |
9874 bl = b.getElementsByTagName(ed.settings.element)[0]; |
9700 r = d.createRange(); |
9875 r = d.createRange(); |
9701 |
9876 |
9702 // Select last location or generated block |
9877 // Select last location or generated block |
9703 if (si != -1) |
9878 if (si != -1) |
9704 r.setStart(t.find(b, 1, si), so); |
9879 r.setStart(t.find(b, 1, si), so); |
9916 bef.innerHTML = '<br />'; |
10091 bef.innerHTML = '<br />'; |
9917 |
10092 |
9918 if (isEmpty(aft)) |
10093 if (isEmpty(aft)) |
9919 aft.innerHTML = isOpera ? ' ' : '<br />'; // Extra space for Opera so that the caret can move there |
10094 aft.innerHTML = isOpera ? ' ' : '<br />'; // Extra space for Opera so that the caret can move there |
9920 |
10095 |
9921 // Opera needs this one backwards |
10096 // Opera needs this one backwards for older versions |
9922 if (isOpera) { |
10097 if (isOpera && parseFloat(opera.version()) < 9.5) { |
9923 r.insertNode(bef); |
10098 r.insertNode(bef); |
9924 r.insertNode(aft); |
10099 r.insertNode(aft); |
9925 } else { |
10100 } else { |
9926 r.insertNode(aft); |
10101 r.insertNode(aft); |
9927 r.insertNode(bef); |
10102 r.insertNode(bef); |
10127 }); |
10302 }); |
10128 |
10303 |
10129 // Fix for bug #1897785, #1898007 |
10304 // Fix for bug #1897785, #1898007 |
10130 if (tinymce.isIE) { |
10305 if (tinymce.isIE) { |
10131 c.onShowMenu.add(function() { |
10306 c.onShowMenu.add(function() { |
10132 var s = ed.selection, n = s.getNode(); |
10307 bm = ed.selection.getBookmark(1); |
10133 |
|
10134 if (n.nodeName == 'IMG') |
|
10135 bm = s.getBookmark(); |
|
10136 else |
|
10137 bm = 0; |
|
10138 }); |
10308 }); |
10139 |
10309 |
10140 c.onHideMenu.add(function() { |
10310 c.onHideMenu.add(function() { |
10141 if (bm) |
10311 if (bm) |
10142 ed.selection.moveToBookmark(bm); |
10312 ed.selection.moveToBookmark(bm); |
10281 |
10451 |
10282 return c; |
10452 return c; |
10283 }, |
10453 }, |
10284 |
10454 |
10285 createColorSplitButton : function(id, s, cc) { |
10455 createColorSplitButton : function(id, s, cc) { |
10286 var t = this, ed = t.editor, cmd, c, cls; |
10456 var t = this, ed = t.editor, cmd, c, cls, bm; |
10287 |
10457 |
10288 if (t.get(id)) |
10458 if (t.get(id)) |
10289 return null; |
10459 return null; |
10290 |
10460 |
10291 s.title = ed.translate(s.title); |
10461 s.title = ed.translate(s.title); |
10318 |
10488 |
10319 // Remove the menu element when the editor is removed |
10489 // Remove the menu element when the editor is removed |
10320 ed.onRemove.add(function() { |
10490 ed.onRemove.add(function() { |
10321 c.destroy(); |
10491 c.destroy(); |
10322 }); |
10492 }); |
10493 |
|
10494 // Fix for bug #1897785, #1898007 |
|
10495 if (tinymce.isIE) { |
|
10496 c.onShowMenu.add(function() { |
|
10497 bm = ed.selection.getBookmark(1); |
|
10498 }); |
|
10499 |
|
10500 c.onHideMenu.add(function() { |
|
10501 if (bm) { |
|
10502 ed.selection.moveToBookmark(bm); |
|
10503 bm = 0; |
|
10504 } |
|
10505 }); |
|
10506 } |
|
10323 |
10507 |
10324 return t.add(c); |
10508 return t.add(c); |
10325 }, |
10509 }, |
10326 |
10510 |
10327 createToolbar : function(id, s, cc) { |
10511 createToolbar : function(id, s, cc) { |
10398 s.center = true; |
10582 s.center = true; |
10399 s.help = false; |
10583 s.help = false; |
10400 s.dialogWidth = s.width + 'px'; |
10584 s.dialogWidth = s.width + 'px'; |
10401 s.dialogHeight = s.height + 'px'; |
10585 s.dialogHeight = s.height + 'px'; |
10402 s.scroll = s.scrollbars || false; |
10586 s.scroll = s.scrollbars || false; |
10403 } else |
10587 } |
10404 s.modal = s.alwaysRaised = s.dialog = s.centerscreen = s.dependent = true; |
|
10405 } |
10588 } |
10406 |
10589 |
10407 // Build features string |
10590 // Build features string |
10408 each(s, function(v, k) { |
10591 each(s, function(v, k) { |
10409 if (tinymce.is(v, 'boolean')) |
10592 if (tinymce.is(v, 'boolean')) |