mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-24 19:33:02 +03:00
Replaced mobiledoc cards with @tryghost/kg-default-cards
no issue - moved card definitions to a new library `@tryghost/kg-default-cards` - moved `createCard` factory function to a new library `@tryghost/kg-card-factory`
This commit is contained in:
parent
a5b14419af
commit
1ee1e68adf
@ -1,44 +0,0 @@
|
||||
// this is a function so that when it's aliased across multiple cards we do not
|
||||
// end up modifying the object by reference
|
||||
module.exports = function markdownCardDefinition() {
|
||||
return {
|
||||
name: 'markdown',
|
||||
type: 'dom',
|
||||
config: {
|
||||
commentWrapper: true
|
||||
},
|
||||
|
||||
render: function (opts) {
|
||||
let markdownHtmlRenderer = require('@tryghost/kg-markdown-html-renderer');
|
||||
let payload = opts.payload;
|
||||
let version = opts.options && opts.options.version || 2;
|
||||
// convert markdown to HTML ready for insertion into dom
|
||||
let html = markdownHtmlRenderer.render(payload.markdown || '');
|
||||
|
||||
if (!html) {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Ghost 1.0's markdown-only renderer wrapped cards. Remove in Ghost 3.0
|
||||
*/
|
||||
if (version === 1) {
|
||||
html = `<div class="kg-card-markdown">${html}</div>`;
|
||||
}
|
||||
|
||||
// use the SimpleDOM document to create a raw HTML section.
|
||||
// avoids parsing/rendering of potentially broken or unsupported HTML
|
||||
return opts.env.dom.createRawHTMLSection(html);
|
||||
},
|
||||
|
||||
absoluteToRelative(urlUtils, payload, options) {
|
||||
payload.markdown = payload.markdown && urlUtils.markdownAbsoluteToRelative(payload.markdown, options);
|
||||
return payload;
|
||||
},
|
||||
|
||||
relativeToAbsolute(urlUtils, payload, options) {
|
||||
payload.markdown = payload.markdown && urlUtils.markdownRelativeToAbsolute(payload.markdown, options);
|
||||
return payload;
|
||||
}
|
||||
};
|
||||
};
|
@ -1,110 +0,0 @@
|
||||
/**
|
||||
<figure class="kg-card kg-bookmark-card">
|
||||
<a href="[URL]" class="kg-bookmark-container">
|
||||
<div class="kg-bookmark-content">
|
||||
<div class="kg-bookmark-title">[TITLE]</div>
|
||||
<div class="kg-bookmark-description">[DESCRIPTION]</div>
|
||||
<div class="kg-bookmark-metadata">
|
||||
<img src="[ICON]" class="kg-bookmark-icon">
|
||||
<span class="kg-bookmark-author">[AUTHOR]</span>
|
||||
<span class="kg-bookmark-publisher">[PUBLISHER]</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="kg-bookmark-thumbnail">
|
||||
<img src="[THUMBNAIL]">
|
||||
</div>
|
||||
</a>
|
||||
</figure>
|
||||
*/
|
||||
|
||||
const createCard = require('./lib/create-card');
|
||||
|
||||
function createElement(dom, elem, classNames = '', attributes = [], text) {
|
||||
let element = dom.createElement(elem);
|
||||
if (classNames) {
|
||||
element.setAttribute('class', classNames);
|
||||
}
|
||||
attributes.forEach((attr) => {
|
||||
element.setAttribute(attr.key, attr.value);
|
||||
});
|
||||
if (text) {
|
||||
element.appendChild(dom.createTextNode(text));
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
module.exports = createCard({
|
||||
name: 'bookmark',
|
||||
type: 'dom',
|
||||
render(opts) {
|
||||
let {payload, env: {dom}} = opts;
|
||||
|
||||
if (!payload.metadata || !payload.metadata.url || !payload.metadata.title || !payload.metadata.description) {
|
||||
return '';
|
||||
}
|
||||
|
||||
let figure = createElement(dom, 'figure', 'kg-card kg-bookmark-card');
|
||||
let linkTag = createElement(dom, 'a', 'kg-bookmark-container', [{
|
||||
key: 'href',
|
||||
value: payload.metadata.url
|
||||
}]);
|
||||
let contentDiv = createElement(dom, 'div', 'kg-bookmark-content');
|
||||
let titleDiv = createElement(dom, 'div', 'kg-bookmark-title', [] , payload.metadata.title);
|
||||
let descriptionDiv = createElement(dom, 'div', 'kg-bookmark-description', [] , payload.metadata.description);
|
||||
let metadataDiv = createElement(dom, 'div', 'kg-bookmark-metadata');
|
||||
let imgIcon = createElement(dom, 'img', 'kg-bookmark-icon', [{
|
||||
key: 'src',
|
||||
value: payload.metadata.icon
|
||||
}]);
|
||||
let authorSpan = createElement(dom, 'span', 'kg-bookmark-author', [] , payload.metadata.author);
|
||||
let publisherSpan = createElement(dom, 'span', 'kg-bookmark-publisher', [] , payload.metadata.publisher);
|
||||
let thumbnailDiv = createElement(dom, 'div', 'kg-bookmark-thumbnail');
|
||||
let thumbnailImg = createElement(dom, 'img', '', [{
|
||||
key: 'src',
|
||||
value: payload.metadata.thumbnail
|
||||
}]);
|
||||
thumbnailDiv.appendChild(thumbnailImg);
|
||||
if (payload.metadata.icon) {
|
||||
metadataDiv.appendChild(imgIcon);
|
||||
}
|
||||
if (payload.metadata.author) {
|
||||
metadataDiv.appendChild(authorSpan);
|
||||
}
|
||||
if (payload.metadata.publisher) {
|
||||
metadataDiv.appendChild(publisherSpan);
|
||||
}
|
||||
contentDiv.appendChild(titleDiv);
|
||||
contentDiv.appendChild(descriptionDiv);
|
||||
contentDiv.appendChild(metadataDiv);
|
||||
linkTag.appendChild(contentDiv);
|
||||
if (payload.metadata.thumbnail) {
|
||||
linkTag.appendChild(thumbnailDiv);
|
||||
}
|
||||
figure.appendChild(linkTag);
|
||||
|
||||
if (payload.caption) {
|
||||
let figcaption = dom.createElement('figcaption');
|
||||
figcaption.appendChild(dom.createRawHTMLSection(payload.caption));
|
||||
figure.appendChild(figcaption);
|
||||
figure.setAttribute('class', `${figure.getAttribute('class')} kg-card-hascaption`);
|
||||
}
|
||||
|
||||
return figure;
|
||||
},
|
||||
|
||||
absoluteToRelative(urlUtils, payload, options) {
|
||||
if (payload.metadata) {
|
||||
payload.metadata.url = payload.metadata.url && urlUtils.absoluteToRelative(payload.metadata.url, options);
|
||||
}
|
||||
payload.caption = payload.caption && urlUtils.htmlAbsoluteToRelative(payload.caption, options);
|
||||
return payload;
|
||||
},
|
||||
|
||||
relativeToAbsolute(urlUtils, payload, options) {
|
||||
if (payload.metadata) {
|
||||
payload.metadata.url = payload.metadata.url && urlUtils.relativeToAbsolute(payload.metadata.url, options);
|
||||
}
|
||||
payload.caption = payload.caption && urlUtils.htmlRelativeToAbsolute(payload.caption, options);
|
||||
return payload;
|
||||
}
|
||||
});
|
@ -1,9 +0,0 @@
|
||||
// this card is just an alias of the `markdown` card which is necessary because
|
||||
// our markdown-only editor was using the `card-markdown` card name
|
||||
const markdownCard = require('./_markdown');
|
||||
const createCard = require('./lib/create-card');
|
||||
|
||||
const v1CompatMarkdownCard = markdownCard();
|
||||
v1CompatMarkdownCard.name = 'card-markdown';
|
||||
|
||||
module.exports = createCard(v1CompatMarkdownCard);
|
@ -1,48 +0,0 @@
|
||||
const createCard = require('./lib/create-card');
|
||||
|
||||
module.exports = createCard({
|
||||
name: 'code',
|
||||
type: 'dom',
|
||||
render(opts) {
|
||||
let payload = opts.payload;
|
||||
let dom = opts.env.dom;
|
||||
|
||||
if (!payload.code) {
|
||||
return '';
|
||||
}
|
||||
|
||||
let pre = dom.createElement('pre');
|
||||
let code = dom.createElement('code');
|
||||
|
||||
if (payload.language) {
|
||||
code.setAttribute('class', `language-${payload.language}`);
|
||||
}
|
||||
|
||||
code.appendChild(dom.createTextNode(payload.code));
|
||||
pre.appendChild(code);
|
||||
|
||||
if (payload.caption) {
|
||||
let figure = dom.createElement('figure');
|
||||
figure.setAttribute('class', 'kg-card kg-code-card');
|
||||
figure.appendChild(pre);
|
||||
|
||||
let figcaption = dom.createElement('figcaption');
|
||||
figcaption.appendChild(dom.createRawHTMLSection(payload.caption));
|
||||
figure.appendChild(figcaption);
|
||||
|
||||
return figure;
|
||||
} else {
|
||||
return pre;
|
||||
}
|
||||
},
|
||||
|
||||
absoluteToRelative(urlUtils, payload, options) {
|
||||
payload.caption = payload.caption && urlUtils.htmlAbsoluteToRelative(payload.caption, options);
|
||||
return payload;
|
||||
},
|
||||
|
||||
relativeToAbsolute(urlUtils, payload, options) {
|
||||
payload.caption = payload.caption && urlUtils.htmlRelativeToAbsolute(payload.caption, options);
|
||||
return payload;
|
||||
}
|
||||
});
|
@ -1,38 +0,0 @@
|
||||
const createCard = require('./lib/create-card');
|
||||
|
||||
module.exports = createCard({
|
||||
name: 'embed',
|
||||
type: 'dom',
|
||||
render(opts) {
|
||||
if (!opts.payload.html) {
|
||||
return '';
|
||||
}
|
||||
|
||||
let {payload, env: {dom}} = opts;
|
||||
|
||||
let figure = dom.createElement('figure');
|
||||
figure.setAttribute('class', 'kg-card kg-embed-card');
|
||||
|
||||
let html = dom.createRawHTMLSection(payload.html);
|
||||
figure.appendChild(html);
|
||||
|
||||
if (payload.caption) {
|
||||
let figcaption = dom.createElement('figcaption');
|
||||
figcaption.appendChild(dom.createRawHTMLSection(payload.caption));
|
||||
figure.appendChild(figcaption);
|
||||
figure.setAttribute('class', `${figure.getAttribute('class')} kg-card-hascaption`);
|
||||
}
|
||||
|
||||
return figure;
|
||||
},
|
||||
|
||||
absoluteToRelative(urlUtils, payload, options) {
|
||||
payload.caption = payload.caption && urlUtils.htmlAbsoluteToRelative(payload.caption, options);
|
||||
return payload;
|
||||
},
|
||||
|
||||
relativeToAbsolute(urlUtils, payload, options) {
|
||||
payload.caption = payload.caption && urlUtils.htmlRelativeToAbsolute(payload.caption, options);
|
||||
return payload;
|
||||
}
|
||||
});
|
@ -1,138 +0,0 @@
|
||||
/**
|
||||
* <figure class="kg-gallery-card kg-width-wide">
|
||||
* <div class="kg-gallery-container>
|
||||
* <div class="kg-gallery-row">
|
||||
* <div class="kg-gallery-image"><img width="" height=""></div>
|
||||
* <div class="kg-gallery-image"><img width="" height=""></div>
|
||||
* <div class="kg-gallery-image"><img width="" height=""></div>
|
||||
* </div>
|
||||
* <div class="kg-gallery-row">
|
||||
* <div class="kg-gallery-image"><img></div>
|
||||
* <div class="kg-gallery-image"><img></div>
|
||||
* </div>
|
||||
* </div>
|
||||
* <figcaption></figcaption>
|
||||
* </figure>
|
||||
*/
|
||||
|
||||
const createCard = require('./lib/create-card');
|
||||
|
||||
const MAX_IMG_PER_ROW = 3;
|
||||
|
||||
module.exports = createCard({
|
||||
name: 'gallery',
|
||||
type: 'dom',
|
||||
render(opts) {
|
||||
let payload = opts.payload;
|
||||
// let version = opts.options.version;
|
||||
let dom = opts.env.dom;
|
||||
|
||||
let isValidImage = (image) => {
|
||||
return image.fileName
|
||||
&& image.src
|
||||
&& image.width
|
||||
&& image.height;
|
||||
};
|
||||
|
||||
let validImages = [];
|
||||
|
||||
if (payload.images && payload.images.length) {
|
||||
validImages = payload.images.filter(isValidImage);
|
||||
}
|
||||
|
||||
if (validImages.length === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
let figure = dom.createElement('figure');
|
||||
figure.setAttribute('class', 'kg-card kg-gallery-card kg-width-wide');
|
||||
|
||||
let container = dom.createElement('div');
|
||||
container.setAttribute('class', 'kg-gallery-container');
|
||||
figure.appendChild(container);
|
||||
|
||||
let buildStructure = function buildStructure(images) {
|
||||
let rows = [];
|
||||
let noOfImages = images.length;
|
||||
|
||||
images.forEach((image, idx) => {
|
||||
let row = image.row;
|
||||
|
||||
if (noOfImages > 1 && (noOfImages % MAX_IMG_PER_ROW === 1) && (idx === (noOfImages - 2))) {
|
||||
row = row + 1;
|
||||
}
|
||||
if (!rows[row]) {
|
||||
rows[row] = [];
|
||||
}
|
||||
|
||||
rows[row].push(image);
|
||||
});
|
||||
|
||||
return rows;
|
||||
};
|
||||
|
||||
let rows = buildStructure(validImages);
|
||||
|
||||
rows.forEach((row) => {
|
||||
let rowDiv = dom.createElement('div');
|
||||
rowDiv.setAttribute('class', 'kg-gallery-row');
|
||||
|
||||
row.forEach((image) => {
|
||||
let imgDiv = dom.createElement('div');
|
||||
imgDiv.setAttribute('class', 'kg-gallery-image');
|
||||
|
||||
let img = dom.createElement('img');
|
||||
img.setAttribute('src', image.src);
|
||||
img.setAttribute('width', image.width);
|
||||
img.setAttribute('height', image.height);
|
||||
|
||||
if (image.alt) {
|
||||
img.setAttribute('alt', image.alt);
|
||||
}
|
||||
if (image.title) {
|
||||
img.setAttribute('title', image.title);
|
||||
}
|
||||
|
||||
imgDiv.appendChild(img);
|
||||
rowDiv.appendChild(imgDiv);
|
||||
});
|
||||
|
||||
container.appendChild(rowDiv);
|
||||
});
|
||||
|
||||
if (payload.caption) {
|
||||
let figcaption = dom.createElement('figcaption');
|
||||
figcaption.appendChild(dom.createRawHTMLSection(payload.caption));
|
||||
figure.appendChild(figcaption);
|
||||
figure.setAttribute('class', `${figure.getAttribute('class')} kg-card-hascaption`);
|
||||
}
|
||||
|
||||
return figure;
|
||||
},
|
||||
|
||||
absoluteToRelative(urlUtils, payload, options) {
|
||||
if (payload.images) {
|
||||
payload.images.forEach((image) => {
|
||||
image.src = image.src && urlUtils.absoluteToRelative(image.src, options);
|
||||
image.caption = image.caption && urlUtils.htmlAbsoluteToRelative(image.caption, options);
|
||||
});
|
||||
}
|
||||
|
||||
payload.caption = payload.caption && urlUtils.htmlAbsoluteToRelative(payload.caption, options);
|
||||
|
||||
return payload;
|
||||
},
|
||||
|
||||
relativeToAbsolute(urlUtils, payload, options) {
|
||||
if (payload.images) {
|
||||
payload.images.forEach((image) => {
|
||||
image.src = image.src && urlUtils.relativeToAbsolute(image.src, options);
|
||||
image.caption = image.caption && urlUtils.htmlRelativeToAbsolute(image.caption, options);
|
||||
});
|
||||
}
|
||||
|
||||
payload.caption = payload.caption && urlUtils.htmlRelativeToAbsolute(payload.caption, options);
|
||||
|
||||
return payload;
|
||||
}
|
||||
});
|
@ -1,9 +0,0 @@
|
||||
const createCard = require('./lib/create-card');
|
||||
|
||||
module.exports = createCard({
|
||||
name: 'hr',
|
||||
type: 'dom',
|
||||
render(opts) {
|
||||
return opts.env.dom.createElement('hr');
|
||||
}
|
||||
});
|
@ -1,28 +0,0 @@
|
||||
const createCard = require('./lib/create-card');
|
||||
|
||||
module.exports = createCard({
|
||||
name: 'html',
|
||||
type: 'dom',
|
||||
config: {
|
||||
commentWrapper: true
|
||||
},
|
||||
render(opts) {
|
||||
if (!opts.payload.html) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// use the SimpleDOM document to create a raw HTML section.
|
||||
// avoids parsing/rendering of potentially broken or unsupported HTML
|
||||
return opts.env.dom.createRawHTMLSection(opts.payload.html);
|
||||
},
|
||||
|
||||
absoluteToRelative(urlUtils, payload, options) {
|
||||
payload.html = payload.html && urlUtils.htmlAbsoluteToRelative(payload.html, options);
|
||||
return payload;
|
||||
},
|
||||
|
||||
relativeToAbsolute(urlUtils, payload, options) {
|
||||
payload.html = payload.html && urlUtils.htmlRelativeToAbsolute(payload.html, options);
|
||||
return payload;
|
||||
}
|
||||
});
|
@ -1,55 +0,0 @@
|
||||
const createCard = require('./lib/create-card');
|
||||
|
||||
module.exports = createCard({
|
||||
name: 'image',
|
||||
type: 'dom',
|
||||
render(opts) {
|
||||
let payload = opts.payload;
|
||||
// let version = opts.options.version;
|
||||
let dom = opts.env.dom;
|
||||
|
||||
if (!payload.src) {
|
||||
return '';
|
||||
}
|
||||
|
||||
let figure = dom.createElement('figure');
|
||||
let figureClass = 'kg-card kg-image-card';
|
||||
if (payload.cardWidth) {
|
||||
figureClass = `${figureClass} kg-width-${payload.cardWidth}`;
|
||||
}
|
||||
figure.setAttribute('class', figureClass);
|
||||
|
||||
let img = dom.createElement('img');
|
||||
img.setAttribute('src', payload.src);
|
||||
img.setAttribute('class', 'kg-image');
|
||||
if (payload.alt) {
|
||||
img.setAttribute('alt', payload.alt);
|
||||
}
|
||||
if (payload.title) {
|
||||
img.setAttribute('title', payload.title);
|
||||
}
|
||||
|
||||
figure.appendChild(img);
|
||||
|
||||
if (payload.caption) {
|
||||
let figcaption = dom.createElement('figcaption');
|
||||
figcaption.appendChild(dom.createRawHTMLSection(payload.caption));
|
||||
figure.appendChild(figcaption);
|
||||
figure.setAttribute('class', `${figure.getAttribute('class')} kg-card-hascaption`);
|
||||
}
|
||||
|
||||
return figure;
|
||||
},
|
||||
|
||||
absoluteToRelative(urlUtils, payload, options) {
|
||||
payload.src = payload.src && urlUtils.absoluteToRelative(payload.src, options);
|
||||
payload.caption = payload.caption && urlUtils.htmlAbsoluteToRelative(payload.caption, options);
|
||||
return payload;
|
||||
},
|
||||
|
||||
relativeToAbsolute(urlUtils, payload, options) {
|
||||
payload.src = payload.src && urlUtils.relativeToAbsolute(payload.src, options);
|
||||
payload.caption = payload.caption && urlUtils.htmlRelativeToAbsolute(payload.caption, options);
|
||||
return payload;
|
||||
}
|
||||
});
|
@ -1,11 +0,0 @@
|
||||
module.exports = [
|
||||
require('./card-markdown'),
|
||||
require('./code'),
|
||||
require('./embed'),
|
||||
require('./bookmark'),
|
||||
require('./hr'),
|
||||
require('./html'),
|
||||
require('./image'),
|
||||
require('./markdown'),
|
||||
require('./gallery')
|
||||
];
|
@ -1,65 +0,0 @@
|
||||
let urlUtils;
|
||||
|
||||
module.exports = function createCard(card) {
|
||||
const defaultTransformer = function (urlUtils, payload) {
|
||||
return payload;
|
||||
};
|
||||
|
||||
const {
|
||||
name,
|
||||
type,
|
||||
config = {},
|
||||
absoluteToRelative = defaultTransformer,
|
||||
relativeToAbsolute = defaultTransformer
|
||||
} = card;
|
||||
|
||||
return {
|
||||
name,
|
||||
type,
|
||||
|
||||
render({env, payload, options}) {
|
||||
const {dom} = env;
|
||||
const cleanName = name.replace(/^card-/, '');
|
||||
|
||||
const cardOutput = card.render({env, payload, options});
|
||||
|
||||
if (!cardOutput) {
|
||||
return cardOutput;
|
||||
}
|
||||
|
||||
if (config.commentWrapper) {
|
||||
const beginComment = dom.createComment(`kg-card-begin: ${cleanName}`);
|
||||
const endComment = dom.createComment(`kg-card-end: ${cleanName}`);
|
||||
const fragment = dom.createDocumentFragment();
|
||||
|
||||
fragment.appendChild(beginComment);
|
||||
fragment.appendChild(cardOutput);
|
||||
fragment.appendChild(endComment);
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
||||
return cardOutput;
|
||||
},
|
||||
|
||||
absoluteToRelative() {
|
||||
// it's necessary to wait until the method is called to require
|
||||
// urlUtils to ensure the class has actually been instantiated
|
||||
// as cards are passed in as an arg to the class instantiation
|
||||
if (!urlUtils) {
|
||||
urlUtils = require('../../../url-utils');
|
||||
}
|
||||
return absoluteToRelative(urlUtils, ...arguments);
|
||||
},
|
||||
|
||||
relativeToAbsolute() {
|
||||
// it's necessary to wait until the method is called to require
|
||||
// urlUtils to ensure the class has actually been instantiated
|
||||
// as cards are passed in as an arg to the class instantiation
|
||||
if (!urlUtils) {
|
||||
urlUtils = require('../../../url-utils');
|
||||
}
|
||||
return relativeToAbsolute(urlUtils, ...arguments);
|
||||
}
|
||||
};
|
||||
};
|
@ -1,6 +0,0 @@
|
||||
const markdownCard = require('./_markdown');
|
||||
const createCard = require('./lib/create-card');
|
||||
|
||||
// uses the _markdown card definition function so that the card definition
|
||||
// can be re-used in aliased cards
|
||||
module.exports = createCard(markdownCard());
|
@ -1,8 +1,26 @@
|
||||
const common = require('../common');
|
||||
const config = require('../../config');
|
||||
|
||||
let cardFactory, cards;
|
||||
|
||||
module.exports = {
|
||||
get cards() {
|
||||
return require('./cards');
|
||||
if (cards) {
|
||||
return cards;
|
||||
}
|
||||
|
||||
const CardFactory = require('@tryghost/kg-card-factory');
|
||||
const defaultCards = require('@tryghost/kg-default-cards');
|
||||
|
||||
cardFactory = new CardFactory({
|
||||
siteUrl: config.get('url')
|
||||
});
|
||||
|
||||
cards = defaultCards.map((card) => {
|
||||
return cardFactory.createCard(card);
|
||||
});
|
||||
|
||||
return cards;
|
||||
},
|
||||
|
||||
get atoms() {
|
||||
|
@ -1,12 +1,11 @@
|
||||
const SimpleDom = require('simple-dom');
|
||||
const Renderer = require('mobiledoc-dom-renderer').default;
|
||||
const common = require('../../common');
|
||||
const atoms = require('../atoms');
|
||||
const cards = require('../cards');
|
||||
const mobiledoc = require('../');
|
||||
const options = {
|
||||
dom: new SimpleDom.Document(),
|
||||
cards: cards,
|
||||
atoms: atoms,
|
||||
cards: mobiledoc.cards,
|
||||
atoms: mobiledoc.atoms,
|
||||
unknownCardHandler: function (args) {
|
||||
common.logging.error(new common.errors.InternalServerError({
|
||||
message: 'Mobiledoc card \'' + args.env.name + '\' not found.'
|
||||
|
@ -1,6 +1,6 @@
|
||||
const UrlUtils = require('@tryghost/url-utils');
|
||||
const config = require('../../config');
|
||||
const cards = require('../mobiledoc/cards');
|
||||
const mobiledoc = require('../mobiledoc');
|
||||
|
||||
const urlUtils = new UrlUtils({
|
||||
url: config.get('url'),
|
||||
@ -10,7 +10,9 @@ const urlUtils = new UrlUtils({
|
||||
slugs: config.get('slugs').protected,
|
||||
redirectCacheMaxAge: config.get('caching:301:maxAge'),
|
||||
baseApiPath: '/ghost/api',
|
||||
cardTransformers: cards
|
||||
get cardTransformers() {
|
||||
return mobiledoc.cards;
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = urlUtils;
|
||||
|
@ -1,238 +0,0 @@
|
||||
const should = require('should');
|
||||
const card = require('../../../../../server/lib/mobiledoc/cards/bookmark');
|
||||
const SimpleDom = require('simple-dom');
|
||||
const serializer = new SimpleDom.HTMLSerializer(SimpleDom.voidMap);
|
||||
|
||||
describe('Bookmark card', function () {
|
||||
it('renders', function () {
|
||||
let opts = {
|
||||
env: {dom: new SimpleDom.Document()},
|
||||
payload: {
|
||||
metadata: {
|
||||
url: 'http://example.com',
|
||||
title: 'Title',
|
||||
description: 'Description',
|
||||
icon: 'http://example.com/icon.png',
|
||||
thumbnail: 'http://exampple.com/thumbnail.png',
|
||||
author: 'Author',
|
||||
publisher: 'Publisher'
|
||||
},
|
||||
caption: 'Caption'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts))
|
||||
.should.equal('<figure class="kg-card kg-bookmark-card kg-card-hascaption"><a class="kg-bookmark-container" href="http://example.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Title</div><div class="kg-bookmark-description">Description</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="http://example.com/icon.png"><span class="kg-bookmark-author">Author</span><span class="kg-bookmark-publisher">Publisher</span></div></div><div class="kg-bookmark-thumbnail"><img src="http://exampple.com/thumbnail.png"></div></a><figcaption>Caption</figcaption></figure>');
|
||||
});
|
||||
|
||||
it('skips icon when missing', function () {
|
||||
let opts = {
|
||||
env: {dom: new SimpleDom.Document()},
|
||||
payload: {
|
||||
metadata: {
|
||||
url: 'http://example.com',
|
||||
title: 'Title',
|
||||
description: 'Description',
|
||||
icon: null,
|
||||
thumbnail: 'http://exampple.com/thumbnail.png',
|
||||
author: 'Author',
|
||||
publisher: 'Publisher'
|
||||
},
|
||||
caption: 'Caption'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts))
|
||||
.should.equal('<figure class="kg-card kg-bookmark-card kg-card-hascaption"><a class="kg-bookmark-container" href="http://example.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Title</div><div class="kg-bookmark-description">Description</div><div class="kg-bookmark-metadata"><span class="kg-bookmark-author">Author</span><span class="kg-bookmark-publisher">Publisher</span></div></div><div class="kg-bookmark-thumbnail"><img src="http://exampple.com/thumbnail.png"></div></a><figcaption>Caption</figcaption></figure>');
|
||||
});
|
||||
|
||||
it('skips thumbnail when missing', function () {
|
||||
let opts = {
|
||||
env: {dom: new SimpleDom.Document()},
|
||||
payload: {
|
||||
metadata: {
|
||||
url: 'http://example.com',
|
||||
title: 'Title',
|
||||
description: 'Description',
|
||||
icon: 'http://example.com/icon.png',
|
||||
thumbnail: null,
|
||||
author: 'Author',
|
||||
publisher: 'Publisher'
|
||||
},
|
||||
caption: 'Caption'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts))
|
||||
.should.equal('<figure class="kg-card kg-bookmark-card kg-card-hascaption"><a class="kg-bookmark-container" href="http://example.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Title</div><div class="kg-bookmark-description">Description</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="http://example.com/icon.png"><span class="kg-bookmark-author">Author</span><span class="kg-bookmark-publisher">Publisher</span></div></div></a><figcaption>Caption</figcaption></figure>');
|
||||
});
|
||||
|
||||
it('skips author when missing', function () {
|
||||
let opts = {
|
||||
env: {dom: new SimpleDom.Document()},
|
||||
payload: {
|
||||
metadata: {
|
||||
url: 'http://example.com',
|
||||
title: 'Title',
|
||||
description: 'Description',
|
||||
icon: 'http://example.com/icon.png',
|
||||
thumbnail: 'http://exampple.com/thumbnail.png',
|
||||
author: null,
|
||||
publisher: 'Publisher'
|
||||
},
|
||||
caption: 'Caption'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts))
|
||||
.should.equal('<figure class="kg-card kg-bookmark-card kg-card-hascaption"><a class="kg-bookmark-container" href="http://example.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Title</div><div class="kg-bookmark-description">Description</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="http://example.com/icon.png"><span class="kg-bookmark-publisher">Publisher</span></div></div><div class="kg-bookmark-thumbnail"><img src="http://exampple.com/thumbnail.png"></div></a><figcaption>Caption</figcaption></figure>');
|
||||
});
|
||||
|
||||
it('skips publisher when missing', function () {
|
||||
let opts = {
|
||||
env: {dom: new SimpleDom.Document()},
|
||||
payload: {
|
||||
metadata: {
|
||||
url: 'http://example.com',
|
||||
title: 'Title',
|
||||
description: 'Description',
|
||||
icon: 'http://example.com/icon.png',
|
||||
thumbnail: 'http://exampple.com/thumbnail.png',
|
||||
author: 'Author',
|
||||
publisher: null
|
||||
},
|
||||
caption: 'Caption'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts))
|
||||
.should.equal('<figure class="kg-card kg-bookmark-card kg-card-hascaption"><a class="kg-bookmark-container" href="http://example.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Title</div><div class="kg-bookmark-description">Description</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="http://example.com/icon.png"><span class="kg-bookmark-author">Author</span></div></div><div class="kg-bookmark-thumbnail"><img src="http://exampple.com/thumbnail.png"></div></a><figcaption>Caption</figcaption></figure>');
|
||||
});
|
||||
|
||||
it('skips caption when missing', function () {
|
||||
let opts = {
|
||||
env: {dom: new SimpleDom.Document()},
|
||||
payload: {
|
||||
metadata: {
|
||||
url: 'http://example.com',
|
||||
title: 'Title',
|
||||
description: 'Description',
|
||||
icon: 'http://example.com/icon.png',
|
||||
thumbnail: 'http://exampple.com/thumbnail.png',
|
||||
author: 'Author',
|
||||
publisher: 'Publisher'
|
||||
},
|
||||
caption: ''
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts))
|
||||
.should.equal('<figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="http://example.com"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Title</div><div class="kg-bookmark-description">Description</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="http://example.com/icon.png"><span class="kg-bookmark-author">Author</span><span class="kg-bookmark-publisher">Publisher</span></div></div><div class="kg-bookmark-thumbnail"><img src="http://exampple.com/thumbnail.png"></div></a></figure>');
|
||||
});
|
||||
|
||||
it('renders nothing when payload is undefined', function () {
|
||||
let opts = {
|
||||
env: {dom: new SimpleDom.Document()},
|
||||
payload: {
|
||||
metadata: undefined
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts))
|
||||
.should.equal('');
|
||||
});
|
||||
|
||||
it('renders nothing when payload metadata is empty', function () {
|
||||
let opts = {
|
||||
env: {dom: new SimpleDom.Document()},
|
||||
payload: {
|
||||
metadata: {}
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts))
|
||||
.should.equal('');
|
||||
});
|
||||
|
||||
it('renders nothing when url is missing', function () {
|
||||
let opts = {
|
||||
env: {dom: new SimpleDom.Document()},
|
||||
payload: {
|
||||
metadata: {
|
||||
url: null,
|
||||
title: 'Test bookmark',
|
||||
description: 'This is just a test'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts))
|
||||
.should.equal('');
|
||||
});
|
||||
|
||||
it('renders nothing when title is missing', function () {
|
||||
let opts = {
|
||||
env: {dom: new SimpleDom.Document()},
|
||||
payload: {
|
||||
metadata: {
|
||||
url: 'http://example.com',
|
||||
title: null,
|
||||
description: 'This is just a test'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts))
|
||||
.should.equal('');
|
||||
});
|
||||
|
||||
it('renders nothing when description is missing', function () {
|
||||
let opts = {
|
||||
env: {dom: new SimpleDom.Document()},
|
||||
payload: {
|
||||
metadata: {
|
||||
url: 'http://example.com',
|
||||
title: 'Test bookmark',
|
||||
description: null
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts))
|
||||
.should.equal('');
|
||||
});
|
||||
|
||||
it('transforms urls absolute to relative', function () {
|
||||
let payload = {
|
||||
metadata: {
|
||||
url: 'http://127.0.0.1:2369/post'
|
||||
},
|
||||
caption: 'A link to <a href="http://127.0.0.1:2369/post">an internal post</a>'
|
||||
};
|
||||
|
||||
const transformed = card.absoluteToRelative(payload, {});
|
||||
|
||||
transformed.metadata.url
|
||||
.should.equal('/post');
|
||||
|
||||
transformed.caption
|
||||
.should.equal('A link to <a href="/post">an internal post</a>');
|
||||
});
|
||||
|
||||
it('transforms urls relative to absolute', function () {
|
||||
let payload = {
|
||||
metadata: {
|
||||
url: '/post'
|
||||
},
|
||||
caption: 'A link to <a href="/post">an internal post</a>'
|
||||
};
|
||||
|
||||
const transformed = card.relativeToAbsolute(payload, {});
|
||||
|
||||
transformed.metadata.url
|
||||
.should.equal('http://127.0.0.1:2369/post');
|
||||
|
||||
transformed.caption
|
||||
.should.equal('A link to <a href="http://127.0.0.1:2369/post">an internal post</a>');
|
||||
});
|
||||
});
|
@ -1,83 +0,0 @@
|
||||
const should = require('should');
|
||||
const card = require('../../../../../server/lib/mobiledoc/cards/card-markdown');
|
||||
const SimpleDom = require('simple-dom');
|
||||
const serializer = new SimpleDom.HTMLSerializer(SimpleDom.voidMap);
|
||||
|
||||
describe('Markdown card (v1 compatibility card)', function () {
|
||||
it('renders', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
markdown: '#HEADING\r\n- list\r\n- items'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.eql('<!--kg-card-begin: markdown--><h1 id="heading">HEADING</h1>\n<ul>\n<li>list</li>\n<li>items</li>\n</ul>\n<!--kg-card-end: markdown-->');
|
||||
});
|
||||
|
||||
it('Accepts invalid HTML in markdown', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
markdown: '#HEADING\r\n<h2>Heading 2>'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.eql('<!--kg-card-begin: markdown--><h1 id="heading">HEADING</h1>\n<h2>Heading 2><!--kg-card-end: markdown-->');
|
||||
});
|
||||
|
||||
it('Renders nothing when payload is undefined', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
markdown: undefined
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.eql('');
|
||||
});
|
||||
|
||||
it('[deprecated] version 1', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
markdown: '#HEADING\r\n- list\r\n- items'
|
||||
},
|
||||
options: {
|
||||
version: 1
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.eql('<!--kg-card-begin: markdown--><div class="kg-card-markdown"><h1 id="heading">HEADING</h1>\n<ul>\n<li>list</li>\n<li>items</li>\n</ul>\n</div><!--kg-card-end: markdown-->');
|
||||
});
|
||||
|
||||
it('transforms urls absolute to relative', function () {
|
||||
let payload = {
|
||||
markdown: 'A link to [an internal post](http://127.0.0.1:2369/post)'
|
||||
};
|
||||
|
||||
const transformed = card.absoluteToRelative(payload, {});
|
||||
|
||||
transformed.markdown
|
||||
.should.equal('A link to [an internal post](/post)');
|
||||
});
|
||||
|
||||
it('transforms urls relative to absolute', function () {
|
||||
let payload = {
|
||||
markdown: 'A link to [an internal post](/post)'
|
||||
};
|
||||
|
||||
const transformed = card.relativeToAbsolute(payload, {});
|
||||
|
||||
transformed.markdown
|
||||
.should.equal('A link to [an internal post](http://127.0.0.1:2369/post)');
|
||||
});
|
||||
});
|
@ -1,83 +0,0 @@
|
||||
const should = require('should');
|
||||
const card = require('../../../../../server/lib/mobiledoc/cards/code');
|
||||
const SimpleDom = require('simple-dom');
|
||||
const serializer = new SimpleDom.HTMLSerializer(SimpleDom.voidMap);
|
||||
|
||||
describe('Code card', function () {
|
||||
it('Renders and escapes', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
code: '<p>Test</p>'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.match('<pre><code><p>Test</p></code></pre>');
|
||||
});
|
||||
|
||||
it('Renders language class if provided', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
code: '<p>Test</p>',
|
||||
language: 'html'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.match('<pre><code class="language-html"><p>Test</p></code></pre>');
|
||||
});
|
||||
|
||||
it('Renders nothing when payload is undefined', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
code: undefined
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.match('');
|
||||
});
|
||||
|
||||
it('Renders a figure if a caption is provided', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
code: '<p>Test</p>',
|
||||
language: 'html',
|
||||
caption: 'Some <strong>HTML</strong>'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.match('<figure class="kg-card kg-code-card"><pre><code class="language-html"><p>Test</p></code></pre><figcaption>Some <strong>HTML</strong></figcaption></figure>');
|
||||
});
|
||||
|
||||
it('transforms urls absolute to relative', function () {
|
||||
let payload = {
|
||||
caption: 'A link to <a href="http://127.0.0.1:2369/post">an internal post</a>'
|
||||
};
|
||||
|
||||
const transformed = card.absoluteToRelative(payload, {});
|
||||
|
||||
transformed.caption
|
||||
.should.equal('A link to <a href="/post">an internal post</a>');
|
||||
});
|
||||
|
||||
it('transforms urls relative to absolute', function () {
|
||||
let payload = {
|
||||
caption: 'A link to <a href="/post">an internal post</a>'
|
||||
};
|
||||
|
||||
const transformed = card.relativeToAbsolute(payload, {});
|
||||
|
||||
transformed.caption
|
||||
.should.equal('A link to <a href="http://127.0.0.1:2369/post">an internal post</a>');
|
||||
});
|
||||
});
|
@ -1,94 +0,0 @@
|
||||
const should = require('should');
|
||||
const card = require('../../../../../server/lib/mobiledoc/cards/embed');
|
||||
const SimpleDom = require('simple-dom');
|
||||
const serializer = new SimpleDom.HTMLSerializer(SimpleDom.voidMap);
|
||||
|
||||
describe('Embed card', function () {
|
||||
it('Embed Card renders', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
html: '<h1>HEADING</h1><p>PARAGRAPH</p>'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.match('<figure class="kg-card kg-embed-card"><h1>HEADING</h1><p>PARAGRAPH</p></figure>');
|
||||
});
|
||||
|
||||
it('Plain content renders', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
html: 'CONTENT'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.match('<figure class="kg-card kg-embed-card">CONTENT</figure>');
|
||||
});
|
||||
|
||||
it('Invalid HTML returns', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
html: '<h1>HEADING<'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.match('<figure class="kg-card kg-embed-card"><h1>HEADING<</figure>');
|
||||
});
|
||||
|
||||
it('Renders nothing when payload is undefined', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
html: undefined
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.match('');
|
||||
});
|
||||
|
||||
it('Renders caption when provided', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
html: 'Testing',
|
||||
caption: '<strong>Caption</strong>'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.match('<figure class="kg-card kg-embed-card kg-card-hascaption">Testing<figcaption><strong>Caption</strong></figcaption></figure>');
|
||||
});
|
||||
|
||||
it('transforms urls absolute to relative', function () {
|
||||
let payload = {
|
||||
caption: 'A link to <a href="http://127.0.0.1:2369/post">an internal post</a>'
|
||||
};
|
||||
|
||||
const transformed = card.absoluteToRelative(payload, {});
|
||||
|
||||
transformed.caption
|
||||
.should.equal('A link to <a href="/post">an internal post</a>');
|
||||
});
|
||||
|
||||
it('transforms urls relative to absolute', function () {
|
||||
let payload = {
|
||||
caption: 'A link to <a href="/post">an internal post</a>'
|
||||
};
|
||||
|
||||
const transformed = card.relativeToAbsolute(payload, {});
|
||||
|
||||
transformed.caption
|
||||
.should.equal('A link to <a href="http://127.0.0.1:2369/post">an internal post</a>');
|
||||
});
|
||||
});
|
@ -1,211 +0,0 @@
|
||||
const should = require('should');
|
||||
const card = require('../../../../../server/lib/mobiledoc/cards/gallery');
|
||||
const SimpleDom = require('simple-dom');
|
||||
const serializer = new SimpleDom.HTMLSerializer(SimpleDom.voidMap);
|
||||
|
||||
describe('Gallery card', function () {
|
||||
it('renders a gallery', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
images: [
|
||||
{
|
||||
row: 0,
|
||||
fileName: 'NatGeo01.jpg',
|
||||
src: '/content/images/2018/08/NatGeo01-9.jpg',
|
||||
width: 3200,
|
||||
height: 1600
|
||||
},
|
||||
{
|
||||
row: 0,
|
||||
fileName: 'NatGeo02.jpg',
|
||||
src: '/content/images/2018/08/NatGeo02-10.jpg',
|
||||
width: 3200,
|
||||
height: 1600
|
||||
},
|
||||
{
|
||||
row: 0,
|
||||
fileName: 'NatGeo03.jpg',
|
||||
src: '/content/images/2018/08/NatGeo03-6.jpg',
|
||||
width: 3200,
|
||||
height: 1600
|
||||
},
|
||||
{
|
||||
row: 1,
|
||||
fileName: 'NatGeo04.jpg',
|
||||
src: '/content/images/2018/08/NatGeo04-7.jpg',
|
||||
alt: 'Alt test',
|
||||
width: 3200,
|
||||
height: 1600
|
||||
},
|
||||
{
|
||||
row: 1,
|
||||
fileName: 'NatGeo05.jpg',
|
||||
src: '/content/images/2018/08/NatGeo05-4.jpg',
|
||||
title: 'Title test',
|
||||
width: 3200,
|
||||
height: 1600
|
||||
},
|
||||
{
|
||||
row: 1,
|
||||
fileName: 'NatGeo06.jpg',
|
||||
src: '/content/images/2018/08/NatGeo06-6.jpg',
|
||||
width: 3200,
|
||||
height: 1600
|
||||
},
|
||||
{
|
||||
row: 2,
|
||||
fileName: 'NatGeo07.jpg',
|
||||
src: '/content/images/2018/08/NatGeo07-5.jpg',
|
||||
width: 3200,
|
||||
height: 1600
|
||||
},
|
||||
{
|
||||
row: 2,
|
||||
fileName: 'NatGeo09.jpg',
|
||||
src: '/content/images/2018/08/NatGeo09-8.jpg',
|
||||
width: 3200,
|
||||
height: 1600
|
||||
}
|
||||
],
|
||||
caption: 'Test caption'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.eql('<figure class="kg-card kg-gallery-card kg-width-wide kg-card-hascaption"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="/content/images/2018/08/NatGeo01-9.jpg" width="3200" height="1600"></div><div class="kg-gallery-image"><img src="/content/images/2018/08/NatGeo02-10.jpg" width="3200" height="1600"></div><div class="kg-gallery-image"><img src="/content/images/2018/08/NatGeo03-6.jpg" width="3200" height="1600"></div></div><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="/content/images/2018/08/NatGeo04-7.jpg" width="3200" height="1600" alt="Alt test"></div><div class="kg-gallery-image"><img src="/content/images/2018/08/NatGeo05-4.jpg" width="3200" height="1600" title="Title test"></div><div class="kg-gallery-image"><img src="/content/images/2018/08/NatGeo06-6.jpg" width="3200" height="1600"></div></div><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="/content/images/2018/08/NatGeo07-5.jpg" width="3200" height="1600"></div><div class="kg-gallery-image"><img src="/content/images/2018/08/NatGeo09-8.jpg" width="3200" height="1600"></div></div></div><figcaption>Test caption</figcaption></figure>');
|
||||
});
|
||||
|
||||
it('renders nothing with no images', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
images: [],
|
||||
caption: 'Test caption'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.eql('');
|
||||
});
|
||||
|
||||
it('renders nothing with no valid images', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
images: [{src: 'undefined'}],
|
||||
caption: 'Test caption'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.eql('');
|
||||
});
|
||||
|
||||
it('skips invalid images', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
images: [
|
||||
{
|
||||
row: 0,
|
||||
fileName: 'NatGeo01.jpg',
|
||||
src: '/content/images/2018/08/NatGeo01-9.jpg',
|
||||
width: 3200,
|
||||
height: 1600
|
||||
},
|
||||
{
|
||||
row: 0,
|
||||
fileName: 'NatGeo02.jpg',
|
||||
src: '/content/images/2018/08/NatGeo02-10.jpg'
|
||||
},
|
||||
{
|
||||
row: 0,
|
||||
fileName: 'NatGeo03.jpg',
|
||||
src: '/content/images/2018/08/NatGeo03-6.jpg',
|
||||
width: 3200,
|
||||
height: 1600
|
||||
}
|
||||
],
|
||||
caption: 'Test caption'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.eql('<figure class="kg-card kg-gallery-card kg-width-wide kg-card-hascaption"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="/content/images/2018/08/NatGeo01-9.jpg" width="3200" height="1600"></div><div class="kg-gallery-image"><img src="/content/images/2018/08/NatGeo03-6.jpg" width="3200" height="1600"></div></div></div><figcaption>Test caption</figcaption></figure>');
|
||||
});
|
||||
|
||||
it('transforms urls absolute to relative', function () {
|
||||
let payload = {
|
||||
images: [
|
||||
{
|
||||
row: 0,
|
||||
fileName: 'NatGeo01.jpg',
|
||||
src: 'http://127.0.0.1:2369/content/images/2018/08/NatGeo01-9.jpg',
|
||||
width: 3200,
|
||||
height: 1600,
|
||||
caption: 'A link to <a href="http://127.0.0.1:2369/post">an internal post</a>'
|
||||
},
|
||||
{
|
||||
row: 0,
|
||||
fileName: 'NatGeo02.jpg',
|
||||
src: 'http://127.0.0.1:2369/content/images/2018/08/NatGeo02-10.jpg',
|
||||
caption: 'A link to <a href="http://127.0.0.1:2369/post">an internal post</a>'
|
||||
}
|
||||
],
|
||||
caption: 'A link to <a href="http://127.0.0.1:2369/post">an internal post</a>'
|
||||
};
|
||||
|
||||
const transformed = card.absoluteToRelative(payload, {});
|
||||
|
||||
transformed.images[0].src
|
||||
.should.equal('/content/images/2018/08/NatGeo01-9.jpg');
|
||||
|
||||
transformed.images[0].caption
|
||||
.should.equal('A link to <a href="/post">an internal post</a>');
|
||||
|
||||
transformed.images[1].src
|
||||
.should.equal('/content/images/2018/08/NatGeo02-10.jpg');
|
||||
|
||||
transformed.images[1].caption
|
||||
.should.equal('A link to <a href="/post">an internal post</a>');
|
||||
|
||||
transformed.caption
|
||||
.should.equal('A link to <a href="/post">an internal post</a>');
|
||||
});
|
||||
|
||||
it('transforms urls relative to absolute', function () {
|
||||
let payload = {
|
||||
images: [
|
||||
{
|
||||
row: 0,
|
||||
fileName: 'NatGeo01.jpg',
|
||||
src: '/content/images/2018/08/NatGeo01-9.jpg',
|
||||
width: 3200,
|
||||
height: 1600
|
||||
},
|
||||
{
|
||||
row: 0,
|
||||
fileName: 'NatGeo02.jpg',
|
||||
src: '/content/images/2018/08/NatGeo02-10.jpg'
|
||||
}
|
||||
],
|
||||
caption: 'A link to <a href="/post">an internal post</a>'
|
||||
};
|
||||
|
||||
const transformed = card.relativeToAbsolute(payload, {});
|
||||
|
||||
transformed.images[0].src
|
||||
.should.equal('http://127.0.0.1:2369/content/images/2018/08/NatGeo01-9.jpg');
|
||||
|
||||
transformed.images[1].src
|
||||
.should.equal('http://127.0.0.1:2369/content/images/2018/08/NatGeo02-10.jpg');
|
||||
|
||||
transformed.caption
|
||||
.should.equal('A link to <a href="http://127.0.0.1:2369/post">an internal post</a>');
|
||||
});
|
||||
});
|
@ -1,28 +0,0 @@
|
||||
const should = require('should');
|
||||
const card = require('../../../../../server/lib/mobiledoc/cards/hr');
|
||||
const SimpleDom = require('simple-dom');
|
||||
const serializer = new SimpleDom.HTMLSerializer(SimpleDom.voidMap);
|
||||
|
||||
describe('HR card', function () {
|
||||
it('generates a horizontal rule', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.match('<hr>');
|
||||
});
|
||||
|
||||
it('transforms urls absolute to relative', function () {
|
||||
let payload = {};
|
||||
const transformed = card.absoluteToRelative(payload, {});
|
||||
transformed.should.deepEqual({});
|
||||
});
|
||||
|
||||
it('transforms urls relative to absolute', function () {
|
||||
let payload = {};
|
||||
const transformed = card.relativeToAbsolute(payload, {});
|
||||
transformed.should.deepEqual({});
|
||||
});
|
||||
});
|
@ -1,80 +0,0 @@
|
||||
const should = require('should');
|
||||
const card = require('../../../../../server/lib/mobiledoc/cards/html');
|
||||
const SimpleDom = require('simple-dom');
|
||||
const serializer = new SimpleDom.HTMLSerializer(SimpleDom.voidMap);
|
||||
|
||||
describe('HTML card', function () {
|
||||
it('HTML Card renders', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
html: '<h1>HEADING</h1><p>PARAGRAPH</p>'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.eql('<!--kg-card-begin: html--><h1>HEADING</h1><p>PARAGRAPH</p><!--kg-card-end: html-->');
|
||||
});
|
||||
|
||||
it('Plain content renders', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
html: 'CONTENT'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.eql('<!--kg-card-begin: html-->CONTENT<!--kg-card-end: html-->');
|
||||
});
|
||||
|
||||
it('Invalid HTML returns', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
html: '<h1>HEADING<'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.eql('<!--kg-card-begin: html--><h1>HEADING<<!--kg-card-end: html-->');
|
||||
});
|
||||
|
||||
it('Renders nothing when payload is undefined', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
html: undefined
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.eql('');
|
||||
});
|
||||
|
||||
it('transforms urls absolute to relative', function () {
|
||||
let payload = {
|
||||
html: 'A link to <a href="http://127.0.0.1:2369/post">an internal post</a>'
|
||||
};
|
||||
|
||||
const transformed = card.absoluteToRelative(payload, {});
|
||||
|
||||
transformed.html
|
||||
.should.equal('A link to <a href="/post">an internal post</a>');
|
||||
});
|
||||
|
||||
it('transforms urls relative to absolute', function () {
|
||||
let payload = {
|
||||
html: 'A link to <a href="/post">an internal post</a>'
|
||||
};
|
||||
|
||||
const transformed = card.relativeToAbsolute(payload, {});
|
||||
|
||||
transformed.html
|
||||
.should.equal('A link to <a href="http://127.0.0.1:2369/post">an internal post</a>');
|
||||
});
|
||||
});
|
@ -1,149 +0,0 @@
|
||||
const should = require('should');
|
||||
const card = require('../../../../../server/lib/mobiledoc/cards/image');
|
||||
const SimpleDom = require('simple-dom');
|
||||
const serializer = new SimpleDom.HTMLSerializer(SimpleDom.voidMap);
|
||||
|
||||
describe('Image card', function () {
|
||||
it('renders an image', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
src: 'https://www.ghost.org/image.png'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.eql('<figure class="kg-card kg-image-card"><img src="https://www.ghost.org/image.png" class="kg-image"></figure>');
|
||||
});
|
||||
|
||||
it('renders an image with caption', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
src: 'https://www.ghost.org/image.png',
|
||||
caption: '<b>Test caption</b>'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.eql('<figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.ghost.org/image.png" class="kg-image"><figcaption><b>Test caption</b></figcaption></figure>');
|
||||
});
|
||||
|
||||
it('renders an image with alt text', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
src: 'https://www.ghost.org/image.png',
|
||||
alt: 'example image'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.eql('<figure class="kg-card kg-image-card"><img src="https://www.ghost.org/image.png" class="kg-image" alt="example image"></figure>');
|
||||
});
|
||||
|
||||
it('renders an image with title attribute', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
src: 'https://www.ghost.org/image.png',
|
||||
title: 'example image'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.eql('<figure class="kg-card kg-image-card"><img src="https://www.ghost.org/image.png" class="kg-image" title="example image"></figure>');
|
||||
});
|
||||
|
||||
it('renders nothing with no src', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
src: '',
|
||||
caption: 'Test caption'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.eql('');
|
||||
});
|
||||
|
||||
describe('sizes', function () {
|
||||
it('standard', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
src: 'https://www.ghost.org/image.png',
|
||||
cardWidth: ''
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.eql('<figure class="kg-card kg-image-card"><img src="https://www.ghost.org/image.png" class="kg-image"></figure>');
|
||||
});
|
||||
|
||||
it('wide', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
src: 'https://www.ghost.org/image.png',
|
||||
cardWidth: 'wide'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.eql('<figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.ghost.org/image.png" class="kg-image"></figure>');
|
||||
});
|
||||
|
||||
it('full', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
src: 'https://www.ghost.org/image.png',
|
||||
cardWidth: 'full'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.eql('<figure class="kg-card kg-image-card kg-width-full"><img src="https://www.ghost.org/image.png" class="kg-image"></figure>');
|
||||
});
|
||||
});
|
||||
|
||||
it('transforms urls absolute to relative', function () {
|
||||
let payload = {
|
||||
src: 'http://127.0.0.1:2369/content/images/2018/08/NatGeo01-9.jpg',
|
||||
caption: 'A link to <a href="http://127.0.0.1:2369/post">an internal post</a>'
|
||||
};
|
||||
|
||||
const transformed = card.absoluteToRelative(payload, {});
|
||||
|
||||
transformed.src
|
||||
.should.equal('/content/images/2018/08/NatGeo01-9.jpg');
|
||||
|
||||
transformed.caption
|
||||
.should.equal('A link to <a href="/post">an internal post</a>');
|
||||
});
|
||||
|
||||
it('transforms urls relative to absolute', function () {
|
||||
let payload = {
|
||||
src: '/content/images/2018/08/NatGeo01-9.jpg',
|
||||
caption: 'A link to <a href="/post">an internal post</a>'
|
||||
};
|
||||
|
||||
const transformed = card.relativeToAbsolute(payload, {});
|
||||
|
||||
transformed.src
|
||||
.should.equal('http://127.0.0.1:2369/content/images/2018/08/NatGeo01-9.jpg');
|
||||
|
||||
transformed.caption
|
||||
.should.equal('A link to <a href="http://127.0.0.1:2369/post">an internal post</a>');
|
||||
});
|
||||
});
|
@ -1,67 +0,0 @@
|
||||
const should = require('should');
|
||||
const card = require('../../../../../server/lib/mobiledoc/cards/markdown');
|
||||
const SimpleDom = require('simple-dom');
|
||||
const serializer = new SimpleDom.HTMLSerializer(SimpleDom.voidMap);
|
||||
|
||||
describe('Markdown card', function () {
|
||||
it('renders', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
markdown: '#HEADING\r\n- list\r\n- items'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.eql('<!--kg-card-begin: markdown--><h1 id="heading">HEADING</h1>\n<ul>\n<li>list</li>\n<li>items</li>\n</ul>\n<!--kg-card-end: markdown-->');
|
||||
});
|
||||
|
||||
it('Accepts invalid HTML in markdown', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
markdown: '#HEADING\r\n<h2>Heading 2>'
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.eql('<!--kg-card-begin: markdown--><h1 id="heading">HEADING</h1>\n<h2>Heading 2><!--kg-card-end: markdown-->');
|
||||
});
|
||||
|
||||
it('Renders nothing when payload is undefined', function () {
|
||||
let opts = {
|
||||
env: {
|
||||
dom: new SimpleDom.Document()
|
||||
},
|
||||
payload: {
|
||||
markdown: undefined
|
||||
}
|
||||
};
|
||||
|
||||
serializer.serialize(card.render(opts)).should.eql('');
|
||||
});
|
||||
|
||||
it('transforms urls absolute to relative', function () {
|
||||
let payload = {
|
||||
markdown: 'A link to [an internal post](http://127.0.0.1:2369/post)'
|
||||
};
|
||||
|
||||
const transformed = card.absoluteToRelative(payload, {});
|
||||
|
||||
transformed.markdown
|
||||
.should.equal('A link to [an internal post](/post)');
|
||||
});
|
||||
|
||||
it('transforms urls relative to absolute', function () {
|
||||
let payload = {
|
||||
markdown: 'A link to [an internal post](/post)'
|
||||
};
|
||||
|
||||
const transformed = card.relativeToAbsolute(payload, {});
|
||||
|
||||
transformed.markdown
|
||||
.should.equal('A link to [an internal post](http://127.0.0.1:2369/post)');
|
||||
});
|
||||
});
|
@ -44,7 +44,9 @@
|
||||
"@tryghost/errors": "^0.1.0",
|
||||
"@tryghost/helpers": "1.1.23",
|
||||
"@tryghost/image-transform": "^0.1.0",
|
||||
"@tryghost/kg-markdown-html-renderer": "1.0.0",
|
||||
"@tryghost/kg-card-factory": "1.0.1",
|
||||
"@tryghost/kg-default-cards": "1.0.1",
|
||||
"@tryghost/kg-markdown-html-renderer": "1.0.2",
|
||||
"@tryghost/members-api": "0.18.0",
|
||||
"@tryghost/members-ssr": "0.7.4",
|
||||
"@tryghost/social-urls": "0.1.6",
|
||||
|
26
yarn.lock
26
yarn.lock
@ -343,19 +343,29 @@
|
||||
optionalDependencies:
|
||||
sharp "^0.25.2"
|
||||
|
||||
"@tryghost/kg-card-factory@1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/kg-card-factory/-/kg-card-factory-1.0.1.tgz#ad4973bab4f7dbc99722c739b2c520831febed54"
|
||||
integrity sha512-qMWypZEths/F5pvbPKSlHJJ4CK4uwMaGM3jB7IdG9uw4kHPxWJFnuUn+QHvEUbcAvS484QTExVEzIc8vmSSN5A==
|
||||
|
||||
"@tryghost/kg-clean-basic-html@^0.1.5":
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/kg-clean-basic-html/-/kg-clean-basic-html-0.1.5.tgz#21cbe9036472c04b2320b1feb359c9c40ff3a300"
|
||||
integrity sha512-jl+NKYryIL+KUQb4XNcMgu9l/K12oASgZYuRqi6GCm0JKhz1qD56vavIpKAlPjJyMOhSfD0MicoX887ijgvqyQ==
|
||||
|
||||
"@tryghost/kg-markdown-html-renderer@1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/kg-markdown-html-renderer/-/kg-markdown-html-renderer-1.0.0.tgz#7a68a5700955b031b29b3a70f7ab5b5391d7746e"
|
||||
integrity sha512-MC+rxwaxkM7g+EkihYr6dmyc8CUkVVahDxjxEcKlVAVWpnB8GN/paaS1Lgv9n9KxqEHCuvewhCDPwH93sczTNg==
|
||||
"@tryghost/kg-default-cards@1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/kg-default-cards/-/kg-default-cards-1.0.1.tgz#f6855db115af0868ecbe443a46123f856e006d9a"
|
||||
integrity sha512-rca9u9dHq9bxvjnZ40LW0DgmBqAcrPT8hnQiC+i67pm+SHixGwcZ/IjB5Y4iilfDffq4k1Rk2sFgfHw+WBUcew==
|
||||
dependencies:
|
||||
"@tryghost/kg-markdown-html-renderer" "^1.0.2"
|
||||
"@tryghost/url-utils" "^0.6.14"
|
||||
|
||||
"@tryghost/kg-markdown-html-renderer@1.0.2", "@tryghost/kg-markdown-html-renderer@^1.0.2":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/kg-markdown-html-renderer/-/kg-markdown-html-renderer-1.0.2.tgz#c2cb8ab23803ce72501831740c6950d12881de9d"
|
||||
integrity sha512-gM0LvLgw+PeK+opUaqqtxY6gMNWaw7oNfUrDzjfYWszRw6CJDp4JrzE5vlyM+divh5HegGUeGsym2yXBBOIQ8g==
|
||||
dependencies:
|
||||
bluebird "^3.7.2"
|
||||
ghost-ignition "^4.1.0"
|
||||
lodash "^4.17.15"
|
||||
markdown-it "^10.0.0"
|
||||
markdown-it-footnote "^3.0.2"
|
||||
markdown-it-lazy-headers "^0.1.3"
|
||||
@ -439,7 +449,7 @@
|
||||
dependencies:
|
||||
unidecode "^0.1.8"
|
||||
|
||||
"@tryghost/url-utils@0.6.14":
|
||||
"@tryghost/url-utils@0.6.14", "@tryghost/url-utils@^0.6.14":
|
||||
version "0.6.14"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/url-utils/-/url-utils-0.6.14.tgz#aa1ef94531530635cba0cb6d75933bda1a557719"
|
||||
integrity sha512-GpEN2ZJXqESsp5lUEDEBNPm0HQholhF3pfPlOUx/r/B6YHXBHCH7blgXwDAoo+/I7mKMDCVNf+AA/FXdCrVgJQ==
|
||||
|
Loading…
Reference in New Issue
Block a user