Skip to content

Commit

Permalink
exclude ids
Browse files Browse the repository at this point in the history
  • Loading branch information
jemikanegara committed Aug 8, 2024
1 parent 6651756 commit 9834573
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 9 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Place the following script inside your <head> tag
#### Optional Configuration:
- **data-use-browser-language**: Automatically sets the language based on the user's browser language. Set to `false` to disable.
- **data-exclude-classes**: List CSS class names to exclude from translation, separated by commas (e.g., `chatbot, no-translate`).
- **data-exclude-ids**: List IDs to exclude from translation, separated by commas (e.g., `user-comment, code-snippet` will prevent translation of elements with ID `user-comment` and `code-snippet`).

View more options [here](#advanced-configuration).

Expand Down
9 changes: 9 additions & 0 deletions browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ if (isBrowser()) {
// COMMON OPTIONAL ATTRIBUTES
const DATA_USE_BROWSER_LANG = "data-use-browser-language"; // default: true
const DATA_EXCLUDE_CLASSES = "data-exclude-classes";
const DATA_EXCLUDE_IDS = "data-exclude-ids";
const DATA_REPLACE_LINKS = "data-replace-links"; // default: true
const DATA_AUTO_CREATE_SELECTOR = "data-auto-create-selector"; // default: true
const DATA_DELAY = "data-timeout"; // default: 0
Expand Down Expand Up @@ -206,6 +207,13 @@ if (isBrowser()) {
const mergedExcludeClasses = [...excludeClassesByComma, ...excludeClassesBySpace];
const excludeClasses = [...new Set(mergedExcludeClasses)]; // get unique values

// exclude ids
const excludeIdsAttr = (window.translationScriptTag.getAttribute(DATA_EXCLUDE_IDS) || "").trim()
const excludeIdsByComma = excludeIdsAttr.split(",").filter(id => !!id).map(id => id.trim());
const excludeIdsBySpace = excludeIdsAttr.split(" ").filter(id => !!id).map(id => id.trim().replaceAll(",", ""));
const mergedExcludeIds = [...excludeIdsByComma, ...excludeIdsBySpace];
const excludeIds = [...new Set(mergedExcludeIds)]; // get unique values

// exclude contents
const excludeContentsAttr = (window.translationScriptTag.getAttribute(DATA_EXCLUDE_CONTENTS) || "").trim()
const splittedContents = getTextInsideBrackets(excludeContentsAttr);
Expand Down Expand Up @@ -235,6 +243,7 @@ if (isBrowser()) {
useBrowserLanguage: !disableAutoTranslate && useBrowserLanguage,
createSelector: createSelector,
excludeClasses,
excludeIds,
excludeContents,
originalLanguage: originalLang,
allowedLanguages: allowedLangs,
Expand Down
9 changes: 5 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const { renderSelectorState } = require('./utils/selector/renderSelectorState.js
const getTranslationCacheFromCloudflare = require('./utils/translation/getTranslationCacheFromCloudflare.js');
const { isCompressionSupported } = require('./utils/compressions.js');
const isUrl = require('./utils/translation/isUrl.js');
const isExcluded = require('./utils/translation/isExcluded.js');
const { isExcludedClassName, isExcludedId } = require('./utils/translation/isExcluded.js');

var isDomListenerAdded;

Expand Down Expand Up @@ -690,11 +690,11 @@ function modifyHtmlStrings(rootElement, language, apiKey, shouldOptimizeSEO) {
if (options.translateFormPlaceholder) {
const inputTags = Array.from(document.getElementsByTagName('input'));
// only include input that has placeholder attribute
const cleanAnchorTags = inputTags.filter((node) => (node.placeholder || "").trim() && !isExcluded(node.className));
const cleanAnchorTags = inputTags.filter((node) => (node.placeholder || "").trim() && !isExcludedClassName(node.className) && !isExcludedId(node.id));

const textareaTags = Array.from(document.getElementsByTagName('textarea'));
// only include textarea that has placeholder attribute
const cleanTextareaTags = textareaTags.filter((node) => (node.placeholder || "").trim() && !isExcluded(node.className));
const cleanTextareaTags = textareaTags.filter((node) => (node.placeholder || "").trim() && !isExcludedClassName(node.className) && !isExcludedId(node.id));

otherNodes.push(
...cleanAnchorTags,
Expand All @@ -705,7 +705,7 @@ function modifyHtmlStrings(rootElement, language, apiKey, shouldOptimizeSEO) {
if (options.translateSelectOptions) {
const optionTags = Array.from(document.getElementsByTagName('option'));
// only include option that has value attribute and make sure the select tag is not excluded
const cleanOptionTags = optionTags.filter((node) => (node.textContent || "").trim() && !isExcluded(node.className) && node.parentElement.tagName == "SELECT" && !isExcluded(node.parentElement.className));
const cleanOptionTags = optionTags.filter((node) => (node.textContent || "").trim() && !isExcludedClassName(node.className) && node.parentElement.tagName == "SELECT" && !isExcludedClassName(node.parentElement.className) && !isExcludedId(node.parentElement.id) && !isExcludedId(node.id));

otherNodes.push(
...cleanOptionTags,
Expand Down Expand Up @@ -864,6 +864,7 @@ function setOptions(apiKey, optsArgs) {
timeout: optsArgs.timeout == null ? 0 : optsArgs.timeout,
pathOptions: optsArgs.pathOptions || {},
apiKey,
excludeIds: optsArgs.excludeIds || [],
excludeClasses: optsArgs.excludeClasses || [],
excludeContents: optsArgs.excludeContents || [],
definedLanguages: getDefinedLanguages(optsArgs.originalLanguage, optsArgs.allowedLanguages),
Expand Down
15 changes: 12 additions & 3 deletions utils/translation/extractTextNodes.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { getGlobalseoOptions, shouldTranslateInlineText, CONTEXT_LIMIT, MAX_WORDS_LENGTH_FOR_CONTEXT, OLD_EXCLUDE_CLASS, MERGE_PREFIX } = require("../configs");
const isExcluded = require("./isExcluded");
const { isExcludedClassName, isExcludedId } = require("./isExcluded");
const isUrl = require("./isUrl");

function collectAllTextContentInsideNode(node, shouldExclude = false) {
Expand All @@ -13,11 +13,15 @@ function collectAllTextContentInsideNode(node, shouldExclude = false) {
child &&
child.className &&
typeof child.className == "string" &&
isExcluded(child.className)
isExcludedClassName(child.className)
) {
return;
}

if (child && child.id && typeof child.id == "string" && isExcludedId(child.id)) {
return;
};

if (child.nodeType === Node.TEXT_NODE && child.textContent.trim()) {
textNodes.push(child);
}
Expand Down Expand Up @@ -273,10 +277,15 @@ function extractTextNodes(node, textNodes) {
node &&
node.className &&
typeof node.className == "string" &&
isExcluded(node.className)
isExcludedClassName(node.className)
) {
return;
}

if (node && node.id && typeof node.id == "string" && isExcludedId(node.id)) {
return;
};

for (let child of node.childNodes) {
extractTextNodes(child, textNodes);
}
Expand Down
12 changes: 10 additions & 2 deletions utils/translation/isExcluded.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
const { getGlobalseoOptions, OLD_EXCLUDE_CLASS } = require("../configs");

function isExcluded(className) {
function isExcludedClassName(className) {
const globalseoOptions = getGlobalseoOptions();

return className.includes(OLD_EXCLUDE_CLASS) || className.includes("globalseo-exclude") || globalseoOptions.excludeClasses.length && globalseoOptions.excludeClasses.some(excludeClass => excludeClass && className.includes(excludeClass))
}
exports.isExcludedClassName = isExcludedClassName;

module.exports = isExcluded;
function isExcludedId(id) {
if (!id) return false;

const globalseoOptions = getGlobalseoOptions();

return globalseoOptions.excludeIds.length && globalseoOptions.excludeIds.some(excludeId => excludeId && id.includes(excludeId))
}
exports.isExcludedId = isExcludedId;

0 comments on commit 9834573

Please sign in to comment.