Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v1.0.6 #29

Merged
merged 3 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/workflows/pr-template-checker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: 'PR Template Checker'
on:
pull_request:
types: [edited, opened, synchronize, reopened]

jobs:
task-check:
runs-on: ubuntu-latest
steps:
- uses: wp-media/pr-checklist-action@master
with:
repo-token: "${{ secrets.PR_TEMPLATE_TOKEN }}"
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "wp-rocket-scripts",
"version": "1.0.5",
"version": "1.0.6",
"description": "Rocket main scripts packages",
"type": "module",
"main": "./src/BeaconEntryPoint.js",
Expand Down
143 changes: 143 additions & 0 deletions src/BeaconLrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
'use strict';

import BeaconUtils from "./Utils.js";

class BeaconLrc {
constructor(config, logger) {
this.config = config;
this.logger = logger;
this.lazyRenderElements = [];
}

async run() {
try {
const elementsInView = this._getLazyRenderElements();
if (elementsInView) {
this._processElements(elementsInView);
}
} catch (err) {
this.errorCode = 'script_error';
this.logger.logMessage('Script Error: ' + err);
}
}

_getLazyRenderElements() {
const elements = document.querySelectorAll('[data-rocket-location-hash]');

if (elements.length <= 0) {
return [];
}

const validElements = Array.from(elements).filter(element => !this._skipElement(element));

return validElements.map(element => ({
element: element,
depth: this._getElementDepth(element),
distance: this._getElementDistance(element),
hash: this._getLocationHash(element)
}));
}

_getElementDepth(element) {
let depth = 0;
let parent = element.parentElement;
while (parent) {
depth++;
parent = parent.parentElement;
}
return depth;
}

_getElementDistance(element) {
const rect = element.getBoundingClientRect();
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
return Math.max(0, rect.top + scrollTop - BeaconUtils.getScreenHeight());
}

_skipElement(element) {
const skipStrings = this.config.skipStrings || ['memex'];
if (!element || !element.id) return false;
return skipStrings.some(str => element.id.toLowerCase().includes(str.toLowerCase()));
}

_shouldSkipElement(element, exclusions) {
if (!element) return false;
for (let i = 0; i < exclusions.length; i++) {
const [attribute, pattern] = exclusions[i];
const attributeValue = element.getAttribute(attribute);
if (attributeValue && new RegExp(pattern, 'i').test(attributeValue)) {
return true;
}
}
return false;
}

_processElements(elements) {
elements.forEach(({ element, depth, distance, hash }) => {
if (this._shouldSkipElement(element, this.config.exclusions || [])) {
return;
}

if ( 'No hash detected' === hash ) {
return;
}

const can_push_hash = element.parentElement && this._getElementDistance(element.parentElement) < this.config.lrc_threshold && distance >= this.config.lrc_threshold;

const color = can_push_hash ? "green" : distance === 0 ? "red" : "";
this.logger.logColoredMessage( `${'\t'.repeat(depth)}${element.tagName} (Depth: ${depth}, Distance from viewport bottom: ${distance}px)`, color );

//const xpath = this._getXPath(element);
//console.log(`%c${'\t'.repeat(depth)}Xpath: ${xpath}`, style);

this.logger.logColoredMessage(`${'\t'.repeat(depth)}Location hash: ${hash}`, color);

this.logger.logColoredMessage(`${'\t'.repeat(depth)}Dimensions Client Height: ${element.clientHeight}`, color);

if (can_push_hash) {
this.lazyRenderElements.push(hash); // Push the hash
this.logger.logMessage(`Element pushed with hash: ${hash}`);
}
});
}

_getXPath(element) {
if (element && element.id !== "") {
return `//*[@id="${element.id}"]`;
}

return this._getElementXPath(element);
}

_getElementXPath(element) {
if (element === document.body) {
return '/html/body';
}
const position = this._getElementPosition(element);
return `${this._getElementXPath(element.parentNode)}/${element.nodeName.toLowerCase()}[${position}]`;
}

_getElementPosition(element) {
let pos = 1;
let sibling = element.previousElementSibling;
while (sibling) {
if (sibling.nodeName === element.nodeName) {
pos++;
}
sibling = sibling.previousElementSibling;
}
return pos;
}

_getLocationHash(element) {
return element.hasAttribute('data-rocket-location-hash')
? element.getAttribute('data-rocket-location-hash')
: 'No hash detected';
}

getResults() {
return this.lazyRenderElements;
}
}

