locize 3.0.4 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/locize.js CHANGED
@@ -281,10 +281,14 @@
281
281
  },
282
282
  requestInitialize: function requestInitialize(payload) {
283
283
  sendMessage('requestInitialize', payload);
284
+ if (api.initInterval) return;
284
285
  api.initInterval = setInterval(function () {
285
286
  repeat = repeat - 1;
286
287
  api.requestInitialize(payload);
287
- if (repeat < 0 && api.initInterval) clearInterval(api.initInterval);
288
+ if (repeat < 0 && api.initInterval) {
289
+ clearInterval(api.initInterval);
290
+ delete api.initInterval;
291
+ }
288
292
  }, 1000);
289
293
  },
290
294
  selectKey: function selectKey(meta) {
@@ -489,6 +493,7 @@
489
493
  function handler$6(payload) {
490
494
  api.initialized = true;
491
495
  clearInterval(api.initInterval);
496
+ delete api.initInterval;
492
497
  api.sendCurrentParsedContent();
493
498
  api.sendCurrentTargetLanguage();
494
499
  }
@@ -2394,8 +2399,29 @@
2394
2399
  find(el);
2395
2400
  return found;
2396
2401
  }
2402
+ function getQsParameterByName(name, url) {
2403
+ if (typeof window === 'undefined') return null;
2404
+ if (!url) url = window.location.href.toLowerCase();
2405
+ name = name.replace(/[\[\]]/g, '\\$&');
2406
+ var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)');
2407
+ var results = regex.exec(url);
2408
+ if (!results) return null;
2409
+ if (!results[2]) return '';
2410
+ return decodeURIComponent(results[2].replace(/\+/g, ' '));
2411
+ }
2397
2412
 
