Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
This issue is a delegate of #251578: More flexible js/css ordering and an alter operation to replace the parameters of drupal_add_js with a single $options parameter.
Comment | File | Size | Author |
---|---|---|---|
#49 | 315797.patch | 13.87 KB | RobLoach |
#42 | drupal_add_js_options-315797-42.patch | 14.03 KB | mfer |
#41 | drupal_add_js_options-315797-40.patch | 14 KB | mfer |
#39 | 315797.patch | 13 KB | RobLoach |
#37 | 315797.patch | 12.96 KB | RobLoach |
Comments
Comment #1
mfer CreditAttribution: mfer commentedI've been mulling over Moshes comment about moving to an options array and it being IDE unfriendly. As an IDE user I see he has a point. My IDE tells me what the parameters are. Should we move everything to a $options array?
Comment #2
RobLoachYeah, we definitely should. Who can remember the parameter ordering? Who enjoys seeing things like:
Considering the #315100: Allow to add JS/CSS libraries (sets of files, settings, and dependent libraries) plans, we'll need an $options parameter because it will give us the option to pass any kind of argument.
This patch switches the parameter to $options and it doesn't work, needs documentation, as well as some hacking with the $reset parameter. Not too sure why I uploaded it, but there it is.
Comment #3
webchickDon't forget that it needs lots of documentation. :)
I'm +1 for code legibility over IDE friendliness, personally. IDEs will also bring up the PHPDoc for a function, so...
Comment #4
RobLoachAdded some documentation, fixed drupal_add_js bugs, added failing tests from previous patch.
Comment #5
keith.smith CreditAttribution: keith.smith commentedOne of these things is not like the others.
- this one is in the form of a question, which the others are not
- doesn't specify the default setting
- and uses "JS" when everything else uses "JavaScript"
- "has been turned on" can be "is enabled"
- Also, "performance section" may need to be a menu path or URL -- off the top of my head, I'm not sure how we refer to it in other instances, so this may be right.
Comment #6
mfer CreditAttribution: mfer commented@keith.smith while I don't disagree that the comment about preprocess could be better it is the same comment describing the argument that is currently used in drupal 6. Any suggestions for the wording?
@Rob Loach this path had 13 failures and 9 exceptions when I ran the tests.
At the beginning of the drupal_add_js function we have:
Do we need to set options to be an array in this else clause? It's default value set in the arguments is an array. If it's not an array the value passed in is turned into a variable on an array. Is there a case when the else would ever be executed?
Why was the
if (isset($data)) {
moved to before the core js files were added? Previously I could call drupal_add_js() and jquery.js and drupal.js were added to the page. That behavior has been changed and won't happen now.This is just from a brief review. I'll try to give it a more thorough look later this week.
Comment #7
RobLoachHi Matt! Thanks for taking a look. Any code changes are more then appreciated, too! :-)
I pretty much just stole the tests from the old patch and stuck them in there without updating it to this drupal_add_js. If we get them working, then that's awesome, if not, we'll fix them as we go through the revamp process. I'd much rather have them work then not work though.
The
$options = array()
is in there because I was hitting some errors when doing the array += merge without it in there. I guess that happens for some calls that pass a NULL in to drupal_add_js? We'd have to investigate more. I'd love absolutely any hacking help you can muster ;-) .Hmmm, I believe that still happens, doesn't it? I just moved the initial $javascript creation stuff out of isset($data) so that we could check the $reset parameter. If you manage to move things around and get it working right, I'll give you a beer? :-)
Comment #8
mfer CreditAttribution: mfer commented@Rob Loach I just looked over the
if (isset($data))
part again and the reason this comes before and envelops the section that adds the jquery.js and drupal.js is so that when you call drupal_add_js() to get the array containing the javascript that has been added it DOESN'T add any javascript to the page.If that if statement is moved after the core js files, like the patch does, when drupal_get_js calls drupal_add_js it will add the core js files if they aren't there and we have them added to every page whether we are using them or not.
The attached patch moves the if statement back where it was. Sadly, this change causes more exceptions when running the tests.
Comment #9
RobLoachThanks for having a look at it. We should just completely rewrite the test suite because those tests were written for the modified drupal_add_js, not this one....
Comment #10
Frando CreditAttribution: Frando commentedWell, I'd propose to leave the $type option as a regular argument instead of an array key in the options array, as the $type significantly changes the general meaning of the function (for $type = 'module' the first argument, $data, is to be a path, while for $type = 'setting' it's an array of variables to be converted to JavaScript, and maybe soon there's also a $type = plugin/library which overloads drupal_add_js yet another time).
So: -1 to squashing the $type into an options array, as it completely controls the meaning of the first argument, and a huge +1 for combining the other arguments in an options array.
Comment #11
RobLoachYou can still pass type through to $options as a string....
All of these result in the same thing happening. Did I understand what you were saying? What do you mean?
Comment #12
mfer CreditAttribution: mfer commented@Frando also, please look at this in relation to #315798: JavaScript Patch #2: Weight where type will most likely change to something like file, setting, and inline where it is a true type and not a cross between type and context.
If you review the patch you will see that code like:
still works just like it did in D6.
Comment #13
RobLoachComment #14
mfer CreditAttribution: mfer commentedThe patch will load jquery.js and drupal.js on every page whether they are called or not.
Comment #15
RobLoachAhh, whoops. I see what's going on now. Thanks, Matt!
Comment #16
RobLoachI moved the check to see if we're adding any data to the registry up. This means that we had to check for the $reset earlier too. Seems to add the correct files when when JavaScript is on the page and doesn't add them when no JavaScript is active. Aggregated JavaScript seems to work correctly.
Comment #17
mfer CreditAttribution: mfer commentedThis looks better but I'll have to actually test it. Why to we pass NULL in as the second argument to drupal_add_js? Why not require passing array() in instead of NULL?
Comment #18
RobLoachEh?
If we pass NULL to $options, it is assumed that we want to pass the default options, or that we're attempting to pass a TRUE to the the $reset argument.
Comment #19
mfer CreditAttribution: mfer commentedI reviewed the patch and it looks good and seems to function correctly.
I'm not marking this RTBC until we have tests. The previous patches made attempts at them and the larger issue this is derived from has them. We should add a few tests before marking RTBC.
Comment #20
RobLoachThis patch provides the following tests:
Default JavaScript is empty.
jQuery is added when a file is added.
Drupal.js is added when file is added.
JavaScript files are correctly added.
Base path JavaScript setting is correctly set.
JavaScript settings are set correctly.
Resetting the JavaScript correctly empties the cache.
jQuery is added when inline scripts are added.
Inline JavaScript is correctly added to the footer.
Getting the rendered JavaScript returns the inline code.'
There could be more, but this is pretty good.
Comment #21
sun$options is always set due to the function signature:
Should probably be NULL.
Comment #22
sunAlso, can we leave out the added $reset option, please? It unnecessarily complicates this patch, and I'm yet unsure whether I would agree with Frando.
Comment #23
mfer CreditAttribution: mfer commented@sun - what's the issue? The full signature is:
If NULL is passed in the else statement is executed making $options = array(). If array() is passed in the if is executed but it's an array so nothing else happens. If a string is passed in both if statements are executed and the string becomes the value of 'type' on the array.
Am I missing something?
Comment #24
sunThanks for the explanation. We do not use such logic in core. Functions that accept an optional, last $reset parameter, use just booleans in the function signature, i.e.
That's possible in this case, too, and will simplify the required logic for treating $options.
Comment #25
RobLoachWe need $reset in there to be able to clear all the cached JavaScript for the testing suite. We could, however, merge it into $options as the $options['type']....
$reset would benefit from #254491: Standardize static caching, but until that's in, we're stuck with this.
Comment #26
mfer CreditAttribution: mfer commentedThis patch changes function declaration to:
function drupal_add_js($data = NULL, $options = array(), $reset = FALSE)
I'm not sure I like the idea of merging $reset into type. That wouldn't be consistent with the rest of core.
I ran the JavaScript tests and they passed. Manually tested several pages and they worked.
Comment #27
sunMuch better now. But:
-
A string for the type ('core', 'module', 'theme', 'setting', 'inline')
is hard to understand.-
or an array which can have any or all of the following keys (these are not valid with type => 'setting')
: not limited to 'setting', I suggest to move the info whether an option is allowed into the description for each option. We also might want to add example code for each possible invocation into the PHPdoc.- Default values are not quickly graspable. Maybe each option description should start with "Defaults to xyz".
Also, there a some changes in whitespace, which should be removed. The changed/added code also uses leading spaces on blank lines, while blank lines should always be blank.
Comment #28
RobLoachAddressed some of the documentation issues as well as added a couple more tests hitting drupal_get_js().
Comment #29
mfer CreditAttribution: mfer commentedSome of the added blank lines have spaces on them. These need to be fixed.
Comment #30
RobLoachComment #31
RobLoachJust realized that we don't need to define the 'scope' as NULL in the drupal_add_js() call in locale.module.
Comment #32
mfer CreditAttribution: mfer commentedUpdated the comment block for drupal_add_js. There were references to $type which is now part of the options array. Removed the $reset part of the if (isset($data) || $reset) because we handle that in the logic directly above it. No need for this now. $options['preprocess'] should only default to true if caching is true. If caching is false preprocessing should be false. Updated to reflect this and added a test for it.
Also, update to a moving head.
Comment #33
RobLoachWe're setting $options['preprocess'] twice here?
Comment #34
mfer CreditAttribution: mfer commentedoops. Why do we have:
Wouldn't it be one less logic argument to have:
If we are setting it here we don't need it in the default options array.
Comment #35
RobLoachHmmm, before it was:
So what if we adopted your un-negative (?) logic:
Comment #36
mfer CreditAttribution: mfer commentedLooks good to me.
Comment #37
RobLoachComment #38
mfer CreditAttribution: mfer commentedRan tests and looked it over. Looks good. Someone other than Rob Loach or I able to take a look and mark RTBC?
Comment #39
RobLoachUpdated to HEAD. Tests still passing. Could someone please give this a review so that we can move onto:
Comment #40
drewish CreditAttribution: drewish commentedI'm only looking at the tests and I'd like to see those refactored a bit. Since we're doing unit testing rather than functional testing I think you should break the single test function into multiple functions. Each function should focus on a specific aspect of the function's operation: testReset, testInline(), testSettings(), testModule(), testTheme(), etc.
The "kitchen sink" style of tests is common in core right now but in IMHO it's very bad practice. Test should serve two purposes:
Monolithic tests generally fail badly because once one portion of the tests fails it cascades through the later tests. This makes it hard to isolate exactly where the fault lies. By breaking the code up into separate tests you may duplicate some code--though if you're duplicating code between a majority of the tests it should probably go into the setUp() function--but you'll have an isolated test that passes or fails on its own.
You also get several positive side effects by writing smaller tests:
Wow, that's starting to sound like something for the handbook.
Comment #41
mfer CreditAttribution: mfer commentedThis patch breaks up the tests as drewish suggests. Also, updates for a moving head.
Comment #42
mfer CreditAttribution: mfer commentedThis patch cleans up a few of the comments in the tests and makes them consistent.
Comment #43
drewish CreditAttribution: drewish commentedmfer, those look great. makes it much easier to see what's going into the function and happening.
Comment #44
drewish CreditAttribution: drewish commentedtook a bit closer look and noticed a couple of things.
testAddSetting() seems like it should also test for the 'drupal' => 'rocks' setting.
example code should be in the following PHPDoc blocks:
I don't like that the $options parameter takes either a string or an array... it seems like it should always be an array. if you are going to have it as separate options i'd suggest testing both ways more explicitly.
Comment #45
mfer CreditAttribution: mfer commented@drewish - For examples is it better to use @code rather then @example?
Comment #46
RobLoachIt looks like @example is only used when the code example is in an external file. @code might be the best to use here.
Comment #47
drewish CreditAttribution: drewish commentedmfer, i'm not sure if it really matters but the example that's being added to drupal_add_js() isn't using either.
Comment #48
mfer CreditAttribution: mfer commentedI took a look at the docs on PHPdoc and @Rob Loach is right. @example references an external file example. @code would be more appropriate for this case.
Comment #49
RobLoachComment #50
Owen Barton CreditAttribution: Owen Barton commentedSubscribing...on my list to review on the train
Comment #51
Dries CreditAttribution: Dries commentedI've reviewed this, ran the tests and everything seemed fine to me. Committed to CVS HEAD. Thanks all.
Comment #52
RobLoachAdded the update documentation notes. If any of you are better writers then me, please have a hack at it.
Comment #53
RobLoachThe next step in making drupal_add_js() awesome is: #315798: JavaScript Patch #2: Weight
Comment #54
Anonymous (not verified) CreditAttribution: Anonymous commentedAutomatically closed -- issue fixed for two weeks with no activity.