You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by sv...@apache.org on 2005/08/17 06:03:20 UTC

svn commit: r233117 [4/5] - in /myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml: ./ resource/ resource/i18n.js/ resource/kupudrawers/ resource/kupuimages/ resource/kupupopups/

Modified: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuhelpers.js
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuhelpers.js?rev=233117&r1=233116&r2=233117&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuhelpers.js (original)
+++ myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuhelpers.js Tue Aug 16 21:02:45 2005
@@ -1,6 +1,6 @@
 /*****************************************************************************
  *
- * Copyright (c) 2003-2004 Kupu Contributors. All rights reserved.
+ * Copyright (c) 2003-2005 Kupu Contributors. All rights reserved.
  *
  * This software is distributed under the terms of the Kupu
  * License. See LICENSE.txt for license text. For a list of Kupu
@@ -75,30 +75,67 @@
 function addEventHandler(element, event, method, context) {
     /* method to add an event handler for both IE and Mozilla */
     var wrappedmethod = new ContextFixer(method, context);
+    var args = new Array(null, null);
+    for (var i=4; i < arguments.length; i++) {
+        args.push(arguments[i]);
+    };
+    wrappedmethod.args = args;
     try {
         if (_SARISSA_IS_MOZ) {
             element.addEventListener(event, wrappedmethod.execute, false);
         } else if (_SARISSA_IS_IE) {
             element.attachEvent("on" + event, wrappedmethod.execute);
         } else {
-            throw "Unsupported browser!";
+            throw _("Unsupported browser!");
         };
+        return wrappedmethod.execute;
     } catch(e) {
-        alert('exception ' + e.message + ' while registering an event handler for element ' + element + ', event ' + event + ', method ' + method);
+        alert(_('exception ${message} while registering an event handler ' +
+                'for element ${element}, event ${event}, method ${method}',
+                {'message': e.message, 'element': element,
+                    'event': event,
+                    'method': method}));
     };
 };
 
 function removeEventHandler(element, event, method) {
     /* method to remove an event handler for both IE and Mozilla */
     if (_SARISSA_IS_MOZ) {
-        window.removeEventListener('focus', method, false);
+        window.removeEventListener(event, method, false);
     } else if (_SARISSA_IS_IE) {
         element.detachEvent("on" + event, method);
     } else {
-        throw "Unsupported browser!";
+        throw _("Unsupported browser!");
     };
 };
 
+/* Replacement for window.document.getElementById()
+ * selector can be an Id (so we maintain backwards compatability)
+ * but is intended to be a subset of valid CSS selectors.
+ * For now we only support the format: "#id tag.class"
+ */
+function getFromSelector(selector) {
+    var match = /#(\S+)\s*([^ .]+)\.(\S+)/.exec(selector);
+    if (!match) {
+        return window.document.getElementById(selector);
+    }
+    var id=match[1], tag=match[2], className=match[3];
+    var base = window.document.getElementById(id);
+    return getBaseTagClass(base, tag, className);
+}
+
+function getBaseTagClass(base, tag, className) {
+    var classPat = new RegExp('\\b'+className+'\\b');
+
+    var nodes = base.getElementsByTagName(tag);
+    for (var i = 0; i < nodes.length; i++) {
+        if (classPat.test(nodes[i].className)) {
+            return nodes[i];
+        }
+    }
+    return null;
+}
+
 function openPopup(url, width, height) {
     /* open and center a popup window */
     var sw = screen.width;
@@ -122,26 +159,25 @@
     select.selectedIndex = 0;
 };
 
