Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 6ca21978

Von Moritz Bunkus vor mehr als 11 Jahren hinzugefügt

  • ID 6ca2197818029fad5253edd8f08988ddc66aa359
  • Vorgänger 4d9d7d51
  • Nachfolger bb8964dd

ClientJS: um jstree-Funktionen erweitert; client_js.js komplett automatisch erzeugen

Unterschiede anzeigen:

SL/ClientJS.pm
13 13
);
14 14

  
15 15
my %supported_methods = (
16
  # ## jQuery basics ##
17

  
16 18
  # Basic effects
17 19
  hide         => 1,
18 20
  show         => 1,
......
56 58
  # Data storage
57 59
  data         => 3,
58 60
  removeData   => 2,
61

  
62
  # ## jstree plugin ## pattern: $.jstree._reference($(<TARGET>)).<FUNCTION>(<ARGS>)
63

  
64
  # Operations on the whole tree
65
  'jstree:lock'          => 1,
66
  'jstree:unlock'        => 1,
67

  
68
  # Opening and closing nodes
69
  'jstree:open_node'     => 2,
70
  'jstree:open_all'      => 2,
71
  'jstree:close_node'    => 2,
72
  'jstree:close_all'     => 2,
73
  'jstree:toggle_node'   => 2,
74
  'jstree:save_opened'   => 1,
75
  'jstree:reopen'        => 1,
76

  
77
  # Modifying nodes
78
  'jstree:rename_node'   => 3,
79
  'jstree:delete_node'   => 2,
80
  'jstree:move_node'     => 5,
81

  
82
  # Selecting nodes (from the 'ui' plugin to jstree)
83
  'jstree:select_node'   => 2,  # $.jstree._reference($(<TARGET>)).<FUNCTION>(<ARGS>, true)
84
  'jstree:deselect_node' => 2,
85
  'jstree:deselect_all'  => 1,
59 86
);
60 87

  
61 88
sub AUTOLOAD {
......
67 94
  $method           =~ s/.*:://;
68 95
  return if $method eq 'DESTROY';
69 96

  
97
  $method      =  (delete($self->{_prefix}) || '') . $method;
70 98
  my $num_args =  $supported_methods{$method};
71
  $::lxdebug->message(0, "autoload method $method");
72 99

  
73 100
  croak "Unsupported jQuery action: $method"                                                    unless defined $num_args;
74 101
  croak "Parameter count mismatch for $method(actual: " . scalar(@args) . " wanted: $num_args)" if     scalar(@args) != $num_args;
......
103 130
  return $controller->render(\$self->to_json, { type => 'json' });
104 131
}
105 132

  
133
sub jstree {
134
  my ($self) = @_;
135
  $self->{_prefix} = 'jstree:';
136
  return $self;
137
}
138

  
106 139
1;
107 140
__END__
108 141

  
......
152 185
    my $html = $self->render('SomeController/the_action', { output => 0 });
153 186
    $js->html('#id_with_new_content', $html);
154 187

  
188
    # Operations on a jstree: rename a node and select it
189
    my $text_block = SL::DB::RequirementSpecTextBlock->new(id => 4711)->load;
190
    $js->jstree->rename_node('#tb-' . $text_block->id, $text_block->title)
191
       ->jstree->select_node('#tb-' . $text_block->id);
192

  
155 193
    # Finally render the JSON response:
156 194
    $self->render($js);
195

  
196
    # Rendering can also be chained, e.g.
197
    $js->html('#selector', $html)
198
       ->render($self);
157 199
  }
158 200

  
159 201
=head1 OVERVIEW
......
210 252

  
211 253
  $controller->render(\$self->to_json, { type => 'json' });
212 254

  
255
=item C<jstree>
256

  
257
Tells C<$self> that the next action is to be called on a jstree
258
instance. For example:
259

  
260
  $js->jstree->rename_node('tb-' . $text_block->id, $text_block->title);
