don't forget that a javascript decorator isa JavaScript, so you can nest
them arbitrarily:

    public static class ThrottlingDecorator extends JavaScript {  <<<<<<<<
    }

JavaScript code = new WhateverDecorator(new ThrottlingDecorator(script));

i'm still not getting what you think is missing from this solution.  it
could be that i don't
understand the requirements fully, but this solution i'm proposing
definitely decorates
to any number of levels you want.


igor.vaynberg wrote:
> 
> im not getting the warm and fuzzy about this. i want to, but im not.
> 
> take our base query which has the similar success and failure points as my
> example. in order to facilitate those you still need the generic
> ajaxcalldecorator design because those placeholders are "inherited" across
> all layers, and JavaScript doesnt support this.
> 
> further what you have done is design a hierarchy where each layer builds
> on
> the previous. but that means each layer has to know the previous layers'
> class so it can override the proper places. this is not true in our ajax
> support. we need to be able to decorate things generically.
> 
> like what you have done today - add a parameter to the back of the url.
> well, maybe someone after you wants to do the same. and maybe someone
> after
> that as well. so it somehow needs to be generic, and i think something
> like
> 
> charsequence buildurl() {
>    return super.buildurl()+"&myparam=foo";
> }
> 
> is the only way to do that unfortunately. i dont see how JavaScript will
> make that easier.
> 
> maybe im just entirely missing the point.
> 
> -igor
> 
> 
> On 4/19/07, Jonathan Locke <[EMAIL PROTECTED]> wrote:
>>
>>
>>
>> oops i forgot the new virtual:
>>
>> class abstract CucumberQuery
>> {
>>     JavaScript getQuery() { return new JavaScript("cucumbers; ${middle};
>> moreCucumbers").merge(getMiddle()); }
>>
>>     protected abstract Javascript getMiddle();
>> }
>>
>>
>> Jonathan Locke wrote:
>> >
>> >
>> > yeah, it's a little tricky, but i think the inheritance hierarchy can
>> > provide the levels you're looking for (sort of as it does now) with
>> > overrides and calls to super.  i'm not sure exactly what you are asking
>> me
>> > to do, but the code might look like this (if i understand you right):
>> >
>> > class QueryGoogle
>> > {
>> >     JavaScript getScript()
>> >     {
>> >         final JavaScript script = new JavaScript("function
>> > wget(
>> http://www.google.com/q=${query},function(){${success}},function(){${failure}}
>> ");
>> >         return script.merge("query", getQuery(), "success",
>> getSuccess(),
>> > "failure", getFailure());
>> >     }
>> >
>> >     protected abstract JavaScript getQuery();
>> >     protected JavaScript getSuccess() { return JavaScript.EMPTY; }
>> >     protected JavaScript getFailure() { return JavaScript.EMPTY; }
>> > }
>> >
>> > class CucumberQuery
>> > {
>> >     JavaScript getQuery() { return new JavaScript("cucumbers"); }
>> > }
>> >
>> > class ThrottlingCucumberQuery extends CucumberQuery
>> > {
>> >     JavaScript getQuery() { return new
>> > ThrottlingDecorator(super.getQuery()); }
>> > }
>> >
>> > class NoTomatoAndAlertCucumberQuery extends CucumberQuery
>> > {
>> >     JavaScript noTomatoes = new JavaScript("...");
>> >     JavaScript alert = new JavaScript("...");
>> >     JavaScript getQuery() { return
>> > super.getQuery().append(noTomatoes).append(alert); }
>> > }
>> >
>> > Of course, if the cucumber script supports some kind of merging, it
>> would
>> > have to provide insertion points, like:
>> >
>> > class CucumberQuery
>> > {
>> >     JavaScript getQuery() { return new JavaScript("cucumbers;
>> ${middle};
>> > moreCucumbers"); }
>> > }
>> >
>> >
>> > igor.vaynberg wrote:
>> >>
>> >> so you got single level layering
>> >>
>> >> but what about multi level?
>> >>
>> >> lets say our default ajax behavior returns this:
>> >>
>> >>         JavaScript code = new JavaScript(
>> >>                 "function
>> >> wget(
>> http://www.google.com/q=${query},function(){${success}},function(){${failure}}
>> ");
>> >>
>> >> now something down the road wants to search google for cucumbers
>> >>
>> >> so it does
>> >>
>> >> return code.merge("query","cucumbers");
>> >>
>> >> something later down the road wants to exclude tomatoes from the
>> search
>> >> results, and also add an alert on failure, but since the previous
>> script
>> >> lost all the placeholders how would that work? i mean its really use
>> it
>> >> or
>> >> lose it.
>> >>
>> >> unless the previous script that added cucumbers now provides its own
>> >> placeholders for all the previous placeholders, but these need to be
>> >> factored into functions or some such.
>> >>
>> >> could you show me what that would look like with your code?
>> >>
>> >> so...
>> >>
>> >>         JavaScript code = new JavaScript(
>> >>                 "function
>> >> wget(
>> http://www.google.com/q=${query},function(){${success}},function(){${failure}}
>> ");
>> >>
>> >> one layer adds cucumbers to the query
>> >>
>> >> the next layer excludes tomatoes and adds an alert on failure
>> >>
>> >> -igor
>> >>
>> >>
>> >> On 4/19/07, Jonathan Locke <[EMAIL PROTECTED]> wrote:
>> >>>
>> >>>
>> >>>
>> >>> A throttling decorator would look like this:
>> >>>
>> >>>     public static class ThrottlingDecorator extends JavaScript {
>> >>>
>> >>>         private static final JavaScript THROTTLER = new JavaScript(
>> >>>                 "wicketThrottler.throttle('${id}', ${milliseconds},
>> >>> ${function});");
>> >>>
>> >>>         public ThrottlingDecorator(final String id,
>> >>>                 final Duration maxFrequency, final JavaScript script)
>> {
>> >>>             super(THROTTLER.merge("id", id, "milliseconds",
>> maxFrequency
>> >>>                     .getMilliseconds(), "function", script.function
>> ()));
>> >>>         }
>> >>>     }
>> >>>
>> >>> and usage of that would be:
>> >>>
>> >>>         code = new ThrottlingDecorator("id", Duration.ONE_SECOND,
>> code);
>> >>>
>> >>>
>> >>> Jonathan Locke wrote:
>> >>> >
>> >>> > Something like class below (although perhaps more efficient) could
>> >>> help
>> >>> us
>> >>> > to decorate and merge javascript in our AJAX code.  Because code
>> >>> merges
>> >>> > only occur one layer at a time, it's as good as an AST for our
>> simple
>> >>> > purposes (we don't need to globally refactor JavaScript, for
>> example,
>> >>> only
>> >>> > combine it neatly), but much easier to use.  I personally would
>> have
>> >>> no
>> >>> > problem breaking the API to make this better, but we could also do
>> >>> this
>> >>> > with 100% backwards compat by simply having things that need
>> >>> JavaScript
>> >>> > make a call to a getWhateverJavaScript() method first and if that
>> >>> returns
>> >>> > null (in the default impl), it could proceed to do what it does
>> now.
>> >>> So
>> >>> > basically if you wanted to assemble your script this new way, you
>> >>> could
>> >>> > override these new methods and the old stuff would be
>> >>> bypassed.  Feedback?
>> >>> >
>> >>> >     Jonathan
>> >>> >
>> >>> > ---
>> >>> >
>> >>> > package thoof.util.javascript;
>> >>> >
>> >>> > import java.io.IOException;
>> >>> > import java.io.InputStream;
>> >>> > import java.util.Collections;
>> >>> > import java.util.HashMap;
>> >>> > import java.util.Map;
>> >>> > import java.util.regex.Pattern;
>> >>> >
>> >>> > import org.apache.wicket.util.io.Streams;
>> >>> > import
>> >>> org.apache.wicket.util.string.interpolator.MapVariableInterpolator;
>> >>> >
>> >>> > public class JavaScript {
>> >>> >
>> >>> >     private final String script;
>> >>> >
>> >>> >     private static final Pattern UNINTERPOLATED_VARIABLES = Pattern
>> >>> >             .compile("\\s*\\$\\{\\w+\\}\\s*");
>> >>> >
>> >>> >     public JavaScript(final String script) {
>> >>> >         this.script = script;
>> >>> >     }
>> >>> >
>> >>> >     public static JavaScript load(final Class<?> type, final String
>> >>> > resourceName) {
>> >>> >         return load(type.getResourceAsStream(resourceName));
>> >>> >     }
>> >>> >
>> >>> >     public static JavaScript load(final InputStream in) {
>> >>> >         try {
>> >>> >             return new JavaScript(Streams.readString(in));
>> >>> >         } catch (final IOException e) {
>> >>> >             throw new IllegalStateException("Cannot load email
>> >>> template",
>> >>> > e);
>> >>> >         }
>> >>> >     }
>> >>> >
>> >>> >     public final JavaScript merge(final Map<String, Object> map) {
>> >>> >         final String mergedScript = new
>> >>> > MapVariableInterpolator(this.script,
>> >>> >                 map).toString();
>> >>> >         return new
>> >>> > JavaScript(UNINTERPOLATED_VARIABLES.matcher(mergedScript)
>> >>> >                 .replaceAll(" "));
>> >>> >     }
>> >>> >
>> >>> >     public final JavaScript merge(final Object... args) {
>> >>> >         if (args.length % 2 != 0) {
>> >>> >             throw new IllegalArgumentException(
>> >>> >                     "Invalid interpolation arguments");
>> >>> >         }
>> >>> >         final Map<String, Object> map = new HashMap<String,
>> Object>();
>> >>> >         for (int i = 0; i < args.length; i += 2) {
>> >>> >             if (args[i] instanceof String) {
>> >>> >                 map.put((String) args[i], args[i + 1]);
>> >>> >             } else {
>> >>> >                 throw new IllegalArgumentException(
>> >>> >                         "Invalid interpolation arguments");
>> >>> >             }
>> >>> >         }
>> >>> >         return merge(map);
>> >>> >     }
>> >>> >
>> >>> >     public final JavaScript prepend(final JavaScript script) {
>> >>> >         return new JavaScript(script + ";" + this.script);
>> >>> >     }
>> >>> >
>> >>> >     public final JavaScript append(final JavaScript script) {
>> >>> >         return new JavaScript(this.script + ";" + script);
>> >>> >     }
>> >>> >
>> >>> >     public final JavaScript function(final String functionName) {
>> >>> >         return new JavaScript("var " + functionName + " = function
>> {
>> "
>> >>> +
>> >>> > script
>> >>> >                 + "};");
>> >>> >     }
>> >>> >
>> >>> >     @Override
>> >>> >     public String toString() {
>> >>> >         return MapVariableInterpolator.interpolate(script,
>> >>> >                 Collections.EMPTY_MAP);
>> >>> >     }
>> >>> >
>> >>> >     public static void main(final String arguments[]) {
>> >>> >         JavaScript code = new JavaScript("var x = 10 + 3");
>> >>> >         System.out.println("" + code.toString());
>> >>> >         code = code.prepend(new JavaScript("a + b"));
>> >>> >         System.out.println("" + code.toString());
>> >>> >         code = code.append(new JavaScript("c + d"));
>> >>> >         System.out.println("" + code.toString());
>> >>> >         code = code.function("callback");
>> >>> >         System.out.println("" + code.toString());
>> >>> >         JavaScript ajax = new JavaScript(
>> >>> >                 "var wcall; ${beforeCallback} wcall =
>> >>> > wicketAjaxGet('${url}', function() { ${success} }, function() {
>> >>> ${failure}
>> >>> > }); ${afterCallback} return !wcall;);");
>> >>> >         code = ajax.merge("url", "/abc/def", "beforeCallback",
>> code,
>> >>> >                 "afterCallback", "a = b + c + d");
>> >>> >         System.out.println("" + code.toString());
>> >>> >     }
>> >>> > }
>> >>> >
>> >>> >
>> >>>
>> >>> --
>> >>> View this message in context:
>> >>> http://www.nabble.com/JavaScript-object-tf3610605.html#a10090957
>> >>> Sent from the Wicket - Dev mailing list archive at Nabble.com.
>> >>>
>> >>>
>> >>
>> >>
>> >
>> >
>>
>> --
>> View this message in context:
>> http://www.nabble.com/JavaScript-object-tf3610605.html#a10091122
>> Sent from the Wicket - Dev mailing list archive at Nabble.com.
>>
>>
> 
> 

-- 
View this message in context: 
http://www.nabble.com/JavaScript-object-tf3610605.html#a10091318
Sent from the Wicket - Dev mailing list archive at Nabble.com.

Reply via email to