DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Coding
  3. Frameworks
  4. Tapestry 5.4: jQuery Support now in place

Tapestry 5.4: jQuery Support now in place

Howard Lewis Ship user avatar by
Howard Lewis Ship
·
Jan. 03, 13 · Interview
Like (0)
Save
Tweet
Share
5.54K Views

Join the DZone community and get the full member experience.

Join For Free

I've spent the last several months significantly reworking Tapestry 5's client-side JavaScript support, in an effort to move away form the tight binding to Prototype. After all of that refactoring, recoding, repositioning, and just-plain-hacking, I was able to do most of the job of introducing jQuery support in just a few hours, yesterday and today.

I'll be producing another preview release pretty soon, or you can get the lastest from Tapestry's master branch.

Currently, the code to switch over from using Prototype to jQuery looks like this (it will get simpler soon):

public class EnableJQueryModule
{
    @Contribute(SymbolProvider.class)
    @ApplicationDefaults
    public static void switchProviderToJQuery(MappedConfiguration<String, Object> configuration)
    {
        configuration.add(SymbolConstants.JAVASCRIPT_INFRASTRUCTURE_PROVIDER, "jquery");
    }

    @Contribute(Compatibility.class)
    public static void disableScriptaculous(MappedConfiguration<Trait, Boolean> configuration)
    {
        configuration.add(Trait.SCRIPTACULOUS, false);
        configuration.add(Trait.INITIALIZERS, false);
    }
}

The first part overrides the provider to be "jquery" (the default provider is "prototype"). In Tapestry terms, the "infastructure framework" provides the APIs for DOM queries, DOM manipulation, and Ajax request handling. If you don't like jQuery, you can easily create your own provider for your favorite framework.

Part of 5.4 is trying to manage all these different compatibility issues at a slightly higher level than configuration symbols; that's the Compatibility service with its Traits. Those two traits disable Scriptaculous support (which isn't needed by jQuery, and won't work without Prototype), and disables support for Tapestry 5.3-style initializers.

Underneath the covers, the way the switch between Prototype and jQuery works is quite simple:

    @Contribute(ModuleManager.class)
    public static void setupFoundationFramework(MappedConfiguration<String, Object> configuration,
                                                @Inject @Symbol(SymbolConstants.JAVASCRIPT_INFRASTRUCTURE_PROVIDER)
                                                String provider,
                                                @Inject @Path("classpath:org/apache/tapestry5/t5-core-dom-prototype.js")
                                                Resource domPrototype,
                                                @Inject @Path("classpath:org/apache/tapestry5/t5-core-dom-jquery.js")
                                                Resource domJQuery)
    {
        if (provider.equals("prototype"))
        {
            configuration.add("t5/core/dom", new JavaScriptModuleConfiguration(domPrototype));
        }

        if (provider.equals("jquery"))
        {
            configuration.add("t5/core/dom", new JavaScriptModuleConfiguration(domJQuery));
        }

        // If someone wants to support a different infastructure, they should set the provider symbol to some other value
        // and contribute their own version of the t5/core/dom module.
    }

The ModuleManager service is the code that handles requests for modules from the client. It has a configuration that is used to handle edge cases, such as treating traditional JavaScript libraries as if they were AMD modules. The code above sets up a server-side override for the module t5/core/dom. All the Tapestry client-side modules use dom; none of them uses Prototype or jQuery directly (except for a couple that access Twitter Bootstrap functionality).

These contributions ensure that when the client-side requests the t5/core/dom module, what will be sent back will be either the Prototype-specific implementation, or the jQuery-specific implementation. Without this contribution, we'd see a 404 error when the dom module was requested. Instead, the client-side doesn't have any idea that dom is special.

The primary job of the dom module is to wrap DOM elements inside a new object, thereby providing a new API that allows various kinds of manipulation, as well as listening to events, or triggering them. The API is a bit of a mashup between Prototype and jQuery, but leans pretty heavily towards jQuery-style operations and naming. dom's secondary job is to support Ajax requests, plus adding event handlers to the document object.

In practice, this can be very concise and readable (partially, thanks to CoffeeScript):

    dom.onDocument events.zone.update, (event) ->

      this.trigger events.zone.willUpdate

      content = event.memo.content

      unless content is undefined
        this.update content

      this.trigger events.zone.didUpdate

In this listing (which supports some of the behavior of the Tapestry Zone component), dom holds the export from module t5/core/dom; it waits for the events.zone.update event to be triggered; the callback is invoked with this set to the wrapper around the element where the event was triggered.

The event here is also a wrapper; its a minimal mix of Prototype and jQuery: I like the memo property from Prototype, so that's present. The event handler triggers a pair of before and after events, and updates the content of the zone. Why the before and after events? By default they do nothing, but it would be simple to add handlers to perform some kind of animation when content is added.

In any case, because all Tapestry client-side modules code against this API, they don't know or care whether the page has loaded Prototype, jQuery, or something else. If you are writing Tapestry components for reuse, coding against the dom API will help ensure that your component will work correctly in all kinds of Tapestry applications. However, when coding an application,. you reserve the right to choose what the infrastructure framework should be: you should feel free to use the infrastructure framework directly ... unless you find the dom API to be easier.



JQuery

Published at DZone with permission of Howard Lewis Ship, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Distributed SQL: An Alternative to Database Sharding
  • How To Use Terraform to Provision an AWS EC2 Instance
  • Understanding gRPC Concepts, Use Cases, and Best Practices
  • Spring Cloud: How To Deal With Microservice Configuration (Part 1)

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: