]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/EditToolbar.php
Chrome does not display the addInfobox
[SourceForge/phpwiki.git] / lib / EditToolbar.php
1 <?php
2 rcs_id('$Id$');
3
4 /**
5  * EDIT Toolbar Initialization.
6  * The default/themes/toolbar.js is from Mediawiki, this PHP is written from scratch.
7  *
8  * Features: 
9  * - save-preview and formatting buttons from mediawiki
10  * - Search&Replace from walterzorn.de
11  * - pageinsert popup by Reini Urban (TODO: should be a pulldown, use acdropdown)
12  */
13
14 class EditToolbar {
15
16     function EditToolbar() {
17         global $WikiTheme;
18
19         $this->tokens = array();
20
21         //FIXME: enable Undo button for all other buttons also, not only the search/replace button
22         if (JS_SEARCHREPLACE) {
23             $this->tokens['JS_SEARCHREPLACE'] = 1;
24             $undo_btn = $WikiTheme->getImageURL("ed_undo.png"); 
25             $undo_d_btn = $WikiTheme->getImageURL("ed_undo_d.png"); 
26             // JS_SEARCHREPLACE from walterzorn.de
27             $js = Javascript("
28 uri_undo_btn   = '".$undo_btn."'
29 msg_undo_alt   = '"._("Undo")."'
30 uri_undo_d_btn = '".$undo_d_btn."'
31 msg_undo_d_alt = '"._("Undo disabled")."'
32 msg_do_undo    = '"._("Operation undone")."'
33 msg_replfound  = '"._("Substring \"\\1\" found \\2 times. Replace with \"\\3\"?")."'
34 msg_replnot    = '"._("String \"%s\" not found.")."'
35 msg_repl_title     = '"._("Search & Replace")."'
36 msg_repl_search    = '"._("Search for")."'
37 msg_repl_replace_with = '"._("Replace with")."'
38 msg_repl_ok        = '"._("OK")."'
39 msg_repl_close     = '"._("Close")."'
40 ");
41             if (empty($WikiTheme->_headers_printed)) {
42                 $WikiTheme->addMoreHeaders($js);
43                 $WikiTheme->addMoreAttr('body', "SearchReplace"," onload='define_f()'");
44             } else { // from an actionpage: WikiBlog, AddComment, WikiForum
45                 printXML($js);
46             }
47         } else {
48             $WikiTheme->addMoreAttr('body', "editfocus", "document.getElementById('edit-content]').editarea.focus()");
49         }
50     
51         if (ENABLE_EDIT_TOOLBAR) {
52             $js = JavaScript('',array('src' => $WikiTheme->_findData("toolbar.js")));
53             if (empty($WikiTheme->_headers_printed))
54                 $WikiTheme->addMoreHeaders($js);
55             else { // from an actionpage: WikiBlog, AddComment, WikiForum
56                 printXML($js);
57                 printXML(JavaScript('define_f()'));
58             }
59         }
60
61         require_once("lib/WikiPluginCached.php");
62         $cache = WikiPluginCached::newCache();
63         $dbi = $GLOBALS['request']->getDbh();
64         // regenerate if number of pages changes (categories, pages, templates)
65         $key = $dbi->numPages();
66         $key .= '+categories+plugin' . (isBrowserSafari() ? '+safari' : '');
67         if (TOOLBAR_PAGELINK_PULLDOWN) {
68             $key .= "+pages";
69         }
70         if (TOOLBAR_TEMPLATE_PULLDOWN) {
71             $key .= "+templates_" . $dbi->getTimestamp();
72         }
73         $id = $cache->generateId($key);
74         $content = $cache->get($id, 'toolbarcache');
75
76         if (!empty($content)) {
77             $this->tokens['EDIT_TOOLBAR'] =& $content;
78         } else {
79             $content = $this->_generate();
80             // regenerate buttons every 3600 seconds
81             $cache->save($id, $content, '+3600', 'toolbarcache'); 
82             $this->tokens['EDIT_TOOLBAR'] =& $content;
83         }
84     }
85
86     function getTokens () {
87         return $this->tokens;
88     }
89
90     function _generate () {
91         global $WikiTheme, $request;
92
93         $toolbar = "document.writeln(\"<div class=\\\"edit-toolbar\\\" id=\\\"toolbar\\\">\");\n";
94         $accessKeyPrefix = $WikiTheme->tooltipAccessKeyPrefix();
95
96         if (ENABLE_EDIT_TOOLBAR) {
97             $username = $request->_user->UserName();
98             if (DISABLE_MARKUP_WIKIWORD or (!isWikiWord($username))) {
99                 $username = '['.$username.']';
100             }
101             $signature = " --".$username." ".CTime();
102             $toolarray = array(
103                            array(
104                                  "image"=>"ed_format_bold.png",
105                                  "open"=>"**",
106                                  "close"=>"**",
107                                  "sample"=>_("Bold text"),
108                                  "title"=>_("Bold text [alt-b]")),
109                            array("image"=>"ed_format_italic.png",
110                                  "open"=>"//",
111                                  "close"=>"//",
112                                  "sample"=>_("Italic text"),
113                                  "title"=>_("Italic text [alt-i]")),
114                            array("image"=>"ed_format_strike.png",
115                                  "open"=>"<s>",
116                                  "close"=>"</s>",
117                                  "sample"=>_("Strike-through text"),
118                                  "title"=>_("Strike")),
119                            array("image"=>"ed_format_color.png",
120                                  "open"=>"%color=green% ",
121                                  "close"=>" %%",
122                                  "sample"=>_("Color text"),
123                                  "title"=>_("Color")),
124                            array("image"=>"ed_pagelink.png",
125                                  "open"=>"[[",
126                                  "close"=>"]]",
127                                  "sample"=>_("PageName|optional label"),
128                                  "title"=>_("Link to page")),
129                            array("image"=>"ed_link.png",
130                                  "open"=>"[[",
131                                  "close"=>"]]",
132                                  "sample"=>_("http://www.example.com|optional label"),
133                                  "title"=>_("External link (remember http:// prefix)")),
134                            array("image"=>"ed_headline.png",
135                                  "open"=>"\\n== ",
136                                  "close"=>" ==\\n",
137                                  "sample"=>_("Headline text"),
138                                  "title"=>_("Level 1 headline")),
139                            array("image"=>"ed_nowiki.png",
140                                  "open"=>"\\<verbatim\\>\\n",
141                                  "close"=>"\\n\\</verbatim\\>",
142                                  "sample"=>_("Insert non-formatted text here"),
143                                  "title"=>_("Ignore wiki formatting")),
144                            array("image"=>"ed_sig.png",
145                                  "open" => $signature,
146                                  "close" => "",
147                                  "sample"=>"",
148                                  "title"=>_("Your signature")),
149                            array("image"=>"ed_hr.png",
150                                  "open"=>"\\n----\\n",
151                                  "close"=>"",
152                                  "sample"=>"",
153                                  "title"=>_("Horizontal line")),
154                            array("image"=>"ed_table.png",
155                                  "open"=>"\\n{| class=\"bordered\"\\n|+ This is the table caption\\n|= This is the table summary\\n|-\\n! Header A !! Header B !! Header C\\n|-\\n| Cell A1 || Cell B1 || Cell C1\\n|-\\n| Cell A2 || Cell B2 || Cell C2\\n|-\\n| Cell A3 || Cell B3 || Cell C3\\n|}\\n",
156                                  "close"=>"",
157                                  "sample"=>"",
158                                  "title"=>_("Sample table")),
159                            array("image"=>"ed_enumlist.png",
160                                  "open"=>"\\n# Item 1\\n# Item 2\\n# Item 3\\n",
161                                  "close"=>"",
162                                  "sample"=>"",
163                                  "title"=>_("Enumeration")),
164                            array("image"=>"ed_list.png",
165                                  "open"=>"\\n* Item 1\\n* Item 2\\n* Item 3\\n",
166                                  "close"=>"",
167                                  "sample"=>"",
168                                  "title"=>_("List")),
169                            array("image"=>"ed_toc.png",
170                                  "open"=>"<<CreateToc with_toclink||=1>>\\n",
171                                  "close"=>"",
172                                  "sample"=>"",
173                                  "title"=>_("Table of Contents")),
174                            array("image"=>"ed_redirect.png",
175                                  "open"=>"<<RedirectTo page=\"",
176                                  "close"=>"\">>",
177                                  "sample"=>_("Page Name"),
178                                  "title"=>_("Redirect")),
179                            array("image"=>"ed_templateplugin.png",
180                                  "open"=>"{{",
181                                  "close"=>"}}",
182                                  "sample"=>_("Template Name"),
183                                  "title"=>_("Template"))
184                            );
185             $btn = new SubmitImageButton(_("Save"), "edit[save]", 'toolbar', 
186                                          $WikiTheme->getImageURL("ed_save.png"));
187             $btn->addTooltip(_("Save"));
188             $btn->setAccesskey("s");
189             $toolbar .= ('document.writeln("'.addslashes($btn->asXml()).'");'."\n");
190             // preview not supported yet on Wikiblog
191             if (empty($WikiTheme->_headers_printed)) {
192                 $btn = new SubmitImageButton(_("Preview"), "edit[preview]", 'toolbar', 
193                                              $WikiTheme->getImageURL("ed_preview.png"));
194                 $btn->addTooltip(_("Preview"));
195                 $btn->setAccesskey("p");
196                 $toolbar .= ('document.writeln("'.addslashes($btn->asXml()).'");'."\n");
197             }
198     
199             foreach ($toolarray as $tool) {
200                 global $WikiTheme;
201                 $image = $WikiTheme->getImageURL($tool["image"]);
202                 $open  = $tool["open"];
203                 $close = $tool["close"];
204                 $sample = addslashes( $tool["sample"] );
205                 // Note that we use the title both for the ALT tag and the TITLE tag of the image.
206                 // Older browsers show a "speedtip" type message only for ALT.
207                 // Ideally these should be different, realistically they
208                 // probably don't need to be.
209                 $tool = $WikiTheme->fixAccesskey($tool);
210                 $title = addslashes( $tool["title"] );
211                 $toolbar .= ("addTagButton('$image','$title','$open','$close','$sample');\n");
212             }
213             /* Fails with Chrome */
214             if (!isBrowserSafari()) {
215                 $toolbar .= ("addInfobox('" 
216                              . addslashes( _("Click a button to get an example text") ) 
217                              . "');\n");
218             }
219         }
220
221         if (JS_SEARCHREPLACE) {
222             $undo_d_btn = $WikiTheme->getImageURL("ed_undo_d.png"); 
223             //$redo_btn = $WikiTheme->getImageURL("ed_redo.png");
224             $sr_btn   = $WikiTheme->getImageURL("ed_replace.png");
225             //TODO: generalize the UNDO button and fix it for Search & Replace
226             $sr_html = HTML(HTML::img
227                             (array('class'=>"toolbar",
228                                    'id'   =>"sr_undo",
229                                    'src'  =>$undo_d_btn,
230                                    'title'=>_("Undo Search & Replace"),
231                                    'alt'  =>_("Undo Search & Replace"),
232                                    //'disabled'=>"disabled",   //non-XHTML conform
233                                    //'onfocus' =>"if(this.blur && undo_buffer_index==0) this.blur()",
234                                    'onclick' =>"do_undo()")),
235                             HTML::img
236                             (array('class'=>"toolbar",
237                                    'src'  => $sr_btn,
238                                    'alt'  =>_("Search & Replace"),
239                                    'title'=>_("Search & Replace")." [$accessKeyPrefix-h]",
240                                    'accesskey' => 'h',
241                                    'onclick'=>"replace()")));
242         } else {
243             $sr_html = '';
244         }
245
246         //TODO: Delegate this to run-time with showing an hidden input at the right, and do 
247         // a seperate moacdropdown and xmlrpc:titleSearch.
248
249         // Button to generate categories, display in extra window as popup and insert
250         $sr_html = HTML($sr_html, $this->categoriesPulldown());
251         // Button to generate plugins, display in extra window as popup and insert
252         $sr_html = HTML($sr_html, $this->pluginPulldown());
253
254         // Button to generate pagenames, display in extra window as popup and insert
255         if (TOOLBAR_PAGELINK_PULLDOWN)
256             $sr_html = HTML($sr_html, $this->pagesPulldown(TOOLBAR_PAGELINK_PULLDOWN));
257         // Button to insert from an template, display pagename in extra window as popup and insert
258         if (TOOLBAR_TEMPLATE_PULLDOWN)
259             $sr_html = HTML($sr_html, $this->templatePulldown(TOOLBAR_TEMPLATE_PULLDOWN));
260
261         // Button to add images, display in extra window as popup and insert
262         if (TOOLBAR_IMAGE_PULLDOWN)
263             $sr_html = HTML($sr_html, $this->imagePulldown(TOOLBAR_IMAGE_PULLDOWN));
264
265         // don't use document.write for replace, otherwise self.opener is not defined.
266         $toolbar_end = "document.writeln(\"</div>\");";
267         if ($sr_html)
268             return HTML(Javascript($toolbar),
269                         "\n", $sr_html, "\n",
270                         Javascript($toolbar_end));
271         else
272             return HTML(Javascript($toolbar . $toolbar_end));
273     }
274
275     //result is cached
276     function categoriesPulldown() {
277         global $WikiTheme;
278
279         require_once('lib/TextSearchQuery.php');
280         $dbi =& $GLOBALS['request']->_dbi;
281         // KEYWORDS formerly known as $KeywordLinkRegexp
282         $pages = $dbi->titleSearch(new TextSearchQuery(KEYWORDS, true));
283         if ($pages) {
284             $categories = array();
285             while ($p = $pages->next()) {
286                 $page = $p->getName();
287                 if (DISABLE_MARKUP_WIKIWORD or (!isWikiWord($page)))
288                     $categories[] = "['$page', '%5B".$page."%5D']";
289                 else
290                     $categories[] = "['$page', '$page']";
291             }
292             if (!$categories) return '';
293             // Ensure this to be inserted at the very end. Hence we added the id to the function.
294             $more_buttons = HTML::img(array('class'=> "toolbar",
295                                             'id' => 'tb-categories',
296                                             'src'  => $WikiTheme->getImageURL("ed_category.png"),
297                                             'title'=>_("AddCategory"),
298                                             'alt'=>"AddCategory", // to detect this at js
299                                             'onclick'=>"showPulldown('".
300                                             _("Insert Categories (double-click)")
301                                             ."',[".join(",",$categories)."],'"
302                                             ._("Insert")."','"
303                                             ._("Close")."','tb-categories')"));
304             return HTML("\n", $more_buttons);
305         }
306         return '';
307     }
308
309     // result is cached. Esp. the args are expensive
310     function pluginPulldown() {
311         global $WikiTheme;
312
313         $plugin_dir = 'lib/plugin';
314         if (defined('PHPWIKI_DIR'))
315             $plugin_dir = PHPWIKI_DIR . "/$plugin_dir";
316         $pd = new fileSet($plugin_dir, '*.php');
317         $plugins = $pd->getFiles();
318         unset($pd);
319         sort($plugins);
320         if (!empty($plugins)) {
321             $plugin_js = '';
322             require_once("lib/WikiPlugin.php");
323             $w = new WikiPluginLoader;
324             foreach ($plugins as $plugin) {
325                 $pluginName = str_replace(".php", "", $plugin);
326                 $p = $w->getPlugin($pluginName, false); // second arg?
327                 // trap php files which aren't WikiPlugin~s
328                 if (strtolower(substr(get_parent_class($p), 0, 10)) == 'wikiplugin') {
329                     $plugin_args = '';
330                     $desc = $p->getArgumentsDescription();
331                     $src = array("\n",'"',"'",'|','[',']','\\');
332                     $replace = array('%0A','%22','%27','%7C','%5B','%5D','%5C');
333                     $desc = str_replace("<br />",' ',$desc->asXML());
334                     if ($desc)
335                         $plugin_args = ' '.str_replace($src, $replace, $desc);
336                     $toinsert = "%0A<<".$pluginName.$plugin_args.">>"; // args?
337                     $plugin_js .= ",['$pluginName','$toinsert']";
338                 }
339             }
340             $plugin_js = substr($plugin_js, 1);
341             $more_buttons = HTML::img(array('class'=>"toolbar",
342                                             'id' => 'tb-plugins',
343                                             'src'  => $WikiTheme->getImageURL("ed_plugins.png"),
344                                             'title'=>_("AddPlugin"),
345                                             'alt'=>_("AddPlugin"),
346                                             'onclick'=>"showPulldown('".
347                                             _("Insert Plugin (double-click)")
348                                             ."',[".$plugin_js."],'"
349                                             ._("Insert")."','"
350                                             ._("Close")."','tb-plugins')"));
351             return HTML("\n", $more_buttons);
352         }
353         return '';
354     }
355
356     // result is cached. Esp. the args are expensive
357     function pagesPulldown($query, $case_exact=false, $regex='auto') {
358         require_once('lib/TextSearchQuery.php');
359         $dbi =& $GLOBALS['request']->_dbi;
360         $page_iter = $dbi->titleSearch(new TextSearchQuery($query, $case_exact, $regex));
361         if ($page_iter->count()) {
362             global $WikiTheme;
363             $pages = array();
364             while ($p = $page_iter->next()) {
365                 $page = $p->getName();
366                 if (DISABLE_MARKUP_WIKIWORD or (!isWikiWord($page)))
367                     $pages[] = "['$page', '%5B".$page."%5D']";
368                 else
369                     $pages[] = "['$page', '$page']";
370             }
371             return HTML("\n", HTML::img(array('class'=>"toolbar",
372                                               'id' => 'tb-pages',
373                                               'src'  => $WikiTheme->getImageURL("ed_pages.png"),
374                                               'title'=>_("AddPageLink"),
375                                               'alt'=>_("AddPageLink"),
376                                               'onclick'=>"showPulldown('".
377                                               _("Insert PageLink (double-click)")
378                                               ."',[".join(",",$pages)."],'"
379                                               ._("Insert")."','"
380                                               ._("Close")."','tb-pages')")));
381         }
382         return '';
383     }
384
385     // result is cached. Esp. the args are expensive
386     function imagePulldown($query, $case_exact=false, $regex='auto') {
387         global $WikiTheme;
388
389         $image_dir = '.';
390         if (defined('UPLOAD_FILE_PATH'))
391             $image_dir = UPLOAD_FILE_PATH . "/$image_dir";
392         $pd = new fileSet($image_dir, '*');
393         $images = $pd->getFiles();
394         unset($pd);
395         sort($images);
396         if (!empty($images)) {
397             $image_js = '';
398             foreach ($images as $image) {
399                 // Select only files ending in ".png", ".gif", ".jpg", ".jpeg"
400                 if (is_image($image)) {
401                     $image_js .= ",['$image','{{".$image."}}']";
402                 }
403             }
404             $image_js = substr($image_js, 1);
405             $more_buttons = HTML::img(array('class'=>"toolbar",
406                                             'id' => 'tb-images',
407                                             'src'  => $WikiTheme->getImageURL("ed_image.png"),
408                                             'title'=>_("AddImage"),
409                                             'alt'=>_("AddImage"),
410                                             'onclick'=>"showPulldown('".
411                                             _("Insert Image (double-click)")
412                                             ."',[".$image_js."],'"
413                                             ._("Insert")."','"
414                                             ._("Close")."','tb-images')"));
415             return HTML("\n", $more_buttons);
416         }
417         return '';
418     }
419
420     // result is cached. Esp. the args are expensive
421     // FIXME!
422     function templatePulldown($query, $case_exact=false, $regex='auto') {
423         global $request;
424         require_once('lib/TextSearchQuery.php');
425         $dbi =& $request->_dbi;
426         $page_iter = $dbi->titleSearch(new TextSearchQuery($query, $case_exact, $regex));
427         $count = 0;
428         if ($page_iter->count()) {
429             global $WikiTheme;
430             $pages_js = '';
431             while ($p = $page_iter->next()) {
432                 $rev = $p->getCurrentRevision();
433                 $toinsert = str_replace(array("\n",'"'), array('_nl','_quot'), $rev->_get_content());
434                 //$toinsert = str_replace("\n",'\n',addslashes($rev->_get_content()));
435                 $pages_js .= ",['".$p->getName()."','_nl$toinsert']";
436             }
437             $pages_js = substr($pages_js, 1);
438             if (!empty($pages_js))
439                 return HTML("\n", HTML::img
440                             (array('class'=>"toolbar",
441                                    'id' => 'tb-templates',
442                                    'src'  => $WikiTheme->getImageURL("ed_template.png"),
443                                    'title'=>_("AddTemplate"),
444                                    'alt'=>_("AddTemplate"),
445                                    'onclick'=>"showPulldown('".
446                                    _("Insert Template (double-click)")
447                                    ."',[".$pages_js."],'"
448                                    ._("Insert")."','"
449                                    ._("Close")."','tb-templates')")));
450         }
451         return '';
452     }
453
454 }
455
456 /*
457 $Log: not supported by cvs2svn $
458 Revision 1.17  2008/08/06 09:25:56  vargenau
459 Button to add images, display in extra window as popup and insert
460
461 Revision 1.16  2008/08/03 15:21:45  vargenau
462 Less arguments for CreateToc button
463
464 Revision 1.15  2008/04/02 18:07:05  vargenau
465 New Edit Toolbar icons for TOC and Color text
466
467 Revision 1.14  2008/02/19 19:07:23  vargenau
468 More icons for toolbar
469
470 Revision 1.13  2007/07/14 12:03:12  rurban
471 just aesthetics
472
473 Revision 1.12  2007/06/02 18:23:36  rurban
474 Added accesskeys
475
476 Revision 1.11  2007/02/17 14:16:21  rurban
477 move define_f after toolbar.js
478
479 Revision 1.10  2007/01/07 18:42:19  rurban
480 Improve id: edit: to edit-. Move search&replace js from body (defined in EditToolbar) to the toolbar.js. Support actionpages. Add tb-name argument to showPulldown
481
482 Revision 1.9  2007/01/02 13:18:26  rurban
483 fix id to edit:content
484
485 Revision 1.8  2006/12/22 00:17:06  rurban
486 add time to signature
487
488 Revision 1.7  2006/09/06 05:45:26  rurban
489 use html tags for emphasis. workaround ^* problem
490
491 Revision 1.6  2006/08/30 05:25:40  rurban
492 Handle inserting DISABLE_MARKUP_WIKIWORD and non wikiword links.
493
494 Revision 1.5  2005/10/29 14:16:17  rurban
495 fix typo
496
497 Revision 1.4  2005/09/29 23:07:58  rurban
498 cache toolbar
499
500 Revision 1.3  2005/09/26 06:25:50  rurban
501 EditToolbar enhancements by Thomas Harding: add plugins args, properly quote control chars. added plugin method getArgumentsDescription to override the default description string
502
503 Revision 1.3  2005/09/22 13:40:00 tharding
504 add modules arguments
505  
506 Revision 1.2  2005/05/06 18:43:41  rurban
507 add AddTemplate EditToolbar icon
508
509 Revision 1.1  2005/01/25 15:19:09  rurban
510 extract Toolbar code from editpage.php
511 */
512
513 // Local Variables:
514 // mode: php
515 // tab-width: 8
516 // c-basic-offset: 4
517 // c-hanging-comment-ender-p: nil
518 // indent-tabs-mode: nil
519 // End:
520 ?>