Subversion Repositories wimsdev

Rev

Rev 8231 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 8231 Rev 9054
Line 5... Line 5...
5
//editor.init(textareaelement, optional callback on loaded)
5
//editor.init(textareaelement, optional callback on loaded)
6
function speckInit(callback) {
6
function speckInit(callback) {
7
    var tas = document.getElementsByTagName("textarea");
7
    var tas = document.getElementsByTagName("textarea");
8
    var found = false;
8
    var found = false;
9
    for(i=0;i<tas.length;i++) {
9
    for(i=0;i<tas.length;i++) {
10
                var ta = tas[i];
10
        var ta = tas[i];
11
                if (ta.className == "iEdit") {
11
        if (ta.className == "iEdit") {
12
                    var editor = new speckEditor();
12
            var editor = new speckEditor();
13
                    editor.init(ta, callback);
13
            editor.init(ta, callback);
14
                    found = true;
14
            found = true;
15
                }
15
        }
16
    }
16
    }
17
    if (!found) {
17
    if (!found) {
18
        if (callback)
18
        if (callback)
19
            callback.call();
19
            callback.call();
20
    }
20
    }
21
        return true;
21
    return true;
22
};
22
};
23
 
23
 
24
//Be sure to call speckClose if you are hiding or removing a speck edit
24
//Be sure to call speckClose if you are hiding or removing a speck edit
25
//from the screen and plan to open another before refreshing the page.
25
//from the screen and plan to open another before refreshing the page.
26
function speckClose() {
26
function speckClose() {
27
    for(var i in iEdit)
27
    for(var i in iEdit)
28
    {
28
    {
29
        iEdit[i].iframe.contentWindow.document.designMode = "off";
29
        iEdit[i].iframe.contentWindow.document.designMode = "off";
-
 
30
    }
-
 
31
};
-
 
32
 
-
 
33
/** (re)Opens all specks **/
-
 
34
function speckOpen() {
-
 
35
    for(var i in iEdit)
-
 
36
    {
-
 
37
        iEdit[i].iframe.contentWindow.document.designMode = "on";
-
 
38
    }
-
 
39
};
-
 
40
 
-
 
41
/** Toggle Html Editor on all specks */
-
 
42
function speckToggleAll() {
-
 
43
    for(var i in iEdit)
-
 
44
    {
-
 
45
        iEdit[i].toggleMode();
30
    }
46
    }
31
};
47
};
32
 
48
 
33
//Collection of all text windows: accessible by:
49
//Collection of all text windows: accessible by:
34
//iEdit[TextAreaId].html();
50
//iEdit[TextAreaId].html();
Line 94... Line 110...
94
    ],
110
    ],
95
 
111
 
96
    //Initialize the edit window
112
    //Initialize the edit window
97
    init: function(ta, callback) {
113
    init: function(ta, callback) {
98
 
114
 
99
            this.ta = ta;
115
        this.ta = ta;
100
        this.id = ta.id;
116
        this.id = ta.id;
101
        iEdit[this.id] = this;
117
        iEdit[this.id] = this;
102
 
118
 
103
            if (callback)
119
        if (callback)
104
                this.loaded = callback;
120
            this.loaded = callback;
105
 
121
 
106
        //Get the current width
122
        //Get the current width
107
        this.width = this.ta.offsetWidth;
123
        this.width = this.ta.offsetWidth;
108
        if (this.width == 0)
124
        if (this.width == 0)
109
                this.width = parseInt(this.ta.style.width);
125
            this.width = parseInt(this.ta.style.width);
110
 
126
 
111
        //Get the current height
127
        //Get the current height
112
        this.height = this.ta.offsetHeight;
128
        this.height = this.ta.offsetHeight;
113
        if (this.height == 0)
129
        if (this.height == 0)
114
                this.height = parseInt(this.ta.style.height);
130
            this.height = parseInt(this.ta.style.height);
115
 
131
 
116
        this.ta.style.display = "none";
132
        this.ta.style.display = "none";
117
 
133
 
118
            this.container = this.$new("div");
134
        this.container = this.$new("div");
119
 
135
 
120
            this.tb = this.$new("div");
136
        this.tb = this.$new("div");
121
            this.tb.className = "speckToolbar";
137
        this.tb.className = "speckToolbar";
122
        this.tb.style.width = this.width + "px";
138
        this.tb.style.width = this.width + "px";
123
        this.container.appendChild(this.tb);
139
        this.container.appendChild(this.tb);
124
 
140
 
125
        //Add the features
141
        //Add the features
126
            for(var i=0;i<this.features.length;i+=2) {
142
        for(var i=0;i<this.features.length;i+=2) {
127
                this.addFeature(this.features[i], this.features[i+1]);
143
            this.addFeature(this.features[i], this.features[i+1]);
128
            }
144
        }
129
 
145
 
130
        this.ta.style.height = (this.height-32) + "px";
146
        this.ta.style.height = (this.height-32) + "px";
131
        this.ta.parentNode.replaceChild(this.container, this.ta);
147
        this.ta.parentNode.replaceChild(this.container, this.ta);
132
            this.container.appendChild(this.ta);
148
        this.container.appendChild(this.ta);
133
 
149
 
134
        this.initEdit();
150
        this.initEdit();
135
 
151
 
136
    },
152
    },
