@tryghost/kg-parser-plugins
Advanced tools
Comparing version 0.5.1 to 0.6.0
@@ -26,2 +26,45 @@ 'use strict'; | ||
// HELPERS ----------------------------------------------------------------- | ||
function _readFigCaptionFromNode(node, payload) { | ||
let figcaption = node.querySelector('figcaption'); | ||
if (figcaption) { | ||
let cleanHtml = cleanBasicHtml(figcaption.innerHTML, options); | ||
payload.caption = payload.caption ? `${payload.caption} / ${cleanHtml}` : cleanHtml; | ||
figcaption.remove(); // cleanup this processed element | ||
} | ||
} | ||
function _readGalleryImageFromNode(node, imgNum) { | ||
let fileName = node.src.match(/[^/]*$/)[0]; | ||
let image = { | ||
fileName, | ||
row: Math.floor(imgNum / 3), | ||
src: node.src | ||
}; | ||
if (node.width) { | ||
image.width = node.width; | ||
} else if (node.dataset && node.dataset.width) { | ||
image.width = parseInt(node.dataset.width, 10); | ||
} | ||
if (node.height) { | ||
image.height = node.height; | ||
} else if (node.dataset && node.dataset.height) { | ||
image.height = parseInt(node.dataset.height, 10); | ||
} | ||
if (node.alt) { | ||
image.alt = node.alt; | ||
} | ||
if (node.title) { | ||
image.title = node.title; | ||
} | ||
return image; | ||
} | ||
// PLUGINS ----------------------------------------------------------------- | ||
@@ -81,2 +124,58 @@ | ||
const kgGalleryCardToCard = (node, builder, {addSection, nodeFinished}) => { | ||
if (node.nodeType !== 1 || node.tagName !== 'FIGURE') { | ||
return; | ||
} | ||
if (!node.className.match(/kg-gallery-card/)) { | ||
return; | ||
} | ||
let payload = {}; | ||
let imgs = Array.from(node.querySelectorAll('img')); | ||
// Process nodes into the payload | ||
payload.images = imgs.map(_readGalleryImageFromNode); | ||
_readFigCaptionFromNode(node, payload); | ||
let cardSection = builder.createCardSection('gallery', payload); | ||
addSection(cardSection); | ||
nodeFinished(); | ||
}; | ||
function grafGalleryToCard(node, builder, {addSection, nodeFinished}) { | ||
function isGrafGallery(node) { | ||
return node.nodeType === 1 && node.tagName === 'DIV' && node.dataset && node.dataset.paragraphCount && node.querySelectorAll('img').length > 0; | ||
} | ||
if (!isGrafGallery(node)) { | ||
return; | ||
} | ||
let payload = {}; | ||
// These galleries exist in multiple divs. Read the images and cation from the first one... | ||
let imgs = Array.from(node.querySelectorAll('img')); | ||
_readFigCaptionFromNode(node, payload); | ||
// ...and then iterate over any remaining divs until we run out of matches | ||
let nextNode = node.nextSibling; | ||
while (nextNode && isGrafGallery(nextNode)) { | ||
let currentNode = nextNode; | ||
imgs = imgs.concat(Array.from(currentNode.querySelectorAll('img'))); | ||
_readFigCaptionFromNode(currentNode, payload); | ||
nextNode = currentNode.nextSibling; | ||
// remove nodes as we go so that they don't go through the parser | ||
currentNode.remove(); | ||
} | ||
// Process nodes into the payload | ||
payload.images = imgs.map(_readGalleryImageFromNode); | ||
let cardSection = builder.createCardSection('gallery', payload); | ||
addSection(cardSection); | ||
nodeFinished(); | ||
} | ||
function figureToImageCard(node, builder, {addSection, nodeFinished}) { | ||
@@ -88,3 +187,2 @@ if (node.nodeType !== 1 || node.tagName !== 'FIGURE') { | ||
let img = node.querySelector('img'); | ||
let figcaption = node.querySelector('figcaption'); | ||
let kgClass = node.className.match(/kg-width-(wide|full)/); | ||
@@ -109,6 +207,3 @@ let grafClass = node.className.match(/graf--layout(FillWidth|OutsetCenter)/); | ||
if (figcaption) { | ||
let cleanHtml = cleanBasicHtml(figcaption.innerHTML, options); | ||
payload.caption = cleanHtml; | ||
} | ||
_readFigCaptionFromNode(node, payload); | ||
@@ -146,2 +241,65 @@ let cardSection = builder.createCardSection('image', payload); | ||
function figureIframeToEmbedCard(node, builder, {addSection, nodeFinished}) { | ||
if (node.nodeType !== 1 || node.tagName !== 'FIGURE') { | ||
return; | ||
} | ||
let iframe = node.querySelector('iframe'); | ||
if (!iframe) { | ||
return; | ||
} | ||
let src = iframe.src; | ||
// If we don't have a src, or it's not an absolute URL, we can't handle this | ||
if (!src || !src.match(/^https?:\/\//i)) { | ||
return; | ||
} | ||
let payload = { | ||
url: src | ||
}; | ||
_readFigCaptionFromNode(node, payload); | ||
payload.html = node.innerHTML; | ||
let cardSection = builder.createCardSection('embed', payload); | ||
addSection(cardSection); | ||
nodeFinished(); | ||
} | ||
function figureBlockquoteToEmbedCard(node, builder, {addSection, nodeFinished}) { | ||
if (node.nodeType !== 1 || node.tagName !== 'FIGURE') { | ||
return; | ||
} | ||
let blockquote = node.querySelector('blockquote'); | ||
let link = node.querySelector('a'); | ||
if (!blockquote || !link) { | ||
return; | ||
} | ||
let url = link.href; | ||
// If we don't have a url, or it's not an absolute URL, we can't handle this | ||
if (!url || !url.match(/^https?:\/\//i)) { | ||
return; | ||
} | ||
let payload = { | ||
url: url | ||
}; | ||
_readFigCaptionFromNode(node, payload); | ||
payload.html = node.innerHTML; | ||
let cardSection = builder.createCardSection('embed', payload); | ||
addSection(cardSection); | ||
nodeFinished(); | ||
} | ||
function figureToCodeCard(node, builder, {addSection, nodeFinished}) { | ||
@@ -168,6 +326,7 @@ if (node.nodeType !== 1 || node.tagName !== 'FIGURE') { | ||
let payload = { | ||
code: code.textContent, | ||
caption: cleanBasicHtml(figcaption.innerHTML, options) | ||
code: code.textContent | ||
}; | ||
_readFigCaptionFromNode(node, payload); | ||
let preClass = pre.getAttribute('class') || ''; | ||
@@ -210,2 +369,19 @@ let codeClass = code.getAttribute('class') || ''; | ||
function figureScriptToHtmlCard(node, builder, {addSection, nodeFinished}) { | ||
if (node.nodeType !== 1 || node.tagName !== 'FIGURE') { | ||
return; | ||
} | ||
let script = node.querySelector('script'); | ||
if (!script || !script.src.match(/^https:\/\/gist\.github\.com/)) { | ||
return; | ||
} | ||
let payload = {html: script.outerHTML}; | ||
let cardSection = builder.createCardSection('html', payload); | ||
addSection(cardSection); | ||
nodeFinished(); | ||
} | ||
return [ | ||
@@ -215,2 +391,5 @@ kgHtmlCardToCard, | ||
removeLeadingNewline, | ||
kgGalleryCardToCard, | ||
figureBlockquoteToEmbedCard, // I think these can contain images | ||
grafGalleryToCard, | ||
figureToImageCard, | ||
@@ -220,3 +399,5 @@ imgToCard, | ||
figureToCodeCard, | ||
preCodeToCard | ||
preCodeToCard, | ||
figureIframeToEmbedCard, | ||
figureScriptToHtmlCard | ||
]; | ||
@@ -223,0 +404,0 @@ } |
@@ -19,2 +19,44 @@ import cleanBasicHtml from '@tryghost/kg-clean-basic-html'; | ||
}; | ||
} // HELPERS ----------------------------------------------------------------- | ||
function _readFigCaptionFromNode(node, payload) { | ||
let figcaption = node.querySelector('figcaption'); | ||
if (figcaption) { | ||
let cleanHtml = cleanBasicHtml(figcaption.innerHTML, options); | ||
payload.caption = payload.caption ? "".concat(payload.caption, " / ").concat(cleanHtml) : cleanHtml; | ||
figcaption.remove(); // cleanup this processed element | ||
} | ||
} | ||
function _readGalleryImageFromNode(node, imgNum) { | ||
let fileName = node.src.match(/[^/]*$/)[0]; | ||
let image = { | ||
fileName, | ||
row: Math.floor(imgNum / 3), | ||
src: node.src | ||
}; | ||
if (node.width) { | ||
image.width = node.width; | ||
} else if (node.dataset && node.dataset.width) { | ||
image.width = parseInt(node.dataset.width, 10); | ||
} | ||
if (node.height) { | ||
image.height = node.height; | ||
} else if (node.dataset && node.dataset.height) { | ||
image.height = parseInt(node.dataset.height, 10); | ||
} | ||
if (node.alt) { | ||
image.alt = node.alt; | ||
} | ||
if (node.title) { | ||
image.title = node.title; | ||
} | ||
return image; | ||
} // PLUGINS ----------------------------------------------------------------- | ||
@@ -83,2 +125,65 @@ // https://github.com/TryGhost/Koenig/issues/1 | ||
const kgGalleryCardToCard = (node, builder, { | ||
addSection, | ||
nodeFinished | ||
}) => { | ||
if (node.nodeType !== 1 || node.tagName !== 'FIGURE') { | ||
return; | ||
} | ||
if (!node.className.match(/kg-gallery-card/)) { | ||
return; | ||
} | ||
let payload = {}; | ||
let imgs = Array.from(node.querySelectorAll('img')); // Process nodes into the payload | ||
payload.images = imgs.map(_readGalleryImageFromNode); | ||
_readFigCaptionFromNode(node, payload); | ||
let cardSection = builder.createCardSection('gallery', payload); | ||
addSection(cardSection); | ||
nodeFinished(); | ||
}; | ||
function grafGalleryToCard(node, builder, { | ||
addSection, | ||
nodeFinished | ||
}) { | ||
function isGrafGallery(node) { | ||
return node.nodeType === 1 && node.tagName === 'DIV' && node.dataset && node.dataset.paragraphCount && node.querySelectorAll('img').length > 0; | ||
} | ||
if (!isGrafGallery(node)) { | ||
return; | ||
} | ||
let payload = {}; // These galleries exist in multiple divs. Read the images and cation from the first one... | ||
let imgs = Array.from(node.querySelectorAll('img')); | ||
_readFigCaptionFromNode(node, payload); // ...and then iterate over any remaining divs until we run out of matches | ||
let nextNode = node.nextSibling; | ||
while (nextNode && isGrafGallery(nextNode)) { | ||
let currentNode = nextNode; | ||
imgs = imgs.concat(Array.from(currentNode.querySelectorAll('img'))); | ||
_readFigCaptionFromNode(currentNode, payload); | ||
nextNode = currentNode.nextSibling; // remove nodes as we go so that they don't go through the parser | ||
currentNode.remove(); | ||
} // Process nodes into the payload | ||
payload.images = imgs.map(_readGalleryImageFromNode); | ||
let cardSection = builder.createCardSection('gallery', payload); | ||
addSection(cardSection); | ||
nodeFinished(); | ||
} | ||
function figureToImageCard(node, builder, { | ||
@@ -93,3 +198,2 @@ addSection, | ||
let img = node.querySelector('img'); | ||
let figcaption = node.querySelector('figcaption'); | ||
let kgClass = node.className.match(/kg-width-(wide|full)/); | ||
@@ -114,6 +218,3 @@ let grafClass = node.className.match(/graf--layout(FillWidth|OutsetCenter)/); | ||
if (figcaption) { | ||
let cleanHtml = cleanBasicHtml(figcaption.innerHTML, options); | ||
payload.caption = cleanHtml; | ||
} | ||
_readFigCaptionFromNode(node, payload); | ||
@@ -156,2 +257,67 @@ let cardSection = builder.createCardSection('image', payload); | ||
function figureIframeToEmbedCard(node, builder, { | ||
addSection, | ||
nodeFinished | ||
}) { | ||
if (node.nodeType !== 1 || node.tagName !== 'FIGURE') { | ||
return; | ||
} | ||
let iframe = node.querySelector('iframe'); | ||
if (!iframe) { | ||
return; | ||
} | ||
let src = iframe.src; // If we don't have a src, or it's not an absolute URL, we can't handle this | ||
if (!src || !src.match(/^https?:\/\//i)) { | ||
return; | ||
} | ||
let payload = { | ||
url: src | ||
}; | ||
_readFigCaptionFromNode(node, payload); | ||
payload.html = node.innerHTML; | ||
let cardSection = builder.createCardSection('embed', payload); | ||
addSection(cardSection); | ||
nodeFinished(); | ||
} | ||
function figureBlockquoteToEmbedCard(node, builder, { | ||
addSection, | ||
nodeFinished | ||
}) { | ||
if (node.nodeType !== 1 || node.tagName !== 'FIGURE') { | ||
return; | ||
} | ||
let blockquote = node.querySelector('blockquote'); | ||
let link = node.querySelector('a'); | ||
if (!blockquote || !link) { | ||
return; | ||
} | ||
let url = link.href; // If we don't have a url, or it's not an absolute URL, we can't handle this | ||
if (!url || !url.match(/^https?:\/\//i)) { | ||
return; | ||
} | ||
let payload = { | ||
url: url | ||
}; | ||
_readFigCaptionFromNode(node, payload); | ||
payload.html = node.innerHTML; | ||
let cardSection = builder.createCardSection('embed', payload); | ||
addSection(cardSection); | ||
nodeFinished(); | ||
} | ||
function figureToCodeCard(node, builder, { | ||
@@ -179,5 +345,7 @@ addSection, | ||
let payload = { | ||
code: code.textContent, | ||
caption: cleanBasicHtml(figcaption.innerHTML, options) | ||
code: code.textContent | ||
}; | ||
_readFigCaptionFromNode(node, payload); | ||
let preClass = pre.getAttribute('class') || ''; | ||
@@ -226,3 +394,26 @@ let codeClass = code.getAttribute('class') || ''; | ||
return [kgHtmlCardToCard, brToSoftBreakAtom, removeLeadingNewline, figureToImageCard, imgToCard, hrToCard, figureToCodeCard, preCodeToCard]; | ||
function figureScriptToHtmlCard(node, builder, { | ||
addSection, | ||
nodeFinished | ||
}) { | ||
if (node.nodeType !== 1 || node.tagName !== 'FIGURE') { | ||
return; | ||
} | ||
let script = node.querySelector('script'); | ||
if (!script || !script.src.match(/^https:\/\/gist\.github\.com/)) { | ||
return; | ||
} | ||
let payload = { | ||
html: script.outerHTML | ||
}; | ||
let cardSection = builder.createCardSection('html', payload); | ||
addSection(cardSection); | ||
nodeFinished(); | ||
} | ||
return [kgHtmlCardToCard, brToSoftBreakAtom, removeLeadingNewline, kgGalleryCardToCard, figureBlockquoteToEmbedCard, // I think these can contain images | ||
grafGalleryToCard, figureToImageCard, imgToCard, hrToCard, figureToCodeCard, preCodeToCard, figureIframeToEmbedCard, figureScriptToHtmlCard]; | ||
} | ||
@@ -229,0 +420,0 @@ |
@@ -31,2 +31,45 @@ /* global DOMParser, window */ | ||
// HELPERS ----------------------------------------------------------------- | ||
function _readFigCaptionFromNode(node, payload) { | ||
let figcaption = node.querySelector('figcaption'); | ||
if (figcaption) { | ||
let cleanHtml = cleanBasicHtml(figcaption.innerHTML, options); | ||
payload.caption = payload.caption ? `${payload.caption} / ${cleanHtml}` : cleanHtml; | ||
figcaption.remove(); // cleanup this processed element | ||
} | ||
} | ||
function _readGalleryImageFromNode(node, imgNum) { | ||
let fileName = node.src.match(/[^/]*$/)[0]; | ||
let image = { | ||
fileName, | ||
row: Math.floor(imgNum / 3), | ||
src: node.src | ||
}; | ||
if (node.width) { | ||
image.width = node.width; | ||
} else if (node.dataset && node.dataset.width) { | ||
image.width = parseInt(node.dataset.width, 10); | ||
} | ||
if (node.height) { | ||
image.height = node.height; | ||
} else if (node.dataset && node.dataset.height) { | ||
image.height = parseInt(node.dataset.height, 10); | ||
} | ||
if (node.alt) { | ||
image.alt = node.alt; | ||
} | ||
if (node.title) { | ||
image.title = node.title; | ||
} | ||
return image; | ||
} | ||
// PLUGINS ----------------------------------------------------------------- | ||
@@ -86,2 +129,58 @@ | ||
const kgGalleryCardToCard = (node, builder, {addSection, nodeFinished}) => { | ||
if (node.nodeType !== 1 || node.tagName !== 'FIGURE') { | ||
return; | ||
} | ||
if (!node.className.match(/kg-gallery-card/)) { | ||
return; | ||
} | ||
let payload = {}; | ||
let imgs = Array.from(node.querySelectorAll('img')); | ||
// Process nodes into the payload | ||
payload.images = imgs.map(_readGalleryImageFromNode); | ||
_readFigCaptionFromNode(node, payload); | ||
let cardSection = builder.createCardSection('gallery', payload); | ||
addSection(cardSection); | ||
nodeFinished(); | ||
}; | ||
function grafGalleryToCard(node, builder, {addSection, nodeFinished}) { | ||
function isGrafGallery(node) { | ||
return node.nodeType === 1 && node.tagName === 'DIV' && node.dataset && node.dataset.paragraphCount && node.querySelectorAll('img').length > 0; | ||
} | ||
if (!isGrafGallery(node)) { | ||
return; | ||
} | ||
let payload = {}; | ||
// These galleries exist in multiple divs. Read the images and cation from the first one... | ||
let imgs = Array.from(node.querySelectorAll('img')); | ||
_readFigCaptionFromNode(node, payload); | ||
// ...and then iterate over any remaining divs until we run out of matches | ||
let nextNode = node.nextSibling; | ||
while (nextNode && isGrafGallery(nextNode)) { | ||
let currentNode = nextNode; | ||
imgs = imgs.concat(Array.from(currentNode.querySelectorAll('img'))); | ||
_readFigCaptionFromNode(currentNode, payload); | ||
nextNode = currentNode.nextSibling; | ||
// remove nodes as we go so that they don't go through the parser | ||
currentNode.remove(); | ||
} | ||
// Process nodes into the payload | ||
payload.images = imgs.map(_readGalleryImageFromNode); | ||
let cardSection = builder.createCardSection('gallery', payload); | ||
addSection(cardSection); | ||
nodeFinished(); | ||
} | ||
function figureToImageCard(node, builder, {addSection, nodeFinished}) { | ||
@@ -93,3 +192,2 @@ if (node.nodeType !== 1 || node.tagName !== 'FIGURE') { | ||
let img = node.querySelector('img'); | ||
let figcaption = node.querySelector('figcaption'); | ||
let kgClass = node.className.match(/kg-width-(wide|full)/); | ||
@@ -114,6 +212,3 @@ let grafClass = node.className.match(/graf--layout(FillWidth|OutsetCenter)/); | ||
if (figcaption) { | ||
let cleanHtml = cleanBasicHtml(figcaption.innerHTML, options); | ||
payload.caption = cleanHtml; | ||
} | ||
_readFigCaptionFromNode(node, payload); | ||
@@ -151,2 +246,65 @@ let cardSection = builder.createCardSection('image', payload); | ||
function figureIframeToEmbedCard(node, builder, {addSection, nodeFinished}) { | ||
if (node.nodeType !== 1 || node.tagName !== 'FIGURE') { | ||
return; | ||
} | ||
let iframe = node.querySelector('iframe'); | ||
if (!iframe) { | ||
return; | ||
} | ||
let src = iframe.src; | ||
// If we don't have a src, or it's not an absolute URL, we can't handle this | ||
if (!src || !src.match(/^https?:\/\//i)) { | ||
return; | ||
} | ||
let payload = { | ||
url: src | ||
}; | ||
_readFigCaptionFromNode(node, payload); | ||
payload.html = node.innerHTML; | ||
let cardSection = builder.createCardSection('embed', payload); | ||
addSection(cardSection); | ||
nodeFinished(); | ||
} | ||
function figureBlockquoteToEmbedCard(node, builder, {addSection, nodeFinished}) { | ||
if (node.nodeType !== 1 || node.tagName !== 'FIGURE') { | ||
return; | ||
} | ||
let blockquote = node.querySelector('blockquote'); | ||
let link = node.querySelector('a'); | ||
if (!blockquote || !link) { | ||
return; | ||
} | ||
let url = link.href; | ||
// If we don't have a url, or it's not an absolute URL, we can't handle this | ||
if (!url || !url.match(/^https?:\/\//i)) { | ||
return; | ||
} | ||
let payload = { | ||
url: url | ||
}; | ||
_readFigCaptionFromNode(node, payload); | ||
payload.html = node.innerHTML; | ||
let cardSection = builder.createCardSection('embed', payload); | ||
addSection(cardSection); | ||
nodeFinished(); | ||
} | ||
function figureToCodeCard(node, builder, {addSection, nodeFinished}) { | ||
@@ -173,6 +331,7 @@ if (node.nodeType !== 1 || node.tagName !== 'FIGURE') { | ||
let payload = { | ||
code: code.textContent, | ||
caption: cleanBasicHtml(figcaption.innerHTML, options) | ||
code: code.textContent | ||
}; | ||
_readFigCaptionFromNode(node, payload); | ||
let preClass = pre.getAttribute('class') || ''; | ||
@@ -215,2 +374,19 @@ let codeClass = code.getAttribute('class') || ''; | ||
function figureScriptToHtmlCard(node, builder, {addSection, nodeFinished}) { | ||
if (node.nodeType !== 1 || node.tagName !== 'FIGURE') { | ||
return; | ||
} | ||
let script = node.querySelector('script'); | ||
if (!script || !script.src.match(/^https:\/\/gist\.github\.com/)) { | ||
return; | ||
} | ||
let payload = {html: script.outerHTML}; | ||
let cardSection = builder.createCardSection('html', payload); | ||
addSection(cardSection); | ||
nodeFinished(); | ||
} | ||
return [ | ||
@@ -220,2 +396,5 @@ kgHtmlCardToCard, | ||
removeLeadingNewline, | ||
kgGalleryCardToCard, | ||
figureBlockquoteToEmbedCard, // I think these can contain images | ||
grafGalleryToCard, | ||
figureToImageCard, | ||
@@ -225,4 +404,6 @@ imgToCard, | ||
figureToCodeCard, | ||
preCodeToCard | ||
preCodeToCard, | ||
figureIframeToEmbedCard, | ||
figureScriptToHtmlCard | ||
]; | ||
} |
{ | ||
"name": "@tryghost/kg-parser-plugins", | ||
"version": "0.5.1", | ||
"version": "0.6.0", | ||
"repository": "https://github.com/TryGhost/Koenig/tree/master/packages/kg-parser-plugins", | ||
@@ -43,3 +43,3 @@ "author": "Ghost Foundation", | ||
}, | ||
"gitHead": "bb81c318c8c96ecdca7a73bdd4f5cc15f9b1b7c6" | ||
"gitHead": "3c069d68c0c538e16ec4728db47b45de39dad905" | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
63084
940