Active-CSS / active-css

The epic event-driven browser language for UI with functionality in one-liner CSS. Over 100 incredible CSS commands for DOM manipulation, ajax, reactive variables, single-page application routing, and lots more. Could CSS be the JavaScript framework of the future?
https://activecss.org
Other
42 stars 7 forks source link

Set up relative URL handling for ajax commands per CSS spec #257

Closed bob2517 closed 1 year ago

bob2517 commented 2 years ago

This came up as a result of the new component syntax where relative URLs in ajax requests were discovered not to work as expected.

ACSS uses relative URLs in the same way as JavaScript, because it was written in JavaScript.

However, it should be working like CSS (for consistency reasons), and CSS handles "../" a bit differently to JavaScript. So there's an issue.

ACSS should be following the CSS spec, so per this: http://www.w3.org/TR/CSS21/syndata.html#value-def-uri

... the "../" should be based on the path of the stylesheet, like CSS.

According to HTML the spec for the base element: "The base element allows authors to specify the document base URL for the purposes of parsing URLs, and the name of the default browsing context for the purposes of following hyperlinks. The element does not represent any content beyond this information."

So it appears that the base element in HTML shouldn't affect the way CSS works, therefore it will not have any effect on ACSS ajax urls. It's possible there may be other areas in ACSS that need to work per the CSS rules, but I can't think of any ATM.

I don't see the point of "./", so I'm leaving it out completely. I'll put it in later if anyone insists. It adds nothing to the syntax tho, AFAICS.

This is essentially a bug fix to get ACSS more aligning to the CSS spec. I don't think this will be a breaking change for anyone, but I'm going to flag it as a breaking change just in case.

Note that this is a handling for ajax requests in ACSS only.

bob2517 commented 2 years ago

Note to self, the original ACSS file reference is available for each command. The only weirdness would come about through a build process on the back-end that concatenates ACSS files from different directories into one file. That would destroy the original relative positions.

But I suspect it would be the same issue in CSS, unless the browser uses a CSS map to work out where a file is, and I haven't seen anything documented on that. From what I can see, sourcemaps only get loaded when devtools is opened. https://www.html5rocks.com/en/tutorials/developertools/sourcemaps/

Any ACSS concatenator could have an option added to maintain relativity of URLs based on the CSS file prior to concatenation, but that would be out of the scope of this issue.

There will need to be a warning placed on the docs for this scenario so people don't fall into that trap.

Also, there could be an attribute added to the base element later which would allow ACSS to use that instead of the stylesheet path, but that's not going to be part of this initially unless that solves a specific scenario.

bob2517 commented 2 years ago

The breaking change specifically will be the non-absolute path version of a url, like:

ajax: file.html;

Per existing functionality this would be gotten from the root being the page itself. Per the new functionality this would be gotten from the root being the ACSS file that this line is written in.

So it might be an issue - it depends on how people have their documents structured I guess, and whether they are using an absolute path or not.

Personally I always use absolute paths for ajax, because otherwise it can get complicated when using the default JavaScript method of using the root being the page - it gets complicated when pages (URLs) are in sub-directories and you need to get to the same JS file. I found that I needed to use absolute paths for that to work sensibly.

For ACSS files though, they should match CSS files, because they can then live in the same (or related) directory as associated css files and the urls can match up.

So I'm going to go ahead with these changes and see what happens after that. We can always have some sort of option to handle relative paths differently if it becomes an issue later on.

dragontheory commented 2 years ago

Very good sir.

This will enable us to have our PROD app root in a sub directory (out side of our control) without having to change the paths on the fly when we publish.

Thank you very much.

bob2517 commented 2 years ago

Groovy. Hopefully should have something on the new branch by the end of the day.

Note to self: embedded ACSS with relative URLs need to work with the page URL as root, as there is no ACSS file to be a root from.

bob2517 commented 2 years ago

This is almost done. I've got it working I think - just need to do a deeply nested test to make sure.

bob2517 commented 2 years ago

I think this is complete, just the docs to do.

The upgrade is now on the 2.11.0 branch: https://github.com/Active-CSS/active-css/tree/2.11.0/dist/v-2-11-0

So, the basic concept is that all relative urls called from a specific ACSS config file are based from the directory where the ACSS file is located.

So it should work with these kinds of relative URLs:

@component html(../myDir/something.html) ...

or

@component html(myDir/something.html) ...

or

ajax: "../myDir/something.html)" ...

or

ajax: "myDir/something.html)" ...
bob2517 commented 2 years ago

Absolute URLs remain unaffected by this change.

bob2517 commented 2 years ago

It doesn't matter what the file extension is that is being called - they will all work in the same way. So any js files, css or txt files will handle in this new way.

bob2517 commented 2 years ago

For embedded ACSS, where there is no ACSS file to have as a root, the path of the URL of the page is taken as the root, and the same syntax examples as above would work (if the files are actually there, of course).

bob2517 commented 2 years ago

That last one for embedded ACSS may need a bit of tweaking depending on feedback, as I don't have a real life scenario for that yet. It may be fine as it is though.