137
    initEdit: function(content) {
153
    initEdit: function(content) {
Line 148... Line 164...
148
 
164
 
149
        //Save style properties with property called savestyle
165
        //Save style properties with property called savestyle
150
        content = this.ta.value.replace(/(style|STYLE|Style)=('|").+?('|")/g, function(match){ return match + " save" + match; });
166
        content = this.ta.value.replace(/(style|STYLE|Style)=('|").+?('|")/g, function(match){ return match + " save" + match; });
151
 
167
 
152
        //Write out current content to the iframe window, include edit mode stylesheet
168
        //Write out current content to the iframe window, include edit mode stylesheet
153
            this.iframe.contentWindow.document.open();
169
        this.iframe.contentWindow.document.open();
154
            //this.iframe.contentWindow.document.write("<html><head><link id='ThemeStyle' href='" + this.editStylePath + "' type='text/css' rel='stylesheet' /></head><body style='background:#fff url();color:#000;'>" + content + "</body></html>");
170
        //this.iframe.contentWindow.document.write("<html><head><link id='ThemeStyle' href='" + this.editStylePath + "' type='text/css' rel='stylesheet' /></head><body style='background:#fff url();color:#000;'>" + content + "</body></html>");
155
            this.iframe.contentWindow.document.write("<html><head></head><body style='background:#fff url();color:#000;'>" + content + "</body></html>");
171
        this.iframe.contentWindow.document.write("<html><head></head><body style='background:#fff url();color:#000;'>" + content + "</body></html>");
156
            this.iframe.contentWindow.document.close();
172
        this.iframe.contentWindow.document.close();
157
 
173
 
158
        this.enterDesignMode();
174
        this.enterDesignMode();
159
 
175
 
160
            return true;
176
        return true;
161
    },
177
    },
162
    enterDesignMode: function() {
178
    enterDesignMode: function() {
163
 
179
 
164
        //Firefox needs a little time for this.
180
        //Firefox needs a little time for this.
165
        if (!this.iframe.contentWindow.document.body) {
181
        if (!this.iframe.contentWindow.document.body) {
166
            var self = this;
182
            var self = this;
167
                setTimeout(function() { self.enterDesignMode(); }, 1);
183
            setTimeout(function() { self.enterDesignMode(); }, 1);
168
                return;
184
            return;
169
            }
185
        }
170
 
186
 
171
            //Turn on design mode
187
        //Turn on design mode
172
            this.iframe.contentWindow.document.designMode = "on";
188
        this.iframe.contentWindow.document.designMode = "on";
173
 
189
 
174
            this.wysiwyg = true;
190
        this.wysiwyg = true;
175
 
191
 
176
        //call loaded event
192
        //call loaded event
177
        if (this.loaded)
193
        if (this.loaded)
178
            this.loaded.call();
194
            this.loaded.call();
179
    },
195
    },
180
    addFeature: function(action, text) {
196
    addFeature: function(action, text) {
181
        switch (action) {
197
        switch (action) {
182
            case "formatblock":
198
            case "formatblock":
183
                    this.hBar = this.$new("div");
199
                this.hBar = this.$new("div");
184
                    this.hBar.id = this.id + "Hbar";
200
                this.hBar.id = this.id + "Hbar";
185
                this.addBar(this.hBar, "formatblock", this.blockOptions, text);
201
                this.addBar(this.hBar, "formatblock", this.blockOptions, text);
186
                this.container.appendChild(this.hBar);
202
                this.container.appendChild(this.hBar);
187
                break;
203
                break;
188
            case "fontname":
204
            case "fontname":
189
                    this.fBar = this.$new("div");
205
                this.fBar = this.$new("div");
190
                    this.fBar.id = this.id + "Fbar";
206
                this.fBar.id = this.id + "Fbar";
191
                this.addBar(this.fBar, "fontname", this.fontOptions, text);
207
                this.addBar(this.fBar, "fontname", this.fontOptions, text);
192
                this.container.appendChild(this.fBar);
208
                this.container.appendChild(this.fBar);
193
                break;
209
                break;
194
            case "fontsize":
210
            case "fontsize":
195
                    this.sBar = this.$new("div");
211
                this.sBar = this.$new("div");
196
                    this.sBar.id = this.id + "Sbar";
212
                this.sBar.id = this.id + "Sbar";
197
                this.addBar(this.sBar, "fontsize", this.fontSizes, text);
213
                this.addBar(this.sBar, "fontsize", this.fontSizes, text);
198
                this.container.appendChild(this.sBar);
214
                this.container.appendChild(this.sBar);
199
                break;
215
                break;
200
            case "forecolor":
216
            case "forecolor":
201
                this.addColor("forecolor", this.colors, text);
217
                this.addColor("forecolor", this.colors, text);
202
                this.container.appendChild(this.cBar);
218
                this.container.appendChild(this.cBar);
203
                break;
219
                break;
204
            case "link":
220
            case "link":
205
                this.addLinkBar("link", text);
221
                this.addLinkBar("link", text);
206
                this.container.appendChild(this.lBar);
222
                this.container.appendChild(this.lBar);
207
                break;
223
                break;
208
            default:
224
            default:
209
                this.tb.appendChild(this.getButton(action, text));
225
                this.tb.appendChild(this.getButton(action, text));
210
                break;
226
                break;
211
        }
227
        }
212
    },
228
    },
213
    getButton: function(action, text) {
229
    getButton: function(action, text) {
214
        var self = this;
230
        var self = this;
215
 
231
 
216
        var button = this.$new("input");
232
        var button = this.$new("input");
217
        button.type = "button";
233
        button.type = "button";
218
        button.id = action + "Button";
234
        button.id = action + "Button";
219
        button.title = text;
235
        button.title = text;
220
        button.className = "speckButton";
236
        button.className = "speckButton";
221
        button.action = action;
237
        button.action = action;
222
        button.onclick = function() { self.execCommand(this); };
238
        button.onclick = function() { self.execCommand(this); };
223
        return button;
239
        return button;
224
    },
240
    },
225
    addColor: function(action, options, text) {
241
    addColor: function(action, options, text) {
226
 
242
 
227
            var button = this.getButton(action, text); // this.$new("input");
243
        var button = this.getButton(action, text); // this.$new("input");
228
        var self = this;
244
        var self = this;
229
        button.onclick = function() { self.showSelect(this); };
245
        button.onclick = function() { self.showSelect(this); };
230
 
246
 
231
            var bar = this.$new("div");
247
        var bar = this.$new("div");
232
            bar.id = action + "Select";
248
        bar.id = action + "Select";
233
            bar.className = "speckColorBar";
249
        bar.className = "speckColorBar";
234
        bar.style.width = (this.width - 2) + "px"; //2 is border width
250
        bar.style.width = (this.width - 2) + "px"; //2 is border width
235
        bar.style.display = "none";
251
        bar.style.display = "none";
236
            for (var i=0;i<options.length;i++)
252
        for (var i=0;i<options.length;i++)
237
            {
253
        {
238
                    var option = this.$new("input");
254
            var option = this.$new("input");
239
                    option.val = options[i];
255
            option.val = options[i];
240
                    option.type = "button";
256
            option.type = "button";
241
                    option.style.backgroundColor = "#" + option.val;
257
            option.style.backgroundColor = "#" + option.val;
242
                    option.action = action;
258
            option.action = action;
243
                    option.className = "speckColor";
259
            option.className = "speckColor";
244
            option.onclick = function() { self.execCommand(this); };
260
            option.onclick = function() { self.execCommand(this); };
245
 
261
 
246
                    bar.appendChild(option);
262
            bar.appendChild(option);
247
            }
263
        }
248
            this.cBar = bar;
264
        this.cBar = bar;
249
        button.selectMenuId = bar.id;
265
        button.selectMenuId = bar.id;
250
        this.tb.appendChild(button);
266
        this.tb.appendChild(button);
251
            return true;
267
        return true;
252
    },
268
    },
253
    addLinkBar: function(action, text) {
269
    addLinkBar: function(action, text) {
254
            var button = this.getButton(action, text); //this.$new("input");
270
        var button = this.getButton(action, text); //this.$new("input");
255
 
271
 
256
        var self = this;
272
        var self = this;
257
        button.onclick = function() { self.showSelect(this); };
273
        button.onclick = function() { self.showSelect(this); };
258
 
274
 
259
            var bar = this.$new("div");
275
        var bar = this.$new("div");
260
            bar.id = action + "linkbar";
276
        bar.id = action + "linkbar";
261
            bar.className = "speckLinkbar";
277
        bar.className = "speckLinkbar";
262
        bar.style.width = (this.width-2) + "px"; //2 is border width
278
        bar.style.width = (this.width-2) + "px"; //2 is border width
263
        bar.style.display = "none";
279
        bar.style.display = "none";
264
 
280
 
265
            this.linkUrl = this.$new("input");
281
        this.linkUrl = this.$new("input");
266
            this.linkUrl.id = this.id + "link";
282
        this.linkUrl.id = this.id + "link";
267
        this.linkUrl.style.width = (this.width - 60) + "px";
283
        this.linkUrl.style.width = (this.width - 60) + "px";
268
        this.linkUrl.value = "http://";
284
        this.linkUrl.value = "http://";
269
 
285
 
270
        var link = this.$new("input");
286
        var link = this.$new("input");
271
        link.type = "button";
287
        link.type = "button";
272
        link.id = "linkingButton";
288
        link.id = "linkingButton";
273
        link.value = "link";
289
        link.value = "link";
274
        link.className = "linkbarButton";
290
        link.className = "linkbarButton";
275
        link.action = "createlink";
291
        link.action = "createlink";
276
        link.onclick = function() { self.execCommand(this) };
292
        link.onclick = function() { self.execCommand(this) };
277
        bar.appendChild(this.linkUrl);
293
        bar.appendChild(this.linkUrl);
278
        bar.appendChild(link);
294
        bar.appendChild(link);
279
 
295
 
280
            this.lBar = bar;
296
        this.lBar = bar;
281
        button.selectMenuId = bar.id;
297
        button.selectMenuId = bar.id;
282
        this.tb.appendChild(button);
298
        this.tb.appendChild(button);
283
            return true;
299
        return true;
284
    },
300
    },
285
    addBar: function(bar, action, options, text) {
301
    addBar: function(bar, action, options, text) {
286
            var button = this.getButton(action, text); //this.$new("input");
302
        var button = this.getButton(action, text); //this.$new("input");
287
        var self = this;
303
        var self = this;
288
        button.onclick = function() { self.showSelect(this); };
304
        button.onclick = function() { self.showSelect(this); };
289
 
305
 
290
            bar.className = "speckBar";
306
        bar.className = "speckBar";
291
        bar.style.width = (this.width-2) + "px";
307
        bar.style.width = (this.width-2) + "px";
292
        bar.style.display = "none";
308
        bar.style.display = "none";
293
 
309
 
294
            for (var i=0;i<options.length;i+=2)
310
        for (var i=0;i<options.length;i+=2)
295
            {
311
        {
296
                    var option = this.$new("input");
312
            var option = this.$new("input");
297
                    option.val = options[i];
313
            option.val = options[i];
298
                    option.value = options[i + 1];
314
            option.value = options[i + 1];
299
                    option.type = "button";
315
            option.type = "button";
300
                    option.action = action;
316
            option.action = action;
301
                    option.editor = this.id;
317
            option.editor = this.id;
302
                    option.className = "speckOption";
318
            option.className = "speckOption";
303
            option.onclick = function() { self.execCommand(this) };
319
            option.onclick = function() { self.execCommand(this) };
304
 
320
 
305
                    bar.appendChild(option);
321
            bar.appendChild(option);
306
            }
322
        }
307
        button.selectMenuId = bar.id;
323
        button.selectMenuId = bar.id;
308
        this.tb.appendChild(button);
324
        this.tb.appendChild(button);
309
            return true;
325
        return true;
310
    },
326
    },
311
    hideSelects: function() {
327
    hideSelects: function() {
312
        var buttons = this.tb.childNodes;
328
        var buttons = this.tb.childNodes;
313
        for(var i=0;i<buttons.length;i++) {
329
        for(var i=0;i<buttons.length;i++) {
314
            var button = buttons[i];
330
            var button = buttons[i];
Line 320... Line 336...
320
        this.lBar.style.display = "none";
336
        this.lBar.style.display = "none";
321
        this.iframe.style.height = (this.height-32) + "px";
337
        this.iframe.style.height = (this.height-32) + "px";
322
        this.ta.style.height = (this.height-32) + "px";
338
        this.ta.style.height = (this.height-32) + "px";
323
    },
339
    },
324
    addLinkbar: function() {
340
    addLinkbar: function() {
325
            this.lBar = this.$new("div");
341
        this.lBar = this.$new("div");
326
            this.lBar.id = this.id + "linkbar";
342
        this.lBar.id = this.id + "linkbar";
327
            this.lBar.className = "speckLinkbar";
343
        this.lBar.className = "speckLinkbar";
328
        this.lBar.style.width = this.width-10 + "px";
344
        this.lBar.style.width = this.width-10 + "px";
329
        this.lBar.style.display = "none";
345
        this.lBar.style.display = "none";
330
 
346
 
331
            this.linkUrl = this.$new("input");
347
        this.linkUrl = this.$new("input");
332
            this.linkUrl.id = this.id + "link";
348
        this.linkUrl.id = this.id + "link";
333
        this.linkUrl.style.width = (this.width - 60) + "px";
349
        this.linkUrl.style.width = (this.width - 60) + "px";
334
        this.linkUrl.value = "http://";
350
        this.linkUrl.value = "http://";
335
 
351
 
336
        var link = this.$new("input");
352
        var link = this.$new("input");
337
        link.type = "button";
353
        link.type = "button";
Line 351... Line 367...
351
            this.lBar.style.display = "none";
367
            this.lBar.style.display = "none";
352
            this.iframe.style.height = (this.height-32) + "px";
368
            this.iframe.style.height = (this.height-32) + "px";
353
        }
369
        }
354
    },
370
    },
355
    setFocus: function() {
371
    setFocus: function() {
356
            if (this.wysiwyg == true)
372
        if (this.wysiwyg == true)
357
                    this.iframe.contentWindow.focus();
373
            this.iframe.contentWindow.focus();
358
            else
374
        else
359
                    this.ta.focus();
375
            this.ta.focus();
360
    },
376
    },
361
    toggleMode: function() {
377
    toggleMode: function() {
362
        this.hideSelects();
378
        this.hideSelects();
363
        if (this.wysiwyg) {
379
        if (this.wysiwyg) {
364
            this.html(); //update html
380
            this.html(); //update html
Line 366... Line 382...
366
            this.iframe.style.display = "none";
382
            this.iframe.style.display = "none";
367
            this.wysiwyg = false;
383
            this.wysiwyg = false;
368
        }
384
        }
369
        else {
385
        else {
370
            this.ta.style.display = "none";
386
            this.ta.style.display = "none";
371
            this.initEdit(this.ta.value);
387
            this.initEdit(this.ta.value);
-
 
388
            this.wysiwyg = true;
-
 
389
        }
-
 
390
    },
-
 
391
    disable: function() {
-
 
392
        this.hideSelects();
-
 
393
        if (this.wysiwyg) {
-
 
394
            this.html(); //update html
-
 
395
            this.ta.style.display = "block";
-
 
396
            this.iframe.style.display = "none";
-
 
397
            this.wysiwyg = false;
-
 
398
        }
-
 
399
    },
-
 
400
    enable: function() {
-
 
401
        this.hideSelects();
-
 
402
        if (!this.wysiwyg) {
-
 
403
            this.ta.style.display = "none";
-
 
404
            this.initEdit(this.ta.value);
372
            this.wysiwyg = true;
405
            this.wysiwyg = true;
373
        }
406
        }
374
    },
407
    },
375
    html: function() {
408
    html: function() {
376
        this.ta.value = this.innerXML(this.iframe.contentWindow.document.body.cloneNode(true));
409
        this.ta.value = this.innerXML(this.iframe.contentWindow.document.body.cloneNode(true));
377
        return this.ta.value;
410
        return this.ta.value;
378
    },
411
    },
379
    showSelect: function(selector) {
412
    showSelect: function(selector) {
380
 
413
 
381
        var selectMenu = document.getElementById(selector.selectMenuId);
414
        var selectMenu = document.getElementById(selector.selectMenuId);
382
 
415
 
383
        //if select bar is already open, close it.
416
        //if select bar is already open, close it.
384
        if (selectMenu.style.display == "block") {
417
        if (selectMenu.style.display == "block") {
385
            this.hideSelects();
418
            this.hideSelects();
Line 393... Line 426...
393
    },
426
    },
394
    execCommand: function(button) {
427
    execCommand: function(button) {
395
 
428
 
396
        var doc = this.iframe.contentWindow.document;
429
        var doc = this.iframe.contentWindow.document;
397
 
430
 
398
            switch (button.action) {
431
        switch (button.action) {
399
                    case "createlink":
432
            case "createlink":
400
                        if (this.linkUrl.value != "") {
433
                if (this.linkUrl.value != "") {
401
                    doc.execCommand(button.action, false, this.linkUrl.value);
434
                    doc.execCommand(button.action, false, this.linkUrl.value);
402
                    this.toggleLinkbar();
435
                    this.toggleLinkbar();
403
                }
436
                }
404
                break;
437
                break;
405
                    case "formatblock":
438
            case "formatblock":
406
                    case "fontsize":
439
            case "fontsize":
407
                    case "forecolor":
440
            case "forecolor":
408
                    case "fontname":
441
            case "fontname":
409
                        doc.execCommand(button.action, false, button.val);
442
                doc.execCommand(button.action, false, button.val);
410
                break;
443
                break;
411
            case "link":
444
            case "link":
412
                this.toggleLinkbar();
445
                this.toggleLinkbar();
413
                break;
446
                break;
414
            case "html":
447
            case "html":
415
                this.toggleMode();
448
                this.toggleMode();
416
                break;
449
                break;
417
                    default:
450
            default:
418
                        doc.execCommand(button.action, false, null);
451
                doc.execCommand(button.action, false, null);
419
                break;
452
                break;
420
        }
453
        }
421
 
454
 
422
        if (button.parentNode.className == "speckSelect") {
455
        if (button.parentNode.className == "speckSelect") {
423
            button.parentNode.style.display = "none";
456
            button.parentNode.style.display = "none";