Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX] CSS Variables: Fix variable handling / relative urls #172

Merged
merged 13 commits into from
Jun 28, 2021

Conversation

petermuessig
Copy link
Contributor

No description provided.

@petermuessig petermuessig requested a review from matz3 June 23, 2021 17:54
@petermuessig
Copy link
Contributor Author

This change ensures that the library variables of sap.tnt in sap_fiori_3 theme defined in the global.less will also be considered for the css_variables.source.less.

@RandomByte
Copy link
Member

RandomByte commented Jun 23, 2021

Not directly related to this: But have you ever tested how url() parameters behave with the current CSS variable generation?

We noticed a difference, probably because Less resolves those URLs coming from imports while the CSS variables somehow "take over" the value without this resolution taking place. We think the first finding (sapDefault_URI) in your Snippix from yesterday's meeting shows such a case.

Maybe we could add a CSS var test case for imported parameters containing something like url('111')?

@petermuessig
Copy link
Contributor Author

@RandomByte - yes the URLs are resolved - I don't know who it does yet -> it could also be related to the access via the browser API or the less generation does it. Will check it.

@petermuessig
Copy link
Contributor Author

petermuessig commented Jun 23, 2021

@RandomByte : AFAICS the rewrite of the URL seems to be missing for the CSS variables. I need to discuss this with @matz3 tomorrow. For the theme-parameters it is done...

@RandomByte
Copy link
Member

We had a brief look yesterday and found that it might be related to the css-variables-collector using isPreEvalVisitor: true while the variable-collector uses isPreVisitor: true. When using the latter, the URLs are resolved as expected.

@petermuessig
Copy link
Contributor Author

URL values in variables are now resolved properly!

const vars = {};
Object.keys(this.vars).forEach((key) => {
const override = this.vars[key].updateAfterEval && varsOverride[key] !== undefined;
if (override && process && process.env && process.env.LESS_OPENUI5_CSSVARS_REPORT_OVERRIDE) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

console log only with ENV variable set (to be on the safe side for eventual usage in browser checking process.env to be available first)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For that I think you would need to to a typeof process check, as just using process will result in a ReferenceError.

@petermuessig
Copy link
Contributor Author

The last change of the tests was necessary to ensure that the last definition of the variable in the less files wins. With the old bahavior of checking the rules in the ruleset it could be that the variable defined in a nested less file overrule the top-level variable which is not the expected behavior. In this case, in sap.ui.table, the wrong variable definition for the delete icon won. This now ensures a proper precedence order.

// in all other cases with no filename (indicates calculated variables)
// or in case of variables in standalone less files we just include them!
const include = !filename ||
(this.config.libPath ? filename.startsWith(`/resources/${this.config.libPath}/themes/`) : true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't rely on the fact that the path starts with /resources/. In the grunt/connect use-case they just start with /sap/....
The current solution in #168 is to lookup the library namespace within the path. Not a bullet-proof solution in case an absolute real FS path is used, but it will at least support the both main use cases (UI5 Tooling + grunt/connect).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, so more my initial regex approach again!

const vars = {};
Object.keys(this.vars).forEach((key) => {
const override = this.vars[key].updateAfterEval && varsOverride[key] !== undefined;
if (override && process && process.env && process.env.LESS_OPENUI5_CSSVARS_REPORT_OVERRIDE) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For that I think you would need to to a typeof process check, as just using process will result in a ReferenceError.

}
});
visitUrl(node, visitArgs) {
// we mark the less variables which should be updated after eval
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My expectation was actually the other way round.
To use the "override" values (from the new preVisitor) in general, and only use the current ones for the variable references (which was the main reason for enabling the preEvalVisitor mode).
Otherwise I'd expect that also some other values might differ unexpectedly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are issues within the isPreEval phase where less variables with the value none also have the URL content - so doing it this way is the best to determine properly the variables and apply only the needed later! All other options require much more code!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. Would be great to have those specialities documented somewhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is described in my comments


const less = require("../thirdparty/less");

const CSSVariablesUrlResolverPlugin = module.exports = function(config) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need another plugin? Can't we just re-use what the variable-collector plugin provides?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of running it at a later point of time! isPreEvalVisitor vs. isPreVisitor - otherwise we have to write ugly if conditions in the coding

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you give me some more details here? VariableCollector also uses isPreVisitor: true, so I would expect it to work almost the same as this plugin.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic for the detection of the URLs is pretty simple and it need to run in the PreVisitor phase. The CSS Var Collector is running in the PreEvalVisitor phase to not resolve the vars. I don't want to run the full enchilada of the code of the CSS Var Collector again in the PreVisitor phase as this is unnecessary and IMO the code of the URL Collector is pretty trivial.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh - got your point - I am checking the url-collector right now

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no need to run anything again.
The variables are already collected and available:

result.variables = oVariableCollector.getVariables(Object.keys(mFileMappings[filename] || {}));

It's a different tree.toCSS run, but both are based on the exact same input, so I wouldn't expect any differences in the values. It's the list we already use for the inline theming parameters, so their values are exactly what we expect. That's why I don't expect the need for another plugin.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

url-collector is not what I meant, and I think it doesn't really fit for this purpose.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

variable-collector seems to be sufficient!

@petermuessig
Copy link
Contributor Author

For that I think you would need to to a typeof process check, as just using process will result in a ReferenceError.

typeof process is not different than process, right? it should be window.process then - let me think...

lib/index.js Outdated Show resolved Hide resolved
lib/index.js Outdated Show resolved Hide resolved
lib/plugin/css-variables-collector.js Outdated Show resolved Hide resolved
@matz3 matz3 changed the title [FIX] Variables: improved detection of library variables [FIX] CSS Variables: Fix variable handling / relative urls Jun 28, 2021
@matz3 matz3 merged commit 6ace17f into master Jun 28, 2021
@matz3 matz3 deleted the fix-libverdetection branch June 28, 2021 18:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants