@@ -7078,6 +7078,99 @@ var AblePlayerInstances = [];
70787078
70797079})(jQuery);
70807080
7081+ var validate = {
7082+ processAndPreprocessTags: function (html) {
7083+ var preprocessedHtml = html.replace(
7084+ /<(v|c|b|i|u|lang|ruby)\.([\w\.]+)([^>]*)>/g,
7085+ function (match, tag, words, otherAttrs) {
7086+ var classAttr = words.split(".").join(" ");
7087+ return "<" + tag + ' class="' + classAttr + '"' + otherAttrs + ">";
7088+ }
7089+ );
7090+
7091+ preprocessedHtml = preprocessedHtml.replace(
7092+ /<lang\s+([\w-]+)([^>]*)>/g,
7093+ function (match, langCode, otherAttrs) {
7094+ return '<lang lang="' + langCode + '"' + otherAttrs + ">";
7095+ }
7096+ );
7097+
7098+ var processedHtml = preprocessedHtml.replace(
7099+ /<v\s+([^>]*?)>/g,
7100+ function (match, p1) {
7101+ var classMatch = p1.match(/class="([^"]*)"/);
7102+ var classAttr = classMatch ? classMatch[0] : "";
7103+ var p1WithoutClass = p1.replace(/class="[^"]*"/, "").trim();
7104+ var parts = p1WithoutClass.split(/\s+/);
7105+ var attributes = [];
7106+ var titleParts = [];
7107+
7108+ parts.forEach(function (part) {
7109+ if (part.indexOf("=") !== -1) {
7110+ attributes.push(part);
7111+ } else {
7112+ titleParts.push(part);
7113+ }
7114+ });
7115+
7116+ var title = titleParts.join(" ");
7117+ var newTag = "<v";
7118+
7119+ if (title) {
7120+ newTag += ' title="' + title + '"';
7121+ }
7122+
7123+ if (attributes.length > 0) {
7124+ newTag += " " + attributes.join(" ");
7125+ }
7126+
7127+ if (classAttr) {
7128+ newTag += " " + classAttr;
7129+ }
7130+
7131+ newTag += ">";
7132+ return newTag;
7133+ }
7134+ );
7135+
7136+ return processedHtml;
7137+ },
7138+
7139+ postprocessCTag: function (vttData) {
7140+ return vttData.replace(
7141+ /<c class="([\w\s]+)">/g,
7142+ function (match, classNames) {
7143+ var classes = classNames.split(" ").join(".");
7144+ return "<c." + classes + ">";
7145+ }
7146+ );
7147+ },
7148+
7149+ postprocessVTag: function (vttData) {
7150+ return vttData.replace(
7151+ /<v class="([\w\s]+)"([^>]*)>/g,
7152+ function (match, classNames, otherAttrs) {
7153+ var classes = classNames.split(" ").join(".");
7154+ return "<v." + classes + otherAttrs + ">";
7155+ }
7156+ );
7157+ },
7158+
7159+ postprocessLangTag: function (vttData) {
7160+ return vttData.replace(
7161+ /<lang lang="([\w-]+)"([^>]*)>/g,
7162+ function (match, langCode, otherAttrs) {
7163+ return "<lang " + langCode + otherAttrs + ">";
7164+ }
7165+ );
7166+ },
7167+ };
7168+
7169+ // Export the object for use in other files
7170+ if (typeof module !== "undefined" && module.exports) {
7171+ module.exports = validate;
7172+ }
7173+
70817174(function ($) {
70827175 // Loads files referenced in track elements, and performs appropriate setup.
70837176 // For example, captions and text descriptions.
@@ -7503,121 +7596,150 @@ var AblePlayerInstances = [];
75037596 }
75047597 };
75057598
7599+ // AblePlayer.prototype.sanitizeVttData = function (vttData) {
7600+ // // Combined function to process <v> tags and preprocess <v.word.word> and <c.word.word> tags
7601+ // function processAndPreprocessTags(html) {
7602+ // // First, preprocess <v.word.word> and <c.word.word> tags
7603+ // var preprocessedHtml = html.replace(
7604+ // /<(v|c|b|i|u|lang|ruby)\.([\w\.]+)([^>]*)>/g,
7605+ // function (match, tag, words, otherAttrs) {
7606+ // var classAttr = words.split(".").join(" ");
7607+ // return "<" + tag + ' class="' + classAttr + '"' + otherAttrs + ">";
7608+ // }
7609+ // );
7610+
7611+ // // Preprocess <lang> tags to replace language code with lang attribute
7612+ // preprocessedHtml = preprocessedHtml.replace(
7613+ // /<lang\s+([\w-]+)([^>]*)>/g,
7614+ // function (match, langCode, otherAttrs) {
7615+ // return '<lang lang="' + langCode + '"' + otherAttrs + ">";
7616+ // }
7617+ // );
7618+
7619+ // // Then, process <v> tags to add title attribute and handle class attribute correctly
7620+ // var processedHtml = preprocessedHtml.replace(
7621+ // /<v\s+([^>]*?)>/g,
7622+ // function (match, p1) {
7623+ // // Extract class attribute if present
7624+ // var classMatch = p1.match(/class="([^"]*)"/);
7625+ // var classAttr = classMatch ? classMatch[0] : "";
7626+
7627+ // // Remove class attribute from p1 to process the title
7628+ // var p1WithoutClass = p1.replace(/class="[^"]*"/, "").trim();
7629+
7630+ // // Split the remaining content by spaces
7631+ // var parts = p1WithoutClass.split(/\s+/);
7632+ // var attributes = [];
7633+ // var titleParts = [];
7634+
7635+ // // Separate attributes and title parts
7636+ // parts.forEach(function (part) {
7637+ // if (part.indexOf("=") !== -1) {
7638+ // attributes.push(part);
7639+ // } else {
7640+ // titleParts.push(part);
7641+ // }
7642+ // });
7643+
7644+ // // Construct the new <v> tag
7645+ // var title = titleParts.join(" ");
7646+ // var newTag =
7647+ // '<v title="' +
7648+ // title +
7649+ // '" ' +
7650+ // attributes.join(" ") +
7651+ // " " +
7652+ // classAttr +
7653+ // ">";
7654+ // return newTag;
7655+ // }
7656+ // );
7657+
7658+ // return processedHtml;
7659+ // }
7660+
7661+ // // Function to postprocess <c> tags
7662+ // function postprocessCTag(vttData) {
7663+ // return vttData.replace(
7664+ // /<c class="([\w\s]+)">/g,
7665+ // function (match, classNames) {
7666+ // var classes = classNames.split(" ").join(".");
7667+ // return "<c." + classes + ">";
7668+ // }
7669+ // );
7670+ // }
7671+
7672+ // // Function to postprocess <v> tags
7673+ // function postprocessVTag(vttData) {
7674+ // return vttData.replace(
7675+ // /<v class="([\w\s]+)"([^>]*)>/g,
7676+ // function (match, classNames, otherAttrs) {
7677+ // var classes = classNames.split(" ").join(".");
7678+ // return "<v." + classes + otherAttrs + ">";
7679+ // }
7680+ // );
7681+ // }
7682+
7683+ // // Function to postprocess <lang> tags
7684+ // function postprocessLangTag(vttData) {
7685+ // return vttData.replace(
7686+ // /<lang lang="([\w-]+)"([^>]*)>/g,
7687+ // function (match, langCode, otherAttrs) {
7688+ // return "<lang " + langCode + otherAttrs + ">";
7689+ // }
7690+ // );
7691+ // }
7692+
7693+ // // Process <v> and <c> attribute processing
7694+ // vttData = processAndPreprocessTags(vttData);
7695+
7696+ // // Configure DOMPurify
7697+ // var config = {
7698+ // ALLOWED_TAGS: ["b", "i", "u", "v", "c", "lang", "ruby", "rt", "rp"],
7699+ // ALLOWED_ATTR: ["title", "class", "lang"],
7700+ // KEEP_CONTENT: true, // Keep the content of removed elements
7701+ // };
7702+
7703+ // // Sanitize the VTT data
7704+ // var sanitizedVttData = DOMPurify.sanitize(vttData, config);
7705+
7706+ // // Postprocessing after sanitizing
7707+ // sanitizedVttData = postprocessCTag(sanitizedVttData);
7708+ // sanitizedVttData = postprocessVTag(sanitizedVttData);
7709+ // sanitizedVttData = postprocessLangTag(sanitizedVttData);
7710+
7711+ // sanitizedVttData = sanitizedVttData.replace(/-->/g, "-->");
7712+
7713+ // // Remove any </v> tags added by DOMPurify but preserve pre-existing ones
7714+ // var originalVttData = vttData;
7715+ // sanitizedVttData = sanitizedVttData.replace(
7716+ // /<\/v>/g,
7717+ // function (match, offset) {
7718+ // return originalVttData.indexOf(match, offset) !== -1 ? match : "";
7719+ // }
7720+ // );
7721+
7722+ // return sanitizedVttData;
7723+ // };
7724+
7725+ // Main function
75067726 AblePlayer.prototype.sanitizeVttData = function (vttData) {
7507- // Combined function to process <v> tags and preprocess <v.word.word> and <c.word.word> tags
7508- function processAndPreprocessTags(html) {
7509- // First, preprocess <v.word.word> and <c.word.word> tags
7510- var preprocessedHtml = html.replace(
7511- /<(v|c|b|i|u|lang|ruby)\.([\w\.]+)([^>]*)>/g,
7512- function (match, tag, words, otherAttrs) {
7513- var classAttr = words.split(".").join(" ");
7514- return "<" + tag + ' class="' + classAttr + '"' + otherAttrs + ">";
7515- }
7516- );
7517-
7518- // Preprocess <lang> tags to replace language code with lang attribute
7519- preprocessedHtml = preprocessedHtml.replace(
7520- /<lang\s+([\w-]+)([^>]*)>/g,
7521- function (match, langCode, otherAttrs) {
7522- return '<lang lang="' + langCode + '"' + otherAttrs + ">";
7523- }
7524- );
7525-
7526- // Then, process <v> tags to add title attribute and handle class attribute correctly
7527- var processedHtml = preprocessedHtml.replace(
7528- /<v\s+([^>]*?)>/g,
7529- function (match, p1) {
7530- // Extract class attribute if present
7531- var classMatch = p1.match(/class="([^"]*)"/);
7532- var classAttr = classMatch ? classMatch[0] : "";
7533-
7534- // Remove class attribute from p1 to process the title
7535- var p1WithoutClass = p1.replace(/class="[^"]*"/, "").trim();
7536-
7537- // Split the remaining content by spaces
7538- var parts = p1WithoutClass.split(/\s+/);
7539- var attributes = [];
7540- var titleParts = [];
7541-
7542- // Separate attributes and title parts
7543- parts.forEach(function (part) {
7544- if (part.indexOf("=") !== -1) {
7545- attributes.push(part);
7546- } else {
7547- titleParts.push(part);
7548- }
7549- });
7550-
7551- // Construct the new <v> tag
7552- var title = titleParts.join(" ");
7553- var newTag =
7554- '<v title="' +
7555- title +
7556- '" ' +
7557- attributes.join(" ") +
7558- " " +
7559- classAttr +
7560- ">";
7561- return newTag;
7562- }
7563- );
7564-
7565- return processedHtml;
7566- }
7567-
7568- // Function to postprocess <c> tags
7569- function postprocessCTag(vttData) {
7570- return vttData.replace(
7571- /<c class="([\w\s]+)">/g,
7572- function (match, classNames) {
7573- var classes = classNames.split(" ").join(".");
7574- return "<c." + classes + ">";
7575- }
7576- );
7577- }
7578-
7579- // Function to postprocess <v> tags
7580- function postprocessVTag(vttData) {
7581- return vttData.replace(
7582- /<v class="([\w\s]+)"([^>]*)>/g,
7583- function (match, classNames, otherAttrs) {
7584- var classes = classNames.split(" ").join(".");
7585- return "<v." + classes + otherAttrs + ">";
7586- }
7587- );
7588- }
7589-
7590- // Function to postprocess <lang> tags
7591- function postprocessLangTag(vttData) {
7592- return vttData.replace(
7593- /<lang lang="([\w-]+)"([^>]*)>/g,
7594- function (match, langCode, otherAttrs) {
7595- return "<lang " + langCode + otherAttrs + ">";
7596- }
7597- );
7598- }
7599-
7600- // Process <v> and <c> attribute processing
7601- vttData = processAndPreprocessTags(vttData);
7727+ vttData = validate.processAndPreprocessTags(vttData);
76027728
7603- // Configure DOMPurify
76047729 var config = {
76057730 ALLOWED_TAGS: ["b", "i", "u", "v", "c", "lang", "ruby", "rt", "rp"],
76067731 ALLOWED_ATTR: ["title", "class", "lang"],
7607- KEEP_CONTENT: true, // Keep the content of removed elements
7732+ KEEP_CONTENT: true,
76087733 };
76097734
7610- // Sanitize the VTT data
76117735 var sanitizedVttData = DOMPurify.sanitize(vttData, config);
76127736
7613- // Postprocessing after sanitizing
7614- sanitizedVttData = postprocessCTag(sanitizedVttData);
7615- sanitizedVttData = postprocessVTag(sanitizedVttData);
7616- sanitizedVttData = postprocessLangTag(sanitizedVttData);
7737+ sanitizedVttData = validate.postprocessCTag(sanitizedVttData);
7738+ sanitizedVttData = validate.postprocessVTag(sanitizedVttData);
7739+ sanitizedVttData = validate.postprocessLangTag(sanitizedVttData);
76177740
76187741 sanitizedVttData = sanitizedVttData.replace(/-->/g, "-->");
76197742
7620- // Remove any </v> tags added by DOMPurify but preserve pre-existing ones
76217743 var originalVttData = vttData;
76227744 sanitizedVttData = sanitizedVttData.replace(
76237745 /<\/v>/g,
0 commit comments