What purpose does a <script> tag serve inside of a <noscript> tag?

JavascriptHtmlNoscript

Javascript Problem Overview


I've been on a "view source" spree lately on websites with interesting design and content. One of those websites, Squarespace, has blocks of <script> tags inside of a <noscript> tag, like so:

<!-- Page is at: http://squarespace.com -->
...
...
<noscript id="inline-deps">
  <link rel="stylesheet" type="text/css" href="//cloud.typography.com/7811972/758964/css/fonts.css" />

  <script type="text/javascript" src="https://static.squarespace.com/static/ta/5134cbefe4b0c6fb04df8065/7400/assets/logomark/logomark.min.js?37"></script>
  <link rel="stylesheet" href="https://static.squarespace.com/static/ta/5134cbefe4b0c6fb04df8065/7400/assets/logomark/logomark.min.css?37" type="text/css" />
</noscript>
...
...

It struck me as odd, and got me googling for info to see if there's some kind of hidden functionality/purpose for such an odd bit of HTML, but to no avail. Is there some kind of purpose to having <script> tags inside of <noscript> elements, or is this just an example of bad HTML?

Javascript Solutions


Solution 1 - Javascript

I did some searching through their code and found this snippet (I've cleaned it up to make it more readable):

var DepLoader = (function () {
  function init() {
    var dependencies = document.getElementById("inline-deps");
    if (!dependencies || JS.hasClass(document.body, "deps--loaded")) {
      webfontsReady();
    } else {
      var html = dependencies.innerText || dependencies.textContent;
      JS.addClass(document.body, "deps--loaded");
      processRaw(html);
    }
  }
  
  function isListed(a, b) {
    for (var i = 0; i < b.length; i++) {
      if (a.indexOf(b[i]) !== -1) {
        return true;
      }
    }
    return false;
  }
  
  function webfontsReady() {
    JS.fireCustom("webfontsReady");
  }
  
  function processRaw(html) {
    var el = document.createElement("div");
    el.innerHTML = html;
    
    var scripts = el.querySelectorAll("script");
    var styles = el.querySelectorAll("link");
    var common, signup, dialog, systemPage, commerce;
    var others = [];
    var inline = [];
    var styleWhiteList = ["site.css", "dialog-", "signup-", "logomark"];
    var scriptBlackList = ["management-", "ckeditor-"];

    for (var i = 0; i < styles.length; i++) {
      var style = styles[i];
      if (style.href.indexOf("fonts.css") !== -1) load(style, webfontsReady);
      if (isListed(style.href, styleWhiteList)) load(style);
    }
    
    for (var i = 0; i < scripts.length; i++) {
      var script = scripts[i];
      var src = script.src;
      
      if (!src && script.getAttribute("data-sqs-type") !== "dynamic-assets-loader" && script.innerHTML.indexOf("SQUARESPACE_ROLLUPS") === -1) {
        eval(script.innerHTML);
      }
    }
        
    if (window.SQUARESPACE_ROLLUPS) {
      for (var key in SQUARESPACE_ROLLUPS) {
        var rollup = SQUARESPACE_ROLLUPS[key];
        var js = rollup.js;
        var css = rollup.css;
        
        if (key.indexOf("common") !== -1) {
          common = js;
        } else if (key.indexOf("commerce") !== -1) {
          commerce = js;
        } else if (key.indexOf("signup") !== -1) {
          signup = js;
        } else if (key.indexOf("dialog") !== -1) {
          dialog = js;
        } else if (key.indexOf("system-page") !== -1) {
          systemPage = js;
        } else if (key) {
          others = others.concat(js);
        } else {
          inline = inline.concat(js);
        }
      }
    }
    
    for (var i = 0; i < scripts.length; s++) {
      var script = scripts[i];
      var src = script.src;
      
      if (!isListed(src, scriptBlackList)) {
        if (src.indexOf("common-") !== -1) {
          common = script;
        } else if (src.indexOf("commerce-") !== -1) {
          commerce = script;
        } else if (src.indexOf("signup-") !== -1) {
          signup = script;
        } else if (src.indexOf("dialog-") !== -1) {
          dialog = script;
        } else if (src.indexOf("system-page-") !== -1) {
          systemPage = script;
        } else if (src) {
          others.push(script);
        } else {
          inline.push(script);
        }
      }
    }
    
    function loadOthers() {
      for (var i = 0; i < inline.length; i++) {
        if (inline[i].getAttribute("data-sqs-type") !== "dynamic-assets-loader") {
          load(inline[a]);
        }
      }
      
      for (var i = 0; i < others.length; i++) {
          load(others[i]);
      }
      
      JS.fireCustom("dependenciesLoaded");
    }

    var loadSystemPage = load.bind(this, systemPage, loadOthers, "system page");
    var loadSignup = load.bind(this, signup, loadSystemPage, "signup");
    var loadCommerce = load.bind(this, commerce, loadSignup, "commerce");
    var loadDialog = load.bind(this, dialog, loadCommerce, "dialog");
    var loadCommon = load.bind(this, common, loadDialog, "common");
    
    loadCommon();
  }
  
  function load(tag, callback, label) {
    var head = document.head;
    
    if (Array.isArray(tag)) tag = { nodeName: "SCRIPT", src: tag[0] };
    
    if (!tag) {
      if (callback) callback();
      return;
    }
    
    if (tag && (tag.src || tag.href)) {
      var child;
      if ("SCRIPT" === tag.nodeName) {
        child = document.createElement("script");
        child.src = tag.src;
        
        if (child.src.indexOf("combo") !== -1) {
          callback = function () {
            Y.Squarespace.FrontSite.Core.domReady(true)
          };
        }
      } else {
        if ("LINK" === tag.nodeName && "stylesheet" === tag.rel) {
          child = document.createElement("link");
          child.href = tag.href;
          child.rel = "stylesheet";
          child.tyle = "text/css";
        }
        
        if (child) {
          child.onload = callback;
          head.appendChild(child);
        }
      }
    } else {
      try {
        eval(tag.innerHTML);
      } catch (e) {}
    }
  }
  
  return { init: init, webfontsReady: webfontsReady };
})();

As you can see, the <noscript> tag has the ID #inline-deps, which is referenced in the code (line 3) to load dependencies asynchronously and on-demand.

They probably use a <noscript> element as it allows them to directly access DOM elements, instead of having to place it in a string or a comment (which I consider particularly bad, as comments are not meant for actual information) and then parse it. It also prevents the execution of scripts and CSS styles until specifically loaded.

I personally find this an abuse of the <noscript> tag. I'm not even sure if it's valid HTML5 code. Using other methods such as declaring dependencies in a JavaScript object with a script loader should be used where practicable.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAgent.Logic_View Question on Stackoverflow
Solution 1 - JavascriptQantas 94 HeavyView Answer on Stackoverflow