in dotcom-rendering/src/lib/find-adslots.amp.ts [51:159]
length: getElementLength(e),
};
});
};
const getLengthOfFollowingTextElements = (
elements: ElementWithLength[],
): number => {
const firstNonTextIndex = elements.findIndex(
(e) => !isTextElement(e.element),
);
return elements
.slice(0, firstNonTextIndex)
.map((e) => e.length)
.reduce((a, b) => a + b, 0);
};
const suitableAdNeighbour = (e: ElementWithLength): boolean => {
return isTextElement(e.element) && e.length > SMALL_PARA_CHARS;
};
const hasForwardBuffer = (
elements: ElementWithLength[],
index: number,
): boolean => {
const forwardElements = elements.slice(index + 1, elements.length);
const meetsThreshold =
getLengthOfFollowingTextElements(forwardElements) >=
NONTEXT_BUFFER_FORWARD;
const noForwardsEmbeds =
forwardElements.filter((e) => isTextElement(e.element)).length ===
forwardElements.length;
const enoughCharsForward = meetsThreshold || noForwardsEmbeds;
const neighbour = elements[index];
const neighbourSuitable = neighbour
? suitableAdNeighbour(neighbour)
: false;
return enoughCharsForward && neighbourSuitable;
};
const hasBackwardBuffer = (
elements: ElementWithLength[],
index: number,
): boolean => {
const backwardsElements = elements.slice(0, index).reverse();
const meetsThreshold =
getLengthOfFollowingTextElements(backwardsElements) >=
NONTEXT_BUFFER_BACKWARD;
const noBackwardsEmbeds =
backwardsElements.filter((e) => isTextElement(e.element)).length ===
backwardsElements.length;
const enoughCharsBackward = meetsThreshold || noBackwardsEmbeds;
const neighbour = elements[index];
return !!neighbour && suitableAdNeighbour(neighbour) && enoughCharsBackward;
};
/**
* There are some magic numbers here - obtained by eyeballing content. Feel free
* to update them if you notice issues.
*/
const sufficientSpaceSinceLastAd = (
charsSinceLastAd: number,
paragraphsSinceLastAd: number,
): boolean => {
return (
(charsSinceLastAd > 700 && paragraphsSinceLastAd > 1) ||
charsSinceLastAd > 900
);
};
const hasSpaceForAd = (
elements: ElementWithLength[],
index: number,
charsSinceLastAd: number,
paragraphsSinceLastAd: number,
): boolean => {
return (
sufficientSpaceSinceLastAd(charsSinceLastAd, paragraphsSinceLastAd) &&
hasBackwardBuffer(elements, index) &&
hasForwardBuffer(elements, index)
);
};
// Returns index of items to place ads *after*
export const findAdSlots = (elements: FEElement[]): number[] => {
let charsSinceLastAd = 0;
let paragraphsSinceLastAd = 0;
let adCount = 0;
const adSlots = [];
const elementsWithLength = getElementsWithLength(elements);
for (let i = 0; i < elementsWithLength.length; i += 1) {
const currentElement = elements[i];
const currentElementWithLength = elementsWithLength[i];
if (
currentElement &&
currentElementWithLength &&
adCount < AD_LIMIT &&
isTextElement(currentElement)
) {