create-conditional / @command
You can create your own pseudo-selectors, or in ACSS terms - "conditionals", and use them in your ACSS config.
@command conditional
Syntax
@command conditional (action command name) {= JavaScript code =}
This is just a nicer-looking syntax added in version 2.2.0 for creating a conditional command, but there are no plans to remove create-conditional. "@command conditional" converts to "create-conditional" during config load and sets the conditional command up immediately. See below for details on how to use the create-conditional action command.
Syntax example:
@command conditional if-more-than-ten-divs {=
let el = doc.querySelectorAll(conditionalValue)[0];
let elCount = el.querySelectorAll('div').length;
return elCount > 10 ? true : false;
=}
create-conditional
Syntax
create-conditional: (conditional function name) {= JavaScript code =} [after (time)][, (conditional name)...];
conditional function name = name of the conditional function to create. Eg. if-div-top-visible, or if-weather-sunny.
JavaScript code = Javascript functionality contained with the Active CSS JavaScript wrappers "{=" and "=}".
This command allows you to create Active CSS conditional function dynamically within the event flow.
You would normally use create-conditional in the body:init event, inside a draw event declaration, or in a shadow DOM initialization event. But it doesn't particularly matter where you choose to use it, as create-conditional will only create a conditional function once. It will not re-create it if it already exists. No variable substitution is allowed in the function. You can only use raw JavaScript - so no Active CSS commands or Active CSS variable syntax. It will run in the context of the scope that it is run. Any variables run in the conditional function should be available in the scope it is run in. So if you are writing a shadow DOM component, the variables are expected to either be already set up in that scope, or you are going to set them up in that scope as part of the function itself.
Creating a conditional function
The function itself that will perform your condition check is written in regular JavaScript, as if you were writing it in an external JavaScript file. But you don't need to declare the function, or any parameters with JavaScript. You have a bunch of variables already set up that you can use, which should provide you with everything you need to set the context of the conditional function.
To illustrate this, if you were creating a function to check if an element contained more than ten div tags within it, it might look like the following example in the config. Certain variables are available that you can use to perform different things, such as the command parameters value and the event selector object. The function command parameters are called the conditional value, and that is found in the string variable "conditionalValue". The names of the variables are similar to those used in the create-command, except there are not as many of them available when you are creating a conditional function:
body:init {
create-conditional: if-more-than-ten-divs {=
// This conditional accepts only one parameter, and it is a selector.
// Get the first selector object, as for this example we only want one object, not multiple.
let el = doc.querySelectorAll(conditionalValue)[0];
// Count the number of div tags in the selector.
let elCount = el.querySelectorAll('div').length;
// If more than ten, return true. If not, return false.
return elCount > 10 ? true : false;
=};
}
Don't forget the semi-colon at the end of the create-command declaration after the "=}" or the create-command won't run!
Also, you are permitted to use comments with "//", as in the above example, because this is native JavaScript. You cannot use "//" in regular config though... always use "/* ... */" when putting comments into regular config.
Back to the example above. You would use the conditional function like this:
#countLeftCol:if-more-than-ten-divs(#str-LeftCol):click {
.... do something
}
or if you were using it as part of a conditional:
@conditional countCheck {
if-more-than-ten-divs: #str-LeftCol;
}
#countLeftCol:countCheck:click {
.... do something
}
How are the function parameters handled?
The parameters are the right-side of the colon ":" in the conditional command, or in the brackets when used as a function.
Eg. "#str-LeftCol" in the command "if-more-than-ten-divs: #str-LeftCol", or "if-more-than-ten-divs(#str-LeftCol)".
The parameters will appear in your function in the variable "conditionalValue". This will be a string. It is up to you how you handle it, with regular JavaScript string manipulation, etc. There is no set method of handling conditional value contents or "parameters" in Active CSS. Each function could potentially handle the parameters differently.
Space-delimited parameters and comma-delimited values are different
In CSS, multiple parameters are separated by a space.
In Active CSS, multiple parameters are separated by a space.
Comma-delimited values are effectively multiply function calls. It will run the function more than once.
Eg.
@conditional myConditional {
if-blah: "michael caine" #fff actor, "delores" #eee character;
}
or
#myButton:if-blah("michael caine" #fff actor, "delores" #eee character):click {...
If you want to have multiple parameters in the same function, you use a space.
If you want to run the function more than once with different parameters, you use a comma.
All syntax uses for the conditional function follow this rule.
So, comma-delimited conditional values are simply multiple re-runs of the same function with different parameters.
Your function will run separately for each comma-delimited value, and so the conditionalValue variable will never contain a comma-delimited list - it will only contain the value it is working on at the time.
Is there a target selector?
No. You get passed data relating to the event selector. That is where the conditional function is being written.
Available variables within the conditional function JavaScript
Commonly used variables are in bold. Be aware of the other variables names so you don't accidentally name your own variables the same.
conditionalName | The name of the conditional function, such as "if-div-blue". |
conditionalValue | The function parameters. Same sort of space-delimited string as an action command value. Any variable substitution has occurred by this point. You won't find any commas in this (unless they are in quotes), because each comma means "run the conditional function again with these next parameters". |
carriedEventObject | If your conditional function is part of an afterAjax type of event, this should contain the element from the event that triggered the ajax call. |
doc | The frame object that received the event. Always use this instead of "document" to stay in the same window frame as the event selector. Don't use "document" unless you are absolutely sure you will always be referencing the main frame. Use doc which will either be set to document or a shadow DOM reference, as applicable. |
e | The event object. Like "click", "mouseover", etc. It is the actual JavaScript event object, which is commonly referred to as "e" in functions, so we've used the same name here. |
conditionalFunc | The name of the function that Active CSS has generated internally for the conditional function, such as "IfDivBlue". |
eventSelector | The event selector element itself, that received the event. This will be an element-type of object. |
eventSelectorName | The name of the event selector. This is a string. |
compDoc |
The "document" or node of the shadow DOM or scoped component, if appropriate. |
component |
The name of the component, if appropriate |
_activeVarScope, scopedVars |
Internal variables containing data to manage user variables. It isn't recommended to mess with these. |
o | This is the same o that appears in the func command. This contains most of the above variables. The reason the variables above exist is that they may be more easily understood in that form than in the o variable. But you can solely use the o variable if you prefer. The values are the same. Do not change o variable contents though - eg. it may have adverse effects like break the event reporting in DevTools, or if you erase the main event object then you might get things going strange. |
Multiple "create-conditional"s in the same declaration
This is done in the same way as any other Active CSS command, by using a comma. The create-conditional command follows the same rules as all the other Active CSS commands.
Eg.:
body:init {
create-conditional: if-my-conditional-a {=
... javascript javascript...
=},
if-my-conditional-b {=
... javascript javascript...
=};
}
Helper functions
_ACSSRepQuo()
This removes the double quotes from a string and unescapes any double quotes within.
Eg.
let str = conditionalValue._ACSSRepQuo();
Getting it to work in browser extension code
So you are building a browser extension, and you try to use create-conditional, and you get an error saying JavaScript cannot be evaluated dynamically due to browser policies. What do you do? You would need to call an external conditional with the if-func command, or get a new conditional function approved for use in the core.