locizify 10.0.0 → 10.0.2

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/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ### 10.0.2
2
+
3
+ - update locize deps
4
+
5
+ ### 10.0.1
6
+
7
+ - update locize dep
8
+
1
9
  ### 10.0.0
2
10
 
3
11
  - BREAKING: bumped `i18next-locize-backend` to v10 and `i18nextify` to v5. Both dropped their `cross-fetch` dependency, so locizify no longer ships the `cross-fetch` / `node-fetch` fallback in its bundle. Native `fetch` is now required (Node ≥ 18, modern browsers, Deno, Bun — all of which ship it). For runtimes without native `fetch`, supply a ponyfill yourself before loading this script, or stay on v9.
package/locizify.js CHANGED
@@ -5929,21 +5929,26 @@ var locizify = (function() {
5929
5929
  while (stack.length > 1) {
5930
5930
  if (!object) return {};
5931
5931
  const key = cleanKey(stack.shift());
5932
+ if (UNSAFE_KEYS.indexOf(key) > -1) return {};
5932
5933
  if (!object[key] && Empty) object[key] = new Empty();
5933
5934
  object = object[key];
5934
5935
  }
5935
5936
  if (!object) return {};
5937
+ const k = cleanKey(stack.shift());
5938
+ if (UNSAFE_KEYS.indexOf(k) > -1) return {};
5936
5939
  return {
5937
5940
  obj: object,
5938
- k: cleanKey(stack.shift())
5941
+ k
5939
5942
  };
5940
5943
  }
5941
5944
  function setPath(object, path, newValue) {
5942
5945
  const { obj, k } = getLastOfPath(object, path, Object);
5946
+ if (obj === void 0) return;
5943
5947
  obj[k] = newValue;
5944
5948
  }
5945
5949
  function pushPath(object, path, newValue, concat) {
5946
5950
  const { obj, k } = getLastOfPath(object, path, Object);
5951
+ if (obj === void 0) return;
5947
5952
  obj[k] = obj[k] || [];
5948
5953
  if (concat) obj[k] = obj[k].concat(newValue);
5949
5954
  if (!concat) obj[k].push(newValue);
@@ -6887,14 +6892,25 @@ var locizify = (function() {
6887
6892
  warning: "#e67a00",
6888
6893
  gray: "#ccc"
6889
6894
  };
6890
- var getIframeUrl = function getIframeUrl() {
6895
+ var resolveEnv = function resolveEnv() {
6891
6896
  var _prc$env;
6892
6897
  var p;
6893
6898
  if (typeof process !== "undefined") p = process;
6894
6899
  if (!p && typeof window !== "undefined") p = window.process;
6895
- var env = ((_prc$env = (p || {}).env) === null || _prc$env === void 0 ? void 0 : _prc$env.locizeIncontext) || "production";
6900
+ return ((_prc$env = (p || {}).env) === null || _prc$env === void 0 ? void 0 : _prc$env.locizeIncontext) || "production";
6901
+ };
6902
+ var getIframeUrl = function getIframeUrl() {
6903
+ var env = resolveEnv();
6896
6904
  return env === "development" ? "http://localhost:3003/" : env === "staging" ? "https://incontext-dev.locize.app" : "https://incontext.locize.app";
6897
6905
  };
6906
+ var getEditorOrigins = function getEditorOrigins() {
6907
+ var env = resolveEnv();
6908
+ return env === "development" ? ["http://localhost:3003", "http://localhost:3000"] : env === "staging" ? ["https://incontext-dev.locize.app", "https://dev.locize.app"] : [
6909
+ "https://incontext.locize.app",
6910
+ "https://www.locize.app",
6911
+ "https://locize.app"
6912
+ ];
6913
+ };
6898
6914
  //#endregion
6899
6915
  //#region node_modules/locize/dist/esm/ui/stylesheet.js
6900
6916
  var sheet = function() {
@@ -7120,10 +7136,25 @@ var locizify = (function() {
7120
7136
  if (!results[2]) return "";
7121
7137
  return decodeURIComponent(results[2].replace(/\+/g, " "));
7122
7138
  }
7123
- var _isInIframe = typeof window !== "undefined";
7124
- try {
7139
+ var isDebug = function() {
7140
+ if (typeof window === "undefined") return false;
7141
+ try {
7142
+ return window.localStorage.getItem("locize-debug") === "true" || getQsParameterByName$1("locizedebug") === "true";
7143
+ } catch (e) {
7144
+ return false;
7145
+ }
7146
+ }();
7147
+ function debugLog() {
7148
+ var _console;
7149
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) args[_key] = arguments[_key];
7150
+ if (isDebug) (_console = console).warn.apply(_console, ["[locize]"].concat(args));
7151
+ }
7152
+ var _isInIframe = false;
7153
+ if (typeof window !== "undefined") try {
7125
7154
  _isInIframe = self !== top;
7126
- } catch (e) {}
7155
+ } catch (e) {
7156
+ _isInIframe = true;
7157
+ }
7127
7158
  var isInIframe = _isInIframe;
7128
7159
  //#endregion
7129
7160
  //#region node_modules/locize/dist/esm/api/postMessage.js
@@ -7159,18 +7190,22 @@ var locizify = (function() {
7159
7190
  var pendingMsgs = [];
7160
7191
  var allowedActionsBeforeInit = ["locizeIsEnabled", "requestInitialize"];
7161
7192
  function sendMessage(action, payload) {
7162
- if (!api.source) {
7163
- var _document$getElementB;
7164
- api.source = (_document$getElementB = document.getElementById("i18next-editor-iframe")) === null || _document$getElementB === void 0 ? void 0 : _document$getElementB.contentWindow;
7193
+ var _document$getElementB;
7194
+ var currentSource = (_document$getElementB = document.getElementById("i18next-editor-iframe")) === null || _document$getElementB === void 0 ? void 0 : _document$getElementB.contentWindow;
7195
+ if (currentSource) {
7196
+ if (api.source && api.source !== currentSource) api.initialized = false;
7197
+ api.source = currentSource;
7165
7198
  }
7166
7199
  if (!api.origin) api.origin = getIframeUrl();
7167
7200
  if (!api.source || !api.source.postMessage || !api.initialized && allowedActionsBeforeInit.indexOf(action) < 0) {
7168
- pendingMsgs.push({
7201
+ debugLog("queueing (editor not connected yet)", action, payload);
7202
+ if (pendingMsgs.length < 100) pendingMsgs.push({
7169
7203
  action,
7170
7204
  payload
7171
7205
  });
7172
7206
  return;
7173
7207
  }
7208
+ debugLog("out", action, payload);
7174
7209
  if (api.legacy) api.source.postMessage(_objectSpread$5({ message: action }, payload), api.origin);
7175
7210
  else api.source.postMessage({
7176
7211
  sender: "i18next-editor",
@@ -7212,12 +7247,14 @@ var locizify = (function() {
7212
7247
  requestInitialize: function requestInitialize(payload) {
7213
7248
  sendMessage("requestInitialize", payload);
7214
7249
  if (api.initInterval) return;
7250
+ repeat = 5;
7215
7251
  api.initInterval = setInterval(function() {
7216
7252
  repeat = repeat - 1;
7217
7253
  api.requestInitialize(payload);
7218
7254
  if (repeat < 0 && api.initInterval) {
7219
7255
  clearInterval(api.initInterval);
7220
7256
  delete api.initInterval;
7257
+ if (!api.initialized) debugLog("handshake gave up: editor never answered requestInitialize");
7221
7258
  }
7222
7259
  }, 2e3);
7223
7260
  },
@@ -7250,17 +7287,24 @@ var locizify = (function() {
7250
7287
  });
7251
7288
  }
7252
7289
  };
7253
- var getExpectedIframeOrigin = function getExpectedIframeOrigin() {
7290
+ var getExpectedEditorOrigins = function getExpectedEditorOrigins() {
7254
7291
  try {
7255
- return new URL(getIframeUrl()).origin;
7292
+ return getEditorOrigins().map(function(url) {
7293
+ return new URL(url).origin;
7294
+ });
7256
7295
  } catch (err) {
7257
- return null;
7296
+ return [];
7258
7297
  }
7259
7298
  };
7260
7299
  if (typeof window !== "undefined") window.addEventListener("message", function(e) {
7261
- var expectedOrigin = getExpectedIframeOrigin();
7262
- if (!expectedOrigin || e.origin !== expectedOrigin) return;
7263
- var _e$data = e.data, sender = _e$data.sender, action = _e$data.action, message = _e$data.message, payload = _e$data.payload;
7300
+ var expectedOrigins = getExpectedEditorOrigins();
7301
+ if (!expectedOrigins.length || expectedOrigins.indexOf(e.origin) < 0) {
7302
+ var _e$data;
7303
+ if (((_e$data = e.data) === null || _e$data === void 0 ? void 0 : _e$data.sender) === "i18next-editor-frame") debugLog("dropped editor message from unexpected origin", e.origin, "expected one of", expectedOrigins);
7304
+ return;
7305
+ }
7306
+ var _e$data2 = e.data, sender = _e$data2.sender, action = _e$data2.action, message = _e$data2.message, payload = _e$data2.payload;
7307
+ debugLog("in", action || message, payload);
7264
7308
  if (message) {
7265
7309
  var usedEventName = getMappedLegacyEvent(message);
7266
7310
  if (handlers[usedEventName]) handlers[usedEventName].forEach(function(fc) {
@@ -7424,9 +7468,11 @@ var locizify = (function() {
7424
7468
  //#endregion
7425
7469
  //#region node_modules/locize/dist/esm/api/handleConfirmInitialized.js
7426
7470
  function handler$5(payload) {
7471
+ var _document$querySelect;
7427
7472
  api.initialized = true;
7428
7473
  clearInterval(api.initInterval);
7429
7474
  delete api.initInterval;
7475
+ (_document$querySelect = document.querySelector(".locize-incontext-error")) === null || _document$querySelect === void 0 || _document$querySelect.remove();
7430
7476
  api.sendCurrentParsedContent();
7431
7477
  api.sendCurrentTargetLanguage();
7432
7478
  }
@@ -7537,12 +7583,15 @@ var locizify = (function() {
7537
7583
  sheet.insertRule(".i18next-editor-popup * { \n -webkit-touch-callout: none; /* iOS Safari */\n -webkit-user-select: none; /* Safari */\n -khtml-user-select: none; /* Konqueror HTML */\n -moz-user-select: none; /* Firefox */\n -ms-user-select: none; /* Internet Explorer/Edge */\n user-select: none; /* Non-prefixed version, currently supported by Chrome and Opera */\n }");
7538
7584
  sheet.insertRule(".i18next-editor-popup .resizer-right {\n width: 15px;\n height: 100%;\n background: transparent;\n position: absolute;\n right: -15px;\n bottom: 0;\n cursor: e-resize;\n }");
7539
7585
  sheet.insertRule(".i18next-editor-popup .resizer-both {\n width: 15px;\n height: 15px;\n background: transparent;\n z-index: 10;\n position: absolute;\n right: -15px;\n bottom: -15px;\n cursor: se-resize;\n }");
7586
+ sheet.insertRule(".locize-incontext-ribbon {\n cursor: pointer;\n position: fixed;\n bottom: 25px;\n right: 25px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 50px;\n height: 50px;\n background-color: rgba(249, 249, 249, 0.8);\n -webkit-backdrop-filter: blur(3px);\n backdrop-filter: blur(3px);\n box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);\n border-radius: 50%;\n }");
7587
+ sheet.insertRule(".locize-incontext-ribbon.locize-incontext-ribbon-left {\n right: auto;\n left: 25px;\n }");
7540
7588
  sheet.insertRule(".i18next-editor-popup .resizer-bottom {\n width: 100%;\n height: 15px;\n background: transparent;\n position: absolute;\n right: 0;\n bottom: -15px;\n cursor: s-resize;\n }");
7541
7589
  }
7542
- function Ribbon(popupEle, onMaximize) {
7590
+ function Ribbon(popupEle, onMaximize, ribbonPosition) {
7543
7591
  var ribbon = document.createElement("div");
7544
7592
  ribbon.setAttribute("data-i18next-editor-element", "true");
7545
- ribbon.style = "\n cursor: pointer;\n position: fixed;\n bottom: 25px;\n right: 25px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 50px;\n height: 50px;\n background-color: rgba(249, 249, 249, 0.2);\n backdrop-filter: blur(3px);\n box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);\n border-radius: 50%;\n ";
7593
+ ribbon.classList.add("locize-incontext-ribbon");
7594
+ if (ribbonPosition === "bottom-left") ribbon.classList.add("locize-incontext-ribbon-left");
7546
7595
  ribbon.onclick = function() {
7547
7596
  onMaximize();
7548
7597
  };
@@ -7567,7 +7616,18 @@ var locizify = (function() {
7567
7616
  return image;
7568
7617
  }
7569
7618
  var popupId = "i18next-editor-popup";
7619
+ function showPopupError(msg) {
7620
+ var popup = document.getElementById(popupId);
7621
+ if (!popup || popup.querySelector(".locize-incontext-error")) return;
7622
+ var err = document.createElement("div");
7623
+ err.className = "locize-incontext-error";
7624
+ err.setAttribute("data-i18next-editor-element", "true");
7625
+ err.textContent = msg;
7626
+ err.style = "\n position: absolute;\n top: 32px;\n left: 0;\n right: 0;\n z-index: 102;\n padding: 8px 10px;\n background-color: ".concat(colors.warning, ";\n color: #fff;\n font: 13px sans-serif;\n ");
7627
+ popup.appendChild(err);
7628
+ }
7570
7629
  function Popup(url, cb) {
7630
+ var opt = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {};
7571
7631
  var popup = document.createElement("div");
7572
7632
  popup.setAttribute("id", popupId);
7573
7633
  popup.classList.add("i18next-editor-popup");
@@ -7584,7 +7644,7 @@ var locizify = (function() {
7584
7644
  setTimeout(function() {
7585
7645
  document.body.removeChild(ribbon);
7586
7646
  }, 1e3);
7587
- });
7647
+ }, opt.ribbonPosition);
7588
7648
  document.body.appendChild(ribbon);
7589
7649
  stopMouseTracking();
7590
7650
  }));
@@ -9148,6 +9208,10 @@ var locizify = (function() {
9148
9208
  var meta = unwrap(trimmedTxt);
9149
9209
  uninstrumentedStore.remove(node.uniqueID, node);
9150
9210
  store.save(node.uniqueID, meta.invisibleMeta, "text", extractHiddenMeta(node.uniqueID, "text", meta), node);
9211
+ } else if (hasHiddenMeta && !merge.length) {
9212
+ var _meta = unwrap(trimmedTxt);
9213
+ uninstrumentedStore.remove(node.uniqueID, node);
9214
+ store.save(node.uniqueID, _meta.invisibleMeta, "text", extractHiddenMeta(node.uniqueID, "text", _meta), node);
9151
9215
  } else if (hasHiddenStartMarker) merge.push({
9152
9216
  childIndex: i,
9153
9217
  child,
@@ -9164,11 +9228,11 @@ var locizify = (function() {
9164
9228
  child,
9165
9229
  text: txt
9166
9230
  });
9167
- var _meta = unwrap(merge.reduce(function(mem, item) {
9231
+ var _meta2 = unwrap(merge.reduce(function(mem, item) {
9168
9232
  return mem + item.text;
9169
9233
  }, ""));
9170
9234
  uninstrumentedStore.removeKey(node.uniqueID, "html", node, txt);
9171
- store.save(node.uniqueID, _meta.invisibleMeta, "html", extractHiddenMeta(node.uniqueID, "html", _meta, merge), node, merge);
9235
+ store.save(node.uniqueID, _meta2.invisibleMeta, "html", extractHiddenMeta(node.uniqueID, "html", _meta2, merge), node, merge);
9172
9236
  merge = [];
9173
9237
  }
9174
9238
  });
@@ -9327,13 +9391,9 @@ var locizify = (function() {
9327
9391
  var popups = document.getElementsByClassName("i18next-editor-popup");
9328
9392
  var elmnt = null;
9329
9393
  var overlay = null;
9330
- var currentZIndex = 1e5;
9331
9394
  for (var i = 0; i < popups.length; i++) {
9332
9395
  var popup = popups[i];
9333
9396
  var header = getHeader(popup);
9334
- popup.onmousedown = function() {
9335
- this.style.zIndex = "" + ++currentZIndex;
9336
- };
9337
9397
  if (header) {
9338
9398
  header.parentPopup = popup;
9339
9399
  header.onmousedown = dragMouseDown;
@@ -9344,7 +9404,6 @@ var locizify = (function() {
9344
9404
  if (overlay) overlay.style.display = "block";
9345
9405
  stopMouseTracking();
9346
9406
  elmnt = this.parentPopup;
9347
- elmnt.style.zIndex = "" + ++currentZIndex;
9348
9407
  e = e || window.event;
9349
9408
  pos3 = e.clientX;
9350
9409
  pos4 = e.clientY;
@@ -9485,7 +9544,11 @@ var locizify = (function() {
9485
9544
  var showInContext = opt.show || getQsParameterByName$1(opt.qsProp || "incontext") === "true";
9486
9545
  var scriptEle = document.getElementById("locize");
9487
9546
  var config = {};
9488
- ["projectId", "version"].forEach(function(attr) {
9547
+ [
9548
+ "projectId",
9549
+ "version",
9550
+ "ribbonPosition"
9551
+ ].forEach(function(attr) {
9489
9552
  if (!scriptEle) return;
9490
9553
  var value = scriptEle.getAttribute(attr.toLowerCase()) || scriptEle.getAttribute("data-" + attr.toLowerCase());
9491
9554
  if (value === "true") value = true;
@@ -9510,11 +9573,47 @@ var locizify = (function() {
9510
9573
  observer.start();
9511
9574
  startMouseTracking(observer);
9512
9575
  if (!isInIframe && !document.getElementById("i18next-editor-popup")) {
9513
- document.body.append(Popup(getIframeUrl(), function() {
9576
+ debugLog("starting InContext popup with config", config, "iframe:", getIframeUrl());
9577
+ if (!config.projectId) console.error("[locize] InContext editor: no projectId configured (script tag attribute, i18next editor/backend options or startStandalone options) - the editor will not find your project.");
9578
+ setTimeout(function() {
9579
+ if (api.initialized) return;
9580
+ console.error("[locize] InContext editor did not connect within 15s. Likely causes: you are not logged in at locize (open https://www.locize.app in another tab and log in), the page CSP blocks frame-src " + getIframeUrl() + ", or an adblocker blocked the iframe. Enable diagnostics via localStorage.setItem('locize-debug', 'true').");
9581
+ showPopupError("Could not connect to the locize editor. Are you logged in at locize.app? See the browser console for details.");
9582
+ }, 15e3);
9583
+ var popupEl = Popup(getIframeUrl(), function() {
9584
+ var _document$getElementB;
9585
+ api.source = (_document$getElementB = document.getElementById("i18next-editor-iframe")) === null || _document$getElementB === void 0 ? void 0 : _document$getElementB.contentWindow;
9586
+ api.initialized = false;
9587
+ if (api.initInterval) {
9588
+ clearInterval(api.initInterval);
9589
+ delete api.initInterval;
9590
+ }
9514
9591
  api.requestInitialize(config);
9515
- }));
9592
+ }, config);
9593
+ document.documentElement.append(popupEl);
9516
9594
  initDragElement();
9517
9595
  initResizeElement();
9596
+ if (typeof MutationObserver === "function") {
9597
+ var MAX_REATTACHMENTS = 5;
9598
+ var WATCH_DURATION_MS = 1e4;
9599
+ var reattachments = 0;
9600
+ var watcher = new MutationObserver(function() {
9601
+ if (document.getElementById("i18next-editor-popup")) return;
9602
+ if (reattachments >= MAX_REATTACHMENTS) {
9603
+ watcher.disconnect();
9604
+ return;
9605
+ }
9606
+ reattachments++;
9607
+ document.documentElement.append(popupEl);
9608
+ });
9609
+ watcher.observe(document.documentElement, {
9610
+ childList: true,
9611
+ subtree: true
9612
+ });
9613
+ setTimeout(function() {
9614
+ return watcher.disconnect();
9615
+ }, WATCH_DURATION_MS);
9616
+ }
9518
9617
  }
9519
9618
  if (typeof window !== "undefined") {
9520
9619
  var oldHref = window.document.location.href;
@@ -9535,7 +9634,7 @@ var locizify = (function() {
9535
9634
  }
9536
9635
  if (document.body) return continueToStart();
9537
9636
  if (typeof window !== "undefined") window.addEventListener("load", function() {
9538
- return continueToStart();
9637
+ continueToStart();
9539
9638
  });
9540
9639
  }
9541
9640
  //#endregion
@@ -9597,7 +9696,7 @@ var locizify = (function() {
9597
9696
  },
9598
9697
  getLocizeDetails: function getLocizeDetails() {
9599
9698
  var backendName;
9600
- 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) backendName = "I18nextLocizeBackend";
9699
+ 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) backendName = "I18NextLocizeBackend";
9601
9700
  else backendName = i18n.services.backendConnector.backend ? i18n.services.backendConnector.backend.constructor.name : "options.resources";
9602
9701
  var opts = {
9603
9702
  backendName,