Dotclear

source: inc/admin/lib.dc.page.php @ 1316:751f3031bcc7

Revision 1316:751f3031bcc7, 19.8 KB checked in by Dsls, 12 years ago (diff)

Manual merge for remaining little things from default, need to cope with this 3px difference in search box...
Btw, fixes checkboxes problems

Line 
1<?php
2# -- BEGIN LICENSE BLOCK ---------------------------------------
3#
4# This file is part of Dotclear 2.
5#
6# Copyright (c) 2003-2011 Olivier Meunier & Association Dotclear
7# Licensed under the GPL version 2.0 license.
8# See LICENSE file or
9# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10#
11# -- END LICENSE BLOCK -----------------------------------------
12if (!defined('DC_RC_PATH')) { return; }
13
14define('DC_AUTH_PAGE','auth.php');
15
16class dcPage
17{
18     private static $loaded_js=array();
19
20     # Auth check
21     public static function check($permissions)
22     {
23          global $core;
24         
25          if ($core->blog && $core->auth->check($permissions,$core->blog->id))
26          {
27               return;
28          }
29         
30          if (session_id()) {
31               $core->session->destroy();
32          }
33          http::redirect(DC_AUTH_PAGE);
34     }
35     
36     # Check super admin
37     public static function checkSuper()
38     {
39          global $core;
40         
41          if (!$core->auth->isSuperAdmin())
42          {
43               if (session_id()) {
44                    $core->session->destroy();
45               }
46               http::redirect(DC_AUTH_PAGE);
47          }
48     }
49     
50     # Top of admin page
51     public static function open($title='',$head='',$popup=false)
52     {
53          global $core, $_ctx;
54         
55          $_ctx->popup = (boolean) $popup;
56          $_ctx->page_header = $head;
57          $_ctx->fillPageTitle($title);
58         
59          ob_start();
60     }
61     
62     public static function close()
63     {
64          $res = ob_get_contents();
65          ob_end_clean();
66         
67          global $core, $_ctx;
68         
69          if ($core->error->flag()) {
70               foreach($core->error->getErrors() as $e) {
71                    $_ctx->addError($e);
72               }
73          }
74          $_ctx->page_content = $res;
75          $core->tpl->display('page_layout.html.twig');
76     }
77     
78     public static function openPopup($title='',$head='')
79     {
80          self::open($title,$head,true);
81     }
82     
83     public static function closePopup()
84     {
85          self::close();
86     }
87
88     public static function message($msg,$timestamp=true,$div=false,$echo=true)
89     {
90          global $core;
91         
92          $res = '';
93          if ($msg != '') {
94               $res = ($div ? '<div class="message">' : '').'<p'.($div ? '' : ' class="message"').'>'.
95                    ($timestamp ? dt::str(__('%H:%M:%S:'),null,$core->auth->getInfo('user_tz')).' ' : '').$msg.
96                    '</p>'.($div ? '</div>' : '');
97               if ($echo) {
98                    echo $res;
99               }
100          }
101          return $res;
102     }
103     
104     public static function help($page,$index='')
105     {
106          # Deprecated but we keep this for plugins.
107     }
108     
109     public static function helpBlock()
110     {
111          $args = func_get_args();
112          if (empty($args)) {
113               return;
114          };
115         
116          global $__resources;
117          if (empty($__resources['help'])) {
118               return;
119          }
120         
121          $content = '';
122          foreach ($args as $v)
123          {
124               if (is_object($v) && isset($v->content)) {
125                    $content .= $v->content;
126                    continue;
127               }
128               
129               if (!isset($__resources['help'][$v])) {
130                    continue;
131               }
132               $f = $__resources['help'][$v];
133               if (!file_exists($f) || !is_readable($f)) {
134                    continue;
135               }
136               
137               $fc = file_get_contents($f);
138               if (preg_match('|<body[^>]*?>(.*?)</body>|ms',$fc,$matches)) {
139                    $content .= $matches[1];
140               } else {
141                    $content .= $fc;
142               }
143          }
144         
145          if (trim($content) == '') {
146               return;
147          }
148         
149          echo
150          '<div id="help"><hr /><div class="help-content clear"><h2>'.__('Help').'</h2>'.
151          $content.
152          '</div></div>';
153     }
154     
155     public static function jsLoad($src)
156     {
157          $escaped_src = html::escapeHTML($src);
158          if (!isset(self::$loaded_js[$escaped_src])) {
159               self::$loaded_js[$escaped_src]=true;
160               return '<script type="text/javascript" src="'.$escaped_src.'"></script>'."\n";
161          }
162     }
163     
164     public static function jsVar($n,$v)
165     {
166          return $n." = '".html::escapeJS($v)."';\n";
167     }
168     
169     public static function jsCommon()
170     {
171          return
172          self::jsLoad('js/jquery/jquery.js').
173          self::jsLoad('js/jquery/jquery.biscuit.js').
174          self::jsLoad('js/jquery/jquery.bgFade.js').
175          self::jsLoad('js/common.js').
176          self::jsLoad('js/prelude.js').
177         
178          '<script type="text/javascript">'."\n".
179          "//<![CDATA[\n".
180          self::jsVar('dotclear.nonce',$GLOBALS['core']->getNonce()).
181         
182          self::jsVar('dotclear.img_plus_src','images/expand.png').
183          self::jsVar('dotclear.img_plus_alt',__('uncover')).
184          self::jsVar('dotclear.img_minus_src','images/hide.png').
185          self::jsVar('dotclear.img_minus_alt',__('hide')).
186          self::jsVar('dotclear.img_menu_on','images/menu_on.png').
187          self::jsVar('dotclear.img_menu_off','images/menu_off.png').
188         
189          self::jsVar('dotclear.msg.help',
190               __('Help about this page')).
191          self::jsVar('dotclear.msg.help_hide',
192               __('Hide')).
193          self::jsVar('dotclear.msg.no_selection',
194               __('no selection')).
195          self::jsVar('dotclear.msg.select_all',
196               __('select all')).
197          self::jsVar('dotclear.msg.invert_sel',
198               __('invert selection')).
199          self::jsVar('dotclear.msg.website',
200               __('Web site:')).
201          self::jsVar('dotclear.msg.email',
202               __('Email:')).
203          self::jsVar('dotclear.msg.ip_address',
204               __('IP address:')).
205          self::jsVar('dotclear.msg.error',
206               __('Error:')).
207          self::jsVar('dotclear.msg.entry_created',
208               __('Entry has been successfully created.')).
209          self::jsVar('dotclear.msg.edit_entry',
210               __('Edit entry')).
211          self::jsVar('dotclear.msg.view_entry',
212               __('view entry')).
213          self::jsVar('dotclear.msg.confirm_delete_posts',
214               __("Are you sure you want to delete selected entries (%s)?")).
215          self::jsVar('dotclear.msg.confirm_delete_post',
216               __("Are you sure you want to delete this entry?")).
217          self::jsVar('dotclear.msg.confirm_spam_delete',
218               __('Are you sure you want to delete all spams?')).
219          self::jsVar('dotclear.msg.confirm_delete_comments',
220               __('Are you sure you want to delete selected comments (%s)?')).
221          self::jsVar('dotclear.msg.confirm_delete_comment',
222               __('Are you sure you want to delete this comment?')).
223          self::jsVar('dotclear.msg.cannot_delete_users',
224               __('Users with posts cannot be deleted.')).
225          self::jsVar('dotclear.msg.confirm_delete_user',
226               __('Are you sure you want to delete selected users (%s)?')).
227          self::jsVar('dotclear.msg.confirm_delete_category',
228               __('Are you sure you want to delete category "%s"?')).
229          self::jsVar('dotclear.msg.confirm_reorder_categories',
230               __('Are you sure you want to reorder all categories?')).
231          self::jsVar('dotclear.msg.confirm_delete_media',
232               __('Are you sure you want to remove media "%s"?')).
233          self::jsVar('dotclear.msg.confirm_extract_current',
234               __('Are you sure you want to extract archive in current directory?')).
235          self::jsVar('dotclear.msg.confirm_remove_attachment',
236               __('Are you sure you want to remove attachment "%s"?')).
237          self::jsVar('dotclear.msg.confirm_delete_lang',
238               __('Are you sure you want to delete "%s" language?')).
239          self::jsVar('dotclear.msg.confirm_delete_plugin',
240               __('Are you sure you want to delete "%s" plugin?')).
241          self::jsVar('dotclear.msg.use_this_theme',
242               __('Use this theme')).
243          self::jsVar('dotclear.msg.remove_this_theme',
244               __('Remove this theme')).
245          self::jsVar('dotclear.msg.confirm_delete_theme',
246               __('Are you sure you want to delete "%s" theme?')).
247          self::jsVar('dotclear.msg.zip_file_content',
248               __('Zip file content')).
249          self::jsVar('dotclear.msg.xhtml_validator',
250               __('XHTML markup validator')).
251          self::jsVar('dotclear.msg.xhtml_valid',
252               __('XHTML content is valid.')).
253          self::jsVar('dotclear.msg.xhtml_not_valid',
254               __('There are XHTML markup errors.')).
255          self::jsVar('dotclear.msg.confirm_change_post_format',
256               __('You have unsaved changes. Switch post format will loose these changes. Proceed anyway?')).
257          self::jsVar('dotclear.msg.load_enhanced_uploader',
258               __('Loading enhanced uploader, please wait.')).
259          "\n//]]>\n".
260          "</script>\n";
261     }
262     
263     public static function jsLoadIE7()
264     {
265          return
266          '<!--[if lt IE 8]>'."\n".
267          self::jsLoad('js/ie7/IE8.js').
268          '<link rel="stylesheet" type="text/css" href="style/iesucks.css" />'."\n".
269          '<![endif]-->'."\n";
270     }
271     
272     public static function jsConfirmClose()
273     {
274          $args = func_get_args();
275          if (count($args) > 0) {
276               foreach ($args as $k => $v) {
277                    $args[$k] = "'".html::escapeJS($v)."'";
278               }
279               $args = implode(',',$args);
280          } else {
281               $args = '';
282          }
283         
284          return
285          self::jsLoad('js/confirm-close.js').
286          '<script type="text/javascript">'."\n".
287          "//<![CDATA[\n".
288          "confirmClosePage = new confirmClose(".$args."); ".
289          "confirmClose.prototype.prompt = '".html::escapeJS(__('You have unsaved changes.'))."'; ".
290          "\n//]]>\n".
291          "</script>\n";
292     }
293     
294     public static function jsPageTabs($default=null)
295     {
296          if ($default) {
297               $default = "'".html::escapeJS($default)."'";
298          }
299         
300          return
301          self::jsLoad('js/jquery/jquery.pageTabs.js').
302          '<script type="text/javascript">'."\n".
303          "//<![CDATA[\n".
304          "\$(function() {\n".
305          "    \$.pageTabs(".$default.");\n".
306          "});\n".
307          "\n//]]>\n".
308          "</script>\n";
309     }
310     
311     public static function jsModal()
312     {
313          return
314          '<link rel="stylesheet" type="text/css" href="style/modal/modal.css" />'."\n".
315          self::jsLoad('js/jquery/jquery.modal.js').
316          '<script type="text/javascript">'."\n".
317          "//<![CDATA[\n".
318          self::jsVar('$.modal.prototype.params.loader_img','style/modal/loader.gif').
319          self::jsVar('$.modal.prototype.params.close_img','style/modal/close.png').
320          "\n//]]>\n".
321          "</script>\n";
322     }
323     
324     public static function jsColorPicker()
325     {
326          return
327          '<link rel="stylesheet" type="text/css" href="style/farbtastic/farbtastic.css" />'."\n".
328          self::jsLoad('js/jquery/jquery.farbtastic.js').
329          self::jsLoad('js/color-picker.js');
330     }
331     
332     public static function jsDatePicker()
333     {
334          return
335          '<link rel="stylesheet" type="text/css" href="style/date-picker.css" />'."\n".
336          self::jsLoad('js/date-picker.js').
337          '<script type="text/javascript">'."\n".
338          "//<![CDATA[\n".
339         
340          "datePicker.prototype.months[0] = '".html::escapeJS(__('January'))."'; ".
341          "datePicker.prototype.months[1] = '".html::escapeJS(__('February'))."'; ".
342          "datePicker.prototype.months[2] = '".html::escapeJS(__('March'))."'; ".
343          "datePicker.prototype.months[3] = '".html::escapeJS(__('April'))."'; ".
344          "datePicker.prototype.months[4] = '".html::escapeJS(__('May'))."'; ".
345          "datePicker.prototype.months[5] = '".html::escapeJS(__('June'))."'; ".
346          "datePicker.prototype.months[6] = '".html::escapeJS(__('July'))."'; ".
347          "datePicker.prototype.months[7] = '".html::escapeJS(__('August'))."'; ".
348          "datePicker.prototype.months[8] = '".html::escapeJS(__('September'))."'; ".
349          "datePicker.prototype.months[9] = '".html::escapeJS(__('October'))."'; ".
350          "datePicker.prototype.months[10] = '".html::escapeJS(__('November'))."'; ".
351          "datePicker.prototype.months[11] = '".html::escapeJS(__('December'))."'; ".
352         
353          "datePicker.prototype.days[0] = '".html::escapeJS(__('Monday'))."'; ".
354          "datePicker.prototype.days[1] = '".html::escapeJS(__('Tuesday'))."'; ".
355          "datePicker.prototype.days[2] = '".html::escapeJS(__('Wednesday'))."'; ".
356          "datePicker.prototype.days[3] = '".html::escapeJS(__('Thursday'))."'; ".
357          "datePicker.prototype.days[4] = '".html::escapeJS(__('Friday'))."'; ".
358          "datePicker.prototype.days[5] = '".html::escapeJS(__('Saturday'))."'; ".
359          "datePicker.prototype.days[6] = '".html::escapeJS(__('Sunday'))."'; ".
360         
361          "datePicker.prototype.img_src = 'images/date-picker.png'; ".
362         
363          "datePicker.prototype.close_msg = '".html::escapeJS(__('close'))."'; ".
364          "datePicker.prototype.now_msg = '".html::escapeJS(__('now'))."'; ".
365         
366          "\n//]]>\n".
367          "</script>\n";
368     }
369     
370     public static function jsToolBar()
371     {
372          $res =
373          '<link rel="stylesheet" type="text/css" href="style/jsToolBar/jsToolBar.css" />'.
374          '<script type="text/javascript" src="js/jsToolBar/jsToolBar.js"></script>';
375         
376          if (isset($GLOBALS['core']->auth) && $GLOBALS['core']->auth->getOption('enable_wysiwyg')) {
377               $res .= '<script type="text/javascript" src="js/jsToolBar/jsToolBar.wysiwyg.js"></script>';
378          }
379         
380          $res .=
381          '<script type="text/javascript" src="js/jsToolBar/jsToolBar.dotclear.js"></script>'.
382          '<script type="text/javascript">'."\n".
383          "//<![CDATA[\n".
384          "jsToolBar.prototype.dialog_url = 'popup.php'; ".
385          "jsToolBar.prototype.iframe_css = '".
386               'body{'.
387                    'font: 12px "DejaVu Sans","Lucida Grande","Lucida Sans Unicode",Arial,sans-serif;'.
388                    'color : #000;'.
389                    'background: #f9f9f9;'.
390                    'margin: 0;'.
391                    'padding : 2px;'.
392                    'border: none;'.
393                    (l10n::getTextDirection($GLOBALS['_lang']) == 'rtl' ? 'direction:rtl;' : '').
394               '}'.
395               'pre, code, kbd, samp {'.
396                    'font-family:"Courier New",Courier,monospace;'.
397                    'font-size : 1.1em;'.
398               '}'.
399               'code {'.
400                    'color : #666;'.
401                    'font-weight : bold;'.
402               '}'.
403               'body > p:first-child {'.
404                    'margin-top: 0;'.
405               '}'.
406          "'; ".
407          "jsToolBar.prototype.base_url = '".html::escapeJS($GLOBALS['core']->blog->host)."'; ".
408          "jsToolBar.prototype.switcher_visual_title = '".html::escapeJS(__('visual'))."'; ".
409          "jsToolBar.prototype.switcher_source_title = '".html::escapeJS(__('source'))."'; ".
410          "jsToolBar.prototype.legend_msg = '".
411          html::escapeJS(__('You can use the following shortcuts to format your text.'))."'; ".
412          "jsToolBar.prototype.elements.blocks.options.none = '".html::escapeJS(__('-- none --'))."'; ".
413          "jsToolBar.prototype.elements.blocks.options.nonebis = '".html::escapeJS(__('-- block format --'))."'; ".
414          "jsToolBar.prototype.elements.blocks.options.p = '".html::escapeJS(__('Paragraph'))."'; ".
415          "jsToolBar.prototype.elements.blocks.options.h1 = '".html::escapeJS(__('Level 1 header'))."'; ".
416          "jsToolBar.prototype.elements.blocks.options.h2 = '".html::escapeJS(__('Level 2 header'))."'; ".
417          "jsToolBar.prototype.elements.blocks.options.h3 = '".html::escapeJS(__('Level 3 header'))."'; ".
418          "jsToolBar.prototype.elements.blocks.options.h4 = '".html::escapeJS(__('Level 4 header'))."'; ".
419          "jsToolBar.prototype.elements.blocks.options.h5 = '".html::escapeJS(__('Level 5 header'))."'; ".
420          "jsToolBar.prototype.elements.blocks.options.h6 = '".html::escapeJS(__('Level 6 header'))."'; ".
421          "jsToolBar.prototype.elements.strong.title = '".html::escapeJS(__('Strong emphasis'))."'; ".
422          "jsToolBar.prototype.elements.em.title = '".html::escapeJS(__('Emphasis'))."'; ".
423          "jsToolBar.prototype.elements.ins.title = '".html::escapeJS(__('Inserted'))."'; ".
424          "jsToolBar.prototype.elements.del.title = '".html::escapeJS(__('Deleted'))."'; ".
425          "jsToolBar.prototype.elements.quote.title = '".html::escapeJS(__('Inline quote'))."'; ".
426          "jsToolBar.prototype.elements.code.title = '".html::escapeJS(__('Code'))."'; ".
427          "jsToolBar.prototype.elements.br.title = '".html::escapeJS(__('Line break'))."'; ".
428          "jsToolBar.prototype.elements.blockquote.title = '".html::escapeJS(__('Blockquote'))."'; ".
429          "jsToolBar.prototype.elements.pre.title = '".html::escapeJS(__('Preformated text'))."'; ".
430          "jsToolBar.prototype.elements.ul.title = '".html::escapeJS(__('Unordered list'))."'; ".
431          "jsToolBar.prototype.elements.ol.title = '".html::escapeJS(__('Ordered list'))."'; ".
432         
433          "jsToolBar.prototype.elements.link.title = '".html::escapeJS(__('Link'))."'; ".
434          "jsToolBar.prototype.elements.link.href_prompt = '".html::escapeJS(__('URL?'))."'; ".
435          "jsToolBar.prototype.elements.link.hreflang_prompt = '".html::escapeJS(__('Language?'))."'; ".
436         
437          "jsToolBar.prototype.elements.img.title = '".html::escapeJS(__('External image'))."'; ".
438          "jsToolBar.prototype.elements.img.src_prompt = '".html::escapeJS(__('URL?'))."'; ".
439         
440          "jsToolBar.prototype.elements.img_select.title = '".html::escapeJS(__('Media chooser'))."'; ".
441          "jsToolBar.prototype.elements.post_link.title = '".html::escapeJS(__('Link to an entry'))."'; ";
442         
443          if (!$GLOBALS['core']->auth->check('media,media_admin',$GLOBALS['core']->blog->id)) {
444               $res .= "jsToolBar.prototype.elements.img_select.disabled = true;\n";
445          }
446         
447          $res .=
448          "\n//]]>\n".
449          "</script>\n";
450         
451          return $res;
452     }
453     
454     public static function jsUpload($params=array(),$base_url=null)
455     {
456          if (!$base_url) {
457               $base_url = path::clean(dirname(preg_replace('/(\?.*$)?/','',$_SERVER['REQUEST_URI']))).'/';
458          }
459         
460          $params = array_merge($params,array(
461               'sess_id='.session_id(),
462               'sess_uid='.$_SESSION['sess_browser_uid'],
463               'xd_check='.$GLOBALS['core']->getNonce()
464          ));
465         
466          return
467          '<link rel="stylesheet" type="text/css" href="style/jsUpload/style.css" />'."\n".
468
469    '<script id="template-upload" type="text/x-tmpl">
470{% for (var i=0, file; file=o.files[i]; i++) { %}
471    <tr class="template-upload fade">
472        <td>
473            <span class="preview"></span>
474        </td>
475        <td>
476            <p class="name">{%=file.name%}</p>
477            {% if (file.error) { %}
478                <div><span class="label label-error">'.__('Error:').'</span> {%=file.error%}</div>
479            {% } %}
480        </td>
481        <td>
482            <p class="size">{%=o.formatFileSize(file.size)%}</p>
483            {% if (!o.files.error) { %}
484                <div class="progress progress-success progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><div class="bar" style="width:0%;"></div></div>
485            {% } %}
486        </td>
487        <td>
488            {% if (!o.files.error && !i && !o.options.autoUpload) { %}
489                <input type="submit" class="button start" value="'.__('Send').'"/>
490            {% } %}
491        </td>
492    </tr>
493{% } %}
494</script>
495<!-- The template to display files available for download -->
496<script id="template-download" type="text/x-tmpl">
497{% for (var i=0, file; file=o.files[i]; i++) { %}
498    <tr class="template-download fade">
499        <td>
500            <span class="preview">
501                {% if (file.thumbnail_url) { %}
502                    <a href="{%=file.url%}" title="{%=file.name%}" data-gallery="gallery" download="{%=file.name%}"><img src="{%=file.thumbnail_url%}"></a>
503                {% } %}
504            </span>
505        </td>
506        <td>
507            <p class="name">{%=file.name%}</p>
508            {% if (file.error) { %}
509                <div><span class="label label-important">'.__('Error:').'</span> {%=file.error%}</div>
510            {% } %}
511        </td>
512        <td>
513            <span class="size">{%=o.formatFileSize(file.size)%}</span>
514        </td>
515        <td>
516            {% if (file.error) { %}
517            <span class="upload-status error"></span>
518            {% } else { %}
519            <span class="upload-status ok"></span>
520            {% } %}
521        </td>
522    </tr>
523{% } %}
524</script>'.
525
526          self::jsLoad('js/jsUpload/vendor/jquery.ui.widget.js').
527    self::jsLoad('js/jsUpload/tmpl.js').
528    self::jsLoad('js/jsUpload/load-image.js').
529          self::jsLoad('js/jsUpload/jquery.iframe-transport.js').
530          self::jsLoad('js/jsUpload/jquery.fileupload.js').
531          self::jsLoad('js/jsUpload/jquery.fileupload-process.js').
532          self::jsLoad('js/jsUpload/jquery.fileupload-resize.js').
533          self::jsLoad('js/jsUpload/jquery.fileupload-ui.js').
534         
535          '<script type="text/javascript">'."\n".
536          "//<![CDATA[\n".
537          "dotclear.jsUpload = {};\n".
538          "dotclear.jsUpload.msg = {};\n".
539          self::jsVar('dotclear.jsUpload.msg.limit_exceeded',__('Limit exceeded.')).
540          self::jsVar('dotclear.jsUpload.msg.size_limit_exceeded',__('File size exceeds allowed limit.')).
541          self::jsVar('dotclear.jsUpload.msg.canceled',__('Canceled.')).
542          self::jsVar('dotclear.jsUpload.msg.http_error',__('HTTP Error:')).
543          self::jsVar('dotclear.jsUpload.msg.error',__('Error:')).
544          self::jsVar('dotclear.jsUpload.msg.choose_file',__('Choose file')).
545          self::jsVar('dotclear.jsUpload.msg.choose_files',__('Choose files')).
546          self::jsVar('dotclear.jsUpload.msg.cancel',__('Cancel')).
547          self::jsVar('dotclear.jsUpload.msg.clean',__('Clean')).
548          self::jsVar('dotclear.jsUpload.msg.upload',__('Upload')).
549          self::jsVar('dotclear.jsUpload.msg.no_file_in_queue',__('No file in queue.')).
550          self::jsVar('dotclear.jsUpload.msg.file_in_queue',__('1 file in queue.')).
551          self::jsVar('dotclear.jsUpload.msg.files_in_queue',__('%d files in queue.')).
552          self::jsVar('dotclear.jsUpload.msg.queue_error',__('Queue error:')).
553          self::jsVar('dotclear.jsUpload.base_url',$base_url).
554          "\n//]]>\n".
555          "</script>\n";
556     }
557     
558     public static function jsToolMan()
559     {
560          return
561          '<script type="text/javascript" src="js/tool-man/core.js"></script>'.
562          '<script type="text/javascript" src="js/tool-man/events.js"></script>'.
563          '<script type="text/javascript" src="js/tool-man/css.js"></script>'.
564          '<script type="text/javascript" src="js/tool-man/coordinates.js"></script>'.
565          '<script type="text/javascript" src="js/tool-man/drag.js"></script>'.
566          '<script type="text/javascript" src="js/tool-man/dragsort.js"></script>'.
567          '<script type="text/javascript" src="js/dragsort-tablerows.js"></script>';
568     }
569     
570     public static function jsMetaEditor()
571     {
572          return
573          '<script type="text/javascript" src="js/meta-editor.js"></script>';
574     }
575}
576?>
Note: See TracBrowser for help on using the repository browser.

Sites map