Skip to content

Commit

Permalink
Autoloader: Fixed data-dependencies and extensions (#2326)
Browse files Browse the repository at this point in the history
  • Loading branch information
RunDevelopment committed Jun 28, 2020
1 parent 8e9d161 commit 1654b25
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 37 deletions.
98 changes: 62 additions & 36 deletions plugins/autoloader/prism-autoloader.js
Expand Up @@ -269,42 +269,54 @@
}

/**
* Returns the path to a grammar, using the language_path and use_minified config keys.
* Returns all additional dependencies of the given element defined by the `data-dependencies` attribute.
*
* @param {string} lang
* @returns {string}
* @param {Element} element
* @returns {string[]}
*/
function getLanguagePath(lang) {
return config.languages_path +
'prism-' + lang
+ (config.use_minified ? '.min' : '') + '.js'
function getDependencies(element) {
var deps = (element.getAttribute('data-dependencies') || '').trim();
if (!deps) {
var parent = element.parentElement;
if (parent && parent.tagName.toLowerCase() === 'pre') {
deps = (parent.getAttribute('data-dependencies') || '').trim();
}
}
return deps ? deps.split(/\s*,\s*/g) : [];
}

/**
* Tries to load the grammar(s) and once loaded, highlights the given element again.
* Returns whether the given language is currently loaded.
*
* @param {string} lang
* @param {HTMLElement} elt
* @returns {boolean}
*/
function registerElement(lang, elt) {
if (lang in lang_aliases) {
lang = lang_aliases[lang];
function isLoaded(lang) {
if (lang.indexOf('!') >= 0) {
// forced reload
return false;
}

// Look for additional dependencies defined on the <code> or <pre> tags
var deps = (elt.getAttribute('data-dependencies') || '').trim();
if (!deps) {
var parent = elt.parentElement;
if (parent && parent.tagName.toLowerCase() === 'pre') {
deps = (parent.getAttribute('data-dependencies') || '').trim();
}
lang = lang_aliases[lang] || lang; // resolve alias

if (lang in Prism.languages) {
// the given language is already loaded
return true;
}

loadLanguages(deps ? deps.split(/\s*,\s*/g) : [], function () {
loadLanguage(lang, function () {
Prism.highlightElement(elt);
});
});
// this will catch extensions like CSS extras that don't add a grammar to Prism.languages
var data = lang_data[lang];
return data && !data.error && data.loading === false;
}

/**
* Returns the path to a grammar, using the language_path and use_minified config keys.
*
* @param {string} lang
* @returns {string}
*/
function getLanguagePath(lang) {
return config.languages_path + 'prism-' + lang + (config.use_minified ? '.min' : '') + '.js'
}

/**
Expand Down Expand Up @@ -364,7 +376,7 @@
lang = lang.replace('!', '');
lang = lang_aliases[lang] || lang;

var load = function () {
function load() {
var data = lang_data[lang];
if (!data) {
data = lang_data[lang] = {
Expand All @@ -376,21 +388,25 @@
error: error
});

if (!force && Prism.languages[lang]) {
languageCallback(lang, "success");
if (!force && isLoaded(lang)) {
// the language is already loaded and we aren't forced to reload
languageCallback(lang, 'success');
} else if (!force && data.error) {
languageCallback(lang, "error");
// the language failed to load before and we don't reload
languageCallback(lang, 'error');
} else if (force || !data.loading) {
// the language isn't currently loading and/or we are forced to reload
data.loading = true;
var src = getLanguagePath(lang);
addScript(src, function () {
data.error = false;

addScript(getLanguagePath(lang), function () {
data.loading = false;
languageCallback(lang, "success");
languageCallback(lang, 'success');

}, function () {
data.loading = false;
data.error = true;
languageCallback(lang, "error");
languageCallback(lang, 'error');
});
}
};
Expand Down Expand Up @@ -423,10 +439,20 @@
}

Prism.hooks.add('complete', function (env) {
if (env.element && env.language && !env.grammar) {
if (env.language !== ignored_language) {
registerElement(env.language, env.element);
}
var element = env.element;
var language = env.language;
if (!element || !language || language === ignored_language) {
return;
}

var deps = getDependencies(element);
deps.push(language);

if (!deps.every(isLoaded)) {
// the language or some dependencies aren't loaded
loadLanguages(dependencies, function () {
Prism.highlightElement(element);
});
}
});

Expand Down
2 changes: 1 addition & 1 deletion plugins/autoloader/prism-autoloader.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 1654b25

Please sign in to comment.