bob2517 commented 2 years ago

Regular CSS commands inside ACSS commands do not have any behaviour change for url type values, because they get handled directly by the browser and those values do not get processed in any way by the ACSS core.

dragontheory commented 2 years ago

Hey there. Just updated to 2-11-0 and am getting an Uncaught TypeError: f[0] is undefined when page loads in FF.

Chrome says Uncaught TypeError: Cannot read properties of undefined (reading 'file')

Trouble shooting here. Just wanted to know if that looks familiar to you.

Wondering if it has to do with paths? Should I have changed them?

From:

@component list-app html("assets/components/list-app/list-app.html" get nocache) {}

to:

@component list-app html("list-app.html" get nocache) {}

Nope. That didn't change the error.

bob2517 commented 2 years ago

Is list-app.html in the same directory as the config file that contains the @component statement? It would need to be if you write it like that. I suspect that is the problem.

Relative URLs do work, but that error message is a bit cryptic - I'll have to take a look at that. I've not changed any other aspect of the core except the relative URL handling, so it looks like it is related to that.

bob2517 commented 2 years ago

You might need to do some "../" insertions...

dragontheory commented 2 years ago

Is list-app.html in the same directory as the config file that contains the @component statement?

Yes. Same directory.

You might need to do some "../" insertions...

Tried many different variations such as "./", "../","../../", "../../../", etc. but nothing changed the error.

Could the error be happening before it gets to these components?

Googled the error and nothing specific came up related to paths.

bob2517 commented 2 years ago

I've not changed anything expect the component handling. Try an absolute path with a slash just to check if it works. I need to shoot out the door now, but will be back shortly.

dragontheory commented 2 years ago

Try an absolute path with a slash just to check if it works.

Verified that before the update everything was working (including absolute paths). Only change was the ACSS update and then started receiving the error.

Switched to the non-minified ACSS version so that line numbers are meaningful...

Here is the full error with line numbers...

Uncaught TypeError: Cannot read properties of undefined (read 'file') at 6046:53
at Array.forEach (<anonymous>)
at _makeVirtualConfig (5913:23)
at _readSiteMap (6443:2)
at _addConfig (5468:3)
at XMLHttpRequest.r.onload [as __zone_symbol__ON_PROPERTYload] (9933:4)
bob2517 commented 2 years ago

Ah! Ok - gimme a sec to fix it. Sorry, just got back from Kung Fu. That line number error helps.

bob2517 commented 2 years ago

I'm doing a blind fix - I'm not getting your error but I can see what is going on from the error message. I'm just doing a final test with a similar directory structure to yours and then I'll do a commit.

I think it's somewhere else in your code that is bringing up the error, and I'm not sure what exactly. But the fix I'm doing should resolve the issue anyway.

bob2517 commented 2 years ago

Test looks good. The fix is on the branch.

As I said, it's a blind fix, which isn't the best kind of fix, because I'm not getting the error that you are seeing, so the fix may result in another error coming up somewhere else. If so, please let me know any line numbers of erroring places, or commit to your repo and I'll take a look directly at it to see what is happening.

dragontheory commented 2 years ago

As I said, it's a blind fix, which isn't the best kind of fix, because I'm not getting the error that you are seeing, so the fix may result in another error coming up somewhere else. If so, please let me know any line numbers of erroring places, or commit to your repo and I'll take a look directly at it to see what is happening.

OK. Will let you know. Greatly appreciate your work.

Thank you!

dragontheory commented 2 years ago

Updated...

Chrome is getting the same errors but with a few line differences...

Uncaught TypeError: Cannot read properties of undefined (reading 'file') at 6047:54
at Array.forEach (<anonymous>)
at _makeVirtualConfig (5913:23)
at _readSiteMap (6449:2)
at _addConfig (5468:3)
at XMLHttpRequest.r.onload [as __zone_symbol__ON_PROPERTYload] (9939:4)

FF is getting this error with no line numbers...

Uncaught TypeError: innerContent[0] is undefined

This is at work so the repo is not accessible.

Googling has yet to reveal anything of substance...

bob2517 commented 2 years ago

I've checked in another fix that hopefully should remove that error, on the 2.11.0 branch.

Let me know if that does the trick. Also look for any errors in any of your component syntaxes that might be causing this to go weird. I'm using the latest core on the docs site offline, where it all works, and my relative URL tests are working ok for me.

bob2517 commented 2 years ago

That Chrome error indicates that there (maybe) could be a syntax error in the config somewhere, so check over your curlies and parentheses. Remove any incomplete code that you don't need. ACSS is not like CSS, in that it will sometimes fail if it finds code that it cannot read properly, and it can end up not loading anything.

If there's still no joy and you can't find anything then I'll add in some more debug error messages for you so we can isolate the syntax error. The error is happening when your config files are first loading into memory.

bob2517 commented 2 years ago

Ok - I'm off to work now and will catch up later. Good luck!

dragontheory commented 2 years ago

Thank you. I will let you know what happens.

bob2517 commented 1 year ago

Closing in preparation for release.