views:

427

answers:

0

Hi guys,

I am using the Jhtml text editor(jHtmlArea-0.6.0.js) Downloaded from the site(http://jhtmlarea.codeplex.com/). I have made some custom changes like adding more events to it. TEven after that, sometimes after adding text/content the events(onchange,onblur....) does not get triggered and the user looses the content when he tries to save the page. I am attaching the code for the editor with this post. If any of you can correct this issue it would really help me.

This issue happens randomly on all browsers. I think I am missing some key events.

Any help is vey much appreciated

-DotnetRocks

(function ($) {
    $.fn.htmlarea = function (opts) {
        if (opts && typeof(opts) === "string") {
            var args = [];
            for (var i = 1; i < arguments.length; i++) {
                args.push(arguments[i])
            }
            var htmlarea = jHtmlArea(this[0]);
            var f = htmlarea[opts];
            if (f) {
                return f.apply(htmlarea, args)
            }
        }
        return this.each(function () {
            jHtmlArea(this, opts)
        })
    };
    var jHtmlArea = window.jHtmlArea = function (elem, options) {
        if (elem.jquery) {
            return jHtmlArea(elem[0])
        }
        if (elem.jhtmlareaObject) {
            return elem.jhtmlareaObject
        } else {
            return new jHtmlArea.fn.init(elem, options)
        }
    };
    jHtmlArea.fn = jHtmlArea.prototype = {
        jhtmlarea: "0.6.0",
        init: function (elem, options) {
            if (elem.nodeName.toLowerCase() === "textarea") {
                var opts = $.extend({},
                jHtmlArea.defaultOptions, options);
                elem.jhtmlareaObject = this;
                var textarea = this.textarea = $(elem);
                var container = this.container = $("<div/>").addClass("jHtmlArea").width(textarea.width()).insertAfter(textarea);
                var toolbar = this.toolbar = $("<div/>").addClass("ToolBar").appendTo(container);
                priv.initToolBar.call(this, opts);
                var iframe = this.iframe = $("<iframe/>").height(textarea.height());
                iframe.width(textarea.width() - ($.browser.msie ? 0 : 4));
                var htmlarea = this.htmlarea = $("<div/>").append(iframe);
                container.append(htmlarea).append(textarea.hide());
                priv.initEditor.call(this, opts);
                priv.attachEditorEvents.call(this);
                iframe.height(iframe.height() - toolbar.height());
                toolbar.width(textarea.width() - 2);
                if (opts.loaded) {
                    opts.loaded.call(this)
                }
            }
        },
        dispose: function () {
            this.textarea.show().insertAfter(this.container);
            this.container.remove();
            this.textarea[0].jhtmlareaObject = null
        },
        execCommand: function (a, b, c) {
            this.iframe[0].contentWindow.focus();
            this.editor.execCommand(a, b || false, c || null);
            this.updateTextArea()
        },
        ec: function (a, b, c) {
            this.execCommand(a, b, c)
        },
        queryCommandValue: function (a) {
            this.iframe[0].contentWindow.focus();
            return this.editor.queryCommandValue(a)
        },
        qc: function (a) {
            return this.queryCommandValue(a)
        },
        getSelectedHTML: function () {
            if ($.browser.msie) {
                return this.getRange().htmlText
            } else {
                var elem = this.getRange().cloneContents();
                return $("<p/>").append($(elem)).html()
            }
        },
        getSelection: function () {
            if ($.browser.msie) {
                return this.editor.selection
            } else {
                return this.iframe[0].contentDocument.defaultView.getSelection()
            }
        },
        getRange: function () {
            var s = this.getSelection();
            if (!s) {
                return null
            }
            return (s.getRangeAt) ? s.getRangeAt(0) : s.createRange()
        },
        pasteHTML: function (html) {
            this.iframe[0].contentWindow.focus();
            var r = this.getRange();
            if ($.browser.msie) {
                r.pasteHTML(html)
            } else if ($.browser.mozilla) {
                r.deleteContents();
                r.insertNode($((html.indexOf("<") != 0) ? $("<span/>").append(html) : html)[0])
            } else {
                r.deleteContents();
                r.insertNode($(this.iframe[0].contentWindow.document.createElement("span")).append($((html.indexOf("<") != 0) ? "<span>" + html + "</span>" : html))[0])
            }
            r.collapse(false);
            r.select()
        },
        cut: function () {
            this.ec("cut")
        },
        copy: function () {
            this.ec("copy")
        },
        paste: function () {
            this.ec("paste")
        },
        bold: function () {
            this.ec("bold")
        },
        italic: function () {
            this.ec("italic")
        },
        underline: function () {
            this.ec("underline")
        },
        strikeThrough: function () {
            this.ec("strikethrough")
        },
        image: function (url) {
            if ($.browser.msie && !url) {
                this.ec("insertImage", true)
            } else {
                this.ec("insertImage", false, (url || prompt("Image URL:", "http://")))
            }
        },
        removeFormat: function () {
            this.ec("removeFormat", false, []);
            this.unlink()
        },
        link: function () {
            if ($.browser.msie) {
                this.ec("createLink", true)
            } else {
                this.ec("createLink", false, prompt("Link URL:", "http://"))
            }
        },
        unlink: function () {
            this.ec("unlink", false, [])
        },
        orderedList: function () {
            this.ec("insertorderedlist")
        },
        unorderedList: function () {
            this.ec("insertunorderedlist")
        },
        superscript: function () {
            this.ec("superscript")
        },
        subscript: function () {
            this.ec("subscript")
        },
        h1: function () {
            this.heading(1)
        },
        h2: function () {
            this.heading(2)
        },
        h3: function () {
            this.heading(3)
        },
        h4: function () {
            this.heading(4)
        },
        h5: function () {
            this.heading(5)
        },
        h6: function () {
            this.heading(6)
        },
        heading: function (h) {
            this.formatBlock($.browser.msie ? "Heading " + h : "h" + h)
        },
        indent: function () {
            this.ec("indent")
        },
        outdent: function () {
            this.ec("outdent")
        },
        insertHorizontalRule: function () {
            this.ec("insertHorizontalRule", false, "ht")
        },
        justifyLeft: function () {
            this.ec("justifyLeft")
        },
        justifyCenter: function () {
            this.ec("justifyCenter")
        },
        justifyRight: function () {
            this.ec("justifyRight")
        },
        increaseFontSize: function () {
            if ($.browser.msie) {
                this.ec("fontSize", false, this.qc("fontSize") + 1)
            } else if ($.browser.safari) {
                this.getRange().surroundContents($(this.iframe[0].contentWindow.document.createElement("span")).css("font-size", "larger")[0])
            } else {
                this.ec("increaseFontSize", false, "big")
            }
        },
        decreaseFontSize: function () {
            if ($.browser.msie) {
                this.ec("fontSize", false, this.qc("fontSize") - 1)
            } else if ($.browser.safari) {
                this.getRange().surroundContents($(this.iframe[0].contentWindow.document.createElement("span")).css("font-size", "smaller")[0])
            } else {
                this.ec("decreaseFontSize", false, "small")
            }
        },
        forecolor: function (c) {
            this.ec("foreColor", false, c || prompt("Enter HTML Color:", "#"))
        },
        formatBlock: function (v) {
            this.ec("formatblock", false, v || null)
        },
        showHTMLView: function () {
            this.updateTextArea();
            this.textarea.show();
            this.htmlarea.hide();
            $("ul li:not(li:has(a.html))", this.toolbar).hide();
            $("ul:not(:has(:visible))", this.toolbar).hide();
            $("ul li a.html", this.toolbar).addClass("highlighted")
        },
        hideHTMLView: function () {
            this.updateHtmlArea();
            this.textarea.hide();
            this.htmlarea.show();
            $("ul", this.toolbar).show();
            $("ul li", this.toolbar).show().find("a.html").removeClass("highlighted")
        },
        toggleHTMLView: function () {
            (this.textarea.is(":hidden")) ? this.showHTMLView() : this.hideHTMLView()
        },
        toHtmlString: function () {
            return this.editor.body.innerHTML
        },
        toString: function () {
            return this.editor.body.innerText
        },
        updateTextArea: function () {
            this.textarea.val(this.toHtmlString())
        },
        updateHtmlArea: function () {
            this.editor.body.innerHTML = this.textarea.val()
        }
    };
    jHtmlArea.fn.init.prototype = jHtmlArea.fn;
    jHtmlArea.defaultOptions = {
        toolbar: [
            ["html"],
            ["bold", "italic", "underline", "strikethrough", "|", "subscript", "superscript"],
            ["increasefontsize", "decreasefontsize"],
            ["orderedlist", "unorderedlist"],
            ["indent", "outdent"],
            ["justifyleft", "justifycenter", "justifyright"],
            ["link", "unlink", "image", "horizontalrule"],
            ["h1", "h2", "h3", "h4", "h5", "h6"],
            ["cut", "copy", "paste"]
        ],
        css: null,
        toolbarText: {
            bold: "Bold",
            italic: "Italic",
            underline: "Underline",
            strikethrough: "Strike-Through",
            cut: "Cut",
            copy: "Copy",
            paste: "Paste",
            h1: "Heading 1",
            h2: "Heading 2",
            h3: "Heading 3",
            h4: "Heading 4",
            h5: "Heading 5",
            h6: "Heading 6",
            indent: "Indent",
            outdent: "Outdent",
            horizontalrule: "Insert Horizontal Rule",
            justifyleft: "Left Justify",
            justifycenter: "Center Justify",
            justifyright: "Right Justify",
            increasefontsize: "Increase Font Size",
            decreasefontsize: "Decrease Font Size",
            forecolor: "Text Color",
            link: "Insert Link",
            unlink: "Remove Link",
            image: "Insert Image",
            orderedlist: "Insert Ordered List",
            unorderedlist: "Insert Unordered List",
            subscript: "Subscript",
            superscript: "Superscript",
            html: "Show/Hide HTML Source View"
        }
    };
    var priv = {
        toolbarButtons: {
            strikethrough: "strikeThrough",
            orderedlist: "orderedList",
            unorderedlist: "unorderedList",
            horizontalrule: "insertHorizontalRule",
            justifyleft: "justifyLeft",
            justifycenter: "justifyCenter",
            justifyright: "justifyRight",
            increasefontsize: "increaseFontSize",
            decreasefontsize: "decreaseFontSize",
            html: function (btn) {
                this.toggleHTMLView()
            }
        },
        initEditor: function (options) {
            var edit = this.editor = this.iframe[0].contentWindow.document;
            edit.designMode = 'on';
            edit.open();
            edit.write(this.textarea.val());
            edit.close();
            if (options.css) {
                var e = edit.createElement('link');
                e.rel = 'stylesheet';
                e.type = 'text/css';
                e.href = options.css;
                edit.getElementsByTagName('head')[0].appendChild(e)
            }
        },
        initToolBar: function (options) {
            var that = this;
            var menuItem = function (className, altText, action) {
                return $("<li/>").append($("<a href='javascript:void(0);'/>").addClass(className).attr("title", altText).click(function () {
                    action.call(that, $(this))
                }))
            };

            function addButtons(arr) {
                var ul = $("<ul/>").appendTo(that.toolbar);
                for (var i = 0; i < arr.length; i++) {
                    var e = arr[i];
                    if ((typeof(e)).toLowerCase() === "string") {
                        if (e === "|") {
                            ul.append($('<li class="separator"/>'))
                        } else {
                            var f = (function (e) {
                                var m = priv.toolbarButtons[e] || e;
                                if ((typeof(m)).toLowerCase() === "function") {
                                    return function (btn) {
                                        m.call(this, btn)
                                    }
                                } else {
                                    return function () {
                                        this[m]();
                                        this.editor.body.focus()
                                    }
                                }
                            })(e.toLowerCase());
                            var t = options.toolbarText[e.toLowerCase()];
                            ul.append(menuItem(e.toLowerCase(), t || e, f))
                        }
                    } else {
                        ul.append(menuItem(e.css, e.text, e.action))
                    }
                }
            };
            if (options.toolbar.length !== 0 && priv.isArray(options.toolbar[0])) {
                for (var i = 0; i < options.toolbar.length; i++) {
                    addButtons(options.toolbar[i])
                }
            } else {
                addButtons(options.toolbar)
            }
        },
        attachEditorEvents: function () {
            var t = this;
            $(this.editor.body).click(function () {
                t.updateTextArea()
            });
            $(this.editor).keyup(function () {
                t.updateTextArea()
            });
            this.textarea.change(function () {
                t.updateHtmlArea()
            });
            $(this.editor).blur(function () {
                t.updateTextArea()
            });
            $(this.editor.body).blur(function () {
                t.updateTextArea()
            });
            this.textarea.blur(function () {
                t.updateTextArea()
            })
        },
        isArray: function (v) {
            return v && typeof v === 'object' && typeof v.length === 'number' && typeof v.splice === 'function' && !(v.propertyIsEnumerable('length'))
        }
    }
})(jQuery);