export default BeaconLrc;
21 changes: 16 additions & 5 deletions src/BeaconManager.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
'use strict';

import BeaconLcp from "./BeaconLcp.js";
import BeaconLrc from "./BeaconLrc.js";
import BeaconUtils from "./Utils.js";
import Logger from "./Logger.js";

class BeaconManager {
constructor(config) {
this.config = config;
this.lcpBeacon = null;
this.lrcBeacon = null;
this.infiniteLoopId = null;
this.errorCode = '';
this.logger = new Logger(this.config.debug);
Expand All @@ -25,21 +27,29 @@ class BeaconManager {
}, 10000);

const isGeneratedBefore = await this._getGeneratedBefore();
let shouldSaveResultsIntoDB = false;

// OCI / LCP / ATF
const shouldGenerateLcp = (
this.config.status.atf && (isGeneratedBefore === false || isGeneratedBefore.lcp === false)
);
const shouldGeneratelrc = (
this.config.status.lrc && (isGeneratedBefore === false || isGeneratedBefore.lrc === false)
);
if (shouldGenerateLcp) {
this.lcpBeacon = new BeaconLcp(this.config, this.logger);
await this.lcpBeacon.run();
shouldSaveResultsIntoDB = true;
} else {
this.logger.logMessage('Not running BeaconLcp because data is already available');
this.logger.logMessage('Not running BeaconLcp because data is already available or feature is disabled');
}

if (shouldGeneratelrc) {
this.lrcBeacon = new BeaconLrc(this.config, this.logger);
await this.lrcBeacon.run();
} else {
this.logger.logMessage('Not running BeaconLrc because data is already available or feature is disabled');
}

if (shouldSaveResultsIntoDB) {
if (shouldGenerateLcp || shouldGeneratelrc) {
this._saveFinalResultIntoDB();
} else {
this.logger.logMessage("Not saving results into DB as no beacon features ran.");
Expand Down Expand Up @@ -84,7 +94,8 @@ class BeaconManager {

_saveFinalResultIntoDB() {
const results = {
lcp: this.lcpBeacon ? this.lcpBeacon.getResults() : null
lcp: this.lcpBeacon ? this.lcpBeacon.getResults() : null,
lrc: this.lrcBeacon ? this.lrcBeacon.getResults() : null
};

const data = new FormData();
Expand Down
7 changes: 7 additions & 0 deletions src/Logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ class Logger {
}
console.log(msg);
}

logColoredMessage( msg, color = 'green' ) {
if (!this.enabled) {
return;
}
console.log(`%c${msg}`, `color: ${color};`);
}
}

export default Logger;
12 changes: 10 additions & 2 deletions src/Utils.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
'use strict';

class BeaconUtils {
static getScreenWidth() {
return window.innerWidth || document.documentElement.clientWidth;
}

static getScreenHeight() {
return window.innerHeight || document.documentElement.clientHeight;
}

static isNotValidScreensize( is_mobile, threshold ) {
const screenWidth = window.innerWidth || document.documentElement.clientWidth;
const screenHeight = window.innerHeight || document.documentElement.clientHeight;
const screenWidth = this.getScreenWidth();
const screenHeight = this.getScreenHeight();

const isNotValidForMobile = is_mobile &&
(screenWidth > threshold.width || screenHeight > threshold.height);
Expand Down
Loading
Loading