261

  
213 262
=back
214 263

  
215 264
=head1 FUNCTIONS EVALUATED ON THE CLIENT SIDE
......
254 303

  
255 304
=back
256 305

  
306
=head2 JSTREE JQUERY PLUGIN
307

  
308
The following functions of the C<jstree> plugin to jQuery are
309
supported:
310

  
311
=over 4
312

  
313
=item Operations on the whole tree
314

  
315
C<lock>, C<unlock>
316

  
317
=item Opening and closing nodes
318

  
319
C<open_node>, C<close_node>, C<toggle_node>, C<open_all>,
320
C<close_all>, C<save_opened>, C<reopen>
321

  
322
=item Modifying nodes
323

  
324
C<rename_node>, C<delete_node>, C<move_node>
325

  
326
=item Selecting nodes (from the 'ui' jstree plugin)
327

  
328
C<select_node>, C<deselect_node>, C<deselect_all>
329

  
330
=back
331

  
257 332
=head1 ADDING SUPPORT FOR ADDITIONAL FUNCTIONS
258 333

  
259 334
In order not having to maintain two files (this one and
260 335
C<js/client_js.js>) there's a script that can parse this file's
261
C<%supported_methods> definition and convert it into the appropriate
262
code ready for manual insertion into C<js/client_js.js>. The steps
263
are:
336
C<%supported_methods> definition and generate the file
337
C<js/client_js.js> accordingly. The steps are:
264 338

  
265 339
=over 2
266 340

  
......
268 342
key is the function name and the value is the number of expected
269 343
parameters.
270 344

  
271
=item 2. Run C<scripts/generate_client_js_actions.pl>
345
=item 2. Run C<scripts/generate_client_js_actions.pl>. It will
346
generate C<js/client_js.js> automatically.
272 347

  
273
=item 3. Edit C<js/client_js.js> and replace the type casing code with
274
the output generated in step 2.
348
=item 3. Reload the files in your browser (cleaning its cache can also
349
help).
275 350

  
276 351
=back
277 352

  
353
The template file used for generated C<js/client_js.js> is
354
C<scripts/generate_client_js_actions.tpl>.
355

  
278 356
=head1 BUGS
279 357

  
280 358
Nothing here yet.
js/client_js.js
1 1
// NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE:
2 2

  
3
// Generate the dispatching lines in this script by running
3
// This file is generated automatically by the script
4 4
// "scripts/generate_client_js_actions.pl". See the documentation for
5 5
// SL/ClientJS.pm for instructions.
6 6

  
......
15 15
    $(data.eval_actions).each(function(idx, action) {
16 16
      // console.log("ACTION " + action[0] + " ON " + action[1]);
17 17

  
18
      // ## jQuery basics ##
18 19
      // Basic effects
19
           if (action[0] == 'hide')         $(action[1]).hide();
20
      else if (action[0] == 'show')         $(action[1]).show();
21
      else if (action[0] == 'toggle')       $(action[1]).toggle();
20
           if (action[0] == 'hide')                 $(action[1]).hide();
21
      else if (action[0] == 'show')                 $(action[1]).show();
22
      else if (action[0] == 'toggle')               $(action[1]).toggle();
22 23

  
23 24
      // DOM insertion, around
24
      else if (action[0] == 'unwrap')       $(action[1]).unwrap();
25
      else if (action[0] == 'wrap')         $(action[1]).wrap(action[2]);
26
      else if (action[0] == 'wrapAll')      $(action[1]).wrapAll(action[2]);
27
      else if (action[0] == 'wrapInner')    $(action[1]).wrapInner(action[2]);
25
      else if (action[0] == 'unwrap')               $(action[1]).unwrap();
26
      else if (action[0] == 'wrap')                 $(action[1]).wrap(action[2]);
27
      else if (action[0] == 'wrapAll')              $(action[1]).wrapAll(action[2]);
28
      else if (action[0] == 'wrapInner')            $(action[1]).wrapInner(action[2]);
28 29

  
29 30
      // DOM insertion, inside
30
      else if (action[0] == 'append')       $(action[1]).append(action[2]);
31
      else if (action[0] == 'appendTo')     $(action[1]).appendTo(action[2]);
32
      else if (action[0] == 'html')         $(action[1]).html(action[2]);
33
      else if (action[0] == 'prepend')      $(action[1]).prepend(action[2]);
34
      else if (action[0] == 'prependTo')    $(action[1]).prependTo(action[2]);
35
      else if (action[0] == 'text')         $(action[1]).text(action[2]);
31
      else if (action[0] == 'append')               $(action[1]).append(action[2]);
32
      else if (action[0] == 'appendTo')             $(action[1]).appendTo(action[2]);
33
      else if (action[0] == 'html')                 $(action[1]).html(action[2]);
34
      else if (action[0] == 'prepend')              $(action[1]).prepend(action[2]);
35
      else if (action[0] == 'prependTo')            $(action[1]).prependTo(action[2]);
36
      else if (action[0] == 'text')                 $(action[1]).text(action[2]);
36 37

  
37 38
      // DOM insertion, outside
38
      else if (action[0] == 'after')        $(action[1]).after(action[2]);
39
      else if (action[0] == 'before')       $(action[1]).before(action[2]);
40
      else if (action[0] == 'insertAfter')  $(action[1]).insertAfter(action[2]);
41
      else if (action[0] == 'insertBefore') $(action[1]).insertBefore(action[2]);
39
      else if (action[0] == 'after')                $(action[1]).after(action[2]);
40
      else if (action[0] == 'before')               $(action[1]).before(action[2]);
41
      else if (action[0] == 'insertAfter')          $(action[1]).insertAfter(action[2]);
42
      else if (action[0] == 'insertBefore')         $(action[1]).insertBefore(action[2]);
42 43

  
43 44
      // DOM removal
44
      else if (action[0] == 'empty')        $(action[1]).empty();
45
      else if (action[0] == 'remove')       $(action[1]).remove();
45
      else if (action[0] == 'empty')                $(action[1]).empty();
46
      else if (action[0] == 'remove')               $(action[1]).remove();
46 47

  
47 48
      // DOM replacement
48
      else if (action[0] == 'replaceAll')   $(action[1]).replaceAll(action[2]);
49
      else if (action[0] == 'replaceWith')  $(action[1]).replaceWith(action[2]);
49
      else if (action[0] == 'replaceAll')           $(action[1]).replaceAll(action[2]);
50
      else if (action[0] == 'replaceWith')          $(action[1]).replaceWith(action[2]);
50 51

  
51 52
      // General attributes
52
      else if (action[0] == 'attr')         $(action[1]).attr(action[2], action[3]);
53
      else if (action[0] == 'prop')         $(action[1]).prop(action[2], action[3]);
54
      else if (action[0] == 'removeAttr')   $(action[1]).removeAttr(action[2]);
55
      else if (action[0] == 'removeProp')   $(action[1]).removeProp(action[2]);
56
      else if (action[0] == 'val')          $(action[1]).val(action[2]);
53
      else if (action[0] == 'attr')                 $(action[1]).attr(action[2], action[3]);
54
      else if (action[0] == 'prop')                 $(action[1]).prop(action[2], action[3]);
55
      else if (action[0] == 'removeAttr')           $(action[1]).removeAttr(action[2]);
56
      else if (action[0] == 'removeProp')           $(action[1]).removeProp(action[2]);
57
      else if (action[0] == 'val')                  $(action[1]).val(action[2]);
57 58

  
58 59
      // Data storage
59
      else if (action[0] == 'data')         $(action[1]).data(action[2], action[3]);
60
      else if (action[0] == 'removeData')   $(action[1]).removeData(action[2]);
60
      else if (action[0] == 'data')                 $(action[1]).data(action[2], action[3]);
61
      else if (action[0] == 'removeData')           $(action[1]).removeData(action[2]);
62

  
63
      // ## jstree plugin ##
64

  
65
      // Operations on the whole tree
66
      else if (action[0] == 'jstree:lock')          $.jstree._reference($(action[1])).lock();
67
      else if (action[0] == 'jstree:unlock')        $.jstree._reference($(action[1])).unlock();
68

  
69
      // Opening and closing nodes
70
      else if (action[0] == 'jstree:open_node')     $.jstree._reference($(action[1])).open_node(action[2]);
71
      else if (action[0] == 'jstree:open_all')      $.jstree._reference($(action[1])).open_all(action[2]);
72
      else if (action[0] == 'jstree:close_node')    $.jstree._reference($(action[1])).close_node(action[2]);
73
      else if (action[0] == 'jstree:close_all')     $.jstree._reference($(action[1])).close_all(action[2]);
74
      else if (action[0] == 'jstree:toggle_node')   $.jstree._reference($(action[1])).toggle_node(action[2]);
75
      else if (action[0] == 'jstree:save_opened')   $.jstree._reference($(action[1])).save_opened();
76
      else if (action[0] == 'jstree:reopen')        $.jstree._reference($(action[1])).reopen();
77

  
78
      // Modifying nodes
79
      else if (action[0] == 'jstree:rename_node')   $.jstree._reference($(action[1])).rename_node(action[2], action[3]);
80
      else if (action[0] == 'jstree:delete_node')   $.jstree._reference($(action[1])).delete_node(action[2]);
81
      else if (action[0] == 'jstree:move_node')     $.jstree._reference($(action[1])).move_node(action[2], action[3], action[4], action[5]);
82

  
83
      // Selecting nodes (from the 'ui' plugin to jstree)
84
      else if (action[0] == 'jstree:select_node')   $.jstree._reference($(action[1])).select_node(action[2], true);
85
      else if (action[0] == 'jstree:deselect_node') $.jstree._reference($(action[1])).deselect_node(action[2]);
86
      else if (action[0] == 'jstree:deselect_all')  $.jstree._reference($(action[1])).deselect_all();
87

  
88
      else                                          console.log('Unknown action: ' + action[0]);
61 89

  
62
      else                                  console.log("Unknown action: " + action[0]);
63 90
    });