-function ParentWithStyleChecker(tagnames, style, stylevalue) {
+function ParentWithStyleChecker(tagnames, style, stylevalue, command) {
     /* small wrapper that provides a generic function to check if a
        button should look pressed in */
     return function(selNode, button, editor, event) {
         /* check if the button needs to look pressed in */
-        var currnode = selNode;
-        if (!currnode) {
-            return;
-        };
-        if (currnode.nodeType == 3) {
-            currnode = currnode.parentNode;
+        if (command) {
+            var result = editor.getInnerDocument().queryCommandState(command)
+            if (result || editor.getSelection().getContentLength() == 0) {
+                return result;
+            };
         };
+        var currnode = selNode;
         while (currnode && currnode.style) {
             for (var i=0; i < tagnames.length; i++) {
                 if (currnode.nodeName.toLowerCase() == tagnames[i].toLowerCase()) {
                     return true;
                 };
             };
-            if (tagnames.contains(currnode.nodeName.toLowerCase()) && 
-                    (style && currnode.style[style] == stylevalue)) {
+            if (style && currnode.style[style] == stylevalue) {
                 return true;
             };
             currnode = currnode.parentNode;
@@ -198,7 +234,7 @@
         calling context.
     */
     var dict = {};
-    var confnode = document.getElementById(islandid);
+    var confnode = getFromSelector(islandid);
     var root = null;
     for (var i=0; i < confnode.childNodes.length; i++) {
         if (confnode.childNodes[i].nodeType == 1) {
@@ -207,7 +243,7 @@
         };
     };
     if (!root) {
-        throw('No element found in the config island!');
+        throw(_('No element found in the config island!'));
     };
     dict = _load_dict_helper(root);
     return dict;
@@ -224,7 +260,6 @@
 
         returns false if no nodes are left
     */
-    
     this.node = node;
     this.current = node;
     this.terminator = continueatnextsibling ? null : node;
@@ -287,7 +322,7 @@
             this will fail if the selection is not inside the node
         */
         if (!this.selectionInsideNode(node)) {
-            throw('Selection not inside the node!');
+            throw(_('Selection not inside the node!'));
         };
         // a bit sneaky: what we'll do is insert a new br node to replace
         // the current selection, then we'll walk up to that node in both
@@ -359,7 +394,7 @@
         /* returns a Boolean to indicate if the selection is resided
             inside the node
         */
-        var currnode = self.getSelectedNode();
+        var currnode = this.parentElement();
         while (currnode) {
             if (currnode == node) {
                 return true;
@@ -508,7 +543,7 @@
             // 'Control range', range consists of a single element, so startOffset is 0
             if (startnodeoffset != 0) {
                 // just an assertion to see if my assumption about this case is right
-                throw('Start node offset detected in a node without children!');
+                throw(_('Start node offset detected in a node without children!'));
             };
             return 0;
         };
@@ -561,8 +596,10 @@
             // node doesn't have any content, so offset is always 0
             if (endnodeoffset != 0) {
                 // just an assertion to see if my assumption about this case is right
-                alert('End node offset detected in a node without children!');
-                throw('End node offset detected in a node without children!');
+                var msg = _('End node offset detected in a node without ' +
+                            'children!');
+                alert(msg);
+                throw(msg);
             };
             return 0;
         };
@@ -641,10 +678,10 @@
         
         // now cut the chunk
         if (!startparent) {
-            throw('Start offset out of range!');
+            throw(_('Start offset out of range!'));
         };
         if (!endparent) {
-            throw('End offset out of range!');
+            throw(_('End offset out of range!'));
         };
 
         var newrange = range.cloneRange();
@@ -765,7 +802,7 @@
                 };
                 currnode = currnode.nextSibling;
             };
-            throw('Offset out of document range');
+            throw(_('Offset out of document range'));
         } else if (realoffset < 0) {
             var currnode = offsetparent.prevSibling;
             var curroffset = 0;
@@ -809,6 +846,15 @@
     this.toString = function() {
         return this.selection.toString();
     };
+
+    this.getRange = function() {
+        return this.selection.getRangeAt(0);
+    }
+    this.restoreRange = function(range) {
+        var selection = this.selection;
+        selection.removeAllRanges();
+        selection.addRange(range);
+    }
 };
 
 MozillaSelection.prototype = new BaseSelection;
@@ -864,12 +910,6 @@
             node was placed, or some value that resolves to true to select
             the placed node
         */
-        // XXX one big hack!!
-        
-        // XXX this method hasn't been optimized *at all* but can probably 
-        // be made a hell of a lot faster, however for now it's complicated
-        // enough the way it is and I want to have it stable first
-        
         if (this.selection.type == 'Control') {
             var range = this.selection.createRange();
             range.item(0).parentNode.replaceChild(newnode, range.item(0));
@@ -882,99 +922,25 @@
                 range.select();
             };
         } else {
-            var selrange = this.selection.createRange();
-            var startpoint = selrange.duplicate();
-            startpoint.collapse();
-            var endpoint = selrange.duplicate();
-            endpoint.collapse(false);
-            var parent = selrange.parentElement();
-            if (parent.tagName=='IMG') parent=parent.parentElement;
-
-            var elrange = selrange.duplicate();
-            elrange.moveToElementText(parent);
-            
-            // now find the start parent and offset
-            var startoffset = this.startOffset();
-            var endoffset = this.endOffset();
-            
-            // copy parent to contain new nodes, don't copy its children (false arg)
-            var newparent = this.document.getDocument().createElement('span');
-            // also make a temp node to copy some temp nodes into later
-            var tempparent = newparent.cloneNode(false);
-
-            // this is awful, it is a hybrid DOM/copy'n'paste solution
-            // first it gets the chunk of data before the selection and
-            // pastes that (as a string) into the new parent, then it appendChilds
-            // the new node and then it pastes the stuff behind the selection 
-            // to a temp node (there's no string paste method to append) and
-            // copies the contents of that to the new node using appendChild...
-
-            // first the first bit, straightforward string pasting
-            var temprange = elrange.duplicate();
-            temprange.moveToElementText(parent);
-            temprange.collapse();
-            temprange.moveEnd('character', startoffset);
-            if (temprange.isEqual(elrange)) {
-                // cursor was on the last position in the parent
-                while (parent.hasChildNodes()) {
-                    newparent.appendChild(parent.firstChild);
-                };
-            } else {
-                // using htmlText here should fix markup problems (opening tags without closing ones etc.)
-                newparent.insertAdjacentHTML('afterBegin', temprange.htmlText);
-            };
-
-            // now some straightforward appendChilding the new node
-            newparent.appendChild(newnode);
-            
-            // getting the rest of the elements behind the selection can only be 
-            // done using htmlText (afaik) so we end up with a string, which we
-            // can not just use to attach to the new node (innerHTML would 
-            // overwrite the content) so we use set it as the innerHTML of the 
-            // temp node and after that's done appendChild all the child elements
-            // of the temp node to the new parent
-            temprange.moveToElementText(parent);
-            temprange.collapse(false);
-            temprange.moveStart('character', -endoffset);
-            if (temprange.isEqual(elrange)) {
-                // cursor was on position 0 of the parent
-                while (parent.hasChildNodes()) {
-                    tempparent.appendChild(parent.firstChild);
-                };
-            } else if (endoffset > 0) {
-                tempparent.insertAdjacentHTML('afterBegin', temprange.htmlText);
-            };
-            while (tempparent.hasChildNodes()) {
-                newparent.appendChild(tempparent.firstChild);
-            };
+            var document = this.document.getDocument();
+            var range = this.selection.createRange();
 
-            // so now we have the result in newparent, replace the old parent in 
-            // the document and we're done
-            //parent.parentNode.replaceChild(newparent, parent);
-            while (parent.hasChildNodes()) {
-                parent.removeChild(parent.firstChild);
-            };
-            while (newparent.hasChildNodes()) {
-                var child = newparent.firstChild;
-                parent.appendChild(newparent.firstChild);
-            };
+            range.pasteHTML('<img id="kupu-tempnode">');
+            tempnode = document.getElementById('kupu-tempnode');
+            tempnode.replaceNode(newnode);
 
             if (selectAfterPlace) {
                 // see MozillaSelection.replaceWithNode() for some comments about
                 // selectAfterPlace
-                var temprange = this.document.getDocument().body.createTextRange();
-                if (selectAfterPlace.nodeType == 1) {
-                    temprange.moveToElementText(selectAfterPlace);
+                if (selectAfterPlace.nodeType == Node.ELEMENT_NODE) {
+                    range.moveToElementText(selectAfterPlace);
                 } else {
-                    temprange.moveToElementText(newnode);
+                    range.moveToElementText(newnode);
                 };
-                //temprange.moveEnd('character', -1);
-                temprange.select();
+                range.select();
             };
         };
-
-        this.selection = this.document.getDocument().selection;
-
+        this.reset();
         return newnode;
     };
 
@@ -1009,15 +975,14 @@
     };
 
     this.getContentLength = function() {
+        if (this.selection.type == 'Control') {
+            return this.selection.createRange().length;
+        };
         var contentlength = 0;
-        var range = this.selection.createRange().duplicate();
-        var startpoint = range.duplicate();
-        startpoint.collapse();
-        var endpoint = range.duplicate();
-        endpoint.collapse(false);
-        while (!startpoint.isEqual(endpoint)) {
-            startpoint.moveEnd('character', 1);
-            startpoint.moveStart('character', 1);
+        var range = this.selection.createRange();
+        var endrange = range.duplicate();
+        while (range.compareEndPoints('StartToEnd', endrange) < 0) {
+            range.move('character', 1);
             contentlength++;
         };
         return contentlength;
@@ -1119,8 +1084,19 @@
         }
     };
     
+    this.getRange = function() {
+        return this.selection.createRange();
+    }
+
+    this.restoreRange = function(range) {
+        try {
+            range.select();
+        } catch(e) {
+        };
+    }
+
     this.toString = function() {
-        return this.selection.createRange().htmlText;
+        return this.selection.createRange().text;
     };
 };
 
@@ -1160,8 +1136,9 @@
         for (var i=0; i < arguments.length; i++) {
             args.push(arguments[i]);
         };
-        self.func.apply(self.context, args);
+        return self.func.apply(self.context, args);
     };
+
 };
 
 /* Alternative implementation of window.setTimeout
@@ -1255,15 +1232,105 @@
     return false;
 };
 
+// return a copy of an array with doubles removed
+Array.prototype.removeDoubles = function() {
+    var ret = [];
+    for (var i=0; i < this.length; i++) {
+        if (!ret.contains(this[i])) {
+            ret.push(this[i]);
+        };
+    };
+    return ret;
+};
+
+Array.prototype.map = function(func) {
+    /* apply 'func' to each element in the array */
+    for (var i=0; i < this.length; i++) {
+        this[i] = func(this[i]);
+    };
+};
+
+Array.prototype.reversed = function() {
+    var ret = [];
+    for (var i = this.length; i > 0; i--) {
+        ret.push(this[i - 1]);
+    };
+    return ret;
+};
+
 // JavaScript has a friggin' blink() function, but not for string stripping...
 String.prototype.strip = function() {
     var stripspace = /^\s*([\s\S]*?)\s*$/;
     return stripspace.exec(this)[1];
 };
 
