Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 6ca21978

Von Moritz Bunkus vor fast 12 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
);
my %supported_methods = (
# ## jQuery basics ##
# Basic effects
hide => 1,
show => 1,
......
# Data storage
data => 3,
removeData => 2,
# ## jstree plugin ## pattern: $.jstree._reference($(<TARGET>)).<FUNCTION>(<ARGS>)
# Operations on the whole tree
'jstree:lock' => 1,
'jstree:unlock' => 1,
# Opening and closing nodes
'jstree:open_node' => 2,
'jstree:open_all' => 2,
'jstree:close_node' => 2,
'jstree:close_all' => 2,
'jstree:toggle_node' => 2,
'jstree:save_opened' => 1,
'jstree:reopen' => 1,
# Modifying nodes
'jstree:rename_node' => 3,
'jstree:delete_node' => 2,
'jstree:move_node' => 5,
# Selecting nodes (from the 'ui' plugin to jstree)
'jstree:select_node' => 2, # $.jstree._reference($(<TARGET>)).<FUNCTION>(<ARGS>, true)
'jstree:deselect_node' => 2,
'jstree:deselect_all' => 1,
);
sub AUTOLOAD {
......
$method =~ s/.*:://;
return if $method eq 'DESTROY';
$method = (delete($self->{_prefix}) || '') . $method;
my $num_args = $supported_methods{$method};
$::lxdebug->message(0, "autoload method $method");
croak "Unsupported jQuery action: $method" unless defined $num_args;
croak "Parameter count mismatch for $method(actual: " . scalar(@args) . " wanted: $num_args)" if scalar(@args) != $num_args;
......
return $controller->render(\$self->to_json, { type => 'json' });
}
sub jstree {
my ($self) = @_;
$self->{_prefix} = 'jstree:';
return $self;
}
1;
__END__
......
my $html = $self->render('SomeController/the_action', { output => 0 });
$js->html('#id_with_new_content', $html);
# Operations on a jstree: rename a node and select it
my $text_block = SL::DB::RequirementSpecTextBlock->new(id => 4711)->load;
$js->jstree->rename_node('#tb-' . $text_block->id, $text_block->title)
->jstree->select_node('#tb-' . $text_block->id);
# Finally render the JSON response:
$self->render($js);
# Rendering can also be chained, e.g.
$js->html('#selector', $html)
->render($self);
}
=head1 OVERVIEW
......
$controller->render(\$self->to_json, { type => 'json' });
=item C<jstree>
Tells C<$self> that the next action is to be called on a jstree
instance. For example:
$js->jstree->rename_node('tb-' . $text_block->id, $text_block->title);
=back
=head1 FUNCTIONS EVALUATED ON THE CLIENT SIDE
......
=back
=head2 JSTREE JQUERY PLUGIN
The following functions of the C<jstree> plugin to jQuery are
supported:
=over 4
=item Operations on the whole tree
C<lock>, C<unlock>
=item Opening and closing nodes
C<open_node>, C<close_node>, C<toggle_node>, C<open_all>,
C<close_all>, C<save_opened>, C<reopen>
=item Modifying nodes
C<rename_node>, C<delete_node>, C<move_node>
=item Selecting nodes (from the 'ui' jstree plugin)
C<select_node>, C<deselect_node>, C<deselect_all>
=back
=head1 ADDING SUPPORT FOR ADDITIONAL FUNCTIONS
In order not having to maintain two files (this one and
C<js/client_js.js>) there's a script that can parse this file's
C<%supported_methods> definition and convert it into the appropriate
code ready for manual insertion into C<js/client_js.js>. The steps
are:
C<%supported_methods> definition and generate the file
C<js/client_js.js> accordingly. The steps are:
=over 2
......
key is the function name and the value is the number of expected
parameters.
=item 2. Run C<scripts/generate_client_js_actions.pl>
=item 2. Run C<scripts/generate_client_js_actions.pl>. It will
generate C<js/client_js.js> automatically.
=item 3. Edit C<js/client_js.js> and replace the type casing code with
the output generated in step 2.
=item 3. Reload the files in your browser (cleaning its cache can also
help).
=back
The template file used for generated C<js/client_js.js> is
C<scripts/generate_client_js_actions.tpl>.
=head1 BUGS
Nothing here yet.
js/client_js.js
// NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE:
// Generate the dispatching lines in this script by running
// This file is generated automatically by the script
// "scripts/generate_client_js_actions.pl". See the documentation for
// SL/ClientJS.pm for instructions.
......
$(data.eval_actions).each(function(idx, action) {
// console.log("ACTION " + action[0] + " ON " + action[1]);
// ## jQuery basics ##
// Basic effects
if (action[0] == 'hide') $(action[1]).hide();
else if (action[0] == 'show') $(action[1]).show();
else if (action[0] == 'toggle') $(action[1]).toggle();
if (action[0] == 'hide') $(action[1]).hide();
else if (action[0] == 'show') $(action[1]).show();
else if (action[0] == 'toggle') $(action[1]).toggle();
// DOM insertion, around
else if (action[0] == 'unwrap') $(action[1]).unwrap();
else if (action[0] == 'wrap') $(action[1]).wrap(action[2]);
else if (action[0] == 'wrapAll') $(action[1]).wrapAll(action[2]);
else if (action[0] == 'wrapInner') $(action[1]).wrapInner(action[2]);
else if (action[0] == 'unwrap') $(action[1]).unwrap();
else if (action[0] == 'wrap') $(action[1]).wrap(action[2]);
else if (action[0] == 'wrapAll') $(action[1]).wrapAll(action[2]);
else if (action[0] == 'wrapInner') $(action[1]).wrapInner(action[2]);
// DOM insertion, inside
else if (action[0] == 'append') $(action[1]).append(action[2]);
else if (action[0] == 'appendTo') $(action[1]).appendTo(action[2]);
else if (action[0] == 'html') $(action[1]).html(action[2]);
else if (action[0] == 'prepend') $(action[1]).prepend(action[2]);
else if (action[0] == 'prependTo') $(action[1]).prependTo(action[2]);
else if (action[0] == 'text') $(action[1]).text(action[2]);
else if (action[0] == 'append') $(action[1]).append(action[2]);
else if (action[0] == 'appendTo') $(action[1]).appendTo(action[2]);
else if (action[0] == 'html') $(action[1]).html(action[2]);
else if (action[0] == 'prepend') $(action[1]).prepend(action[2]);
else if (action[0] == 'prependTo') $(action[1]).prependTo(action[2]);
else if (action[0] == 'text') $(action[1]).text(action[2]);
// DOM insertion, outside
else if (action[0] == 'after') $(action[1]).after(action[2]);
else if (action[0] == 'before') $(action[1]).before(action[2]);
else if (action[0] == 'insertAfter') $(action[1]).insertAfter(action[2]);
else if (action[0] == 'insertBefore') $(action[1]).insertBefore(action[2]);
else if (action[0] == 'after') $(action[1]).after(action[2]);
else if (action[0] == 'before') $(action[1]).before(action[2]);
else if (action[0] == 'insertAfter') $(action[1]).insertAfter(action[2]);
else if (action[0] == 'insertBefore') $(action[1]).insertBefore(action[2]);
// DOM removal
else if (action[0] == 'empty') $(action[1]).empty();
else if (action[0] == 'remove') $(action[1]).remove();
else if (action[0] == 'empty') $(action[1]).empty();
else if (action[0] == 'remove') $(action[1]).remove();
// DOM replacement
else if (action[0] == 'replaceAll') $(action[1]).replaceAll(action[2]);
else if (action[0] == 'replaceWith') $(action[1]).replaceWith(action[2]);
else if (action[0] == 'replaceAll') $(action[1]).replaceAll(action[2]);
else if (action[0] == 'replaceWith') $(action[1]).replaceWith(action[2]);
// General attributes
else if (action[0] == 'attr') $(action[1]).attr(action[2], action[3]);
else if (action[0] == 'prop') $(action[1]).prop(action[2], action[3]);
else if (action[0] == 'removeAttr') $(action[1]).removeAttr(action[2]);
else if (action[0] == 'removeProp') $(action[1]).removeProp(action[2]);
else if (action[0] == 'val') $(action[1]).val(action[2]);
else if (action[0] == 'attr') $(action[1]).attr(action[2], action[3]);
else if (action[0] == 'prop') $(action[1]).prop(action[2], action[3]);
else if (action[0] == 'removeAttr') $(action[1]).removeAttr(action[2]);
else if (action[0] == 'removeProp') $(action[1]).removeProp(action[2]);
else if (action[0] == 'val') $(action[1]).val(action[2]);
// Data storage
else if (action[0] == 'data') $(action[1]).data(action[2], action[3]);
else if (action[0] == 'removeData') $(action[1]).removeData(action[2]);
else if (action[0] == 'data') $(action[1]).data(action[2], action[3]);
else if (action[0] == 'removeData') $(action[1]).removeData(action[2]);
// ## jstree plugin ##
// Operations on the whole tree
else if (action[0] == 'jstree:lock') $.jstree._reference($(action[1])).lock();
else if (action[0] == 'jstree:unlock') $.jstree._reference($(action[1])).unlock();
// Opening and closing nodes
else if (action[0] == 'jstree:open_node') $.jstree._reference($(action[1])).open_node(action[2]);
else if (action[0] == 'jstree:open_all') $.jstree._reference($(action[1])).open_all(action[2]);
else if (action[0] == 'jstree:close_node') $.jstree._reference($(action[1])).close_node(action[2]);
else if (action[0] == 'jstree:close_all') $.jstree._reference($(action[1])).close_all(action[2]);
else if (action[0] == 'jstree:toggle_node') $.jstree._reference($(action[1])).toggle_node(action[2]);
else if (action[0] == 'jstree:save_opened') $.jstree._reference($(action[1])).save_opened();
else if (action[0] == 'jstree:reopen') $.jstree._reference($(action[1])).reopen();
// Modifying nodes
else if (action[0] == 'jstree:rename_node') $.jstree._reference($(action[1])).rename_node(action[2], action[3]);
else if (action[0] == 'jstree:delete_node') $.jstree._reference($(action[1])).delete_node(action[2]);
else if (action[0] == 'jstree:move_node') $.jstree._reference($(action[1])).move_node(action[2], action[3], action[4], action[5]);
// Selecting nodes (from the 'ui' plugin to jstree)
else if (action[0] == 'jstree:select_node') $.jstree._reference($(action[1])).select_node(action[2], true);
else if (action[0] == 'jstree:deselect_node') $.jstree._reference($(action[1])).deselect_node(action[2]);
else if (action[0] == 'jstree:deselect_all') $.jstree._reference($(action[1])).deselect_all();
else console.log('Unknown action: ' + action[0]);
else console.log("Unknown action: " + action[0]);
});
console.log("current_content_type " + $('#current_content_type').val() + ' ID ' + $('#current_content_id').val());
// console.log("current_content_type " + $('#current_content_type').val() + ' ID ' + $('#current_content_id').val());
}
scripts/generate_client_js_actions.pl
use File::Slurp;
use List::Util qw(first max);
use Template;
my $file_name = (first { -f } qw(SL/ClientJS.pm ../SL/ClientJS.pm)) || die "ClientJS.pm not found";
my $rel_dir = (first { -f "${_}/SL/ClientJS.pm" } qw(. ..)) || die "ClientJS.pm not found";
my @actions;
foreach (read_file($file_name)) {
foreach (read_file("${rel_dir}/SL/ClientJS.pm")) {
chomp;
next unless (m/^my \%supported_methods/ .. m/^\);/);
push @actions, [ 'action', $1, $2 ] if m/^\s+([a-zA-Z]+)\s*=>\s*(\d+),$/;
push @actions, [ 'comment', $1 ] if m/^\s+#\s+(.+)/;
push @actions, [ 'action', $1, $2, $3 ] if m/^ \s+ '? ([a-zA-Z_:]+) '? \s*=>\s* (\d+) , (?: \s* \# \s+ (.+))? $/x;
push @actions, [ 'comment', $1, $2 ] if m/^ \s+\# \s+ (.+?) (?: \s* pattern: \s+ (.+))? $/x;
}
my $longest = max map { length($_->[1]) } grep { $_->[0] eq 'action' } @actions;
my $first = 1;
my $output;
my $longest = max map { length($_->[1]) } grep { $_->[0] eq 'action' } @actions;
my $first = 1;
my $default_pattern = '$(<TARGET>).<FUNCTION>(<ARGS>)';
my $pattern = $default_pattern;
my $output = '';
# else if (action[0] == 'hide') $(action[1]).hide();
foreach my $action (@actions) {
if ($action->[0] eq 'comment') {
print "\n" unless $first;
print " // ", $action->[1], "\n";
$output .= "\n" unless $first;
$output .= " // " . $action->[1] . "\n";
$pattern = $action->[2] eq '<DEFAULT>' ? $default_pattern : $action->[2] if $action->[2];
} else {
my $args = $action->[2] == 1 ? '' : join(', ', map { "action[$_]" } (2..$action->[2]));
printf(' %s if (action[0] == \'%s\')%s $(action[1]).%s(%s);' . "\n",
$first ? ' ' : 'else',
$action->[1],
' ' x ($longest - length($action->[1])),
$action->[1],
$args);
$first = 0;
$output .= sprintf(' %s if (action[0] == \'%s\')%s ',
$first ? ' ' : 'else',
$action->[1],
' ' x ($longest - length($action->[1])));
my $function = $action->[1];
$function =~ s/.*://;
my $call = $action->[3] || $pattern;
$call =~ s/<TARGET>/'action[1]'/eg;
$call =~ s/<FUNCTION>/$function/eg;
$call =~ s/<ARGS>/$args/eg;
$output .= $call . ";\n";
$first = 0;
}
}
printf "\n else\%sconsole.log('Unknown action: ' + action[0]);\n", ' ' x (4 + 2 + 6 + 3 + 4 + 2 + $longest + 1);
$output .= sprintf "\n else\%sconsole.log('Unknown action: ' + action[0]);\n", ' ' x (4 + 2 + 6 + 3 + 4 + 2 + $longest + 1);
my $template = Template->new({ RELATIVE => 1 });
$template->process($rel_dir . '/scripts/generate_client_js_actions.tpl', { actions => $output }, $rel_dir . '/js/client_js.js') || die $template->error(), "\n";
print "js/client_js.js generated automatically.\n";
scripts/generate_client_js_actions.tpl
// NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE:
// This file is generated automatically by the script
// "scripts/generate_client_js_actions.pl". See the documentation for
// SL/ClientJS.pm for instructions.
function eval_json_result(data) {
if (!data)
return;
if ((data.js || '') != '')
eval(data.js);
if (data.eval_actions)
$(data.eval_actions).each(function(idx, action) {
// console.log("ACTION " + action[0] + " ON " + action[1]);
[% actions %]
});
// console.log("current_content_type " + $('#current_content_type').val() + ' ID ' + $('#current_content_id').val());
}

Auch abrufbar als: Unified diff