]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/EditToolbar.php
Added accesskeys
[SourceForge/phpwiki.git] / lib / EditToolbar.php
1 <?php
2 rcs_id('$Id: EditToolbar.php,v 1.12 2007-06-02 18:23:36 rurban Exp $');
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';
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;
92
93         $toolbar = "document.writeln(\"<div class=\\\"edit-toolbar\\\" id=\\\"toolbar\\\">\");\n";
94         $accessKeyPrefix = $WikiTheme->tooltipAccessKeyPrefix();
95
96         if (ENABLE_EDIT_TOOLBAR) {
97             $username = $GLOBALS['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"=>"<strong>",
106                                  "close"=>"</strong>",
107                                  "sample"=>_("Bold text"),
108                                  "title"=>_("Bold text [alt-b]")),
109                            array("image"=>"ed_format_italic.png",
110                                  "open"=>"<em>",
111                                  "close"=>"</em>",
112                                  "sample"=>_("Italic text"),
113                                  "title"=>_("Italic text [alt-i]")),
114                            array("image"=>"ed_pagelink.png",
115                                  "open"=>"[",
116                                  "close"=>"]",
117                                  "sample"=>_("optional label | PageName"),
118                                  "title"=>_("Link to page")),
119                            array("image"=>"ed_link.png",
120                                  "open"=>"[",
121                                  "close"=>"]",
122                                  "sample"=>_("optional label | http://www.example.com"),
123                                  "title"=>_("External link (remember http:// prefix)")),
124                            array("image"=>"ed_headline.png",
125                                  "open"=>"\\n!!! ",
126                                  "close"=>"\\n",
127                                  "sample"=>_("Headline text"),
128                                  "title"=>_("Level 1 headline")),
129                            array("image"=>"ed_image.png",
130                                  "open"=>"[ ",
131                                  "close"=>" ]",
132                                  "sample"=>_("Example.jpg"),
133                                  "title"=>_("Embedded image")),
134                            array("image"=>"ed_nowiki.png",
135                                  "open"=>"\\<verbatim\\>\\n",
136                                  "close"=>"\\n\\</verbatim\\>",
137                                  "sample"=>_("Insert non-formatted text here"),
138                                  "title"=>_("Ignore wiki formatting")),
139                            array("image"=>"ed_sig.png",
140                                  "open" => $signature,
141                                  "close" => "",
142                                  "sample"=>"",
143                                  "title"=>_("Your signature")),
144                            array("image"=>"ed_hr.png",
145                                  "open"=>"\\n----\\n",
146                                  "close"=>"",
147                                  "sample"=>"",
148                                  "title"=>_("Horizontal line"))
149                            );
150             $btn = new SubmitImageButton(_("Save"), "edit[save]", 'toolbar', 
151                                          $WikiTheme->getImageURL("ed_save.png"));
152             $btn->addTooltip(_("Save"));
153             $btn->setAccesskey("s");
154             $toolbar .= ('document.writeln("'.addslashes($btn->asXml()).'");'."\n");
155             // preview not supported yet on Wikiblog
156             if (empty($WikiTheme->_headers_printed)) {
157                 $btn = new SubmitImageButton(_("Preview"), "edit[preview]", 'toolbar', 
158                                              $WikiTheme->getImageURL("ed_preview.png"));
159                 $btn->addTooltip(_("Preview"));
160                 $btn->setAccesskey("p");
161                 $toolbar .= ('document.writeln("'.addslashes($btn->asXml()).'");'."\n");
162             }
163     
164             foreach ($toolarray as $tool) {
165                 global $WikiTheme;
166                 $image = $WikiTheme->getImageURL($tool["image"]);
167                 $open  = $tool["open"];
168                 $close = $tool["close"];
169                 $sample = addslashes( $tool["sample"] );
170                 // Note that we use the title both for the ALT tag and the TITLE tag of the image.
171                 // Older browsers show a "speedtip" type message only for ALT.
172                 // Ideally these should be different, realistically they
173                 // probably don't need to be.
174                 $tool = $WikiTheme->fixAccesskey($tool);
175                 $title = addslashes( $tool["title"] );
176                 $toolbar .= ("addTagButton('$image','$title','$open','$close','$sample');\n");
177             }
178             $toolbar .= ("addInfobox('" 
179                          . addslashes( _("Click a button to get an example text") ) 
180                          . "');\n");
181         }
182
183         if (JS_SEARCHREPLACE) {
184             $undo_d_btn = $WikiTheme->getImageURL("ed_undo_d.png"); 
185             //$redo_btn = $WikiTheme->getImageURL("ed_redo.png");
186             $sr_btn   = $WikiTheme->getImageURL("ed_replace.png");
187             //TODO: generalize the UNDO button and fix it for Search & Replace
188             $sr_html = HTML(HTML::img
189                             (array('class'=>"toolbar",
190                                    'id'   =>"sr_undo",
191                                    'src'  =>$undo_d_btn,
192                                    'title'=>_("Undo Search & Replace"),
193                                    'alt'  =>_("Undo Search & Replace"),
194                                    //'disabled'=>"disabled",   //non-XHTML conform
195                                    //'onfocus' =>"if(this.blur && undo_buffer_index==0) this.blur()",
196                                    'onclick' =>"do_undo()")),
197                             HTML::img
198                             (array('class'=>"toolbar",
199                                    'src'  => $sr_btn,
200                                    'alt'  =>_("Search & Replace"),
201                                    'title'=>_("Search & Replace")." [$accessKeyPrefix-h]",
202                                    'accesskey' => 'h',
203                                    'onclick'=>"replace()")));
204         } else {
205             $sr_html = '';
206         }
207
208         //TODO: Delegate this to run-time with showing an hidden input at the right, and do 
209         // a seperate moacdropdown and xmlrpc:titleSearch.
210
211         // Button to generate categories, display in extra window as popup and insert
212         $sr_html = HTML($sr_html, $this->categoriesPulldown());
213         // Button to generate plugins, display in extra window as popup and insert
214         $sr_html = HTML($sr_html, $this->pluginPulldown());
215
216         // Button to generate pagenames, display in extra window as popup and insert
217         if (TOOLBAR_PAGELINK_PULLDOWN)
218             $sr_html = HTML($sr_html, $this->pagesPulldown(TOOLBAR_PAGELINK_PULLDOWN));
219         // Button to insert from an template, display pagename in extra window as popup and insert
220         if (TOOLBAR_TEMPLATE_PULLDOWN)
221             $sr_html = HTML($sr_html, $this->templatePulldown(TOOLBAR_TEMPLATE_PULLDOWN));
222
223         // don't use document.write for replace, otherwise self.opener is not defined.
224         $toolbar_end = "document.writeln(\"</div>\");";
225         if ($sr_html)
226             return HTML(Javascript($toolbar),
227                         "\n", $sr_html, "\n",
228                         Javascript($toolbar_end));
229         else
230             return HTML(Javascript($toolbar . $toolbar_end));
231     }
232
233     //result is cached
234     function categoriesPulldown() {
235         global $WikiTheme;
236
237         require_once('lib/TextSearchQuery.php');
238         $dbi =& $GLOBALS['request']->_dbi;
239         // KEYWORDS formerly known as $KeywordLinkRegexp
240         $pages = $dbi->titleSearch(new TextSearchQuery(KEYWORDS, true));
241         if ($pages) {
242             $categories = array();
243             while ($p = $pages->next()) {
244                 $page = $p->getName();
245                 if (DISABLE_MARKUP_WIKIWORD or (!isWikiWord($page)))
246                     $categories[] = "['$page', '%5B".$page."%5D']";
247                 else
248                     $categories[] = "['$page', '$page']";
249             }
250             if (!$categories) return '';
251             // Ensure this to be inserted at the very end. Hence we added the id to the function.
252             $more_buttons = HTML::img(array('class'=> "toolbar",
253                                             'id' => 'tb-categories',
254                                             'src'  => $WikiTheme->getImageURL("ed_category.png"),
255                                             'title'=>_("AddCategory"),
256                                             'alt'=>"AddCategory", // to detect this at js
257                                             'onclick'=>"showPulldown('".
258                                             _("Insert Categories (double-click)")
259                                             ."',[".join(",",$categories)."],'"
260                                             ._("Insert")."','"
261                                             ._("Close")."','tb-categories')"));
262             return HTML("\n", $more_buttons);
263         }
264         return '';
265     }
266
267     // result is cached. Esp. the args are expensive
268     function pluginPulldown() {
269         global $WikiTheme;
270
271         $plugin_dir = 'lib/plugin';
272         if (defined('PHPWIKI_DIR'))
273             $plugin_dir = PHPWIKI_DIR . "/$plugin_dir";
274         $pd = new fileSet($plugin_dir, '*.php');
275         $plugins = $pd->getFiles();
276         unset($pd);
277         sort($plugins);
278         if (!empty($plugins)) {
279             $plugin_js = '';
280             require_once("lib/WikiPlugin.php");
281             $w = new WikiPluginLoader;
282             foreach ($plugins as $plugin) {
283                 $pluginName = str_replace(".php", "", $plugin);
284                 $p = $w->getPlugin($pluginName, false); // second arg?
285                 // trap php files which aren't WikiPlugin~s
286                 if (strtolower(substr(get_parent_class($p), 0, 10)) == 'wikiplugin') {
287                     $plugin_args = '';
288                     $desc = $p->getArgumentsDescription();
289                     $src = array("\n",'"',"'",'|','[',']','\\');
290                     $replace = array('%0A','%22','%27','%7C','%5B','%5D','%5C');
291                     $desc = str_replace("<br />",' ',$desc->asXML());
292                     if ($desc)
293                         $plugin_args = ' '.str_replace($src, $replace, $desc);
294                     $toinsert = "%0A<?plugin ".$pluginName.$plugin_args."?>"; // args?
295                     $plugin_js .= ",['$pluginName','$toinsert']";
296                 }
297             }
298             $plugin_js = substr($plugin_js, 1);
299             $more_buttons = HTML::img(array('class'=>"toolbar",
300                                             'id' => 'tb-plugins',
301                                             'src'  => $WikiTheme->getImageURL("ed_plugins.png"),
302                                             'title'=>_("AddPlugin"),
303                                             'alt'=>_("AddPlugin"),
304                                             'onclick'=>"showPulldown('".
305                                             _("Insert Plugin (double-click)")
306                                             ."',[".$plugin_js."],'"
307                                             ._("Insert")."','"
308                                             ._("Close")."','tb-plugins')"));
309             return HTML("\n", $more_buttons);
310         }
311         return '';
312     }
313
314     // result is cached. Esp. the args are expensive
315     function pagesPulldown($query, $case_exact=false, $regex='auto') {
316         require_once('lib/TextSearchQuery.php');
317         $dbi =& $GLOBALS['request']->_dbi;
318         $page_iter = $dbi->titleSearch(new TextSearchQuery($query, $case_exact, $regex));
319         if ($page_iter->count()) {
320             global $WikiTheme;
321             $pages = array();
322             while ($p = $page_iter->next()) {
323                 $page = $p->getName();
324                 if (DISABLE_MARKUP_WIKIWORD or (!isWikiWord($page)))
325                     $pages[] = "['$page', '%5B".$page."%5D']";
326                 else
327                     $pages[] = "['$page', '$page']";
328             }
329             return HTML("\n", HTML::img(array('class'=>"toolbar",
330                                               'id' => 'tb-pages',
331                                               'src'  => $WikiTheme->getImageURL("ed_pages.png"),
332                                               'title'=>_("AddPageLink"),
333                                               'alt'=>_("AddPageLink"),
334                                               'onclick'=>"showPulldown('".
335                                               _("Insert PageLink (double-click)")
336                                               ."',[".join(",",$pages)."],'"
337                                               ._("Insert")."','"
338                                               ._("Close")."','tb-pages')")));
339         }
340         return '';
341     }
342
343     // result is cached. Esp. the args are expensive
344     // FIXME!
345     function templatePulldown($query, $case_exact=false, $regex='auto') {
346         global $request;
347         require_once('lib/TextSearchQuery.php');
348         $dbi =& $request->_dbi;
349         $page_iter = $dbi->titleSearch(new TextSearchQuery($query, $case_exact, $regex));
350         $count = 0;
351         if ($page_iter->count()) {
352             global $WikiTheme;
353             $pages_js = '';
354             while ($p = $page_iter->next()) {
355                 $rev = $p->getCurrentRevision();
356                 $toinsert = str_replace(array("\n",'"'), array('_nl','_quot'), $rev->_get_content());
357                 //$toinsert = str_replace("\n",'\n',addslashes($rev->_get_content()));
358                 $pages_js .= ",['".$p->getName()."','_nl$toinsert']";
359             }
360             $pages_js = substr($pages_js, 1);
361             if (!empty($pages_js))
362                 return HTML("\n", HTML::img
363                             (array('class'=>"toolbar",
364                                    'id' => 'tb-templates',
365                                    'src'  => $WikiTheme->getImageURL("ed_template.png"),
366                                    'title'=>_("AddTemplate"),
367                                    'alt'=>_("AddTemplate"),
368                                    'onclick'=>"showPulldown('".
369                                    _("Insert Template (double-click)")
370                                    ."',[".$pages_js."],'"
371                                    ._("Insert")."','"
372                                    ._("Close")."','tb-templates')")));
373         }
374         return '';
375     }
376
377 }
378
379 /*
380 $Log: not supported by cvs2svn $
381 Revision 1.11  2007/02/17 14:16:21  rurban
382 move define_f after toolbar.js
383
384 Revision 1.10  2007/01/07 18:42:19  rurban
385 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
386
387 Revision 1.9  2007/01/02 13:18:26  rurban
388 fix id to edit:content
389
390 Revision 1.8  2006/12/22 00:17:06  rurban
391 add time to signature
392
393 Revision 1.7  2006/09/06 05:45:26  rurban
394 use html tags for emphasis. workaround ^* problem
395
396 Revision 1.6  2006/08/30 05:25:40  rurban
397 Handle inserting DISABLE_MARKUP_WIKIWORD and non wikiword links.
398
399 Revision 1.5  2005/10/29 14:16:17  rurban
400 fix typo
401
402 Revision 1.4  2005/09/29 23:07:58  rurban
403 cache toolbar
404
405 Revision 1.3  2005/09/26 06:25:50  rurban
406 EditToolbar enhancements by Thomas Harding: add plugins args, properly quote control chars. added plugin method getArgumentsDescription to override the default description string
407
408 Revision 1.3  2005/09/22 13:40:00 tharding
409 add modules arguments
410  
411 Revision 1.2  2005/05/06 18:43:41  rurban
412 add AddTemplate EditToolbar icon
413
414 Revision 1.1  2005/01/25 15:19:09  rurban
415 extract Toolbar code from editpage.php
416 */
417
418 // Local Variables:
419 // mode: php
420 // tab-width: 8
421 // c-basic-offset: 4
422 // c-hanging-comment-ender-p: nil
423 // indent-tabs-mode: nil
424 // End:
425 ?>