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