2413
+ var mutationTriggeringElements = {};
2398
2414
  function ignoreMutation(ele) {
2415
+ if (ele.uniqueID) {
2416
+ var info = mutationTriggeringElements[ele.uniqueID];
2417
+ if (info && info.triggered > 10 && info.lastTriggerDate + 500 < Date.now()) {
2418
+ if (!info.warned && console) {
2419
+ console.warn('locize ::: ignoring element change - an element is rerendering too often in short interval', '\n', 'consider adding the "data-locize-editor-ignore:" attribute to the element:', ele);
2420
+ info.warned = true;
2421
+ }
2422
+ return true;
2423
+ }
2424
+ }
2399
2425
  var ret = ele.dataset && (ele.dataset.i18nextEditorElement === 'true' || ele.dataset.locizeEditorIgnore === 'true');
2400
2426
  if (!ret && ele.parentElement) return ignoreMutation(ele.parentElement);
2401
2427
  return ret;
@@ -2424,6 +2450,12 @@
2424
2450
  if (mutation.type === 'attributes' && !validAttributes.includes(mutation.attributeName)) {
2425
2451
  return;
2426
2452
  }
2453
+ Object.keys(mutationTriggeringElements).forEach(function (k) {
2454
+ var info = mutationTriggeringElements[k];
2455
+ if (info.lastTriggerDate + 60000 < Date.now()) {
2456
+ delete mutationTriggeringElements[k];
2457
+ }
2458
+ });
2427
2459
  if (mutation.type === 'childList') {
2428
2460
  var notOurs = 0;
2429
2461
  if (!ignoreMutation(mutation.target)) {
@@ -2439,8 +2471,18 @@
2439
2471
  if (notOurs === 0) return;
2440
2472
  }
2441
2473
  triggerMutation = true;
2474
+ if (mutation.target && mutation.target.uniqueID) {
2475
+ var info = mutationTriggeringElements[mutation.target.uniqueID] || {
2476
+ triggered: 0
2477
+ };
2478
+ info.triggered = info.triggered + 1;
2479
+ info.lastTriggerDate = Date.now();
2480
+ mutationTriggeringElements[mutation.target.uniqueID] = info;
2481
+ }
2442
2482
  var includedAlready = targetEles.reduce(function (mem, element) {
2443
- if (mem || element.contains(mutation.target) || !mutation.target.parentElement) return true;
2483
+ if (mem || element.contains(mutation.target) || !mutation.target.parentElement) {
2484
+ return true;
2485
+ }
2444
2486
  return false;
2445
2487
  }, false);
2446
2488
  if (!includedAlready) {
@@ -2468,9 +2510,13 @@
2468
2510
  };
2469
2511
  }
2470
2512
 
2471
- function isInViewport(element) {
2472
- var rect = element.getBoundingClientRect();
2473
- return rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth);
2513
+ function isInViewport(el) {
2514
+ var rect = el.getBoundingClientRect();
2515
+ var windowHeight = window.innerHeight || document.documentElement.clientHeight;
2516
+ var windowWidth = window.innerWidth || document.documentElement.clientWidth;
2517
+ var vertInView = rect.top <= windowHeight && rect.top + rect.height >= 0;
2518
+ var horInView = rect.left <= windowWidth && rect.left + rect.width >= 0;
2519
+ return vertInView && horInView;
2474
2520
  }
2475
2521
  function mouseDistanceFromElement(mouseEvent, element) {
2476
2522
  var $n = element,
@@ -2481,9 +2527,9 @@
2481
2527
  y: mY
2482
2528
  },
2483
2529
  off = $n.getBoundingClientRect(),
2484
- ny1 = off.top + document.body.scrollTop,
2530
+ ny1 = off.top + document.documentElement.scrollTop,
2485
2531
  ny2 = ny1 + $n.offsetHeight,
2486
- nx1 = off.left + document.body.scrollLeft,
2532
+ nx1 = off.left + document.documentElement.scrollLeft,
2487
2533
  nx2 = nx1 + $n.offsetWidth,
2488
2534
  maxX1 = Math.max(mX, nx1),
2489
2535
  minX2 = Math.min(mX, nx2),
@@ -2854,89 +2900,94 @@
2854
2900
  try {
2855
2901
  isInIframe = self !== top;
2856
2902
  } catch (e) {}
2903
+ function configurePostProcessor(i18next, options) {
2904
+ i18next.use(SubliminalPostProcessor);
2905
+ if (typeof options.postProcess === 'string') {
2906
+ options.postProcess = [options.postProcess, 'subliminal'];
2907
+ } else if (Array.isArray(options.postProcess)) {
2908
+ options.postProcess.push('subliminal');
2909
+ } else {
2910
+ options.postProcess = 'subliminal';
2911
+ }
2912
+ options.postProcessPassResolved = true;
2913
+ }
2914
+ function getImplementation(i18n) {
2915
+ var impl = {
2916
+ getResource: function getResource(lng, ns, key) {
2917
+ return i18n.getResource(lng, ns, key);
2918
+ },
2919
+ setResource: function setResource(lng, ns, key, value) {
2920
+ return i18n.addResource(lng, ns, key, value, {
2921
+ silent: true
2922
+ });
2923
+ },
2924
+ getResourceBundle: function getResourceBundle(lng, ns, cb) {
2925
+ i18n.loadNamespaces(ns, function () {
2926
+ cb(i18n.getResourceBundle(lng, ns));
2927
+ });
2928
+ },
2929
+ getLng: function getLng() {
2930
+ return i18n.languages[0];
2931
+ },
2932
+ getSourceLng: function getSourceLng() {
2933
+ var fallback = i18n.options.fallbackLng;
2934
+ if (typeof fallback === 'string') return fallback;
2935
+ if (Array.isArray(fallback)) return fallback[fallback.length - 1];
2936
+ if (fallback && fallback["default"]) {
2937
+ if (typeof fallback["default"] === 'string') return fallback;
2938
+ if (Array.isArray(fallback["default"])) return fallback["default"][fallback["default"].length - 1];
2939
+ }
2940
+ if (typeof fallback === 'function') {
2941
+ var res = fallback(i18n.resolvedLanguage);
2942
+ if (typeof res === 'string') return res;
2943
+ if (Array.isArray(res)) return res[res.length - 1];
2944
+ }
2945
+ return 'dev';
2946
+ },
2947
+ getLocizeDetails: function getLocizeDetails() {
2948
+ var backendName;
2949
+ if (i18n.services.backendConnector.backend && i18n.services.backendConnector.backend.options && i18n.services.backendConnector.backend.options.loadPath && i18n.services.backendConnector.backend.options.loadPath.indexOf('.locize.') > 0) {
2950
+ backendName = 'I18NextLocizeBackend';
2951
+ } else {
2952
+ backendName = i18n.services.backendConnector.backend ? i18n.services.backendConnector.backend.constructor.name : 'options.resources';
2953
+ }
2954
+ var opts = {
2955
+ backendName: backendName,
2956
+ sourceLng: impl.getSourceLng(),
2957
+ i18nFormat: i18n.options.compatibilityJSON === 'v3' ? 'i18next_v3' : 'i18next_v4',
2958
+ i18nFramework: 'i18next',
2959
+ isLocizify: i18n.options.isLocizify,
2960
+ defaultNS: i18n.options.defaultNS
2961
+ };
2962
+ if (!i18n.options.backend && !i18n.options.editor) return opts;
2963
+ var pickFrom = i18n.options.backend || i18n.options.editor;
2964
+ return _objectSpread(_objectSpread({}, opts), {}, {
2965
+ projectId: pickFrom.projectId,
2966
+ version: pickFrom.version
2967
+ });
2968
+ },
2969
+ bindLanguageChange: function bindLanguageChange(cb) {
2970
+ i18n.on('languageChanged', cb);
2971
+ },
2972
+ bindMissingKeyHandler: function bindMissingKeyHandler(cb) {
2973
+ i18n.options.missingKeyHandler = function (lng, ns, k, val, isUpdate, opts) {
2974
+ if (!isUpdate) cb(lng, ns, k, val);
2975
+ };
2976
+ },
2977
+ triggerRerender: function triggerRerender() {
2978
+ i18n.emit('editorSaved');
2979
+ }
2980
+ };
2981
+ return impl;
2982
+ }
2857
2983
  var i18next;
2858
2984
  var locizePlugin = {
2859
2985
  type: '3rdParty',
2860
2986
  init: function init(i18n) {
2861
2987
  var options = i18n.options;
2862
2988
  i18next = i18n;
2863
- if (!isInIframe) {
2864
- i18next.use(SubliminalPostProcessor);
2865
- if (typeof options.postProcess === 'string') {
2866
- options.postProcess = [options.postProcess, 'subliminal'];
2867
- } else if (Array.isArray(options.postProcess)) {
2868
- options.postProcess.push('subliminal');
2869
- } else {
2870
- options.postProcess = 'subliminal';
2871
- }
2872
- options.postProcessPassResolved = true;
2873
- }
2874
- var impl = {
2875
- getResource: function getResource(lng, ns, key) {
2876
- return i18n.getResource(lng, ns, key);
2877
- },
2878
- setResource: function setResource(lng, ns, key, value) {
2879
- return i18n.addResource(lng, ns, key, value, {
2880
- silent: true
2881
- });
2882
- },
2883
- getResourceBundle: function getResourceBundle(lng, ns, cb) {
2884
- i18n.loadNamespaces(ns, function () {
2885
- cb(i18n.getResourceBundle(lng, ns));
2886
- });
2887
- },
2888
- getLng: function getLng() {
2889
- return i18n.languages[0];
2890
- },
2891
- getSourceLng: function getSourceLng() {
2892
- var fallback = i18n.options.fallbackLng;
2893
- if (typeof fallback === 'string') return fallback;
2894
- if (Array.isArray(fallback)) return fallback[fallback.length - 1];
2895
- if (fallback && fallback["default"]) {
2896
- if (typeof fallback["default"] === 'string') return fallback;
2897
- if (Array.isArray(fallback["default"])) return fallback["default"][fallback["default"].length - 1];
2898
- }
2899
- if (typeof fallback === 'function') {
2900
- var res = fallback(i18n.resolvedLanguage);
2901
- if (typeof res === 'string') return res;
2902
- if (Array.isArray(res)) return res[res.length - 1];
2903
- }
2904
- return 'dev';
2905
- },
2906
- getLocizeDetails: function getLocizeDetails() {
2907
- var backendName;
2908
- if (i18n.services.backendConnector.backend && i18n.services.backendConnector.backend.options && i18n.services.backendConnector.backend.options.loadPath && i18n.services.backendConnector.backend.options.loadPath.indexOf('.locize.') > 0) {
2909
- backendName = 'I18NextLocizeBackend';
2910
- } else {
2911
- backendName = i18n.services.backendConnector.backend ? i18n.services.backendConnector.backend.constructor.name : 'options.resources';
2912
- }
2913
- var opts = {
2914
- backendName: backendName,
2915
- sourceLng: impl.getSourceLng(),
2916
- i18nFormat: i18n.options.compatibilityJSON === 'v3' ? 'i18next_v3' : 'i18next_v4',
2917
- i18nFramework: 'i18next',
2918
- isLocizify: i18n.options.isLocizify,
2919
- defaultNS: i18n.options.defaultNS
2920
- };
2921
- if (!i18n.options.backend && !i18n.options.editor) return opts;
2922
- var pickFrom = i18n.options.backend || i18n.options.editor;
2923
- return _objectSpread(_objectSpread({}, opts), {}, {
2924
- projectId: pickFrom.projectId,
2925
- version: pickFrom.version
2926
- });
2927
- },
2928
- bindLanguageChange: function bindLanguageChange(cb) {
2929
- i18n.on('languageChanged', cb);
2930
- },
2931
- bindMissingKeyHandler: function bindMissingKeyHandler(cb) {
2932
- i18n.options.missingKeyHandler = function (lng, ns, k, val, isUpdate, opts) {
2933
- if (!isUpdate) cb(lng, ns, k, val);
2934
- };
2935
- },
2936
- triggerRerender: function triggerRerender() {
2937
- i18n.emit('editorSaved');
2938
- }
2939
- };
2989
+ if (!isInIframe) configurePostProcessor(i18next, options);
2990
+ var impl = getImplementation(i18n);
2940
2991
  if (!isInIframe) {
2941
2992
  start(impl);
2942
2993
  } else {
@@ -2944,6 +2995,25 @@
2944
2995
  }
2945
2996
  }
2946
2997
  };
2998
+ var locizeEditorPlugin = function locizeEditorPlugin() {
2999
+ var opt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
3000
+ opt.qsProp = opt.qsProp || 'incontext';
3001
+ return {
3002
+ type: '3rdParty',
3003
+ init: function init(i18n) {
3004
+ var options = i18n.options;
3005
+ i18next = i18n;
3006
+ var showInContext = getQsParameterByName(opt.qsProp) === 'true';
3007
+ if (!isInIframe && showInContext) configurePostProcessor(i18next, options);
3008
+ var impl = getImplementation(i18n);
3009
+ if (!isInIframe && showInContext) {
3010
+ start(impl);
3011
+ } else {
3012
+ startLegacy(impl);
3013
+ }
3014
+ }
3015
+ };
3016
+ };
2947
3017
 
2948
3018
  function startStandalone() {
2949
3019
  startLegacy({
@@ -2969,6 +3039,7 @@
2969
3039
  PostProcessor: SubliminalPostProcessor,
2970
3040
  addLocizeSavedHandler: addLocizeSavedHandler,
2971
3041
  locizePlugin: locizePlugin,
3042
+ locizeEditorPlugin: locizeEditorPlugin,
2972
3043
  turnOn: turnOn,
2973
3044
  turnOff: turnOff,
2974
3045
  setEditorLng: setEditorLng,
@@ -2979,6 +3050,7 @@
2979
3050
  exports.addLocizeSavedHandler = addLocizeSavedHandler;
2980
3051
  exports.containsHiddenMeta = containsHiddenMeta;
2981
3052
  exports["default"] = index;
3053
+ exports.locizeEditorPlugin = locizeEditorPlugin;
2982
3054
  exports.locizePlugin = locizePlugin;
2983
3055
  exports.setEditorLng = setEditorLng;
2984
3056
  exports.startStandalone = startStandalone;