@sitecore-jss/sitecore-jss
Version:
This module is provided as a part of Sitecore JavaScript Rendering SDK. It contains the core JSS APIs (layout service) and utilities.
126 lines (125 loc) • 5.58 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSrcSet = exports.updateImageUrl = exports.replaceMediaUrlPrefix = exports.getRequiredParams = exports.findEditorImageTag = void 0;
const lodash_unescape_1 = __importDefault(require("lodash.unescape"));
const url_parse_1 = __importDefault(require("url-parse"));
// finds an img tag with HTML attributes
const imgTagRegex = /<img([^>]+)\/>/i;
// finds all the HTML attributes in a string
const htmlAttrsRegex = /([^=\s]+)(="([^"]*)")?/gi;
// finds the Sitecore media URL prefix
const mediaUrlPrefixRegex = /\/([-~]{1})\/media\//i;
/**
* Makes a request to Sitecore Content Service for the specified item path.
* @param {string} editorMarkup the markup to parse
* @returns {object | null} found image tag; null in case if not found
*/
const findEditorImageTag = (editorMarkup) => {
// match the tag
const tagMatch = editorMarkup.match(imgTagRegex);
if (!tagMatch || tagMatch.length < 2) {
return null;
}
// find the attrs and turn them into a Map
const attrs = {};
let match = htmlAttrsRegex.exec(tagMatch[1]);
while (match !== null) {
attrs[match[1]] = (0, lodash_unescape_1.default)(match[3]);
match = htmlAttrsRegex.exec(tagMatch[1]);
}
return {
imgTag: tagMatch[0],
attrs,
};
};
exports.findEditorImageTag = findEditorImageTag;
/**
* Get required query string params which should be merged with user params
* @param {object} qs layout service parsed query string
* @returns {object} requiredParams
*/
const getRequiredParams = (qs) => {
const { rev, db, la, vs, ts } = qs;
return { rev, db, la, vs, ts };
};
exports.getRequiredParams = getRequiredParams;
/**
* Replace `/~/media` or `/-/media` with `/~/jssmedia` or `/-/jssmedia`, respectively.
* Can use `mediaUrlPrefix` in order to use a custom prefix.
* @param {string} url The URL to replace the media URL prefix in
* @param {RegExp} [mediaUrlPrefix] The regex to match the media URL prefix
* @returns {string} The URL with the media URL prefix replaced
*/
const replaceMediaUrlPrefix = (url, mediaUrlPrefix = mediaUrlPrefixRegex) => {
const parsed = (0, url_parse_1.default)(url, {}, true);
const match = mediaUrlPrefix.exec(parsed.pathname);
if (match && match.length > 1) {
// regex will provide us with /-/ or /~/ type
parsed.set('pathname', parsed.pathname.replace(mediaUrlPrefix, `/${match[1]}/jssmedia/`));
}
return parsed.toString();
};
exports.replaceMediaUrlPrefix = replaceMediaUrlPrefix;
/**
* Prepares a Sitecore media URL with `params` for use by the JSS media handler.
* This is done by replacing `/~/media` or `/-/media` with `/~/jssmedia` or `/-/jssmedia`, respectively.
* Provided `params` are used as the querystring parameters for the media URL.
* Can use `mediaUrlPrefix` in order to use a custom prefix.
* If no `params` are sent, the original media URL is returned.
* @param {string} url The URL to prepare
* @param {object} [params] The querystring parameters to use
* @param {RegExp} [mediaUrlPrefix] The regex to match the media URL prefix
* @returns {string} The prepared URL
*/
const updateImageUrl = (url, params, mediaUrlPrefix = mediaUrlPrefixRegex) => {
if (!params || Object.keys(params).length === 0) {
// if params aren't supplied, no need to run it through JSS media handler
return url;
}
// polyfill node `global` in browser to workaround https://github.com/unshiftio/url-parse/issues/150
if (typeof window !== 'undefined' && !window.global) {
window.global = {};
}
const parsed = (0, url_parse_1.default)((0, exports.replaceMediaUrlPrefix)(url, mediaUrlPrefix), {}, true);
const requiredParams = (0, exports.getRequiredParams)(parsed.query);
const query = Object.assign({}, params);
Object.entries(requiredParams).forEach(([key, param]) => {
if (param) {
query[key] = param;
}
});
parsed.set('query', query);
return parsed.toString();
};
exports.updateImageUrl = updateImageUrl;
/**
* Receives an array of `srcSet` parameters that are iterated and used as parameters to generate
* a corresponding set of updated Sitecore media URLs via @see updateImageUrl. The result is a comma-delimited
* list of media URLs with respective dimension parameters.
* @example
* // returns '/ipsum.jpg?h=1000&w=1000 1000w, /ipsum.jpg?mh=250&mw=250 250w'
* getSrcSet('/ipsum.jpg', [{ h: 1000, w: 1000 }, { mh: 250, mw: 250 } ])
* More information about `srcSet`: {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img}
* @param {string} url The URL to prepare
* @param {Array} srcSet The array of parameters to use
* @param {object} [imageParams] The querystring parameters to use
* @param {RegExp} [mediaUrlPrefix] The regex to match the media URL prefix
* @returns {string} The prepared URL
*/
const getSrcSet = (url, srcSet, imageParams, mediaUrlPrefix) => {
return srcSet
.map((params) => {
const newParams = Object.assign(Object.assign({}, imageParams), params);
const imageWidth = newParams.w || newParams.mw;
if (!imageWidth) {
return null;
}
return `${(0, exports.updateImageUrl)(url, newParams, mediaUrlPrefix)} ${imageWidth}w`;
})
.filter((value) => value)
.join(', ');
};
exports.getSrcSet = getSrcSet;