xref: /dokuwiki/lib/scripts/toolbar.js (revision 07b758d519aea391a47e43078884056964e232ee)
1
2// used to identify pickers
3var pickercounter=0;
4
5/**
6 * Create a toolbar
7 *
8 * @param  string tbid ID of the element where to insert the toolbar
9 * @param  string edid ID of the editor textarea
10 * @param  array  tb   Associative array defining the buttons
11 * @author Andreas Gohr <andi@splitbrain.org>
12 */
13function initToolbar(tbid,edid,tb){
14    var toolbar = $(tbid);
15    if(!toolbar) return;
16    var edit = $(edid);
17    if(!edit) return;
18    if(edit.readonly) return;
19
20    //empty the toolbar area:
21    toolbar.innerHTML='';
22
23    var cnt = tb.length;
24    for(var i=0; i<cnt; i++){
25        var actionFunc;
26
27        // create new button
28        var btn = createToolButton(tb[i]['icon'],
29                                   tb[i]['title'],
30                                   tb[i]['key']);
31
32
33        // type is a tb function -> assign it as onclick
34        actionFunc = 'tb_'+tb[i]['type'];
35        if( isFunction(window[actionFunc]) ){
36            addEvent(btn,'click', function(func,btn, props, edid){
37                return function(){
38                    window[func](btn, props, edid);
39                    return false;
40                }
41            }(actionFunc,btn,tb[i],edid) );
42            //above fixes the scope problem as descried at http://www.mennovanslooten.nl/blog/post/62
43            toolbar.appendChild(btn);
44            continue;
45        }
46
47        // type is a init function -> execute it
48        actionFunc = 'addBtnAction'+tb[i]['type'].charAt(0).toUpperCase()+tb[i]['type'].substring(1);
49        if( isFunction(window[actionFunc]) ){
50            if(window[actionFunc](btn, tb[i], edid)){
51                toolbar.appendChild(btn);
52            }
53            continue;
54        }
55
56        alert('unknown toolbar type: '+tb[i]['type']+'  '+actionFunc);
57    } // end for
58
59}
60
61/**
62 * Button action for format buttons
63 *
64 * @param  DOMElement btn   Button element to add the action to
65 * @param  array      props Associative array of button properties
66 * @param  string     edid  ID of the editor textarea
67 * @author Gabriel Birke <birke@d-scribe.de>
68 * @author Andreas Gohr <andi@splitbrain.org>
69 */
70function tb_format(btn, props, edid) {
71    var sample = props['title'];
72    if(props['sample']){
73        sample = props['sample'];
74    }
75    insertTags(edid,
76               fixtxt(props['open']),
77               fixtxt(props['close']),
78               fixtxt(sample));
79    pickerClose();
80    return false;
81}
82
83/**
84 * Button action for format buttons
85 *
86 * This works exactly as tb_format() except that, if multiple lines
87 * are selected, each line will be formatted seperately
88 *
89 * @param  DOMElement btn   Button element to add the action to
90 * @param  array      props Associative array of button properties
91 * @param  string     edid  ID of the editor textarea
92 * @author Gabriel Birke <birke@d-scribe.de>
93 * @author Andreas Gohr <andi@splitbrain.org>
94 */
95function tb_formatln(btn, props, edid) {
96    var sample = props['title'];
97    if(props['sample']){
98        sample = props['sample'];
99    }
100    sample = fixtxt(sample);
101
102    props['open']  = fixtxt(props['open']);
103    props['close'] = fixtxt(props['close']);
104
105    // is something selected?
106    var opts;
107    var selection = getSelection($(edid));
108    if(selection.getLength()){
109        sample = selection.getText();
110        opts = {nosel: true};
111    }else{
112        opts = {
113            startofs: props['open'].length,
114            endofs: props['close'].length
115        };
116    }
117
118    sample = sample.split("\n").join(props['close']+"\n"+props['open']);
119    sample = props['open']+sample+props['close'];
120
121    pasteText(selection,sample,opts);
122
123    pickerClose();
124    return false;
125}
126
127/**
128 * Button action for insert buttons
129 *
130 * @param  DOMElement btn   Button element to add the action to
131 * @param  array      props Associative array of button properties
132 * @param  string     edid  ID of the editor textarea
133 * @author Gabriel Birke <birke@d-scribe.de>
134 * @author Andreas Gohr <andi@splitbrain.org>
135 */
136function tb_insert(btn, props, edid) {
137    insertAtCarret(edid,fixtxt(props['insert']));
138    pickerClose();
139}
140
141
142/**
143 * Add button action for picker buttons and create picker element
144 *
145 * @param  DOMElement btn   Button element to add the action to
146 * @param  array      props Associative array of button properties
147 * @param  string     edid  ID of the editor textarea
148 * @return boolean    If button should be appended
149 * @author Gabriel Birke <birke@d-scribe.de>
150 */
151function addBtnActionPicker(btn, props, edid) {
152    var pickerid = 'picker'+(pickercounter++);
153    createPicker(pickerid, props, edid);
154    addEvent(btn,'click',function(){
155        pickerToggle(pickerid,btn);
156        return false;
157    });
158    return true;
159}
160
161function addBtnActionLinkwiz(btn, props, edid) {
162    linkwiz.init($(edid));
163    addEvent(btn,'click',function(){
164        linkwiz.toggle();
165        return false;
166    });
167    return true;
168}
169
170
171/**
172 * Show/Hide a previosly created picker window
173 *
174 * @author Andreas Gohr <andi@splitbrain.org>
175 */
176function pickerToggle(pickerid,btn){
177    var picker = $(pickerid);
178    if(picker.style.display == 'none'){
179        var x = findPosX(btn);
180        var y = findPosY(btn);
181        picker.style.display = 'block';
182        picker.style.left = (x+3)+'px';
183        picker.style.top = (y+btn.offsetHeight+3)+'px';
184    }else{
185        picker.style.display = 'none';
186    }
187}
188
189/**
190 * Close all open pickers
191 *
192 * @author Andreas Gohr <andi@splitbrain.org>
193 */
194function pickerClose(){
195    var pobjs = getElementsByClass('picker');
196    for(var i=0; i<pobjs.length; i++){
197        pobjs[i].style.display = 'none';
198    }
199}
200
201
202/**
203 * Replaces \n with linebreaks
204 */
205function fixtxt(str){
206    return str.replace(/\\n/g,"\n");
207}
208
209