tml-js-browser
Advanced tools
Comparing version 0.4.26 to 0.4.28
@@ -65,30 +65,2 @@ /** | ||
includeTools: function(app, locale, callback) { | ||
utils.addCSS(window.document, app.tools.stylesheet, false); | ||
utils.addCSS(window.document, app.css, true); | ||
utils.addJS(window.document, 'tml-jssdk', app.tools.javascript, function() { | ||
Tml.app_key = app.key; | ||
Tml.host = app.tools.host; | ||
Tml.current_source = app.current_source; | ||
Tml.default_locale = app.default_locale; | ||
Tml.page_locale = locale; | ||
Tml.locale = locale; | ||
var shortcutFn = function(sc){ | ||
return function() { | ||
eval(app.shortcuts[sc]); // jshint ignore:line | ||
}; | ||
}; | ||
if (app.isFeatureEnabled("shortcuts")) { | ||
for (var sc in app.shortcuts) { | ||
shortcut.add(sc, shortcutFn(sc)); | ||
} | ||
} | ||
if (callback) callback(); | ||
}); | ||
}, | ||
includeAgent: function(app, options, callback) { | ||
@@ -95,0 +67,0 @@ var agent_host = options.host || "https://tools.translationexchange.com/agent/stable/agent.min.js"; |
890
lib/index.js
@@ -34,506 +34,554 @@ /** | ||
var tml = require('tml-js'); | ||
var helpers = require('./helpers'); | ||
var DomTokenizer = require('./tokenizers/dom'); | ||
(function (root, factory) { | ||
function addToRoot(result) { | ||
//for backwards compatibility - always copy everything to global object | ||
if (root) { | ||
var DEFAULT_HOST = "https://api.translationexchange.com"; | ||
var mutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; | ||
for (var key in result) { | ||
if (result.hasOwnProperty(key)) { | ||
root[key] = result[key]; | ||
} | ||
} | ||
} | ||
} | ||
tml = tml.utils.extend(tml, { | ||
version: '/* @echo VERSION */', | ||
if (typeof define === 'function' && define.amd) { | ||
//console.log('amd load'); | ||
define([], factory); | ||
} | ||
else if (typeof exports === 'object') { | ||
//console.log('exports load', module); | ||
module.exports = factory(); | ||
addToRoot(module.exports); | ||
} | ||
else { | ||
//console.log('global load'); | ||
addToRoot(factory()); | ||
} | ||
}(window, function () { | ||
app: null, | ||
block_options: [], | ||
root_element: null, | ||
options: {}, | ||
var tml = require('tml-js'); | ||
var helpers = require('./helpers'); | ||
var DomTokenizer = require('./tokenizers/dom'); | ||
var Emitter = require('tiny-emitter'); | ||
var emitter = new Emitter(); | ||
/** | ||
* Initializes TML library | ||
* @param options | ||
* @param callback | ||
*/ | ||
init: function(options, callback) { | ||
options = options || {}; | ||
var DEFAULT_HOST = "https://api.translationexchange.com"; | ||
var mutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; | ||
tml.options = options; | ||
tml.config.debug = (options.debug ? options.debug : tml.config.debug); | ||
tml = tml.utils.extend(tml, { | ||
version: '/* @echo VERSION */', | ||
options.preferred_languages = options.preferred_languages || helpers.getBrowserLanguages(); | ||
on: emitter.on.bind(emitter), | ||
off: emitter.off.bind(emitter), | ||
once: emitter.once.bind(emitter), | ||
emit: emitter.emit.bind(emitter), | ||
if (tml.config.debug || options.info) | ||
helpers.printWelcomeMessage(tml.version); | ||
app: null, | ||
block_options: [], | ||
root_element: null, | ||
options: {}, | ||
tml.initApplication(options, callback); | ||
}, | ||
/** | ||
* Initializes TML library | ||
* @param options | ||
* @param callback | ||
*/ | ||
init: function (options, callback) { | ||
options = options || {}; | ||
/** | ||
* Initializes application | ||
* | ||
* @param options | ||
* @param callback | ||
*/ | ||
initApplication: function(options, callback) { | ||
var t0 = new Date(); | ||
tml.options = options; | ||
tml.config.debug = (options.debug ? options.debug : tml.config.debug); | ||
var cookie = helpers.getCookie(options.key); | ||
options.preferred_languages = options.preferred_languages || helpers.getBrowserLanguages(); | ||
var cache_version = null; | ||
if (!options.current_source) { | ||
options.current_source = function () { | ||
return helpers.getCurrentSource({}); | ||
}; | ||
} | ||
if (options.cache && options.cache.version) | ||
cache_version = options.cache.version; | ||
if (tml.config.debug || options.info) { | ||
helpers.printWelcomeMessage(tml.version); | ||
} | ||
tml.config.registerApiAdapter('ajax', require('./api_adapters/ajax')); | ||
tml.config.api = 'ajax'; | ||
tml.initApplication(options, function () { | ||
tml.startKeyListener(); | ||
tml.startSourceListener(options); | ||
if (callback) { | ||
callback(); | ||
} | ||
}); | ||
}, | ||
tml.config.registerCacheAdapters({ | ||
inline: require('./cache_adapters/inline'), | ||
browser: require('./cache_adapters/browser') | ||
}); | ||
// submit any newly registered keys every 3 seconds | ||
startKeyListener: function () { | ||
if (tml.getApplication().isInlineModeEnabled()) { | ||
var app = tml.getApplication(); | ||
var freq = 3000; | ||
setInterval(function () { | ||
app.submitMissingTranslationKeys(); | ||
}, freq); | ||
} | ||
}, | ||
options = tml.utils.merge(tml.config, { | ||
delayed_flush: true, | ||
api: "ajax", | ||
current_source: helpers.getCurrentSource(options), | ||
current_locale: helpers.getCurrentLocale(options.key, options.current_locale), | ||
current_translator: cookie.translator ? new tml.Translator(cookie.translator) : null, | ||
accepted_locales: window.navigator.languages, | ||
cache: { | ||
enabled: true, | ||
adapter: "browser", | ||
version: cache_version | ||
} | ||
}, options); | ||
refreshSource: function (options) { | ||
var self = this; | ||
var source = helpers.getCurrentSource(options); | ||
var app = tml.getApplication(); | ||
var key = tml.utils.generateKey(source); // utils | ||
var locale = app.current_locale; | ||
options.fetch_version = (options.cache.adapter == 'browser' && !cache_version); | ||
var updateSource = function () { | ||
if (self.tokenizer) { | ||
self.tokenizer.updateAllNodes(); | ||
} | ||
}; | ||
tml.config.initCache(options.key); | ||
// console.log(options); | ||
if (!app.getSource(source)) { | ||
app.loadSources([source], locale, function (sources) { | ||
if (sources.length > 0 && sources[0] && sources[0].sources && sources[0].sources.length > 0) { | ||
app.loadSources(sources[0].sources, app.current_locale, updateSource); | ||
} else { | ||
updateSource(); | ||
} | ||
}); | ||
} | ||
}, | ||
tml.app = new tml.Application({ | ||
key: options.key, | ||
token: options.token, | ||
host: options.host || DEFAULT_HOST | ||
}); | ||
// keep track of route changes and update source | ||
startSourceListener: function (options) { | ||
var self = this; | ||
var app = tml.getApplication(); | ||
tml.app.init(options, function (err) { | ||
if (err) { | ||
throw new Error(err); | ||
} | ||
if ((options.translateBody || options.translate_body) && mutationObserver) { | ||
tml.translateElement(document); | ||
} | ||
tml.domReady(function(){ | ||
if ((options.translateBody || options.translate_body) && !mutationObserver) { | ||
tml.translateElement(document.body); | ||
function setSource(method) { | ||
return function () { | ||
if (method) { | ||
method.apply(history, arguments); | ||
} | ||
self.refreshSource(options); | ||
}; | ||
} | ||
var t1 = new Date(); | ||
tml.logger.debug("page render took " + (t1 - t0) + " mls"); | ||
window.history.pushState = setSource(window.history.pushState); | ||
window.history.replaceState = setSource(window.history.replaceState); | ||
window.addEventListener('popstate', setSource()); | ||
}, | ||
tml.updateLanguageSelector(); | ||
/** | ||
* Initializes application | ||
* | ||
* @param options | ||
* @param callback | ||
*/ | ||
initApplication: function (options, callback) { | ||
var t0 = new Date(); | ||
if ((options.translateTitle || options.translate_title) && document.title !== "") { | ||
document.title = tml.translateLabel(document.title); | ||
} | ||
var cookie = helpers.getCookie(options.key); | ||
if (!options.agent) { | ||
options.agent = { | ||
type: 'agent', | ||
cache: 864000000 | ||
}; | ||
} | ||
var cache_version = null; | ||
if (options.agent.type == "agent") { | ||
helpers.includeAgent(tml.app, { | ||
host: options.agent.host, | ||
cache: options.agent.cache, | ||
domains: options.agent.domains || {}, | ||
locale: options.current_locale, | ||
source: options.current_source, | ||
languages: tml.app.languages | ||
}, function () { | ||
if (callback) callback(); | ||
}); | ||
} else { | ||
helpers.includeTools(tml.app, options.current_locale, function () { | ||
if (callback) callback(); | ||
}); | ||
} | ||
if (options.cache && options.cache.version) | ||
cache_version = options.cache.version; | ||
if (typeof(options.onLoad) == "function") { | ||
options.onLoad(tml.app); | ||
} | ||
}); | ||
tml.config.registerApiAdapter('ajax', require('./api_adapters/ajax')); | ||
tml.config.api = 'ajax'; | ||
// if version is hardcoded - don't bother checking the version | ||
if (options.fetch_version) { | ||
setTimeout(function () { | ||
tml.config.getCache().fetchVersion(function (current_version) { | ||
tml.app.getApiClient().getReleaseVersion(function (new_version) { | ||
if (current_version != new_version) | ||
tml.config.getCache().clear(); | ||
}); | ||
}); | ||
}, 1000); | ||
} | ||
}); | ||
}, | ||
tml.config.registerCacheAdapters({ | ||
inline: require('./cache_adapters/inline'), | ||
browser: require('./cache_adapters/browser') | ||
}); | ||
/** | ||
* Fires when DOM is ready | ||
* | ||
* @param fn | ||
*/ | ||
domReady: function(fn){ | ||
if (!document.readyState || /ded|te/.test(document.readyState)) { | ||
fn(); | ||
} else { | ||
document.addEventListener("DOMContentLoaded", fn, false); | ||
} | ||
}, | ||
options = tml.utils.merge(tml.config, { | ||
delayed_flush: true, | ||
api: "ajax", | ||
current_source: helpers.getCurrentSource(options), | ||
current_locale: helpers.getCurrentLocale(options.key, options.current_locale), | ||
current_translator: cookie.translator ? new tml.Translator(cookie.translator) : null, | ||
accepted_locales: window.navigator.languages, | ||
cache: { | ||
enabled: true, | ||
adapter: "browser", | ||
version: cache_version | ||
} | ||
}, options); | ||
/** | ||
* Updates language selector | ||
*/ | ||
updateLanguageSelector: function() { | ||
var languageSelector = document.querySelectorAll("[data-tml-language-selector], [tml-language-selector]"); | ||
options.fetch_version = (options.cache.adapter == 'browser' && !cache_version); | ||
if (languageSelector.length === 0) return; | ||
for (var i=0; i<languageSelector.length; i++) { | ||
var type = languageSelector[i].getAttribute("data-tml-language-selector"); | ||
type = type || 'popup'; | ||
var element = languageSelector[i].getAttribute("data-tml-language-selector-element"); | ||
element = element || 'div'; | ||
var toggle = languageSelector[i].getAttribute("data-tml-toggle") == 'true'; | ||
var toggle_label = languageSelector[i].getAttribute("data-tml-toggle-label"); | ||
var powered_by = languageSelector[i].getAttribute("data-tml-powered-by") == 'true'; | ||
languageSelector[i].innerHTML = tml.getLanguageSelector(type, { | ||
element: element, | ||
container: languageSelector[i], | ||
toggle: toggle, | ||
toggle_label: toggle_label, | ||
powered_by: powered_by | ||
}); | ||
tml.scripts.language_selector_init(tml.app, type); | ||
} | ||
}, | ||
tml.config.initCache(options.key); | ||
// console.log(options); | ||
/** | ||
* Changes language | ||
* | ||
* @param locale | ||
*/ | ||
changeLanguage: function(locale) { | ||
tml.app.changeLanguage(locale, function(language) { | ||
helpers.updateCurrentLocale(tml.options.key, locale); | ||
tml.config.currentLanguage = tml.app.getCurrentLanguage(); | ||
tml.app = new tml.Application({ | ||
key: options.key, | ||
token: options.token, | ||
host: options.host || DEFAULT_HOST | ||
}); | ||
if (this.tokenizer) | ||
this.tokenizer.updateAllNodes(); | ||
tml.app.init(options, function (err) { | ||
tml.updateLanguageSelector(); | ||
if ((options.translateBody || options.translate_body) && mutationObserver) { | ||
tml.translateElement(document); | ||
} | ||
if (tml.utils.isFunction(tml.options.onLanguageChange)) | ||
tml.options.onLanguageChange(language); | ||
}.bind(this)); | ||
}, | ||
tml.domReady(function () { | ||
/** | ||
* Translates a string | ||
* | ||
* @param label | ||
* @param description | ||
* @param tokens | ||
* @param options | ||
* @returns {*} | ||
*/ | ||
translate: function(label, description, tokens, options) { | ||
if(!tml.app) { | ||
throw new Error("Invalid application."); | ||
} | ||
if ((options.translateBody || options.translate_body) && !mutationObserver) { | ||
tml.translateElement(document.body); | ||
} | ||
var params = tml.utils.normalizeParams(label, description, tokens, options); | ||
params.label = params.label.replace(/\s\s+/g, ' '); | ||
var t1 = new Date(); | ||
tml.logger.debug("page render took " + (t1 - t0) + " mls"); | ||
params.options = tml.utils.extend({}, { | ||
current_locale: tml.app.current_locale, | ||
current_source: tml.app.current_source, | ||
current_translator: tml.app.current_translator, | ||
block_options: (tml.block_options || []) | ||
}, params.options); | ||
if ((options.translateTitle || options.translate_title) && document.title !== "") { | ||
document.title = tml.translateLabel(document.title); | ||
} | ||
return tml.app.getCurrentLanguage().translate(params); | ||
}, | ||
if (!options.agent) options.agent = {}; | ||
/** | ||
* Translates a label | ||
* | ||
* @param label | ||
* @param description | ||
* @param tokens | ||
* @param options | ||
* @returns {*} | ||
*/ | ||
translateLabel: function(label, description, tokens, options) { | ||
var params = tml.utils.normalizeParams(label, description, tokens, options); | ||
params.options.skip_decorations = true; | ||
return tml.translate(params); | ||
}, | ||
helpers.includeAgent(tml.app, { | ||
host: options.agent.host, | ||
cache: options.agent.cache || 864000000, | ||
domains: options.agent.domains || {}, | ||
locale: tml.app.current_locale, | ||
source: tml.app.current_source, | ||
sdk: options.sdk || 'tml-js v' + tml.version, | ||
css: tml.app.css, | ||
languages: tml.app.languages | ||
}, function () { | ||
if (callback) callback(); | ||
}); | ||
/** | ||
* Translates an element | ||
* | ||
* @param container | ||
*/ | ||
translateElement: function(container) { | ||
container = (typeof container === "string") ? document.getElementById(container) : container; | ||
if (typeof(options.onLoad) == "function") { | ||
options.onLoad(tml.app); | ||
} | ||
}); | ||
tml.config.currentLanguage = tml.app.getCurrentLanguage(); | ||
// if version is hardcoded - don't bother checking the version | ||
if (options.fetch_version) { | ||
setTimeout(function () { | ||
tml.config.getCache().fetchVersion(function (current_version) { | ||
tml.app.getApiClient().getReleaseVersion(function (new_version) { | ||
if (current_version != new_version) | ||
tml.config.getCache().clear(); | ||
}); | ||
}); | ||
}, 1000); | ||
} | ||
}); | ||
}, | ||
this.tokenizer = new DomTokenizer(container, {}, { | ||
debug: false, | ||
current_source: tml.app.current_source || 'index', | ||
current_translator: tml.app.current_translator | ||
}); | ||
/** | ||
* Fires when DOM is ready | ||
* | ||
* @param fn | ||
*/ | ||
domReady: function (fn) { | ||
if (!document.readyState || /ded|te/.test(document.readyState)) { | ||
fn(); | ||
} else { | ||
document.addEventListener("DOMContentLoaded", fn, false); | ||
} | ||
}, | ||
if(/ded|te/.test(document.readyState)) { | ||
this.tokenizer.translateDOM(document.body); | ||
} else if (mutationObserver) { | ||
if(document.body) { | ||
this.tokenizer.translateDOM(document.body); | ||
} | ||
this.translateNow(); | ||
} | ||
}, | ||
/** | ||
* Changes language | ||
* | ||
* @param locale | ||
*/ | ||
changeLanguage: function (locale) { | ||
tml.app.changeLanguage(locale, function (language) { | ||
helpers.updateCurrentLocale(tml.options.key, locale); | ||
tml.config.currentLanguage = tml.app.getCurrentLanguage(); | ||
/** | ||
* Translates DOM | ||
*/ | ||
translateNow: function(){ | ||
var observer, tokenizer = this.tokenizer; | ||
var moHandler = function(mutations) { | ||
var nodeList = []; | ||
if (mutations.length > 0) { | ||
mutations.forEach(function(mutation) { | ||
var target = mutation.target; | ||
var nodes = mutation.addedNodes || []; | ||
if (this.tokenizer) { | ||
this.tokenizer.updateAllNodes(); | ||
} | ||
if (nodes.length > 0) { | ||
for (var i = nodes.length - 1; i > -1; i--) { | ||
var node = nodes[i]; | ||
if(node.tagName && node.tagName.toLowerCase().indexOf("tml:") != -1) continue; | ||
if(node.tagName && node.tagName.toLowerCase().indexOf("script") != -1) continue; | ||
nodeList.push(node); | ||
} | ||
if (tml.utils.isFunction(tml.options.onLanguageChange)) { | ||
tml.options.onLanguageChange(language); | ||
} | ||
}); | ||
nodeList.forEach(function(n){ | ||
tokenizer.translateDOM(n); | ||
tml.emit('language-change', language); | ||
}.bind(this)); | ||
}, | ||
/** | ||
* Translates a string | ||
* | ||
* @param label | ||
* @param description | ||
* @param tokens | ||
* @param options | ||
* @returns {*} | ||
*/ | ||
translate: function (label, description, tokens, options) { | ||
if (!tml.app) { | ||
throw new Error("Invalid application."); | ||
} | ||
var params = tml.utils.normalizeParams(label, description, tokens, options); | ||
params.label = params.label.replace(/\s\s+/g, ' '); | ||
params.options = tml.utils.extend({}, { | ||
current_locale: tml.app.current_locale, | ||
current_source: tml.app.current_source, | ||
current_translator: tml.app.current_translator, | ||
block_options: (tml.block_options || []) | ||
}, params.options); | ||
return tml.app.getCurrentLanguage().translate(params); | ||
}, | ||
/** | ||
* Translates a label | ||
* | ||
* @param label | ||
* @param description | ||
* @param tokens | ||
* @param options | ||
* @returns {*} | ||
*/ | ||
translateLabel: function (label, description, tokens, options) { | ||
var params = tml.utils.normalizeParams(label, description, tokens, options); | ||
params.options.skip_decorations = true; | ||
return tml.translate(params); | ||
}, | ||
/** | ||
* Translates an element | ||
* | ||
* @param container | ||
*/ | ||
translateElement: function (container) { | ||
container = (typeof container === "string") ? document.getElementById(container) : container; | ||
tml.config.currentLanguage = tml.app.getCurrentLanguage(); | ||
this.tokenizer = new DomTokenizer(container, {}, { | ||
debug: false, | ||
current_source: tml.app.current_source || 'index', | ||
current_translator: tml.app.current_translator | ||
}); | ||
if(document.readyState == "interactive") { | ||
observer.disconnect(); | ||
if (/ded|te/.test(document.readyState)) { | ||
this.tokenizer.translateDOM(document.body); | ||
this.translateNow(); | ||
} else if (mutationObserver) { | ||
if (document.body) { | ||
this.tokenizer.translateDOM(document.body); | ||
} | ||
this.translateNow(); | ||
} | ||
} | ||
}; | ||
}, | ||
observer = new mutationObserver(moHandler); | ||
observer.observe(document, { | ||
subtree: true, | ||
attributes: true, | ||
attributeOldValue: false, | ||
childList: true, | ||
characterData: true, | ||
characterDataOldValue: false | ||
}); | ||
}, | ||
/** | ||
* Translates DOM | ||
*/ | ||
translateNow: function () { | ||
var observer, tokenizer = this.tokenizer; | ||
var moHandler = function (mutations) { | ||
var nodeList = []; | ||
if (mutations.length > 0) { | ||
mutations.forEach(function (mutation) { | ||
var target = mutation.target; | ||
var nodes = mutation.addedNodes || []; | ||
/** | ||
* Translates text nodes | ||
* | ||
* @param parent_node | ||
* @param text_node | ||
* @param label | ||
*/ | ||
translateTextNode: function(parent_node, text_node, label) { | ||
// we need to handle empty spaces better | ||
var sanitized_label = tml.utils.sanitizeString(label); | ||
if (tml.utils.isNumber(sanitized_label)) return; | ||
if (sanitized_label === null || sanitized_label.length === 0) return; | ||
var translation = this.translate(sanitized_label); | ||
if (nodes.length > 0) { | ||
for (var i = nodes.length - 1; i > -1; i--) { | ||
var node = nodes[i]; | ||
if (node.tagName && node.tagName.toLowerCase().indexOf("tml:") != -1) continue; | ||
if (node.tagName && node.tagName.toLowerCase().indexOf("script") != -1) continue; | ||
nodeList.push(node); | ||
} | ||
} | ||
}); | ||
if (/^\s/.test(label)) translation = " " + translation; | ||
if (/\s$/.test(label)) translation = translation + " "; | ||
nodeList.forEach(function (n) { | ||
tokenizer.translateDOM(n); | ||
}); | ||
var translated_node = document.createElement("span"); | ||
// translated_node.style.border = '1px dotted green'; | ||
translated_node.innerHTML = translation; | ||
if (document.readyState == "interactive") { | ||
if(!tml.options.translateBody || tml.options.disableAutoTranslate) { | ||
observer.disconnect(); | ||
} | ||
} | ||
} | ||
}; | ||
// translated_node.style.border = '1px dotted red'; | ||
parent_node.replaceChild(translated_node, text_node); | ||
}, | ||
observer = new mutationObserver(moHandler); | ||
observer.observe(document, { | ||
subtree: true, | ||
attributes: true, | ||
attributeOldValue: false, | ||
childList: true, | ||
characterData: true, | ||
characterDataOldValue: false | ||
}); | ||
}, | ||
/** | ||
* Translates text elements | ||
* | ||
* @param element | ||
*/ | ||
translateTextElements: function(element) { | ||
if (tml.utils.element('tml_status_node')) return; | ||
/** | ||
* Translates text nodes | ||
* | ||
* @param parent_node | ||
* @param text_node | ||
* @param label | ||
*/ | ||
translateTextNode: function (parent_node, text_node, label) { | ||
// we need to handle empty spaces better | ||
var sanitized_label = tml.utils.sanitizeString(label); | ||
if (tml.utils.isNumber(sanitized_label)) return; | ||
if (sanitized_label === null || sanitized_label.length === 0) return; | ||
var translation = this.translate(sanitized_label); | ||
console.log("Initializing text nodes..."); | ||
if (/^\s/.test(label)) translation = " " + translation; | ||
if (/\s$/.test(label)) translation = translation + " "; | ||
// add node to the document so it is not processed twice | ||
var status_node = document.createElement('div'); | ||
status_node.id = 'tml_status_node'; | ||
status_node.style.display = 'none'; | ||
document.body.appendChild(status_node); | ||
var translated_node = document.createElement("span"); | ||
// translated_node.style.border = '1px dotted green'; | ||
translated_node.innerHTML = translation; | ||
var text_nodes = []; | ||
var tree_walker = document.createTreeWalker(element || document.body, NodeFilter.SHOW_TEXT, null, false); | ||
while (tree_walker.nextNode()) { | ||
text_nodes.push(tree_walker.currentNode); | ||
} | ||
// translated_node.style.border = '1px dotted red'; | ||
parent_node.replaceChild(translated_node, text_node); | ||
}, | ||
console.log("Found " + text_nodes.length + " text nodes"); | ||
/** | ||
* Translates text elements | ||
* | ||
* @param element | ||
*/ | ||
translateTextElements: function (element) { | ||
if (tml.utils.element('tml_status_node')) return; | ||
var disable_sentences = true; | ||
console.log("Initializing text nodes..."); | ||
for (i = 0; i < text_nodes.length; i++) { | ||
var current_node = text_nodes[i]; | ||
var parent_node = current_node.parentNode; | ||
// add node to the document so it is not processed twice | ||
var status_node = document.createElement('div'); | ||
status_node.id = 'tml_status_node'; | ||
status_node.style.display = 'none'; | ||
document.body.appendChild(status_node); | ||
if (!parent_node) continue; | ||
var text_nodes = []; | ||
var tree_walker = document.createTreeWalker(element || document.body, NodeFilter.SHOW_TEXT, null, false); | ||
while (tree_walker.nextNode()) { | ||
text_nodes.push(tree_walker.currentNode); | ||
} | ||
// no scripts | ||
if (parent_node.tagName == "script" || parent_node.tagName == "SCRIPT") continue; | ||
console.log("Found " + text_nodes.length + " text nodes"); | ||
var label = current_node.nodeValue || ""; | ||
var disable_sentences = true; | ||
// console.log(label); | ||
for (i = 0; i < text_nodes.length; i++) { | ||
var current_node = text_nodes[i]; | ||
var parent_node = current_node.parentNode; | ||
// no html image tags | ||
if (label.indexOf("<img") != -1) continue; | ||
if (!parent_node) continue; | ||
// no comments | ||
if (label.indexOf("<!-") != -1) continue; | ||
// no scripts | ||
if (parent_node.tagName == "script" || parent_node.tagName == "SCRIPT") continue; | ||
var sentences = label.split(". "); | ||
this.translateTextNode(parent_node, current_node, label); | ||
} | ||
}, | ||
var label = current_node.nodeValue || ""; | ||
/** | ||
* Returns application | ||
* | ||
* @returns {*} | ||
*/ | ||
getApplication: function() { | ||
return tml.app; | ||
}, | ||
// console.log(label); | ||
/** | ||
* Returns current source | ||
* | ||
* @returns {*} | ||
*/ | ||
getCurrentSource: function() { | ||
return tml.app.current_source; | ||
}, | ||
// no html image tags | ||
if (label.indexOf("<img") != -1) continue; | ||
/** | ||
* Returns current translator | ||
* | ||
* @returns {*} | ||
*/ | ||
getCurrentTranslator: function() { | ||
return tml.app.current_translator; | ||
}, | ||
// no comments | ||
if (label.indexOf("<!-") != -1) continue; | ||
/** | ||
* Returns current language | ||
* | ||
* @returns {*} | ||
*/ | ||
getCurrentLanguage: function() { | ||
return tml.app.getCurrentLanguage(); | ||
}, | ||
var sentences = label.split(". "); | ||
this.translateTextNode(parent_node, current_node, label); | ||
} | ||
}, | ||
/** | ||
* Generates a language selector | ||
* | ||
* @param type | ||
* @param options | ||
* @returns {*} | ||
*/ | ||
getLanguageSelector: function(type, options) { | ||
options = tml.utils.merge(options || {}, { | ||
current_language: tml.getCurrentLanguage(), | ||
client_side: true | ||
}); | ||
return tml.scripts.language_selector(tml.app, type, options); | ||
}, | ||
/** | ||
* Returns application | ||
* | ||
* @returns {*} | ||
*/ | ||
getApplication: function () { | ||
return tml.app; | ||
}, | ||
/** | ||
* Encloses block options | ||
* | ||
* @param options | ||
* @param callback | ||
*/ | ||
block: function(options, callback) { | ||
tml.block_options.unshift(options); | ||
callback(); | ||
tml.block_options.pop(); | ||
}, | ||
/** | ||
* Returns current source | ||
* | ||
* @returns {*} | ||
*/ | ||
getCurrentSource: function () { | ||
return tml.app.current_source; | ||
}, | ||
/** | ||
* Begins block options | ||
* | ||
* @param options | ||
*/ | ||
beginBlock: function(options) { | ||
tml.block_options.unshift(options); | ||
}, | ||
/** | ||
* Returns current translator | ||
* | ||
* @returns {*} | ||
*/ | ||
getCurrentTranslator: function () { | ||
return tml.app.current_translator; | ||
}, | ||
/** | ||
* Ends block options | ||
*/ | ||
endBlock: function() { | ||
tml.block_options.pop(); | ||
}, | ||
/** | ||
* Returns current language | ||
* | ||
* @returns {*} | ||
*/ | ||
getCurrentLanguage: function () { | ||
return tml.app.getCurrentLanguage(); | ||
}, | ||
/** | ||
* Clears cache | ||
*/ | ||
clearCache: function() { | ||
tml.config.getCache().clear(); | ||
} | ||
/** | ||
* Encloses block options | ||
* | ||
* @param options | ||
* @param callback | ||
*/ | ||
block: function (options, callback) { | ||
tml.block_options.unshift(options); | ||
callback(); | ||
tml.block_options.pop(); | ||
}, | ||
}); | ||
/** | ||
* Begins block options | ||
* | ||
* @param options | ||
*/ | ||
beginBlock: function (options) { | ||
tml.block_options.unshift(options); | ||
}, | ||
/** | ||
* Ends block options | ||
*/ | ||
endBlock: function () { | ||
tml.block_options.pop(); | ||
}, | ||
/** | ||
* browser window extensions and helpers | ||
* | ||
* @type {Tml.translate|Function} | ||
*/ | ||
/** | ||
* Clears cache | ||
*/ | ||
clearCache: function () { | ||
tml.config.getCache().clear(); | ||
} | ||
window.tml = tml; | ||
window.tr = tml.translate; | ||
window.trl = tml.translateLabel; | ||
window.tre = tml.translateElement; | ||
window.tml_application = tml.getApplication; | ||
window.tml_current_source = tml.getCurrentSource; | ||
window.tml_current_translator = tml.getCurrentTranslator; | ||
window.tml_current_language = tml.getCurrentLanguage; | ||
window.tml_language_selector = tml.getLanguageSelector; | ||
window.tml_block = tml.block; | ||
window.tml_begin_block = tml.beginBlock; | ||
window.tml_end_block = tml.endBlock; | ||
}); | ||
return { | ||
tml: tml, | ||
tr: tml.translate, | ||
trl: tml.translateLabel, | ||
tre: tml.translateElement, | ||
tml_application: tml.getApplication, | ||
tml_current_source: tml.getCurrentSource, | ||
tml_current_translator: tml.getCurrentTranslator, | ||
tml_current_language: tml.getCurrentLanguage, | ||
tml_block: tml.block, | ||
tml_begin_block: tml.beginBlock, | ||
tml_end_block: tml.endBlock, | ||
window.util = tml.utils; // TODO: is it being used? | ||
util: tml.utils | ||
}; | ||
} | ||
)); |
@@ -1,37 +0,8 @@ | ||
/** | ||
* Copyright (c) 2015 Translation Exchange, Inc. | ||
* | ||
* _______ _ _ _ ______ _ | ||
* |__ __| | | | | (_) | ____| | | | ||
* | |_ __ __ _ _ __ ___| | __ _| |_ _ ___ _ __ | |__ __ _____| |__ __ _ _ __ __ _ ___ | ||
* | | '__/ _` | '_ \/ __| |/ _` | __| |/ _ \| '_ \| __| \ \/ / __| '_ \ / _` | '_ \ / _` |/ _ \ | ||
* | | | | (_| | | | \__ \ | (_| | |_| | (_) | | | | |____ > < (__| | | | (_| | | | | (_| | __/ | ||
* |_|_| \__,_|_| |_|___/_|\__,_|\__|_|\___/|_| |_|______/_/\_\___|_| |_|\__,_|_| |_|\__, |\___| | ||
* __/ | | ||
* |___/ | ||
* Permission is hereby granted, free of charge, to any person obtaining | ||
* a copy of this software and associated documentation files (the | ||
* "Software"), to deal in the Software without restriction, including | ||
* without limitation the rights to use, copy, modify, merge, publish, | ||
* distribute, sublicense, and/or sell copies of the Software, and to | ||
* permit persons to whom the Software is furnished to do so, subject to | ||
* the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be | ||
* included in all copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
*/ | ||
var tml = require('tml-js'); | ||
var config = tml.config; | ||
var utils = tml.utils; | ||
var dom = require('../helpers/dom-helpers'); | ||
var DomTokenizer = function(doc, context, options) { | ||
@@ -46,5 +17,13 @@ this.doc = doc; | ||
content_cache:[], | ||
content_nodes:[], | ||
contentCache :[], | ||
contentNodes :[], | ||
translatedNodes :[], | ||
getOption: function(name) { | ||
if(typeof this.options[name] === 'undefined' || this.options[name] === null) { | ||
return utils.hashValue(config.translator_options, name); | ||
} | ||
return this.options[name]; | ||
}, | ||
translate: function() { | ||
@@ -55,5 +34,5 @@ return this.translateTree(this.doc); | ||
updateAllNodes: function(){ | ||
for(var i=0,l=this.content_cache.length;i<l;i++){ | ||
if(this.content_cache[i].container) { | ||
this.content_cache[i].container.innerHTML = this.translateTml(this.content_cache[i].tml, this.content_cache[i].data); | ||
for(var i=0,l=this.contentCache.length;i<l;i++){ | ||
if(this.contentCache[i].container) { | ||
this.contentCache[i].container.innerHTML = this.translateTml(this.contentCache[i].tml, this.contentCache[i].data); | ||
} | ||
@@ -64,2 +43,3 @@ } | ||
replaceNodes: function(nodes) { | ||
var ti = document.createElement("tml:inline"); | ||
@@ -74,12 +54,10 @@ var parent = nodes[0] && nodes[0].parentNode; | ||
if(!translation || this.isEmptyString(tml) || this.isUntranslatableText(text) || this.isNoTranslate(parent)) return; | ||
if(!translation || this.isEmptyString(tml) || this.isUntranslatableText(text) || !this.isTranslatable(parent)) return; | ||
if(nodes.length !== parent.childNodes.length) { | ||
//setTimeout(function(){ | ||
parent.insertBefore(ti, nodes[0]); | ||
ti.innerHTML = translation; | ||
ti.insertAdjacentHTML("beforebegin", "\n"); | ||
ti.insertAdjacentHTML("afterend", "\n"); | ||
nodes.forEach(function(n){parent.removeChild(n);}); | ||
//}.bind(this),0); | ||
parent.insertBefore(ti, nodes[0]); | ||
ti.innerHTML = translation; | ||
ti.insertAdjacentHTML("beforebegin", "\n"); | ||
ti.insertAdjacentHTML("afterend", "\n"); | ||
nodes.forEach(function(n){parent.removeChild(n);}); | ||
container = ti; | ||
@@ -95,5 +73,5 @@ } else { | ||
if(this.content_nodes.indexOf(container) == -1) { | ||
this.content_cache.push({container: container, tml: tml, data: data}); | ||
this.content_nodes.push(container); | ||
if(this.contentNodes.indexOf(container) == -1) { | ||
this.contentCache.push({container: container, tml: tml, data: data}); | ||
this.contentNodes.push(container); | ||
} | ||
@@ -104,11 +82,3 @@ | ||
isUntranslatableText: function(text) { | ||
return ( | ||
this.isEmptyString(text) || // empty | ||
text.match(/^[0-9,.\s]+$/) // numbers | ||
); | ||
}, | ||
translatedNodes: [], | ||
translateDOM: function(node) { | ||
@@ -118,6 +88,3 @@ if(this.translatedNodes.indexOf(node) !== -1) return; | ||
if (node.nodeType == 3) { | ||
node.nodeValue = node.nodeValue; | ||
return; | ||
} | ||
if (node.nodeType == 3) { return; } | ||
@@ -129,8 +96,8 @@ var source = node.nodeType == 1 && this.getSourceBlock(node); | ||
var l = node.childNodes.length, i = l, buffer = []; | ||
while(i--) { | ||
var child = node.childNodes[l-i-1]; | ||
if(!child || this.isNoTranslate(child)) continue; | ||
var buffer = []; | ||
for(var i=0;i<node.childNodes.length;i++) { | ||
var child = node.childNodes[i]; | ||
if(!child || !this.isTranslatable(child)) continue; | ||
if (child.nodeType == 3 || this.isInlineNode(child) && this.hasInlineSiblings(child)) { | ||
if (child.nodeType == 3 || dom.isInline(child) && dom.hasInlineSiblings(child)) { | ||
buffer.push(child); | ||
@@ -144,3 +111,9 @@ } else { | ||
if (buffer.length>0) this.replaceNodes(buffer); | ||
if (buffer.length>0) { | ||
if(buffer.length == 1 && buffer[0].nodeType == 1) { | ||
this.translateDOM(buffer[0]); | ||
} else { | ||
this.replaceNodes(buffer); | ||
} | ||
} | ||
@@ -151,51 +124,25 @@ if(source) { | ||
}, | ||
matchesUntranslatableSelector: function(node){ | ||
var matcher, slctrs = this.getOption("ignore_elements") || []; | ||
if(slctrs) { | ||
for(var i=0,l=slctrs.length; i<l;i++) { | ||
var slctr = slctrs[i] + "," + slctrs[i] + " *"; | ||
matcher = | ||
(node.matches && node.matches(slctr)) || | ||
(node.webkitMatches && node.webkitMatches(slctr)) || | ||
(node.mozMatches && node.mozMatches(slctr)) || | ||
(node.msMatches && node.msMatches(slctr)); | ||
if(matcher) return true; | ||
} | ||
} | ||
return false; | ||
}, | ||
getSourceBlock: function(node) { | ||
var matcher, els = config.sourceElements || []; | ||
if (els) { | ||
for(var i=0,l=els.length; i<l;i++) { | ||
var slctr = els[i].selector; | ||
var name = els[i].name; | ||
matcher = | ||
(node.matches && node.matches(slctr)) || | ||
(node.webkitMatches && node.webkitMatches(slctr)) || | ||
(node.mozMatches && node.mozMatches(slctr)) || | ||
(node.msMatches && node.msMatches(slctr)); | ||
if(matcher) return name; | ||
if(config.sourceElements) { | ||
var match = dom.matchesSelectors(node, config.sourceElements); | ||
if(match) { | ||
return node.getAttribute('name') || node.getAttribute('id') || node.getAttribute('class'); | ||
} | ||
} | ||
return node.getAttribute('data-tml-source') || false; | ||
}, | ||
isNoTranslate: function(node) { | ||
// Comments are not translatable | ||
if (node.nodeType == 8) | ||
return true; | ||
// Elements | ||
isTranslatable: function(node) { | ||
if (node.nodeType == 8) { return false; } | ||
if (node.nodeType == 3) { node = node.parentNode; } | ||
if (node.nodeType == 1) { | ||
return ( | ||
(this.getOption("nodes.scripts").indexOf(node.tagName.toLowerCase()) != -1) || | ||
(node.hasAttribute('notranslate')) || | ||
(this.matchesUntranslatableSelector(node)) | ||
); | ||
return !dom.matchesSelectors(node, ([]).concat( | ||
(this.getOption("nodes.scripts") || []), | ||
(this.getOption("ignore_elements") || []), | ||
(['[notranslate]','.notranslate','tml\\:label']) | ||
), true); | ||
} | ||
return false; | ||
return true; | ||
}, | ||
@@ -232,28 +179,8 @@ | ||
isValidTml: function(tml) { | ||
var tokens = /<\/?([a-z][a-z0-9]*)\b[^>]*>|{([a-z0-9_\.]+)}/gi; | ||
return !this.isEmptyString(tml.replace(tokens, '')); | ||
}, | ||
hasChildNodes: function(node) { | ||
if (!node.childNodes) return false; | ||
return (node.childNodes.length > 0); | ||
}, | ||
isBetweenSeparators: function(node) { | ||
if (this.isSeparatorNode(node.previousSibling) && !this.isValidTextNode(node.nextSibling)) | ||
return true; | ||
if (this.isSeparatorNode(node.nextSibling) && !this.isValidTextNode(node.previousSibling)) | ||
return true; | ||
return false; | ||
}, | ||
generateTmlTags: function(node) { | ||
if(node.nodeType == 3) { | ||
return node.nodeValue; | ||
} | ||
if(node.nodeType == 3) { return node.nodeValue; } | ||
if (this.isNoTranslate(node)) { | ||
if (!this.isTranslatable(node)) { | ||
var tokenName = this.contextualize(this.adjustName(node), node.innerHTML); | ||
@@ -272,6 +199,3 @@ return "{" + tokenName + "}"; | ||
var child = node.childNodes[i]; | ||
if (child.nodeType == 3) // text node | ||
buffer = buffer + child.nodeValue; | ||
else | ||
buffer = buffer + this.generateTmlTags(child); | ||
buffer = buffer + ((child.nodeType == 3) ? child.nodeValue : this.generateTmlTags(child)); | ||
} | ||
@@ -284,3 +208,3 @@ var tokenContext = this.generateHtmlToken(node); | ||
if (this.isSelfClosingNode(node)){ | ||
if (dom.isSelfClosing(node)){ | ||
tml = '{' + token + '}'; | ||
@@ -322,18 +246,2 @@ } else { | ||
getOption: function(name) { | ||
if(typeof this.options[name] === 'undefined' || this.options[name] === null) { | ||
return utils.hashValue(config.translator_options, name); | ||
} | ||
return this.options[name]; | ||
}, | ||
debugTranslation: function(translation) { | ||
return this.getOption("debug_format").replace('{$0}', translation); | ||
}, | ||
isEmptyString: function(tml) { | ||
tml = tml.replace(/[\s\n\r\t\0\x0b\xa0\xc2]/g, ''); | ||
return (tml === ''); | ||
}, | ||
resetContext: function() { | ||
@@ -347,64 +255,3 @@ this.tokens = [].concat(this.context); | ||
isOnlyChild: function(node) { | ||
if (!node.parentNode) return false; | ||
return (node.parentNode.childNodes.length == 1); | ||
}, | ||
hasInlineSiblings: function(node) { | ||
return ( | ||
(node.parentNode && node.parentNode.childNodes.length > 1) && | ||
(node.previousSibling && (this.isInlineNode(node.previousSibling) || this.isValidTextNode(node.previousSibling))) || | ||
(node.nextSibling && (this.isInlineNode(node.nextSibling) || this.isValidTextNode(node.nextSibling))) | ||
); | ||
}, | ||
isInlineNode: function(node) { | ||
return ( | ||
node.nodeType == 1 && | ||
this.getOption("nodes.inline").indexOf(node.tagName.toLowerCase()) != -1 && | ||
!this.isOnlyChild(node) | ||
); | ||
}, | ||
isContainerNode: function(node) { | ||
return (node.nodeType == 1 && !this.isInlineNode(node)); | ||
}, | ||
isSelfClosingNode: function(node) { | ||
return (!node.firstChild); | ||
}, | ||
isIgnoredNode: function(node) { | ||
if (node.nodeType != 1) return true; | ||
return (this.getOption("nodes.ignored").indexOf(node.tagName.toLowerCase()) != -1); | ||
}, | ||
isValidTextNode: function(node) { | ||
if (!node) return false; | ||
return (node.nodeType == 3 && !this.isEmptyString(node.nodeValue)); | ||
}, | ||
isSeparatorNode: function(node) { | ||
if (!node) return false; | ||
return (node.nodeType == 1 && this.getOption("nodes.splitters").indexOf(node.tagName.toLowerCase()) != -1); | ||
}, | ||
sanitizeValue: function(value) { | ||
return value.replace(/^\s+/,''); | ||
}, | ||
replaceSpecialCharacters: function(text) { | ||
if (!this.getOption("data_tokens.special.enabled")) return text; | ||
var matches = text.match(this.getOption("data_tokens.special.regex")); | ||
var self = this; | ||
matches.forEach(function(match) { | ||
token = match.substring(1, match.length - 2); | ||
self.context[token] = match; | ||
text = text.replace(match, "{" + token + "}"); | ||
}); | ||
return text; | ||
}, | ||
generateDataTokens: function(text) { | ||
@@ -454,6 +301,6 @@ var self = this; | ||
} | ||
return text; | ||
}, | ||
generateHtmlToken: function(node, value) { | ||
@@ -466,7 +313,8 @@ var name = node.tagName.toLowerCase(); | ||
if (attributes.length === 0) { | ||
if (this.isSelfClosingNode(node)) { | ||
if (name == "br" || name == "hr") | ||
if (dom.isSelfClosing(node)) { | ||
if (dom.isSeparator(node)){ | ||
return '<' + name + '/>'; | ||
else | ||
} else { | ||
return '<' + name + '>' + '</' + name + '>'; | ||
} | ||
} | ||
@@ -490,8 +338,9 @@ return '<' + name + '>' + value + '</' + name + '>'; | ||
if (this.isSelfClosingNode(node)) | ||
if (dom.isSelfClosing(node)) { | ||
return '<' + name + ' ' + attr + '>' + '</' + name + '>'; | ||
} | ||
return '<' + name + ' ' + attr + '>' + value + '</' + name + '>'; | ||
}, | ||
adjustName: function(node) { | ||
@@ -504,2 +353,3 @@ var name = node.tagName.toLowerCase(); | ||
contextualize: function(name, context) { | ||
@@ -521,2 +371,32 @@ if (this.tokens[name] && this.tokens[name] != context) { | ||
// String Helpers | ||
isEmptyString: function(tml) { | ||
tml = tml.replace(/[\s\n\r\t\0\x0b\xa0\xc2]/g, ''); | ||
return (tml === ''); | ||
}, | ||
isUntranslatableText: function(text) { | ||
return ( | ||
this.isEmptyString(text) || // empty | ||
text.match(/^[0-9,.\s]+$/) // numbers | ||
); | ||
}, | ||
isValidTml: function(tml) { | ||
var tokens = /<\/?([a-z][a-z0-9]*)\b[^>]*>|{([a-z0-9_\.]+)}/gi; | ||
return !this.isEmptyString(tml.replace(tokens, '')); | ||
}, | ||
sanitizeValue: function(value) { | ||
return value.replace(/^\s+/,''); | ||
}, | ||
// Debugging | ||
debug: function(doc) { | ||
@@ -529,5 +409,4 @@ this.doc = doc; | ||
var padding = new Array(depth+1).join('='); | ||
console.log(padding + "=> " + (typeof node) + ": " + dom.nodeInfo(node)); | ||
console.log(padding + "=> " + (typeof node) + ": " + this.nodeInfo(node)); | ||
if (node.childNodes) { | ||
@@ -542,31 +421,10 @@ var self = this; | ||
nodeInfo: function(node) { | ||
var info = []; | ||
info.push(node.nodeType); | ||
debugTranslation: function(translation) { | ||
return this.getOption("debug_format").replace('{$0}', translation); | ||
} | ||
if (node.nodeType == 1) | ||
info.push(node.tagName); | ||
if (this.isInlineNode(node)) { | ||
info.push("inline"); | ||
if (this.hasInlineSiblings(node)) | ||
info.push("sentence"); | ||
else | ||
info.push("only translatable"); | ||
} | ||
if (this.isSelfClosingNode(node)) | ||
info.push("self closing"); | ||
if (this.isOnlyChild(node)) | ||
info.push("only child"); | ||
if (node.nodeType == 3) | ||
return "[" + info.join(", ") + "]" + ': "' + node.nodeValue + '"'; | ||
return "[" + info.join(", ") + "]"; | ||
} | ||
}; | ||
module.exports = DomTokenizer; |
{ | ||
"name": "tml-js-browser", | ||
"description": "Translation plugin for browsers.", | ||
"version": "0.4.26", | ||
"version": "0.4.28", | ||
"author": { | ||
@@ -47,2 +47,3 @@ "name": "Michael Berkovich", | ||
"dependencies": { | ||
"tiny-emitter": "^1.0.2", | ||
"tml-js": "~0.4.9" | ||
@@ -78,3 +79,5 @@ }, | ||
} | ||
}, | ||
"browserify-shim": { | ||
} | ||
} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
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
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
517191
23
10962
2
2
+ Addedtiny-emitter@^1.0.2
+ Addedtiny-emitter@1.2.0(transitive)