Revision a82f3bef
Von Moritz Bunkus vor etwa 11 Jahren hinzugefügt
SL/ClientJS.pm | ||
---|---|---|
13 | 13 |
); |
14 | 14 |
|
15 | 15 |
my %supported_methods = ( |
16 |
# ## Non-jQuery methods ## |
|
17 |
flash => 2, # kivi.display_flash(<TARGET>, <ARGS>) |
|
18 |
|
|
19 | 16 |
# ## jQuery basics ## |
20 | 17 |
|
21 | 18 |
# Basic effects |
... | ... | |
112 | 109 |
# ## other stuff ## |
113 | 110 |
redirect_to => 1, # window.location.href = <TARGET> |
114 | 111 |
|
112 |
flash => 2, # kivi.display_flash(<TARGET>, <ARGS>) |
|
115 | 113 |
reinit_widgets => 0, # kivi.reinit_widgets() |
114 |
run => -1, # kivi.run(<TARGET>, <ARGS>) |
|
115 |
run_once_for => 3, # kivi.run_once_for(<TARGET>, <ARGS>) |
|
116 | 116 |
); |
117 | 117 |
|
118 | 118 |
sub AUTOLOAD { |
... | ... | |
133 | 133 |
my $num_args = $supported_methods{$method}; |
134 | 134 |
|
135 | 135 |
croak "Unsupported jQuery action: $method" unless defined $num_args; |
136 |
croak "Parameter count mismatch for $method(actual: " . scalar(@args) . " wanted: $num_args)" if scalar(@args) != $num_args; |
|
136 |
|
|
137 |
if ($num_args > 0) { |
|
138 |
croak "Parameter count mismatch for $method(actual: " . scalar(@args) . " wanted: $num_args)" if scalar(@args) != $num_args; |
|
139 |
} else { |
|
140 |
$num_args *= -1; |
|
141 |
croak "Parameter count mismatch for $method(actual: " . scalar(@args) . " wanted at least: $num_args)" if scalar(@args) < $num_args; |
|
142 |
$num_args = scalar @args; |
|
143 |
} |
|
137 | 144 |
|
138 | 145 |
foreach my $idx (0..$num_args - 1) { |
139 | 146 |
# Force flattening from SL::Presenter::EscapedText and trim leading whitespace for scalars |
... | ... | |
447 | 454 |
|
448 | 455 |
=back |
449 | 456 |
|
457 |
=head2 KIVITENDO FUNCTIONS |
|
458 |
|
|
459 |
The following functions from the C<kivi> namespace are supported: |
|
460 |
|
|
461 |
=over 4 |
|
462 |
|
|
463 |
=item Displaying stuff |
|
464 |
|
|
465 |
C<flash> (don't call directly, use L</flash> instead) |
|
466 |
|
|
467 |
=item Running functions |
|
468 |
|
|
469 |
C<run>, C<run_once_for> |
|
470 |
|
|
471 |
=item Widgets |
|
472 |
|
|
473 |
C<reinit_widgets> |
|
474 |
|
|
475 |
=back |
|
476 |
|
|
450 | 477 |
=head2 JQUERY FUNCTIONS |
451 | 478 |
|
452 | 479 |
The following jQuery functions are supported: |
... | ... | |
481 | 508 |
|
482 | 509 |
C<attr>, C<prop>, C<removeAttr>, C<removeProp>, C<val> |
483 | 510 |
|
511 |
=item Class attributes |
|
512 |
|
|
513 |
C<addClass>, C<removeClass>, C<toggleClass> |
|
514 |
|
|
484 | 515 |
=item Data storage |
485 | 516 |
|
486 | 517 |
C<data>, C<removeData> |
... | ... | |
500 | 531 |
|
501 | 532 |
=back |
502 | 533 |
|
503 |
=head2 JSTREE JQUERY PLUGIN
|
|
534 |
=head2 JQUERY POPUP DIALOG PLUGIN
|
|
504 | 535 |
|
505 |
The following functions of the C<jstree> plugin to jQuery are |
|
536 |
Supported functions of the C<popup dialog> plugin to jQuery. They are |
|
537 |
invoked by first calling C<dialog> in the ClientJS instance and then |
|
538 |
the function itself: |
|
539 |
|
|
540 |
$js->dialog->close(...); |
|
541 |
|
|
542 |
=over 4 |
|
543 |
|
|
544 |
=item Closing and removing the popup |
|
545 |
|
|
546 |
C<close> |
|
547 |
|
|
548 |
=back |
|
549 |
|
|
550 |
=head2 AJAXFORM JQUERY PLUGIN |
|
551 |
|
|
552 |
The following functions of the C<ajaxForm> plugin to jQuery are |
|
506 | 553 |
supported: |
507 | 554 |
|
508 | 555 |
=over 4 |
509 | 556 |
|
557 |
=item All functions by the generic accessor function: |
|
558 |
|
|
559 |
C<ajaxForm> |
|
560 |
|
|
561 |
=back |
|
562 |
|
|
563 |
=head2 JSTREE JQUERY PLUGIN |
|
564 |
|
|
565 |
Supported functions of the C<jstree> plugin to jQuery. They are |
|
566 |
invoked by first calling C<jstree> in the ClientJS instance and then |
|
567 |
the function itself: |
|
568 |
|
|
569 |
$js->jstree->open_node(...); |
|
570 |
|
|
571 |
=over 4 |
|
572 |
|
|
510 | 573 |
=item Operations on the whole tree |
511 | 574 |
|
512 | 575 |
C<lock>, C<unlock> |
... | ... | |
537 | 600 |
|
538 | 601 |
=item 1. Add lines in this file to the C<%supported_methods> hash. The |
539 | 602 |
key is the function name and the value is the number of expected |
540 |
parameters. |
|
603 |
parameters. The value can be negative to indicate that the function |
|
604 |
takes at least the absolute of this value as parameters and optionally |
|
605 |
more. In such a case the C<E<lt>ARGSE<gt>> format expands to an actual |
|
606 |
array (and the individual elements if the value is positive>. |
|
541 | 607 |
|
542 | 608 |
=item 2. Run C<scripts/generate_client_js_actions.pl>. It will |
543 | 609 |
generate C<js/client_js.js> automatically. |
js/client_js.js | ||
---|---|---|
29 | 29 |
$(data.eval_actions).each(function(idx, action) { |
30 | 30 |
// console.log("ACTION " + action[0] + " ON " + action[1]); |
31 | 31 |
|
32 |
// ## Non-jQuery methods ## |
|
33 |
if (action[0] == 'flash') kivi.display_flash(action[1], action[2]); |
|
34 |
|
|
35 | 32 |
// ## jQuery basics ## |
36 |
|
|
37 | 33 |
// Basic effects |
38 |
else if (action[0] == 'hide') $(action[1]).hide();
|
|
34 |
if (action[0] == 'hide') $(action[1]).hide();
|
|
39 | 35 |
else if (action[0] == 'show') $(action[1]).show(); |
40 | 36 |
else if (action[0] == 'toggle') $(action[1]).toggle(); |
41 | 37 |
|
... | ... | |
127 | 123 |
|
128 | 124 |
// ## other stuff ## |
129 | 125 |
else if (action[0] == 'redirect_to') window.location.href = action[1]; |
126 |
else if (action[0] == 'flash') kivi.display_flash(action[1], action[2]); |
|
130 | 127 |
else if (action[0] == 'reinit_widgets') kivi.reinit_widgets(); |
128 |
else if (action[0] == 'run') kivi.run(action[1], action.slice(2, action.length)); |
|
129 |
else if (action[0] == 'run_once_for') kivi.run_once_for(action[1], action[2], action[3]); |
|
131 | 130 |
|
132 | 131 |
else console.log('Unknown action: ' + action[0]); |
133 | 132 |
|
js/kivi.js | ||
---|---|---|
99 | 99 |
|
100 | 100 |
return true; |
101 | 101 |
}; |
102 |
|
|
103 |
// Run code only once for each matched element |
|
104 |
// |
|
105 |
// This allows running the function 'code' exactly once for each |
|
106 |
// element that matches 'selector'. This is achieved by storing the |
|
107 |
// state with jQuery's 'data' function. The 'identification' is |
|
108 |
// required for differentiating unambiguously so that different code |
|
109 |
// functions can still be run on the same elements. |
|
110 |
// |
|
111 |
// 'code' can be either a function or the name of one. It must |
|
112 |
// resolve to a function that receives the jQueryfied element as its |
|
113 |
// sole argument. |
|
114 |
// |
|
115 |
// Returns nothing. |
|
116 |
ns.run_once_for = function(selector, identification, code) { |
|
117 |
var attr_name = 'data-run-once-for-' + identification.toLowerCase().replace(/[^a-z]+/g, '-'); |
|
118 |
var fn = typeof code === 'function' ? code : ns.get_function_by_name(code); |
|
119 |
if (!fn) { |
|
120 |
console.error('kivi.run_once_for(..., "' + code + '"): No function by that name found'); |
|
121 |
return; |
|
122 |
} |
|
123 |
|
|
124 |
$(selector).filter(function() { return $(this).data(attr_name) != true; }).each(function(idx, elt) { |
|
125 |
var $elt = $(elt); |
|
126 |
$elt.data(attr_name, true); |
|
127 |
fn($elt); |
|
128 |
}); |
|
129 |
}; |
|
130 |
|
|
131 |
// Run a function by its name passing it some arguments |
|
132 |
// |
|
133 |
// This is a function useful mainly for the ClientJS functionality. |
|
134 |
// It finds a function by its name and then executes it on an empty |
|
135 |
// object passing the elements in 'args' (an array) as the function |
|
136 |
// parameters retuning its result. |
|
137 |
// |
|
138 |
// Logs an error to the console and returns 'undefined' if the |
|
139 |
// function cannot be found. |
|
140 |
ns.run = function(function_name, args) { |
|
141 |
var fn = ns.get_function_by_name(function_name); |
|
142 |
if (fn) |
|
143 |
return fn.apply({}, args); |
|
144 |
|
|
145 |
console.error('kivi.run("' + function_name + '"): No function by that name found'); |
|
146 |
return undefined; |
|
147 |
}; |
|
102 | 148 |
}); |
103 | 149 |
|
104 | 150 |
kivi = namespace('kivi'); |
scripts/generate_client_js_actions.pl | ||
---|---|---|
15 | 15 |
|
16 | 16 |
next unless (m/^my \%supported_methods/ .. m/^\);/); |
17 | 17 |
|
18 |
push @actions, [ 'action', $1, $2, $3 ] if m/^ \s+ '? ([a-zA-Z_:]+) '? \s*=>\s* (\d+) , (?: \s* \# \s+ (.+))? $/x; |
|
18 |
push @actions, [ 'action', $1, $2, $3 ] if m/^ \s+ '? ([a-zA-Z_:]+) '? \s*=>\s* (-? \d+) , (?: \s* \# \s+ (.+))? $/x;
|
|
19 | 19 |
push @actions, [ 'comment', $1, $2 ] if m/^ \s+\# \s+ (.+?) (?: \s* pattern: \s+ (.+))? $/x; |
20 | 20 |
} |
21 | 21 |
|
... | ... | |
33 | 33 |
$pattern = $action->[2] eq '<DEFAULT>' ? $default_pattern : $action->[2] if $action->[2]; |
34 | 34 |
|
35 | 35 |
} else { |
36 |
my $args = $action->[2] == 1 ? '' : join(', ', map { "action[$_]" } (2..$action->[2])); |
|
36 |
my $args = $action->[2] == 1 ? '' |
|
37 |
: $action->[2] < 0 ? 'action.slice(2, action.length)' |
|
38 |
: join(', ', map { "action[$_]" } (2..$action->[2])); |
|
37 | 39 |
|
38 | 40 |
$output .= sprintf(' %s if (action[0] == \'%s\')%s ', |
39 | 41 |
$first ? ' ' : 'else', |
Auch abrufbar als: Unified diff
ClientJS: neue Funktionen "run()", "run_once_for()"; Dokumentation