]> git.donarmstrong.com Git - roundcube.git/blobdiff - program/js/tiny_mce/themes/advanced/editor_template_src.js
Imported Upstream version 0.5
[roundcube.git] / program / js / tiny_mce / themes / advanced / editor_template_src.js
index 21eb259a205a9da0d3c46f24deb13b0b309b8ff9..279ca359ce3d9f6246367d3df302ccbc94b1b12e 100644 (file)
@@ -1,8 +1,11 @@
 /**\r
- * $Id: editor_template_src.js 1045 2009-03-04 20:03:18Z spocke $\r
+ * editor_template_src.js\r
  *\r
- * @author Moxiecode\r
- * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.\r
+ * Copyright 2009, Moxiecode Systems AB\r
+ * Released under LGPL License.\r
+ *\r
+ * License: http://tinymce.moxiecode.com/license\r
+ * Contributing: http://tinymce.moxiecode.com/contributing\r
  */\r
 \r
 (function(tinymce) {\r
 \r
                                        if (k == v && v >= 1 && v <= 7) {\r
                                                k = v + ' (' + t.sizes[v - 1] + 'pt)';\r
-\r
-                                               if (ed.settings.convert_fonts_to_spans) {\r
-                                                       cl = s.font_size_classes[v - 1];\r
-                                                       v = s.font_size_style_values[v - 1] || (t.sizes[v - 1] + 'pt');\r
-                                               }\r
+                                               cl = s.font_size_classes[v - 1];\r
+                                               v = s.font_size_style_values[v - 1] || (t.sizes[v - 1] + 'pt');\r
                                        }\r
 \r
                                        if (/^\s*\./.test(v))\r
 \r
                        // Init editor\r
                        ed.onInit.add(function() {\r
-                               ed.onNodeChange.add(t._nodeChanged, t);\r
+                               if (!ed.settings.readonly)\r
+                                       ed.onNodeChange.add(t._nodeChanged, t);\r
 \r
                                if (ed.settings.content_css !== false)\r
                                        ed.dom.loadCSS(ed.baseURI.toAbsolute("themes/advanced/skins/" + ed.settings.skin + "/content.css"));\r
                },\r
 \r
                _importClasses : function(e) {\r
-                       var ed = this.editor, c = ed.controlManager.get('styleselect');\r
+                       var ed = this.editor, ctrl = ed.controlManager.get('styleselect');\r
+\r
+                       if (ctrl.getLength() == 0) {\r
+                               each(ed.dom.getClasses(), function(o, idx) {\r
+                                       var name = 'style_' + idx;\r
+\r
+                                       ed.formatter.register(name, {\r
+                                               inline : 'span',\r
+                                               attributes : {'class' : o['class']},\r
+                                               selector : '*'\r
+                                       });\r
 \r
-                       if (c.getLength() == 0) {\r
-                               each(ed.dom.getClasses(), function(o) {\r
-                                       c.add(o['class'], o['class']);\r
+                                       ctrl.add(o['class'], name);\r
                                });\r
                        }\r
                },\r
 \r
                _createStyleSelect : function(n) {\r
-                       var t = this, ed = t.editor, cf = ed.controlManager, c = cf.createListBox('styleselect', {\r
+                       var t = this, ed = t.editor, ctrlMan = ed.controlManager, ctrl;\r
+\r
+                       // Setup style select box\r
+                       ctrl = ctrlMan.createListBox('styleselect', {\r
                                title : 'advanced.style_select',\r
-                               onselect : function(v) {\r
-                                       if (c.selectedValue === v) {\r
-                                               ed.execCommand('mceSetStyleInfo', 0, {command : 'removeformat'});\r
-                                               c.select();\r
-                                               return false;\r
-                                       } else\r
-                                               ed.execCommand('mceSetCSSClass', 0, v);\r
+                               onselect : function(name) {\r
+                                       var matches, formatNames = [];\r
+\r
+                                       each(ctrl.items, function(item) {\r
+                                               formatNames.push(item.value);\r
+                                       });\r
+\r
+                                       ed.focus();\r
+                                       ed.undoManager.add();\r
+\r
+                                       // Toggle off the current format\r
+                                       matches = ed.formatter.matchAll(formatNames);\r
+                                       if (matches[0] == name)\r
+                                               ed.formatter.remove(name);\r
+                                       else\r
+                                               ed.formatter.apply(name);\r
+\r
+                                       ed.undoManager.add();\r
+                                       ed.nodeChanged();\r
+\r
+                                       return false; // No auto select\r
                                }\r
                        });\r
 \r
-                       if (c) {\r
-                               each(ed.getParam('theme_advanced_styles', '', 'hash'), function(v, k) {\r
-                                       if (v)\r
-                                               c.add(t.editor.translate(k), v);\r
-                               });\r
+                       // Handle specified format\r
+                       ed.onInit.add(function() {\r
+                               var counter = 0, formats = ed.getParam('style_formats');\r
+\r
+                               if (formats) {\r
+                                       each(formats, function(fmt) {\r
+                                               var name, keys = 0;\r
+\r
+                                               each(fmt, function() {keys++;});\r
+\r
+                                               if (keys > 1) {\r
+                                                       name = fmt.name = fmt.name || 'style_' + (counter++);\r
+                                                       ed.formatter.register(name, fmt);\r
+                                                       ctrl.add(fmt.title, name);\r
+                                               } else\r
+                                                       ctrl.add(fmt.title);\r
+                                       });\r
+                               } else {\r
+                                       each(ed.getParam('theme_advanced_styles', '', 'hash'), function(val, key) {\r
+                                               var name;\r
+\r
+                                               if (val) {\r
+                                                       name = 'style_' + (counter++);\r
 \r
-                               c.onPostRender.add(function(ed, n) {\r
-                                       if (!c.NativeListBox) {\r
+                                                       ed.formatter.register(name, {\r
+                                                               inline : 'span',\r
+                                                               classes : val,\r
+                                                               selector : '*'\r
+                                                       });\r
+\r
+                                                       ctrl.add(t.editor.translate(key), name);\r
+                                               }\r
+                                       });\r
+                               }\r
+                       });\r
+\r
+                       // Auto import classes if the ctrl box is empty\r
+                       if (ctrl.getLength() == 0) {\r
+                               ctrl.onPostRender.add(function(ed, n) {\r
+                                       if (!ctrl.NativeListBox) {\r
                                                Event.add(n.id + '_text', 'focus', t._importClasses, t);\r
                                                Event.add(n.id + '_text', 'mousedown', t._importClasses, t);\r
                                                Event.add(n.id + '_open', 'focus', t._importClasses, t);\r
                                });\r
                        }\r
 \r
-                       return c;\r
+                       return ctrl;\r
                },\r
 \r
                _createFontSelect : function() {\r
                        var c, t = this, ed = t.editor;\r
 \r
-                       c = ed.controlManager.createListBox('fontselect', {title : 'advanced.fontdefault', cmd : 'FontName'});\r
+                       c = ed.controlManager.createListBox('fontselect', {\r
+                               title : 'advanced.fontdefault',\r
+                               onselect : function(v) {\r
+                                       ed.execCommand('FontName', false, v);\r
+\r
+                                       // Fake selection, execCommand will fire a nodeChange and update the selection\r
+                                       c.select(function(sv) {\r
+                                               return v == sv;\r
+                                       });\r
+\r
+                                       return false; // No auto select\r
+                               }\r
+                       });\r
+\r
                        if (c) {\r
                                each(ed.getParam('theme_advanced_fonts', t.settings.theme_advanced_fonts, 'hash'), function(v, k) {\r
                                        c.add(ed.translate(k), v, {style : v.indexOf('dings') == -1 ? 'font-family:' + v : ''});\r
                        var t = this, ed = t.editor, c, i = 0, cl = [];\r
 \r
                        c = ed.controlManager.createListBox('fontsizeselect', {title : 'advanced.font_size', onselect : function(v) {\r
-                               if (v.fontSize)\r
+                               if (v['class']) {\r
+                                       ed.focus();\r
+                                       ed.undoManager.add();\r
+                                       ed.formatter.toggle('fontsize_class', {value : v['class']});\r
+                                       ed.undoManager.add();\r
+                                       ed.nodeChanged();\r
+                               } else\r
                                        ed.execCommand('FontSize', false, v.fontSize);\r
-                               else {\r
-                                       each(t.settings.theme_advanced_font_sizes, function(v, k) {\r
-                                               if (v['class'])\r
-                                                       cl.push(v['class']);\r
-                                       });\r
 \r
-                                       ed.editorCommands._applyInlineStyle('span', {'class' : v['class']}, {check_classes : cl});\r
-                               }\r
+                               // Fake selection, execCommand will fire a nodeChange and update the selection\r
+                               c.select(function(sv) {\r
+                                       return v == sv;\r
+                               });\r
+\r
+                               return false; // No auto select\r
                        }});\r
 \r
                        if (c) {\r
                },\r
 \r
                resizeTo : function(w, h) {\r
-                       var ed = this.editor, s = ed.settings, e = DOM.get(ed.id + '_tbl'), ifr = DOM.get(ed.id + '_ifr'), dh;\r
+                       var ed = this.editor, s = this.settings, e = DOM.get(ed.id + '_tbl'), ifr = DOM.get(ed.id + '_ifr');\r
 \r
                        // Boundery fix box\r
                        w = Math.max(s.theme_advanced_resizing_min_width || 100, w);\r
                        w = Math.min(s.theme_advanced_resizing_max_width || 0xFFFF, w);\r
                        h = Math.min(s.theme_advanced_resizing_max_height || 0xFFFF, h);\r
 \r
-                       // Calc difference between iframe and container\r
-                       dh = e.clientHeight - ifr.clientHeight;\r
-\r
                        // Resize iframe and container\r
-                       DOM.setStyle(ifr, 'height', h - dh);\r
-                       DOM.setStyles(e, {width : w, height : h});\r
+                       DOM.setStyle(e, 'height', '');\r
+                       DOM.setStyle(ifr, 'height', h);\r
+\r
+                       if (s.theme_advanced_resize_horizontal) {\r
+                               DOM.setStyle(e, 'width', '');\r
+                               DOM.setStyle(ifr, 'width', w);\r
+\r
+                               // Make sure that the size is never smaller than the over all ui\r
+                               if (w < e.clientWidth)\r
+                                       DOM.setStyle(ifr, 'width', e.clientWidth);\r
+                       }\r
                },\r
 \r
                destroy : function() {\r
                                                if (!o)\r
                                                        return;\r
 \r
-                                               if (s.theme_advanced_resize_horizontal)\r
-                                                       c.style.width = Math.max(10, o.cw) + 'px';\r
-\r
-                                               c.style.height = Math.max(10, o.ch) + 'px';\r
-                                               DOM.get(ed.id + '_ifr').style.height = Math.max(10, parseInt(o.ch) + t.deltaHeight) + 'px';\r
+                                               t.resizeTo(o.cw, o.ch);\r
                                        });\r
                                }\r
 \r
                                ed.onPostRender.add(function() {\r
                                        Event.add(ed.id + '_resize', 'mousedown', function(e) {\r
-                                               var c, p, w, h, n, pa;\r
-\r
-                                               // Measure container\r
-                                               c = DOM.get(ed.id + '_tbl');\r
-                                               w = c.clientWidth;\r
-                                               h = c.clientHeight;\r
-\r
-                                               miw = s.theme_advanced_resizing_min_width || 100;\r
-                                               mih = s.theme_advanced_resizing_min_height || 100;\r
-                                               maw = s.theme_advanced_resizing_max_width || 0xFFFF;\r
-                                               mah = s.theme_advanced_resizing_max_height || 0xFFFF;\r
-\r
-                                               // Setup placeholder\r
-                                               p = DOM.add(DOM.get(ed.id + '_parent'), 'div', {'class' : 'mcePlaceHolder'});\r
-                                               DOM.setStyles(p, {width : w, height : h});\r
-\r
-                                               // Replace with placeholder\r
-                                               DOM.hide(c);\r
-                                               DOM.show(p);\r
-\r
-                                               // Create internal resize obj\r
-                                               r = {\r
-                                                       x : e.screenX,\r
-                                                       y : e.screenY,\r
-                                                       w : w,\r
-                                                       h : h,\r
-                                                       dx : null,\r
-                                                       dy : null\r
-                                               };\r
-\r
-                                               // Start listening\r
-                                               mf = Event.add(DOM.doc, 'mousemove', function(e) {\r
-                                                       var w, h;\r
-\r
-                                                       // Calc delta values\r
-                                                       r.dx = e.screenX - r.x;\r
-                                                       r.dy = e.screenY - r.y;\r
-\r
-                                                       // Boundery fix box\r
-                                                       w = Math.max(miw, r.w + r.dx);\r
-                                                       h = Math.max(mih, r.h + r.dy);\r
-                                                       w = Math.min(maw, w);\r
-                                                       h = Math.min(mah, h);\r
-\r
-                                                       // Resize placeholder\r
-                                                       if (s.theme_advanced_resize_horizontal)\r
-                                                               p.style.width = w + 'px';\r
+                                               var mouseMoveHandler1, mouseMoveHandler2,\r
+                                                       mouseUpHandler1, mouseUpHandler2,\r
+                                                       startX, startY, startWidth, startHeight, width, height, ifrElm;\r
 \r
-                                                       p.style.height = h + 'px';\r
+                                               function resizeOnMove(e) {\r
+                                                       width = startWidth + (e.screenX - startX);\r
+                                                       height = startHeight + (e.screenY - startY);\r
 \r
-                                                       return Event.cancel(e);\r
-                                               });\r
-\r
-                                               me = Event.add(DOM.doc, 'mouseup', function(e) {\r
-                                                       var ifr;\r
+                                                       t.resizeTo(width, height);\r
+                                               };\r
 \r
+                                               function endResize(e) {\r
                                                        // Stop listening\r
-                                                       Event.remove(DOM.doc, 'mousemove', mf);\r
-                                                       Event.remove(DOM.doc, 'mouseup', me);\r
-\r
-                                                       c.style.display = '';\r
-                                                       DOM.remove(p);\r
-\r
-                                                       if (r.dx === null)\r
-                                                               return;\r
-\r
-                                                       ifr = DOM.get(ed.id + '_ifr');\r
-\r
-                                                       if (s.theme_advanced_resize_horizontal)\r
-                                                               c.style.width = Math.max(10, r.w + r.dx) + 'px';\r
-\r
-                                                       c.style.height = Math.max(10, r.h + r.dy) + 'px';\r
-                                                       ifr.style.height = Math.max(10, ifr.clientHeight + r.dy) + 'px';\r
+                                                       Event.remove(DOM.doc, 'mousemove', mouseMoveHandler1);\r
+                                                       Event.remove(ed.getDoc(), 'mousemove', mouseMoveHandler2);\r
+                                                       Event.remove(DOM.doc, 'mouseup', mouseUpHandler1);\r
+                                                       Event.remove(ed.getDoc(), 'mouseup', mouseUpHandler2);\r
 \r
+                                                       // Store away the size\r
                                                        if (s.theme_advanced_resizing_use_cookie) {\r
                                                                Cookie.setHash("TinyMCE_" + ed.id + "_size", {\r
-                                                                       cw : r.w + r.dx,\r
-                                                                       ch : r.h + r.dy\r
+                                                                       cw : width,\r
+                                                                       ch : height\r
                                                                });\r
                                                        }\r
-                                               });\r
+                                               };\r
+\r
+                                               e.preventDefault();\r
+\r
+                                               // Get the current rect size\r
+                                               startX = e.screenX;\r
+                                               startY = e.screenY;\r
+                                               ifrElm = DOM.get(t.editor.id + '_ifr');\r
+                                               startWidth = width = ifrElm.clientWidth;\r
+                                               startHeight = height = ifrElm.clientHeight;\r
 \r
-                                               return Event.cancel(e);\r
+                                               // Register envent handlers\r
+                                               mouseMoveHandler1 = Event.add(DOM.doc, 'mousemove', resizeOnMove);\r
+                                               mouseMoveHandler2 = Event.add(ed.getDoc(), 'mousemove', resizeOnMove);\r
+                                               mouseUpHandler1 = Event.add(DOM.doc, 'mouseup', endResize);\r
+                                               mouseUpHandler2 = Event.add(ed.getDoc(), 'mouseup', endResize);\r
                                        });\r
                                });\r
                        }\r
                        n = tb = null;\r
                },\r
 \r
-               _nodeChanged : function(ed, cm, n, co) {\r
-                       var t = this, p, de = 0, v, c, s = t.settings, cl, fz, fn;\r
-\r
-                       if (s.readonly)\r
-                               return;\r
+               _nodeChanged : function(ed, cm, n, co, ob) {\r
+                       var t = this, p, de = 0, v, c, s = t.settings, cl, fz, fn, formatNames, matches;\r
 \r
                        tinymce.each(t.stateControls, function(c) {\r
                                cm.setActive(c, ed.queryCommandState(t.controls[c][1]));\r
                        });\r
 \r
+                       function getParent(name) {\r
+                               var i, parents = ob.parents, func = name;\r
+\r
+                               if (typeof(name) == 'string') {\r
+                                       func = function(node) {\r
+                                               return node.nodeName == name;\r
+                                       };\r
+                               }\r
+\r
+                               for (i = 0; i < parents.length; i++) {\r
+                                       if (func(parents[i]))\r
+                                               return parents[i];\r
+                               }\r
+                       };\r
+\r
                        cm.setActive('visualaid', ed.hasVisual);\r
                        cm.setDisabled('undo', !ed.undoManager.hasUndo() && !ed.typing);\r
                        cm.setDisabled('redo', !ed.undoManager.hasRedo());\r
                        cm.setDisabled('outdent', !ed.queryCommandState('Outdent'));\r
 \r
-                       p = DOM.getParent(n, 'A');\r
+                       p = getParent('A');\r
                        if (c = cm.get('link')) {\r
                                if (!p || !p.name) {\r
                                        c.setDisabled(!p && co);\r
 \r
                        if (c = cm.get('anchor')) {\r
                                c.setActive(!!p && p.name);\r
-\r
-                               if (tinymce.isWebKit) {\r
-                                       p = DOM.getParent(n, 'IMG');\r
-                                       c.setActive(!!p && DOM.getAttrib(p, 'mce_name') == 'a');\r
-                               }\r
                        }\r
 \r
-                       p = DOM.getParent(n, 'IMG');\r
+                       p = getParent('IMG');\r
                        if (c = cm.get('image'))\r
                                c.setActive(!!p && n.className.indexOf('mceItem') == -1);\r
 \r
                        if (c = cm.get('styleselect')) {\r
-                               if (n.className) {\r
-                                       t._importClasses();\r
-                                       c.select(n.className);\r
-                               } else\r
-                                       c.select();\r
+                               t._importClasses();\r
+\r
+                               formatNames = [];\r
+                               each(c.items, function(item) {\r
+                                       formatNames.push(item.value);\r
+                               });\r
+\r
+                               matches = ed.formatter.matchAll(formatNames);\r
+                               c.select(matches[0]);\r
                        }\r
 \r
                        if (c = cm.get('formatselect')) {\r
-                               p = DOM.getParent(n, DOM.isBlock);\r
+                               p = getParent(DOM.isBlock);\r
 \r
                                if (p)\r
                                        c.select(p.nodeName.toLowerCase());\r
                        }\r
 \r
-                       if (ed.settings.convert_fonts_to_spans) {\r
-                               ed.dom.getParent(n, function(n) {\r
-                                       if (n.nodeName === 'SPAN') {\r
-                                               if (!cl && n.className)\r
-                                                       cl = n.className;\r
+                       // Find out current fontSize, fontFamily and fontClass\r
+                       getParent(function(n) {\r
+                               if (n.nodeName === 'SPAN') {\r
+                                       if (!cl && n.className)\r
+                                               cl = n.className;\r
 \r
-                                               if (!fz && n.style.fontSize)\r
-                                                       fz = n.style.fontSize;\r
+                                       if (!fz && n.style.fontSize)\r
+                                               fz = n.style.fontSize;\r
 \r
-                                               if (!fn && n.style.fontFamily)\r
-                                                       fn = n.style.fontFamily.replace(/[\"\']+/g, '').replace(/^([^,]+).*/, '$1').toLowerCase();\r
-                                       }\r
+                                       if (!fn && n.style.fontFamily)\r
+                                               fn = n.style.fontFamily.replace(/[\"\']+/g, '').replace(/^([^,]+).*/, '$1').toLowerCase();\r
+                               }\r
+\r
+                               return false;\r
+                       });\r
 \r
-                                       return false;\r
+                       if (c = cm.get('fontselect')) {\r
+                               c.select(function(v) {\r
+                                       return v.replace(/^([^,]+).*/, '$1').toLowerCase() == fn;\r
                                });\r
+                       }\r
 \r
-                               if (c = cm.get('fontselect')) {\r
-                                       c.select(function(v) {\r
-                                               return v.replace(/^([^,]+).*/, '$1').toLowerCase() == fn;\r
-                                       });\r
-                               }\r
+                       // Select font size\r
+                       if (c = cm.get('fontsizeselect')) {\r
+                               // Use computed style\r
+                               if (s.theme_advanced_runtime_fontsize && !fz && !cl)\r
+                                       fz = ed.dom.getStyle(n, 'fontSize', true);\r
 \r
-                               if (c = cm.get('fontsizeselect')) {\r
-                                       c.select(function(v) {\r
-                                               if (v.fontSize && v.fontSize === fz)\r
-                                                       return true;\r
+                               c.select(function(v) {\r
+                                       if (v.fontSize && v.fontSize === fz)\r
+                                               return true;\r
 \r
-                                               if (v['class'] && v['class'] === cl)\r
-                                                       return true;\r
-                                       });\r
-                               }\r
-                       } else {\r
-                               if (c = cm.get('fontselect'))\r
-                                       c.select(ed.queryCommandValue('FontName'));\r
-\r
-                               if (c = cm.get('fontsizeselect')) {\r
-                                       v = ed.queryCommandValue('FontSize');\r
-                                       c.select(function(iv) {\r
-                                               return iv.fontSize == v;\r
-                                       });\r
-                               }\r
+                                       if (v['class'] && v['class'] === cl)\r
+                                               return true;\r
+                               });\r
                        }\r
 \r
                        if (s.theme_advanced_path && s.theme_advanced_statusbar_location) {\r
                                p = DOM.get(ed.id + '_path') || DOM.add(ed.id + '_path_row', 'span', {id : ed.id + '_path'});\r
                                DOM.setHTML(p, '');\r
 \r
-                               ed.dom.getParent(n, function(n) {\r
+                               getParent(function(n) {\r
                                        var na = n.nodeName.toLowerCase(), u, pi, ti = '';\r
 \r
+                                       /*if (n.getAttribute('_mce_bogus'))\r
+                                               return;\r
+*/\r
                                        // Ignore non element and hidden elements\r
                                        if (n.nodeType != 1 || n.nodeName === 'BR' || (DOM.hasClass(n, 'mceItemHidden') || DOM.hasClass(n, 'mceItemRemoved')))\r
                                                return;\r
                                                        break;\r
 \r
                                                case 'font':\r
-                                                       if (s.convert_fonts_to_spans)\r
-                                                               na = 'span';\r
-\r
                                                        if (v = DOM.getAttrib(n, 'face'))\r
                                                                ti += 'font: ' + v + ' ';\r
 \r
                                                ti += 'id: ' + v + ' ';\r
 \r
                                        if (v = n.className) {\r
-                                               v = v.replace(/(webkit-[\w\-]+|Apple-[\w\-]+|mceItem\w+|mceVisualAid)/g, '');\r
+                                               v = v.replace(/\b\s*(webkit|mce|Apple-)\w+\s*\b/g, '')\r
 \r
-                                               if (v && v.indexOf('mceItem') == -1) {\r
+                                               if (v) {\r
                                                        ti += 'class: ' + v + ' ';\r
 \r
                                                        if (DOM.isBlock(n) || na == 'img' || na == 'span')\r