+String.prototype.reduceWhitespace = function() {
+    /* returns a string in which all whitespace is reduced 
+        to a single, plain space */
+    var spacereg = /(\s+)/g;
+    var copy = this;
+    while (true) {
+        var match = spacereg.exec(copy);
+        if (!match) {
+            return copy;
+        };
+        copy = copy.replace(match[0], ' ');
+    };
+};
+
+String.prototype.entitize = function() {
+    var ret = this.replace(/&/g, '&amp;');
+    ret = ret.replace(/"/g, '&quot;');
+    ret = ret.replace(/</g, '&lt;');
+    ret = ret.replace(/>/g, '&gt;');
+    return ret;
+};
+
+String.prototype.deentitize = function() {
+    var ret = this.replace(/&gt;/g, '>');
+    ret = ret.replace(/&lt;/g, '<');
+    ret = ret.replace(/&quot;/g, '"');
+    ret = ret.replace(/&amp;/g, '&');
+    return ret;
+};
+
+String.prototype.urldecode = function() {
+    var reg = /%([a-fA-F0-9]{2})/g;
+    var str = this;
+    while (true) {
+        var match = reg.exec(str);
+        if (!match || !match.length) {
+            break;
+        };
+        var repl = new RegExp(match[0], 'g');
+        str = str.replace(repl, String.fromCharCode(parseInt(match[1], 16)));
+    };
+    return str;
+};
+
+String.prototype.centerTruncate = function(maxlength) {
+    if (this.length <= maxlength) {
+        return this;
+    };
+    var chunklength = maxlength / 2 - 3;
+    var start = this.substr(0, chunklength);
+    var end = this.substr(this.length - chunklength);
+    return start + ' ... ' + end;
+};
+
 //----------------------------------------------------------------------------
 // Exceptions
 //----------------------------------------------------------------------------
+
+function debug(str, win) {
+    if (!win) {
+        win = window;
+    };
+    var doc = win.document;
+    var div = doc.createElement('div');
+    div.appendChild(doc.createTextNode(str));
+    doc.getElementsByTagName('body')[0].appendChild(div);
+};
 
 // XXX don't know if this is the regular way to define exceptions in JavaScript?
 function Exception() {

Modified: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuimages/image.png
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuimages/image.png?rev=233117&r1=233116&r2=233117&view=diff
==============================================================================
Binary files - no diff available.

Modified: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuimages/table.png
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuimages/table.png?rev=233117&r1=233116&r2=233117&view=diff
==============================================================================
Binary files - no diff available.

Added: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuimages/text-check.png
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuimages/text-check.png?rev=233117&view=auto
==============================================================================
Binary file - no diff available.

Propchange: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuimages/text-check.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Modified: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuinit.js
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuinit.js?rev=233117&r1=233116&r2=233117&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuinit.js (original)
+++ myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuinit.js Tue Aug 16 21:02:45 2005
@@ -1,6 +1,6 @@
 /*****************************************************************************
  *
- * Copyright (c) 2003-2004 Kupu Contributors. All rights reserved.
+ * Copyright (c) 2003-2005 Kupu Contributors. All rights reserved.
  *
  * This software is distributed under the terms of the Kupu
  * License. See LICENSE.txt for license text. For a list of Kupu
@@ -59,7 +59,7 @@
     };
 
     var boldchecker = ParentWithStyleChecker(new Array('b', 'strong'),
-					     'font-weight', 'bold');
+                                             'fontWeight', 'bold', 'bold');
     var boldbutton = new KupuStateButton('kupu-bold-button', 
                                          execCommand('bold'),
                                          boldchecker,
@@ -68,7 +68,7 @@
     kupu.registerTool('boldbutton', boldbutton);
 
     var italicschecker = ParentWithStyleChecker(new Array('i', 'em'),
-						'font-style', 'italic');
+                                              'fontStyle', 'italic', 'italic');
     var italicsbutton = new KupuStateButton('kupu-italic-button', 
                                            execCommand('italic'),
                                            italicschecker, 
@@ -76,7 +76,8 @@
                                            'kupu-italic-pressed');
     kupu.registerTool('italicsbutton', italicsbutton);
 
-    var underlinechecker = ParentWithStyleChecker(new Array('u'));
+    var underlinechecker = ParentWithStyleChecker(new Array('u'),
+                                   'textDecoration', 'underline', 'underline');
     var underlinebutton = new KupuStateButton('kupu-underline-button', 
                                               execCommand('underline'),
                                               underlinechecker,
@@ -84,7 +85,8 @@
                                               'kupu-underline-pressed');
     kupu.registerTool('underlinebutton', underlinebutton);
 
-    var subscriptchecker = ParentWithStyleChecker(new Array('sub'));
+    var subscriptchecker = ParentWithStyleChecker(new Array('sub'),
+                                                  null, null, 'subscript');
     var subscriptbutton = new KupuStateButton('kupu-subscript-button',
                                               execCommand('subscript'),
                                               subscriptchecker,
@@ -92,7 +94,8 @@
                                               'kupu-subscript-pressed');
     kupu.registerTool('subscriptbutton', subscriptbutton);
 
-    var superscriptchecker = ParentWithStyleChecker(new Array('super', 'sup'));
+    var superscriptchecker = ParentWithStyleChecker(new Array('super', 'sup'),
+                                                    null, null, 'superscript');
     var superscriptbutton = new KupuStateButton('kupu-superscript-button', 
                                                 execCommand('superscript'),
                                                 superscriptchecker,
@@ -156,9 +159,6 @@
     var linktoolbox = new LinkToolBox("kupu-link-input", "kupu-link-button", 'kupu-toolbox-links', 'kupu-toolbox', 'kupu-toolbox-active');
     linktool.registerToolBox('linktoolbox', linktoolbox);
 
-    var zoom = new KupuZoomTool('kupu-zoom-button');
-    kupu.registerTool('zoomtool', zoom);
-
     var imagetool = new ImageTool();
     kupu.registerTool('imagetool', imagetool);
     var imagetoolbox = new ImageToolBox('kupu-image-input', 'kupu-image-addbutton', 
@@ -185,6 +185,17 @@
                                             'kupu-editor-textarea');
     kupu.registerTool('sourceedittool', sourceedittool);
 
+    var spellchecker = new KupuSpellChecker('kupu-spellchecker-button',
+                                            'spellcheck.cgi');
+    kupu.registerTool('spellchecker', spellchecker);
+
+    var zoom = new KupuZoomTool('kupu-zoom-button');
+    kupu.registerTool('zoomtool', zoom);
+
+    var cleanupexpressions = new CleanupExpressionsTool(
+            'kupucleanupexpressionselect', 'kupucleanupexpressionbutton');
+    kupu.registerTool('cleanupexpressions', cleanupexpressions);
+
     // Drawers...
 
     // Function that returns function to open a drawer
@@ -228,10 +239,12 @@
                                                     conf['search_images_uri']);
         drawertool.registerDrawer('imagelibdrawer', imagelibdrawer);
     } catch(e) {
-        alert('There was a problem initializing the drawers. Most likely the ' +
-                'XSLT or XML files aren\'t available. If this is not the ' +
-                'Kupu demo version, check your files or the service that ' +
-                'provide them (error: ' + (e.message || e.toString()) + ').');
+        var msg = _('There was a problem initializing the drawers. Most ' +
+                'likely the XSLT or XML files aren\'t available. If this ' +
+                'is not the Kupu demo version, check your files or the ' +
+                'service that provide them (error: ${error}).',
+                {'error': (e.message || e.toString())});
+        alert(msg);
     };
 
     var linkdrawer = new LinkDrawer('kupu-linkdrawer', linktool);
@@ -239,10 +252,6 @@
 
     var tabledrawer = new TableDrawer('kupu-tabledrawer', tabletool);
     drawertool.registerDrawer('tabledrawer', tabledrawer);
-
-    var cleanupexpressions = new CleanupExpressionsTool(
-            'kupucleanupexpressionselect', 'kupucleanupexpressionbutton');
-    kupu.registerTool('cleanupexpressions', cleanupexpressions);
 
     // register some cleanup filter
     // remove tags that aren't in the XHTML DTD

Added: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuinspector.js
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuinspector.js?rev=233117&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuinspector.js (added)
+++ myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuinspector.js Tue Aug 16 21:02:45 2005
@@ -0,0 +1,229 @@
+/*****************************************************************************
+ *
+ * Copyright (c) 2003-2005 Kupu Contributors. All rights reserved.
+ *
+ * This software is distributed under the terms of the Kupu
+ * License. See LICENSE.txt for license text. For a list of Kupu
+ * Contributors see CREDITS.txt.
+ *
+ *****************************************************************************/
+
+// $Id: kupuinspector.js 9879 2005-03-18 12:04:00Z yuppie $
+
+/* The Kupu Inspector tool 
+
+    An Kupu Tool (plugin) that will can be used to show and set attributes
+    on elements. It will show a list of the current element and all of its
+    parents (starting with the body element and working to the current one)
+    with input fields for a default set of attributes and, if defined, a
+    set for that particular element type.
+*/
+
+//----------------------------------------------------------------------------
+// Helper classes
+//----------------------------------------------------------------------------
+
+function Panel() {
+    /* the container (user interface element) of the elements */
+    this.elements = new Array();
+    
+    this.element = document.createElement('table');
+    this.element.style.width = '100%';
+    this.tbody = document.createElement('tbody');
+    this.element.appendChild(this.tbody);
+    
+    this.addElement = function(element) {
+        this.elements.push(element);
+        for (var i=0; i < element.nodes.length; i++) {
+            this.tbody.appendChild(element.nodes[i]);
+        };
+    };
+};
+
+function Element(node, panel, visibility) {
+    /* an element in the panel (reflecting an element in the document) */
+    this.panel = panel;
+    this.node = node;
+    this.nodes = new Array();
+    this.default_visibility = visibility;
+    
+    // create a header
+    var labelrow = document.createElement('tr');
+    var labelcell = document.createElement('th');
+    labelcell.style.textDecoration = 'underline';
+    labelcell.style.cursor = 'default';
+    labelcell.setAttribute('colSpan', '2');
+    labelrow.appendChild(labelcell);
+    var nodename = node.nodeName.toLowerCase();
+    var labeltext = document.createTextNode(nodename);
+    labelcell.appendChild(labeltext);
+    
+    this.nodes.push(labelrow);
+
+    this._displayvar = _SARISSA_IS_IE ? 'block' : 'table-row';
+    
+    this.addAttribute = function(attr) {
+        /* add an attribute */
+        
+        function changeHandler() {
+            var name = this.getAttribute('name');
+            var value = this.value;
+            if (name == 'className') {
+                this.element.className = value;
+            } else {
+                this.element.setAttribute(name, value);
+            };
+        };
+        
+        var row = document.createElement('tr');
+        var style = this.default_visibility ? this._displayvar : 'none';
+        row.style.display = style;
+        var labelcell = document.createElement('td');
+        labelcell.style.fontSize = '10px';
+        row.appendChild(labelcell);
+        var text = document.createTextNode(attr + ': ');
+        labelcell.appendChild(text);
+        labelcell.style.color = 'blue';
+        var inputcell = document.createElement('td');
+        inputcell.setAttribute('width', '100%');
+        row.appendChild(inputcell);
+        var input = document.createElement('input');
+        input.setAttribute('type', 'text');
+        input.setAttribute('value', attr == 'className' ? node.className : node.getAttribute(attr));
+        input.setAttribute('name', attr);
+        input.style.width = "100%";
+        input.element = this.node;
+        addEventHandler(input, 'change', changeHandler, input);
+        inputcell.appendChild(input);
+        this.nodes.push(row);
+    };
+
+    this.addStyle = function(stylename) {
+        var row = document.createElement('tr');
+        var style = this.default_visibility ? this._displayvar : 'none';
+        row.style.display = style;
+        var labelcell = document.createElement('td');
+        labelcell.style.fontSize = '10px';
+        row.appendChild(labelcell);
+        var text = document.createTextNode(stylename + ': ');
+        labelcell.appendChild(text);
+        labelcell.style.color = 'red';
+        var inputcell = document.createElement('td');
+        //inputcell.setAttribute('width', '100%');
+        row.appendChild(inputcell);
+        var input = document.createElement('input');
+        input.setAttribute('type', 'text');
+        input.setAttribute('value', node.style[stylename]);
+        input.setAttribute('name', stylename);
+        input.style.width = "100%";
+        input.element = this.node;
+        addEventHandler(input, 'change', function() {this.element.style[this.getAttribute('name')] = this.value}, input);
+        inputcell.appendChild(input);
+        this.nodes.push(row);
+    };
+
+    this.setVisibility = function(visibility) {
+        for (var i=1; i < this.nodes.length; i++) {
+            this.nodes[i].style.display = visibility ? this._displayvar : 'none';
+        };
+    };
+
+    this.setVisible = function() {
+        for (var i=0; i < this.panel.elements.length; i++) {
+            var el = this.panel.elements[i];
+            if (el != this) {
+                el.setVisibility(false);
+            };
+            this.setVisibility(true);
+        };
+    };
+
+    addEventHandler(labelrow, 'click', this.setVisible, this);
+};
+
+//----------------------------------------------------------------------------
+// The inspector
+//----------------------------------------------------------------------------
+
+function KupuInspector(inspectorelement) {
+    /* the Inspector tool, a tool to set attributes on elements */
+    
+    this.element = getFromSelector(inspectorelement);
+    this._lastnode = null;
+
+    this.default_attrs = new Array('id', 'className');
+    this.special_attrs = {'a': new Array('href', 'name', 'target'),
+                            'img': new Array('url', 'width', 'height'),
+                            'ul': new Array('type'),
+                            'ol': new Array('type'),
+                            'table': new Array('border', 'cellPadding', 'cellSpacing'),
+                            'td': new Array('align')
+                            };
+    this.styles = new Array('background', 'borderWidth', 'borderColor', 
+                                'borderStyle', 'color', 'fontSize', 
+                                'fontFamily', 'float', 'height', 
+                                'lineHeight', 'margin', 'padding', 
+                                'textAlign', 'verticalAlign', 'whiteApace', 
+                                'width');
+    
+    this.updateState = function(selNode, event) {
+        /* repopulate the inspector (if required) */
+        if (selNode != this._lastnode) {
+            // we need to repopulate
+            this._lastnode = selNode
+            this._clear();
+            var panel = new Panel();
+            var currnode = selNode;
+            // walk up to the body, add the elements in an array so we can
+            // walk through it backwards later on
+            var els = new Array();
+            while (currnode.nodeName.toLowerCase() != 'html') {
+                // only use element nodes
+                if (currnode.nodeType == 1) {
+                    els.push(currnode);
+                };
+                currnode = currnode.parentNode;
+            };
+
+            for (var i=0; i < els.length; i++) {
+                // now build an element
+                var node = els[els.length - i - 1];
+                var nodename = node.nodeName.toLowerCase();
+                var visibility = (i == els.length - 1);
+                var element = new Element(node, panel, visibility);
+                
+                // walk through the default attrs
+                for (var j=0; j < this.default_attrs.length; j++) {
+                    var attr = this.default_attrs[j];
+                    element.addAttribute(attr);
+                };
+                // check if there are any special attrs for this type of element
+                if (nodename in this.special_attrs) {
+                    var sattrs = this.special_attrs[nodename];
+                    // add the attrs
+                    for (var j=0; j < sattrs.length; j++) {
+                        var attr = sattrs[j];
+                        element.addAttribute(attr);
+                    };
+                };
+                // and add all applicable styles
+                for (var j=0; j < this.styles.length; j++) {
+                    var style = this.styles[j];
+                    if (style in node.style) {
+                        element.addStyle(style);
+                    };
+                };
+                panel.addElement(element);
+            };
+            this.element.appendChild(panel.element);
+        };
+    };
+
+    this._clear = function() {
+        while (this.element.childNodes.length) {
+            this.element.removeChild(this.element.childNodes[0]);
+        };
+    };
+};
+
+KupuInspector.prototype = new KupuTool;

Propchange: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuinspector.js
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuinspector.js
------------------------------------------------------------------------------
    svn:keywords = "Id Author LastChangedDate LastChangedBy LastChangedRevision"

Propchange: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuinspector.js
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuloggers.js
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuloggers.js?rev=233117&r1=233116&r2=233117&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuloggers.js (original)
+++ myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuloggers.js Tue Aug 16 21:02:45 2005
@@ -1,6 +1,6 @@
 /*****************************************************************************
  *
- * Copyright (c) 2003-2004 Kupu Contributors. All rights reserved.
+ * Copyright (c) 2003-2005 Kupu Contributors. All rights reserved.
  *
  * This software is distributed under the terms of the Kupu
  * License. See LICENSE.txt for license text. For a list of Kupu
@@ -40,7 +40,7 @@
 function PlainLogger(debugelid, maxlength) {
     /* writes messages to a debug tool and throws errors */
 
-    this.debugel = document.getElementById(debugelid);
+    this.debugel = getFromSelector(debugelid);
     this.maxlength = maxlength;
     
     this.log = function(message, severity) {

Added: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupumultieditor.js
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupumultieditor.js?rev=233117&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupumultieditor.js (added)
+++ myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupumultieditor.js Tue Aug 16 21:02:45 2005
@@ -0,0 +1,190 @@
+/*****************************************************************************
+ *
+ * Copyright (c) 2003-2005 Kupu Contributors. All rights reserved.
+ *
+ * This software is distributed under the terms of the Kupu
+ * License. See LICENSE.txt for license text. For a list of Kupu
+ * Contributors see CREDITS.txt.
+ *
+ *****************************************************************************/
+
+// $Id: kupumultieditor.js 3450 2004-03-28 11:07:30Z guido $
+
+function KupuMultiEditor(documents, config, logger) {
+    /* multiple kupus in one form */
+    this.documents = documents; // array of documents
+    this.config = config;
+    this.log = logger;
+    this.tools = {};
+
+    this._designModeAttempts = 0;
+    this._initialized = false;
+
+    this._previous_range = null;
+
+    // here's where the current active document will be stored
+    this._current_document = documents[0];
+    
+    this.initialize = function() {
+        this._initializeEventHandlers();
+        this.getDocument().getWindow().focus();
+        if (this.getBrowserName() == 'IE') {
+            for (var i=0; i < this.documents.length; i++) {
+                var body = this.documents[i].getDocument().getElementsByTagName('body')[0];
+                body.setAttribute('contentEditable', 'true');
+            };
+            // provide an 'afterInit' method on KupuEditor.prototype
+            // for additional bootstrapping (after editor init)
+            this._initialized = true;
+            if (this.afterInit) {
+                this.afterInit();
+            };
+            this._saveSelection();
+            this.logMessage(_('Editor initialized'));
+        } else {
+            this._setDesignModeWhenReady();
+        };
+    };
+
+    this.updateStateHandler = function(event) {
+        /* check whether the event is interesting enough to trigger the 
+        updateState machinery and act accordingly */
+        var interesting_codes = new Array(8, 13, 37, 38, 39, 40, 46);
+        if (event.type == 'click' || event.type == 'dblclick' || 
+                event.type == 'select' ||
+                (event.type == 'keyup' && 
+                    interesting_codes.contains(event.keyCode))) {
+            var target = event.target ? event.target : event.srcElement;
+            // find the document targeted
+            while (target.nodeType != 9) {
+                target = target.parentNode;
+            };
+            var document = null;
+            for (var i=0; i < this.documents.length; i++) {
+                document = this.documents[i];
+                if (document.getDocument() == target) {
+                    break;
+                };
+            };
+            if (!document) {
+                alert('No document found!');
+                return;
+            };
+            this._current_document = document;
+            this.updateState(event);
+        };
+        // unfortunately it's not possible to do this on blur, since that's
+        // too late. also (some versions of?) IE 5.5 doesn't support the
+        // onbeforedeactivate event, which would be ideal here...
+        if (this.getBrowserName() == 'IE') {
+            this._saveSelection();
+        };
+    };
+
+    this.saveDocument = function() {
+        throw('Not supported, use prepareForm to attach the editor to a form');
+    };
+
+    this.getDocument = function() {
+        /* return the current active document */
+        return this._current_document;
+    };
+
+    this._initializeEventHandlers = function() {
+        /* attache the event handlers to the iframe */
+        for (var i=0; i < this.documents.length; i++) {
+            var doc = this.documents[i].getDocument();
+            this._addEventHandler(doc, "click", this.updateStateHandler, this);
+            this._addEventHandler(doc, "keyup", this.updateStateHandler, this);
+            if (this.getBrowserName() == "IE") {
+                this._addEventHandler(doc, "dblclick", this.updateStateHandler, this);
+                this._addEventHandler(doc, "select", this.updateStateHandler, this);
+            };
+        };
+    };
+
+    this._setDesignModeWhenReady = function() {
+        this._designModeSetAttempts++;
+        if (this._designModeSetAttempts > 25) {
+            alert(_('Couldn\'t set design mode. Kupu will not work on this browser.'));
+            return;
+        };
+        var should_retry = false;
+        for (var i=0; i < this.documents.length; i++) {
+            var document = this.documents[i];
+            if (!document._designModeSet) {
+                try {
+                    this._setDesignMode(document);
+                    document._designModeSet = true;
+                } catch(e) {
+                    should_retry = true;
+                };
+            };
+        };
+        if (should_retry) {
+            timer_instance.registerFunction(this, this._setDesignModeWhenReady, 100);
+        } else {
+            // provide an 'afterInit' method on KupuEditor.prototype
+            // for additional bootstrapping (after editor init)
+            if (this.afterInit) {
+                this.afterInit();
+            };
+            this._initialized = true;
+        };
+    };
+
+    this._setDesignMode = function(doc) {
+        doc.getDocument().designMode = "On";
+        doc.execCommand("undo");
+    };
+
+    // XXX perhaps we can partially move this to a helper method to approve
+    // code reuse?
+    this.prepareForm = function(form, idprefix) {
+        /* add some fields to the form and place the contents of the iframes 
+        */
+        var sourcetool = this.getTool('sourceedittool');
+        if (sourcetool) {sourcetool.cancelSourceMode();};
+
+        // make sure people can't edit or save during saving
+        if (!this._initialized) {
+            return;
+        }
+        this._initialized = false;
+        
+        // set the window status so people can see we're actually saving
+        window.status= _("Please wait while saving document...");
+
+        // set a default id
+        if (!idprefix) {
+            idprefix = 'kupu';
+        };
+        
+        // pass the content through the filters
+        this.logMessage(_("Starting HTML cleanup"));
+        var contents = new Array();
+        for (var i=0; i < this.documents.length; i++) {
+            var transform = this._filterContent(this.documents[i].getDocument().documentElement);
+            contents.push(this._serializeOutputToString(transform));
+        };
+        
+        this.logMessage(_("Cleanup done, sending document to server"));
+        
+        // now create the form input, since IE 5.5 doesn't support the 
+        // ownerDocument property we use window.document as a fallback (which
+        // will almost by definition be correct).
+        var document = form.ownerDocument ? form.ownerDocument : window.document;
+        for (var i=0; i < contents.length; i++) {
+            var ta = document.createElement('textarea');
+            ta.style.visibility = 'hidden';
+            var text = document.createTextNode(contents[i]);
+            ta.appendChild(text);
+            ta.setAttribute('name', idprefix + '_' + i);
+            
+            // and add it to the form
+            form.appendChild(ta);
+        };
+    };
+};
+
+KupuMultiEditor.prototype = new KupuEditor;

Propchange: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupumultieditor.js
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupumultieditor.js
------------------------------------------------------------------------------
    svn:keywords = "Id Author LastChangedDate LastChangedBy LastChangedRevision"

Propchange: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupumultieditor.js
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupupopups/image.html
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupupopups/image.html?rev=233117&r1=233116&r2=233117&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupupopups/image.html (original)
+++ myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupupopups/image.html Tue Aug 16 21:02:45 2005
@@ -4,7 +4,7 @@
 <script type="text/javascript">
 
 function saveImage() {
-    var f = document.getElementById('imageform');
+    var f = getFromSelector('imageform');
     imagetool.createImage(f.url.value);
     window.close();
 };

Modified: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupupopups/link.html
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupupopups/link.html?rev=233117&r1=233116&r2=233117&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupupopups/link.html (original)
+++ myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupupopups/link.html Tue Aug 16 21:02:45 2005
@@ -14,8 +14,8 @@
 };
 
 function saveLink() {
-    var f = document.getElementById('linkform');
-    var typeel = document.getElementById('anchorradio');
+    var f = getFromSelector('linkform');
+    var typeel = getFromSelector('anchorradio');
     var linktype =  (typeel.checked || typeel.getAttribute('checked')) ? 'anchor' : 'link';
     linktool.createLink(f.url.value, linktype, f.name.value, f.target.value);
     window.close();

Modified: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupusourceedit.js
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupusourceedit.js?rev=233117&r1=233116&r2=233117&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupusourceedit.js (original)
+++ myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupusourceedit.js Tue Aug 16 21:02:45 2005
@@ -1,6 +1,6 @@
 /*****************************************************************************
  *
- * Copyright (c) 2003-2004 Kupu Contributors. All rights reserved.
+ * Copyright (c) 2003-2005 Kupu Contributors. All rights reserved.
  *
  * This software is distributed under the terms of the Kupu
  * License. See LICENSE.txt for license text. For a list of Kupu
@@ -13,12 +13,12 @@
 
 function SourceEditTool(sourcebuttonid, sourceareaid) {
     /* Source edit tool to edit document's html source */
-    this.sourceButton = document.getElementById(sourcebuttonid);
+    this.sourceButton = getFromSelector(sourcebuttonid);
     this.sourcemode = false;
     this._currently_editing = null;
 
     this.getSourceArea = function() {
-        return document.getElementById(sourceareaid);
+        return getFromSelector(sourceareaid);
     }
 
     this.cancelSourceMode = function() {
@@ -33,7 +33,7 @@
         this.editor = editor;
         this._fixTabIndex(this.sourceButton);
         addEventHandler(this.sourceButton, "click", this.switchSourceEdit, this);
-        this.editor.logMessage('Source edit tool initialized');
+        this.editor.logMessage(_('Source edit tool initialized'));
     };
  
     this.switchSourceEdit = function(event, nograb) {
@@ -55,7 +55,7 @@
 
             var data='';
             if(kupu.config.filtersourceedit) {
-                window.status = 'Cleaning up HTML...';
+                window.status = _('Cleaning up HTML...');
                 var transform = kupu._filterContent(kupu.getInnerDocument().documentElement);
                 data = kupu.getXMLBody(transform);
                 data = kupu._fixupSingletons(data).replace(/<\/?body[^>]*>/g, "");
@@ -89,20 +89,26 @@
             this._currently_editing = null;
         };
         this.sourcemode = !this.sourcemode;
-     };
+    };
+    this.enable = function() {
+        KupuButtonEnable(this.sourceButton);
+    }
+    this.disable = function() {
+        KupuButtonDisable(this.sourceButton);
+    }
 };
 
 SourceEditTool.prototype = new KupuTool;
 
 function MultiSourceEditTool(sourcebuttonid, textareaprefix) {
     /* Source edit tool to edit document's html source */
-    this.sourceButton = document.getElementById(sourcebuttonid);
+    this.sourceButton = getFromSelector(sourcebuttonid);
     this.textareaprefix = textareaprefix;
 
     this.getSourceArea = function() {
         var docobj = this._currently_editing||kupu.getDocument();
         var sourceareaid = this.textareaprefix + docobj.getEditable().id;
-        return document.getElementById(sourceareaid);
+        return getFromSelector(sourceareaid);
     }
 
     this._currently_editing = null;

Added: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuspellchecker.js
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuspellchecker.js?rev=233117&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuspellchecker.js (added)
+++ myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuspellchecker.js Tue Aug 16 21:02:45 2005
@@ -0,0 +1,200 @@
+function KupuSpellChecker(buttonid, scripturl, spanstyle, 
+                            winwidth, winheight, skip_tags) {
+    this.button = document.getElementById(buttonid);
+    this.scripturl = scripturl;
+    this.spanstyle = spanstyle || 'color: red; ' +
+                                    'text-decoration: underline;';
+    this.winwidth = winwidth || '600';
+    this.winheight = winheight || '400';
+    this.skip_tags = skip_tags || ['head', 'script'];
+};
+
+KupuSpellChecker.prototype = new KupuTool;
+
+KupuSpellChecker.prototype.initialize = function(editor) {
+    this.editor = editor;
+    addEventHandler(this.button, 'click', this.check, this);
+};
+
+KupuSpellChecker.prototype.check = function() {
+    var request = new XMLHttpRequest();
+    request.open('POST', this.scripturl, true);
+    request.setRequestHeader('Content-Type', 
+                                'application/x-www-form-urlencoded');
+    request.onreadystatechange = new ContextFixer(
+                                    this.stateChangeHandler,
+                                    this,
+                                    request).execute;
+    var result = this.getCurrentContents();
+    result = escape(result.strip().replace('\n', ' ').reduceWhitespace());
+    request.send('text=' + result);
+};
+
+KupuSpellChecker.prototype.stateChangeHandler = function(request) {
+    if (request.readyState == 4) {
+        if (request.status == '200') {
+            var result = request.responseXML;
+            result = this.xmlToMapping(result);
+            if (!result) {
+                alert(_('There were no errors.'));
+            } else {
+                this.displayUnrecognized(result);
+            };
+        } else {
+            alert(_('Error loading data, status ${status}',
+                    {'status': request.status}));
+        };
+    };
+};
+
+KupuSpellChecker.prototype.getCurrentContents = function() {
+    var doc = this.editor.getInnerDocument().documentElement;
+    var iterator = new NodeIterator(doc);
+    var bits = [];
+    while (true) {
+        var node = iterator.next();
+        if (!node) {
+            break;
+        };
+        while (this.skip_tags.contains(node.nodeName.toLowerCase())) {
+            node = node.nextSibling;
+            iterator.setCurrent(node);
+        };
+        if (node.nodeType == 3) {
+            bits.push(node.nodeValue);
+        };
+    };
+    return bits.join(' ');
+};
+
+KupuSpellChecker.prototype.displayUnrecognized = function(mapping) {
+    // copy the current editable document into a new window
+    var doc = this.editor.getInnerDocument();
+    var docel = doc.documentElement;
+    var win = window.open('kupublank.html', 'spellchecker', 
+                            'width=' + this.winwidth + ',' +
+                            'height=' + this.winheight + ',toolbar=no,' +
+                            'menubar=no,scrollbars=yes,status=yes');
+    if (!win) {
+        alert(
+            _('This feature requires pop-ups to be enabled on your browser!'));
+        return;
+    };
+    var html = docel.innerHTML;
+    // when Moz tries to set the content-type, for some reason leaving this
+    // in breaks the feature(?!?)
+    html = html.replace(/<meta[^>]*http-equiv="[Cc]ontent-[Tt]ype"[^>]*>/gm, 
+                        '');
+    win.document.write('<html>' + html + '</html>');
+    win.deentitize = function(str) {return str.deentitize()};
+    win.document.close();
+    if (!win.document.getElementsByTagName('body').length) {
+        addEventHandler(win, 'load', this.continueDisplay, this, win, mapping);
+    } else {
+        this.continueDisplay(win, mapping);
+    };
+};
+
+KupuSpellChecker.prototype.continueDisplay = function(win, mapping) {
+    /* walk through all elements of the body, colouring the text nodes */
+    // start it all with a timeout to make Mozilla render the content first
+    timer_instance.registerFunction(this, this.continueDisplayHelper,
+                                    1000, win, mapping);
+};
+
+KupuSpellChecker.prototype.continueDisplayHelper = function(win, mapping) {
+    var body = win.document.getElementsByTagName('body')[0];
+    body.setAttribute('contentEditable', 'false');
+    var iterator = new NodeIterator(body);
+    var node = iterator.next();
+    timer_instance.registerFunction(this, this.displayHelperNodeLoop,
+                                    10, iterator, node, win, mapping);
+};
+
+KupuSpellChecker.prototype.displayHelperNodeLoop = function(iterator, node, 
+                                                                win, mapping) {
+    if (!node) {
+        return;
+    };
+    var next = iterator.next();
+    if (node.nodeType == 3) {
+        if (win.closed) {
+            return;
+        };
+        var span = win.document.createElement('span');
+        var before = node.nodeValue;
+        var after = this.colourText(before, mapping);
+        if (before != after) {
+            span.innerHTML = after;
+            var last = span.lastChild;
+            var parent = node.parentNode;
+            parent.replaceChild(last, node);
+            while (span.hasChildNodes()) {
+                parent.insertBefore(span.firstChild, last);
+            };
+        };
+    } else if (node.nodeType == 1 && node.nodeName.toLowerCase() == 'a') {
+        var cancelEvent = function(e) {
+            if (e.preventDefault) {
+                e.preventDefault();
+            } else {
+                e.returnValue = false;
+            };
+            return false;
+        };
+        addEventHandler(node, 'click', cancelEvent);
+        addEventHandler(node, 'mousedown', cancelEvent);
+        addEventHandler(node, 'mouseup', cancelEvent);
+    };
+    // using a timeout here makes Moz render the coloring while it's busy, and
+    // will make it stop popping up 'do you want to continue' prompts...
+    timer_instance.registerFunction(this, this.displayHelperNodeLoop,
+                                    10, iterator, next, win, mapping);
+};
+
+KupuSpellChecker.prototype.colourText = function(text, mapping) {
+    var currtext = text;
+    var newtext = '';
+    for (var word in mapping) {
+        var replacements = mapping[word];
+        replacements = replacements.entitize();
+        replacements = replacements.replace(/\'/g, "&apos;");
+        var reg = new RegExp('^(.*\\\W)?(' + word + ')(\\\W.*)?$', 'mg');
+        while (true) {
+            var match = reg.exec(currtext);
+            if (!match) {
+                newtext += currtext;
+                currtext = newtext;
+                newtext = '';
+                break;
+            };
+            var m = (match[1] || '') + match[2];
+            newtext += currtext.substr(0, currtext.indexOf(m));
+            newtext += (match[1] || '') +
+                        '<span style="' + this.spanstyle + '" ' +
+                        'onclick="alert(deentitize(\'' + 
+                        replacements + '\'));" ' +
+                        'title="' + replacements + '">' +
+                        match[2] +
+                        '</span>';
+            currtext = currtext.substr(currtext.indexOf(m) + m.length);
+        };
+    };
+    return currtext;
+};
+
+KupuSpellChecker.prototype.xmlToMapping = function(docnode) {
+    var docel = docnode.documentElement;
+    var result = {};
+    var incorrect = docel.getElementsByTagName('incorrect');
+    for (var i=0; i < incorrect.length; i++) {
+        var word = incorrect[i].firstChild.firstChild.nodeValue;
+        var replacements = '';
+        if (incorrect[i].lastChild.hasChildNodes()) {
+            replacements = incorrect[i].lastChild.firstChild.nodeValue;
+        };
+        result[word] = replacements;
+    };
+    var attrs = [];
+    return result;
+};

Propchange: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuspellchecker.js
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuspellchecker.js
------------------------------------------------------------------------------
    svn:keywords = "Id Author LastChangedDate LastChangedBy LastChangedRevision"

Propchange: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupuspellchecker.js
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupustart.js
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupustart.js?rev=233117&r1=233116&r2=233117&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupustart.js (original)
+++ myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupustart.js Tue Aug 16 21:02:45 2005
@@ -1,6 +1,6 @@
 /*****************************************************************************
  *
- * Copyright (c) 2003-2004 Kupu Contributors. All rights reserved.
+ * Copyright (c) 2003-2005 Kupu Contributors. All rights reserved.
  *
  * This software is distributed under the terms of the Kupu
  * License. See LICENSE.txt for license text. For a list of Kupu
@@ -11,14 +11,32 @@
 // $Id$
 
 function startKupu() {
+    // first let's load the message catalog
+    // if there's no global 'i18n_message_catalog' variable available, don't
+    // try to load any translations
+    if (window.i18n_message_catalog) {
+        var request = new XMLHttpRequest();
+        // sync request, scary...
+        request.open('GET', 'kupu-pox.cgi', false);
+        request.send('');
+        if (request.status != '200') {
+            alert('Error loading translation (status ' + status +
+                    '), falling back to english');
+        } else {
+            // load successful, continue
+            var dom = request.responseXML;
+            window.i18n_message_catalog.initialize(dom);
+        };
+    };
+    
     // initialize the editor, initKupu groks 1 arg, a reference to the iframe
-    var frame = document.getElementById('kupu-editor'); 
+    var frame = getFromSelector('kupu-editor'); 
     var kupu = initKupu(frame);
     
     // this makes the editor's content_changed attribute set according to changes
     // in a textarea or input (registering onchange, see saveOnPart() for more
     // details)
-    kupu.registerContentChanger(document.getElementById('kupu-editor-textarea'));
+    kupu.registerContentChanger(getFromSelector('kupu-editor-textarea'));
 
     // let's register saveOnPart(), to ask the user if he wants to save when 
     // leaving after editing

Modified: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupustart_form.js
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupustart_form.js?rev=233117&r1=233116&r2=233117&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupustart_form.js (original)
+++ myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupustart_form.js Tue Aug 16 21:02:45 2005
@@ -1,6 +1,6 @@
 /*****************************************************************************
  *
- * Copyright (c) 2003-2004 Kupu Contributors. All rights reserved.
+ * Copyright (c) 2003-2005 Kupu Contributors. All rights reserved.
  *
  * This software is distributed under the terms of the Kupu
  * License. See LICENSE.txt for license text. For a list of Kupu
@@ -11,8 +11,46 @@
 // $Id$
 
 function startKupu() {
-    var frame = document.getElementById('kupu-editor'); 
+    // initialize the editor, initKupu groks 1 arg, a reference to the iframe
+    var frame = getFromSelector('kupu-editor'); 
     var kupu = initKupu(frame);
+    
+    // first let's load the message catalog
+    // if there's no global 'i18n_message_catalog' variable available, don't
+    // try to load any translations
+    if (!window.i18n_message_catalog) {
+        continueStartKupu(kupu);
+        return kupu;
+    };
+    // loading will be done asynchronously (to keep Mozilla from freezing)
+    // so we'll continue in a follow-up function (continueStartKupu() below)
+    var handler = function(request) {
+        if (this.readyState == 4) {
+            var status = this.status;
+            if (status != '200') {
+            	// myFaces : alert disabled right now (Needs to be fixed)
+                //alert(_('Error loading translation (status ${status} ' +
+                //        '), falling back to english'), {'status': status});
+                continueStartKupu(kupu);
+                return;
+            };
+            var dom = this.responseXML;
+            window.i18n_message_catalog.initialize(dom);
+            continueStartKupu(kupu);
+        };
+    };
+    var request = new XMLHttpRequest();
+    request.onreadystatechange = (new ContextFixer(handler, request)).execute;
+    request.open('GET', 'kupu.pox', true);
+    request.send('');
+
+    // we need to return a reference to the editor here for certain 'external'
+    // stuff, developers should note that it's not yet initialized though, we
+    // need to wait for i18n data before we can do that
+    return kupu;
+};
+
+function continueStartKupu(kupu) {
     kupu.initialize();
 
     return kupu;

Added: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupustart_multi.js
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupustart_multi.js?rev=233117&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupustart_multi.js (added)
+++ myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupustart_multi.js Tue Aug 16 21:02:45 2005
@@ -0,0 +1,55 @@
+/*****************************************************************************
+ *
+ * Copyright (c) 2003-2005 Kupu Contributors. All rights reserved.
+ *
+ * This software is distributed under the terms of the Kupu
+ * License. See LICENSE.txt for license text. For a list of Kupu
+ * Contributors see CREDITS.txt.
+ *
+ *****************************************************************************/
+
+// $Id$
+
+function startKupu() {
+    // initialize the editor, this version groks an array of iframeids
+    var iframeids = new Array('kupu_1', 'kupu_2', 'kupu_3');
+    var kupu = initKupu(iframeids); 
+
+    // if there's no global 'i18n_message_catalog' variable available, don't
+    // try to load any translations
+    if (!window.i18n_message_catalog) {
+        continueStartKupu(kupu);
+        return kupu;
+    };
+    // loading will be done asynchronously (to keep Mozilla from freezing)
+    // so we'll continue in a follow-up function (continueStartKupu() below)
+    var handler = function(request) {
+        if (this.readyState == 4) {
+            var status = this.status;
+            if (status != '200') {
+                alert(_('Error loading translation (status ${status} ' +
+                        '), falling back to english'), {'status': status});
+                continueStartKupu(kupu);
+                return;
+            };
+            var dom = this.responseXML;
+            window.i18n_message_catalog.initialize(dom);
+            continueStartKupu(kupu);
+        };
+    };
+    var request = new XMLHttpRequest();
+    request.onreadystatechange = (new ContextFixer(handler, request)).execute;
+    request.open('GET', 'kupu.pox', true);
+    request.send('');
+
+    // we need to return a reference to the editor here for certain 'external'
+    // stuff, developers should note that it's not yet initialized though, we
+    // need to wait for i18n data before we can do that
+    return kupu;
+};
+
+function continueStartKupu(kupu) {
+    kupu.initialize();
+
+    return kupu;
+};

Propchange: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupustart_multi.js
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupustart_multi.js
------------------------------------------------------------------------------
    svn:keywords = "Id Author LastChangedDate LastChangedBy LastChangedRevision"

Propchange: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupustart_multi.js
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupustyles.css
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupustyles.css?rev=233117&r1=233116&r2=233117&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupustyles.css (original)
+++ myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/kupustyles.css Tue Aug 16 21:02:45 2005
@@ -2,7 +2,7 @@
  *
  * Kupu common styles
  *
- * Copyright (c) 2003-2004 Kupu Contributors. See CREDITS.txt
+ * Copyright (c) 2003-2005 Kupu Contributors. See CREDITS.txt
  *
  * Instead of customizing this file, it is recommended to add your own
  * CSS file.  Feel free to use whole or parts of this for your own
@@ -18,57 +18,43 @@
 }
 
 div.kupu-fulleditor .kupu-fulleditor-zoomed {
-  /*border: solid 3px ButtonHighlight;*/
   height: 100%;
-   padding: 0px;
+  padding: 0px;
 }
 
 div.kupu-fulleditor .kupu-editorframe {
-  margin-right: 20em;
-}
-
-div.kupu-fulleditor-zoomed .kupu-editorframe {
    margin: 0px;
+   margin-right: 20em;
    border: none;
 }
 
 div.kupu-fulleditor-zoomed {
-   z-index: 1;
+   z-index: 100;
    margin: 0; border: none;
    position: fixed;
    top: 0; left: 0;
    background-color: white;
 }
 
-div.kupu-fulleditor-zoomed div.kupu-toolboxes {
-  display: none;
-}
-
 * html div.kupu-fulleditor-zoomed {
    position: absolute; /* IE */
 }
 
 div.kupu-fulleditor-zoomed .kupu-editor-iframe {
   border: none;
-  margin: 0px;
+  margin: 0;
 }
 
 div.kupu-smalleditor .kupu-editorframe {
   margin-right: 0.2em;
 }
 
-/*
-div.kupu-sourcemode #kupu-editor {
-   display: none;
-}
-
-div.kupu-sourcemode textarea.kupu-editor-textarea {
-   display: block;
-}*/
-
 div.kupu-sourcemode span.kupu-tb-buttongroup,
-div.kupu-sourcemode select { display: none; }
+body.kupu-fulleditor-zoomed select { display: none; }
+body.kupu-fulleditor-zoomed div.kupu-fulleditor-zoomed select { display: inline; }
+div.kupu-sourcemode select { display: none !IMPORTANT; }
 div.kupu-sourcemode span#kupu-logo,
+div.kupu-sourcemode span#kupu-zoom,
 div.kupu-sourcemode span#kupu-source { display: inline; }
 
 div.kupu-smalleditor {
@@ -85,7 +71,7 @@
   border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
 }
 
-#kupu-tb-buttons button {
+.kupu-tb-buttons button {
   color: ButtonText;
   border: 1px solid ButtonFace;
   margin-top: 0;
@@ -95,13 +81,13 @@
   background-repeat: no-repeat;
 }
 
-#kupu-tb-buttons button:hover {
+.kupu-tb-buttons button:hover {
   cursor: default;
   border: 1px solid;
   border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
 }
 
-#kupu-tb-buttons button:active {
+.kupu-tb-buttons button:active {
   border: 1px solid;
   border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
 }
@@ -111,6 +97,7 @@
   margin-right: 2px;
 }
 
+
 .kupu-bold {background-image: url("kupuimages/bold.png");}
 .kupu-bold-pressed {background-image: url("kupuimages/bold.png"); background-color: white;}
 .kupu-forecolor {background-image: url("kupuimages/text-color.png");}
@@ -132,13 +119,14 @@
 .kupu-justifycenter {background-image: url("kupuimages/justify-center.png");}
 .kupu-justifyleft {background-image: url("kupuimages/justify-left.png");}
 .kupu-justifyright {background-image: url("kupuimages/justify-right.png");}
-.kupu-logo {background-image: url("kupuimages/kupu_icon.gif");}
+button.kupu-logo {background-image: url("kupuimages/kupu_icon.gif");}
 .kupu-outdent {background-image: url("kupuimages/outdent.png");}
 .kupu-redo {background-image: url("kupuimages/redo.png");}
 .kupu-save {background-image: url("kupuimages/save.png");}
 .kupu-save-and-exit {background-image: url("kupuimages/exit.gif");}
 .kupu-space {background-image: url("kupuimages/space.gif");}
 .kupu-source {background-image: url("kupuimages/view-source.png");}
+.kupu-spellchecker {background-image: url("kupuimages/text-check.png");}
 .kupu-subscript {background-image: url("kupuimages/subscript.png");}
 .kupu-subscript-pressed {background-image: url("kupuimages/subscript.png"); background-color: white}
 .kupu-superscript {background-image: url("kupuimages/superscript.png");}
@@ -152,12 +140,12 @@
 .kupu-zoom {background-image: url("kupuimages/zoom-in.gif");}
 .kupu-zoom-pressed {background-image: url("kupuimages/zoom-out.gif");}
 
-#kupu-tb-buttons button.invisible { 
+.kupu-tb-buttons button.invisible { 
   display: none;
   /*visibility: hidden;*/
 }
 
-#kupu-tb-buttons button.visible { 
+.kupu-tb-buttons button.visible { 
   display: inline;
 }
 
@@ -167,7 +155,7 @@
   border: solid 2px ButtonFace;
 }
 
