Reputation: 3257
Using Symfony 2.8.24 and jQuery 3.2.1
Been googling for this for a while now and, yes, there are lots of similar cases, involving using relative paths for resource loading but, none I have found which explains what I need, so SO:
I need to include (or load or append to head
or something) a css
file which is (lets say for simplicity) in the same folder as the js
file, I'm trying to do so (and this is the real problem) using a relative path to it, (and this is the real real problem) relative to the js
file, NOT the html
file.
I really don't know if this is even possible so, you know, IMPOSSIBLE is a valid answer.
Also, the whole point of this is portability of course, this plugin I'm trying to make uses several css and js files all sitting in different folders inside the plugin folder structure and I intend to include (or load or append to head
or something) each one if and when necessary. If I could do that making the process oblivious of where the plugin's top folder is copied, I would not have to change the absolute paths every time I use it in a different project.
Current/unwanted state:
var cssId = 'cssId';
if (!document.getElementById(cssId)) {
var head = document.getElementsByTagName('head')[0];
var link = document.createElement('link');
$(link).attr({
'id': cssId,
'rel': 'stylesheet',
'type': 'text/css',
'href': urlBase + '/js/plugins/PluginName/main.css', //PROBLEM HERE
//ideally previous line would be like: 'href': 'main.css',
'media': 'all'
});
head.appendChild(link);
}
Insights and ideas, on me!
Upvotes: 1
Views: 2065
Reputation: 3295
A tricky hack would be to use Error.stack, which is supported in current browsers but is not yet standardized.
c1CssImport = function (location) { // todo: handle absolute urls
const e = new Error();
const calledFile = e.stack.split('\n')[2].match(/[a-z]+:[^:]+/);
const calledUrl = new URL(calledFile);
calledUrl.search = '';
const target = new URL(location, calledUrl).toString();
for (let el of document.querySelectorAll('link[rel=stylesheet]')) {
if (el.href === target) return; // already loaded
}
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = target;
document.head.append(link);
// todo: return a promise
}
Then just call c1CssImport() where you like to include relative-url based css files:
c1CssImport('./ui.css');
note:
For js includes i recommentd using js modules
Upvotes: 1