64 91

  
65
  console.log("current_content_type " + $('#current_content_type').val() + ' ID ' + $('#current_content_id').val());
92
  // console.log("current_content_type " + $('#current_content_type').val() + ' ID ' + $('#current_content_id').val());
66 93
}
scripts/generate_client_js_actions.pl
5 5

  
6 6
use File::Slurp;
7 7
use List::Util qw(first max);
8
use Template;
8 9

  
9
my $file_name = (first { -f } qw(SL/ClientJS.pm ../SL/ClientJS.pm)) || die "ClientJS.pm not found";
10
my $rel_dir = (first { -f "${_}/SL/ClientJS.pm" } qw(. ..)) || die "ClientJS.pm not found";
10 11
my @actions;
11 12

  
12
foreach (read_file($file_name)) {
13
foreach (read_file("${rel_dir}/SL/ClientJS.pm")) {
13 14
  chomp;
14 15

  
15 16
  next unless (m/^my \%supported_methods/ .. m/^\);/);
16 17

  
17
  push @actions, [ 'action',  $1, $2 ] if m/^\s+([a-zA-Z]+)\s*=>\s*(\d+),$/;
18
  push @actions, [ 'comment', $1     ] if m/^\s+#\s+(.+)/;
18
  push @actions, [ 'action',  $1, $2, $3 ] if m/^ \s+ '? ([a-zA-Z_:]+) '? \s*=>\s* (\d+) , (?: \s* \# \s+ (.+))? $/x;
19
  push @actions, [ 'comment', $1, $2     ] if m/^ \s+\# \s+ (.+?) (?: \s* pattern: \s+ (.+))? $/x;
19 20
}
20 21

  
21
my $longest   = max map { length($_->[1]) } grep { $_->[0] eq 'action' } @actions;
22
my $first     = 1;
23
my $output;
22
my $longest         = max map { length($_->[1]) } grep { $_->[0] eq 'action' } @actions;
23
my $first           = 1;
24
my $default_pattern = '$(<TARGET>).<FUNCTION>(<ARGS>)';
25
my $pattern         = $default_pattern;
26
my $output          = '';
24 27

  
25
#      else if (action[0] == 'hide')        $(action[1]).hide();
26 28
foreach my $action (@actions) {
27 29
  if ($action->[0] eq 'comment') {
28
    print "\n" unless $first;
29
    print "      // ", $action->[1], "\n";
30
    $output .= "\n" unless $first;
31
    $output .= "      // " . $action->[1] . "\n";
32

  
33
    $pattern = $action->[2] eq '<DEFAULT>' ? $default_pattern : $action->[2] if $action->[2];
30 34

  
31 35
  } else {
32 36
    my $args = $action->[2] == 1 ? '' : join(', ', map { "action[$_]" } (2..$action->[2]));
33 37

  
34
    printf('      %s if (action[0] == \'%s\')%s $(action[1]).%s(%s);' . "\n",
35
           $first ? '    ' : 'else',
36
           $action->[1],
37
           ' ' x ($longest - length($action->[1])),
38
           $action->[1],
39
           $args);
40
    $first = 0;
38
    $output .= sprintf('      %s if (action[0] == \'%s\')%s ',
39
                       $first ? '    ' : 'else',
40
                       $action->[1],
41
                       ' ' x ($longest - length($action->[1])));
42

  
43
    my $function =  $action->[1];
44
    $function    =~ s/.*://;
45

  
46
    my $call     =  $action->[3] || $pattern;
47
    $call        =~ s/<TARGET>/'action[1]'/eg;
48
    $call        =~ s/<FUNCTION>/$function/eg;
49
    $call        =~ s/<ARGS>/$args/eg;
50

  
51
    $output .= $call . ";\n";
52
    $first   = 0;
41 53
  }
42 54
}
43 55

  
44
printf "\n      else\%sconsole.log('Unknown action: ' + action[0]);\n", ' ' x (4 + 2 + 6 + 3 + 4 + 2 + $longest + 1);
56
$output .= sprintf "\n      else\%sconsole.log('Unknown action: ' + action[0]);\n", ' ' x (4 + 2 + 6 + 3 + 4 + 2 + $longest + 1);
57

  
58
my $template = Template->new({ RELATIVE => 1 });
59
$template->process($rel_dir . '/scripts/generate_client_js_actions.tpl', { actions => $output }, $rel_dir . '/js/client_js.js') || die $template->error(), "\n";
60
print "js/client_js.js generated automatically.\n";
scripts/generate_client_js_actions.tpl
1
// NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE:
2

  
3
// This file is generated automatically by the script
4
// "scripts/generate_client_js_actions.pl". See the documentation for
5
// SL/ClientJS.pm for instructions.
6

  
7
function eval_json_result(data) {
8
  if (!data)
9
    return;
10

  
11
  if ((data.js || '') != '')
12
    eval(data.js);
13

  
14
  if (data.eval_actions)
15
    $(data.eval_actions).each(function(idx, action) {
16
      // console.log("ACTION " + action[0] + " ON " + action[1]);
17

  
18
[% actions %]
19
    });
20

  
21
  // console.log("current_content_type " + $('#current_content_type').val() + ' ID ' + $('#current_content_id').val());
22
}

Auch abrufbar als: Unified diff