-#kupu-editor {
+iframe.kupu-editor-iframe {
   height: 450px;
   width: 99%;
 }
@@ -187,6 +175,10 @@
   font-size: 0.8em;
 }
 
+div.kupu-fulleditor-zoomed div.kupu-toolboxes {
+  display: none;
+}
+
 div.kupu-toolbox, div.kupu-toolbox-active {
   margin-bottom: 1em;
 }
@@ -230,8 +222,8 @@
   display: none;
 }
 
-div.kupu-toolbox table#kupu-toolbox-addtable input, 
-div.kupu-toolbox-active table#kupu-toolbox-edittable input {
+div.kupu-toolbox table.kupu-toolbox-addtable input, 
+div.kupu-toolbox-active table.kupu-toolbox-edittable input {
   width: 20px;
 }
 
@@ -239,19 +231,8 @@
   background-color: ButtonFace;
 }
 
-div.kupu-toolbox button {
-  font-size: 0.9em;
-  border: 1px solid;
-  border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
-}
-
-div.kupu-toolbox button:active {
-  border: 1px solid;
-  border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
-}
-
-#kupu-toolbox-editlink, #kupu-toolbox-edittable,
-#kupu-ulstyles, #kupu-olstyles {
+.kupu-toolbox-editlink, .kupu-toolbox-edittable,
+.kupu-ulstyles, .kupu-olstyles {
   display: none;
 }
 
@@ -274,3 +255,11 @@
   /* border: outset 1px; */
 }
 
+div.kupu-drawer {
+   overflow: auto;
+}
+
+button.disabled {
+   opacity:0.5;
+   filter:alpha(opacity=50);
+}

Added: myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/myFaces.css
URL: http://svn.apache.org/viewcvs/myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/myFaces.css?rev=233117&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/myFaces.css (added)
+++ myfaces/tomahawk/trunk/src/java/org/apache/myfaces/custom/inputHtml/resource/myFaces.css Tue Aug 16 21:02:45 2005
@@ -0,0 +1,7 @@
+div.kupu-fulleditor .kupu-editorframe {
+	height: 100%;
+	border: silver solid 1px;
+}
+.kupu-fulleditor{
+	padding-bottom: 47px;
+}
\ No newline at end of file