1

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!

5
  • 2
    What's the point? Relative paths in JS file are counted based on the HTML file where the JS is run, not based on the path where the JS file has been saved. Commented Dec 27, 2017 at 17:43
  • @Teemu that's something I didn't know, thanx. Then again, how does it help me, sorry, I'm really not seeing how to use your tip for my problem, or does this mean there is no way to achieve what I want... Commented Dec 27, 2017 at 19:24
  • You can change the base of a HTML document with base element, though this may mess the navigation. Commented Dec 27, 2017 at 19:43
  • @Teemu, does it mean it's gonna be up to the user of the plugin (me in this case) to manually include in their html every css and js file they need when needed because there is no way to "pull" them from where ever the files are inside the plugin folder structure? Commented Dec 27, 2017 at 20:08
  • More or less yes. A consistent folder structure would help, also in some conditions you can get value for the urlBase variable, see stackoverflow.com/a/22745553/1169519 . An alternative is to use a task runner, like Gulp or Grunt. Commented Dec 28, 2017 at 5:26

1 Answer 1

1

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:

  • you dont need jQuery
  • The script only includes the CSS once
  • absolute urls are not handled in this script
  • i dont know if js-files included from other domains can handle this technic (not tested)

For js includes i recommentd using js modules

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.