Forum OpenACS Q&A: ajaxhelper and its tests

Collapse
Posted by Jim Lynch on
So when I installed ajaxhelper, I didn't know it had tests, but it does, in the dir packages/ajaxhelper/www/tests. When looking at the automated test page (/test), no tests show up.

Can someone look and try to see why this is? (the one I'm using is in https://github.com/openacs/ajaxhelper on branch oacs-5-8)

Anyone have any success at running the tests?

-Jim

Collapse
Posted by Gustaf Neumann on
jim,

the test cases of the automated tests in OpenACS are are defined with aa_register_case, which defines finally procs with funny names like _${package_name}__$case. These test cases are picked up during the load of a package and they are therefore part of the blueprint and part of the function set of the interpreters in every connection thread (which is memory-wise not the best). Type in a ds/shell e.g. "info commands ::_acs-tcl__*" and you will see the loaded test-cases for acs-tcl. The test cases must reside in the $package/tcl/ directory to be picked up by package loading.

Ajaxhelper does not have such test-cases defined, therefore no such test-cases are shown by automated testing. I am not sure, what kind of tests were intended in ajaxhelper/www/tests/, but that looks like unfinished work to me.

ajaxhelper was developed before the various CDNs (like googleapis.com, or yahoo cdn) became available. We have certainly not the necessary resources to keep copies of the most popular javascript frameworks in various versions around, or to test the effects of every new release on our packages. All large sites i know of design their templates by themselves and main in this process copies of the .js frameworks of their choice on their own. Therefore, the future of the ajaxhelper package is not clear to me.

Collapse
Posted by Jim Lynch on
Gustaf,

Yeah, the things you're saying make sense,,, in any case, I did run 2 of the test files by browsing to them, the tests themselves are located in ajaxhelper/www/tests, so I could run the tests by browsing to /(place ajaxhelper mounted)/tests/test_foo (where there existed /(place ajaxhelper mounted)/tests/test_foo.tcl and .adp). Neither worked, so it was at that point of failure that I also doubted the future of the package, but I've been wrong enough times (i.e., things worked anyway) to let that sway me too far. I also remember when we were playing with yui a few years before yahoo killed it, at that time what was on a few minds was to recraft ajaxhelper, as they felt that while the idea of an "ajax helper" was a good one, things were changing such that the then-current content of ajaxhelper had to be replaced or reworked.

Do you, or does anyone, have recommendations on how to use ajax currently (if not thru the use of ajaxhelper)?

It seems ajaxhelper has an automount set in the package metadata, for /ajax, and it has been declared to be a singleton.

-Jim

Collapse
Posted by Antonio Pisano on
In my opinion, current client side javascript environments are something too complex and hardboiling to be encapsulated in a package that would fit the needs of everybody.

Of course we could opt for including some of the less intrusive ones into specific UI features in OpenACS. I refer to "light" frameworks as JQuery or such.

However we choose, I fear this "marriage" could abruptly be broken on the next change of direction for web technologies, and would of course mean more work from the community to keep pace with framework development. A real example of this is Ajax Filestorage, build on ExtJS 2 if I recall correctly, and now quite useless, until someone finds time and will to rework it.

From a platform point of view I think we should focus on server side, either by producing plain text, markups/XML or JSON from data, as OpenACS is really good at it and leave fancy client side tecnology to the taste and needs of the single.

Antonio

Collapse
Posted by Benjamin Brink on
Indeed, Antonio.

I wonder. Why is a server-side web app development platform such as OpenACS including /resources/acs-subsite/core.js in acs-core the way it does?

core.js in the generic template has mobile usability issues[1]

It seems like a poor example of how to use js in a dynamic templating environment.

1. developers.google.com/speed/docs/insights/BlockingJS

Collapse
Posted by Benjamin Brink on
Hi Jim,

You asked:

"Do you, or does anyone, have recommendations on how to use ajax currently (if not thru the use of ajaxhelper)?"

Just wanted to point out that ajaxhelper includes some useful icons; That's the only way I use it.

The icons comply with the GPL license --a task that may otherwise be tedious to verify individually.

Some icons use reasonably standardized imagery for UI --and is a larger set than available at: acs-subsite/resources

Collapse
Posted by Antonio Pisano on
Regarding the use of core.js, I think it won't be a big deal to move its inclusion so it complies with best practices.

Have you already pointed out where it happens in templates?

Collapse
Posted by Benjamin Brink on
core.js is referred to in www/blank-master.tcl

packages/openacs-default-theme/lib/plain-master.adp refers to blank-master

Collapse
Posted by Antonio Pisano on
Will put an eye on that one of these days, thanks!
Collapse
Posted by Jim Lynch on
Antonio,

If I can boil down what you're saying, it's that trying to be as general as possible isn't really possible, or at least it's the typical thing of generalities having diminishing returns.

Fair enough.

So then my (opinion eliciting) question to you becomes, do you think ajaxhelper should just go away? Or, what uses do you see it applied to?

-Jim

PS to anyone, could you post something about its original purpose?

Collapse
Posted by Jim Lynch on
Benjamin,

OK, so would it be in any way useful to factor those out into another package? Was anything like this done already?

-Jim

Collapse
Posted by Benjamin Brink on
I don't know that it would be worthwhile to factor out the icons. One could generate similar ones if the package wasn't available --just using them to minimize time to produce packages by using existing resources.
Collapse
Posted by Gustaf Neumann on
A fairly clean approach is to place frameworks into theme packages (similar to the openacs-default-theme), which are tailored manually per site. From my experiences, one cannot ignore theming in application packages (such as xowiki, xowf,....) completely but that can be controlled via package parameters. For practical reasons, theming should be kept under full control of a site admin who needs fine-grained control over version upgrades.
Collapse
Posted by Benjamin Brink on
Thank you for that suggestion, Gustaf.

I hadn't thought through how to handle changes with the dependency of openacs-default-theme/lib/plain-master on www/blank-master

Of course, one can copy blank-master to a custom themed package and modify it there. To help track changes in blank-master versions, keep a local unchanged copy of blank-master in the theme to diff against openacs revisions.

Collapse
Posted by Antonio Pisano on
A simple fix for the issue with core.js is replacing line

template::head::add_javascript -src "/resources/acs-subsite/core.js"

in blank-master.tcl with

template::add_body_script -type "text/javascript" -src "/resources/acs-subsite/core.js"

so javascript will be put at the bottom of the page without blocking page loading anymore. Quick test didn't show signs of regressions, but should be checked throughly

Maybe this kind of changes should be made in other parts of the framework where javascript is involved, moving inclusion from head to body.

A little shortcoming with this is that template::head::add_script handles multiple inclusions of the same script and also their order of inclusion, while template::add_body_script doesn't.

If my change seems legit to you people I can commit

For reference:

http://www.openacs.org/api-doc/proc-view?proc=template%3a%3ahead%3a%3aadd_javascript&source_p=1

http://www.openacs.org/api-doc/proc-view?proc=template%3a%3aadd_body_script&source_p=1

Collapse
Posted by Antonio Pisano on
In the same script blank-master.tcl we have xinha and tinymce inclusion, plus other miscellaneous stuff which would fall under the same case of bad practice.

I'd say the same replacement I've suggested should be ok, but I cannot seriously test every possible difference.

I can go for it anyway, but this change should be audited by people using editor on their sites (I don't)

Collapse
Posted by Benjamin Brink on
Antonio,

To serve the community perhaps a transitional approach should be used.

Apply the change for core.js, since that is the one required script and has no conflicts with (any) existing template::add_body_script calls.

Insert a code comment with the calls to template::head::add_javascript in blank-master.tcl. The comment should urge switching to template::add_body_script after testing for reasons stated.

cheers,
Ben

Collapse
Posted by Antonio Pisano on
Committed change for core.js and warned for remaining cases in blank-master.

All the best

Antonio

Collapse
Posted by Benjamin Brink on
Thank you, Antonio!
Collapse
Posted by Gustaf Neumann on
hmm, i am not sure, whether the inclusion of core.js on every html page this is the best solution. Including core.js in every page means to increase the size of every page by 50 KB. On our production site, we have up to 4mio page views per day, that would mean to increase the traffic by 200 GB per day, if i have not messed up the zeros.

The better approach is to cache the core.js with a high expire time, or to use async loading.

The more important issue is, whether we really need all of core.js on every page. The largest part of it is the calendar widget, which should be only included in pages that need this.

Collapse
Posted by Antonio Pisano on
Of course we can decide about this too, but just to be clear, core.js was already included before, just in a "bad" way.

As far as I know, core.js is required for templating features as form focus property for adp files and checkbox selection for templating::list.

We should probably revise javascript codebase really essential, move its inclusion at the right place and get rid of the rest. For example, we still ship extjs2, which is very old, and maybe other stuff that doesn't really belong in OpenAcs.

Collapse
Posted by Gustaf Neumann on
The "old bad way" was that with a stock OpenACS, the js was loaded as an extra resource, the "modified bad way" is that it is now increasing the size of every html page by 50 KB. Assuming that the average HTML size is about 50KB [1], the literal inclusion (the new way) doubles the size. This is especially bad for mobile devices. When setting expire time high on this static resource (as recommended by the usual guidelines), the old way did not require a retransmit at all.

I would appreciate much more if someone separates out the various pieces of core.js for different usage scenarios, and includes the stuff were needed over including the whole mess on every page.

-g

[1] http://www.sitepoint.com/average-page-weight-increases-15-2014/

Collapse
Posted by Benjamin Brink on
Great idea to separate out the various pieces of core.js to their usage areas.

Perhaps this is a good time to add a parameter with a reasonable default expiration for serving static files. ( https://openacs.org/forums/message-view?message_id=4231891 )

Collapse
Posted by Antonio Pisano on
Sorry, but I don't understand: checking network usage from Chromium on my installation, now that core.js is in body, I see that response from server is "304 not modified", so caching is taking place into browser and no extra traffic is generated.

The same happens reverting to the previous way of including: js is loaded only the first time and then taken from cache.

Why should page size increase?

Collapse
Posted by Gustaf Neumann on
Antonio sorry, i misread. the change is not is not including the core.js literally (i.e. replacing the link by inlining the content, but just moving the definition down to the body. seems that i do too many things at a time.

moving stuff down will work most probably for "widgets" like the calender widget, but not for functions which will be needed earlier.

Many of the functions are not needed at all (imho), the calendar should go into its own file, the acs_List* and acs_KeypressGoto are still needed. It would be appreciated if someone can shed more light on the functions marked with "?"

The move-to-the-body-change might break the focus handling in the blank-master.

document.getElementById -> ancient stuff, not needed

acs_Focus -> www/blank-master.tcl
acs_FormRefresh -> ?
acs_CopyText -> ?

acs_RichText_* -> packages/acs-templating/tcl/richtext-or-file-procs.tcl
acs_rte* ->  www/blank-compat.tcl
acs_initHtmlArea -> ?

acs_ListFindInput -> packages/assessment/www/asm-admin/session-delete.tcl
acs_ListCheckAll -> packages/acs-templating/tcl/list-procs.tcl
acs_ListBulkActionClick -> packages/acs-templating/tcl/list-procs.tcl
acs_KeypressGoto: packages/acs-templating/resources/forms/confirm-button.adp

Calendar
Collapse
Posted by Antonio Pisano on
I'm having a look, but I need opinion on this:
I think we should change template::add_body_script code so it checks for duplicate inclusion of the same script as template::head::add_script does.

The need for this comes from this consideration: to keep js inclusion the closest possible to the tcl actually requiring that, I would put acs_RichText_* inclusion into template::widget::richtext_or_file proc. This proc can be called multiple times for each widget, so it would be convenient if we had a mean to avoid multiple inclusion in body.

As multiple inclusion of the same script in body could make sense (multiple execution of the same code) this should be parametric. I was thinking about the following:

- if the flag 'once_p' is given, behave like template::head::add_script and update reference into script array
- if flag is not given, put script into the 'anonymous' special element of array so no check is performed
- change template::head::prepare_multirows so it knows that now body_scripts is an array, rather that a plain list

What do you think about that?

Collapse
Posted by Neophytos Demetriou on
I think it's very good idea. In fact, I did something similar in the templating system (http://www.tcl.tk/community/tcl2013/EuroTcl/presentations/EuroTcl2013-Demetriou-WebTemplating.pdf) I developed (not suggesting we replace the existing one), just that I will try to have a look and make improvements (or other changes) like the one you suggest, if that were to be accepted from the community/maintainers of course.
Collapse
Posted by Jim Lynch on
I would just ask... is the reason for this change simply to include the javascript elsewhere (body instead of head)?

I think it's a good idea to check for dups. In fact, thought should be placed on whether there should be two separate namespaces (one for body, one for head) or one namespace for both -- do we want to deny a dup that originated in the head whose destination is body, or vise versa?

-Jim

Collapse
Posted by Antonio Pisano on
We already have two separate procs to include js in head or in body, and for a good reason I think, as they must be put in different places on the page.

Javascript in head should never be replicated, as it is meant to be loaded and/or executed just once, while body could have multiple inclusions (js that should fire the same for each row in a table is an example)

I don't think there is need for merging the two procs in a more generical one. Some little code replication exists, but removing that could be as good as letting thing as they are, leaving space for further difference in script management.

Collapse
Posted by Neophytos Demetriou on
FWIW, aforementioned templating system checks and combines scripts in terms of their purpose/usage i.e. whether a page is for registered users or the public. It also separates the scripts between those that can be deferred and those that are not [see slide 15 in the aforementioned EuroTCL presentation]. This is accomplished by tagging a JS code snippet with the relevant word, e.g. "public", "private", "defer", "nodefer" [templating system generates the files automatically]. Similarly, one could generate scripts for different browsers, language codes, and so forth.
Collapse
Posted by Antonio Pisano on
Neophytos Demetriou, I think I recall now I already gave a look at your slides some time ago. Your templating system seems very interesting!

Consider preparing/referring to a tutorial or other further documentation, as it could really encourage its usage and our feedback!

Collapse
Posted by Neophytos Demetriou on
Hi Antonio, I would very much like to do that (re: tutorial) though later in the summer as I'm somewhat swamped with a number of different things these days. That said, I would be glad to contribute in the development of the existing templating system or even integrating the two systems if the community finds that to be constructive. Overall, I'm all for contributing more in open-source projects, and OpenACS in particular, including bringing the work I've been doing over the years to converge with the existing codebase. Not sure what the best way is just yet. Just letting everyone know that I'm willing and, hopefully, perceived to be able to get the job done.