mapshaper 0.6.41 → 0.6.43

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.
@@ -1125,21 +1125,26 @@
1125
1125
  var self = {}, html = '';
1126
1126
  var _cancel, _close;
1127
1127
  var warningRxp = /^Warning: /;
1128
- var el = El('div').appendTo('body').addClass('error-wrapper');
1129
- var infoBox = El('div').appendTo(el).addClass('error-box info-box selectable');
1128
+ var el = El('div').appendTo('body').addClass('alert-wrapper');
1129
+ var infoBox = El('div').appendTo(el).addClass('alert-box info-box selectable');
1130
+ El('div').appendTo(infoBox).addClass('close2-btn').on('click', function() {
1131
+ if (_cancel) _cancel();
1132
+ self.close();
1133
+ });
1134
+ var container = El('div').appendTo(infoBox);
1130
1135
  if (!title && warningRxp.test(msg)) {
1131
1136
  title = 'Warning';
1132
1137
  msg = msg.replace(warningRxp, '');
1133
1138
  }
1134
1139
  if (title) {
1135
- html += `<div class="error-title">${title}</div>`;
1140
+ El('div').addClass('alert-title').text(title).appendTo(container);
1136
1141
  }
1137
- html += `<p class="error-message">${msg}</p>`;
1138
- El('div').appendTo(infoBox).addClass('close2-btn').on('click', function() {
1139
- if (_cancel) _cancel();
1140
- self.close();
1141
- });
1142
- El('div').appendTo(infoBox).addClass('error-content').html(html);
1142
+ var content = El('div').appendTo(infoBox);
1143
+ if (msg) {
1144
+ content.html(`<p class="error-message">${msg}</p>`);
1145
+ }
1146
+
1147
+ self.container = function() { return content; };
1143
1148
 
1144
1149
  self.onCancel = function(cb) {
1145
1150
  _cancel = cb;
@@ -4023,10 +4028,10 @@
4023
4028
 
4024
4029
  function render() {
4025
4030
  renderLayerList();
4026
- renderFileList();
4031
+ renderSourceFileList();
4027
4032
  }
4028
4033
 
4029
- function renderFileList() {
4034
+ function renderSourceFileList() {
4030
4035
  var list = el.findChild('.file-list');
4031
4036
  var files = [];
4032
4037
  list.empty();
@@ -5064,6 +5069,26 @@
5064
5069
  _stop = stop;
5065
5070
  }
5066
5071
 
5072
+ // get detailed error information from error stack (if available)
5073
+ // Example stack string (Node.js):
5074
+ /*
5075
+ /Users/someuser/somescript.js:226
5076
+ opacity: Math.round(weight * 5 / 5 // 0.2 0.4 0.6 etc
5077
+ ^
5078
+
5079
+ SyntaxError: missing ) after argument list
5080
+ at internalCompileFunction (node:internal/vm:73:18)
5081
+ at wrapSafe (node:internal/modules/cjs/loader:1149:20)
5082
+ at Module._compile (node:internal/modules/cjs/loader:1190:27)
5083
+ ...
5084
+ */
5085
+ function getErrorDetail(e) {
5086
+ var parts = (typeof e.stack == 'string') ? e.stack.split(/\n\s*\n/) : [];
5087
+ if (parts.length > 1 || true) {
5088
+ return '\nError details:\n' + parts[0];
5089
+ }
5090
+ return '';
5091
+ }
5067
5092
 
5068
5093
  // print a message to stdout
5069
5094
  function print() {
@@ -7993,8 +8018,7 @@
7993
8018
  // stash a function for refreshing the current popup when data changes
7994
8019
  // while the popup is being displayed (e.g. while dragging a label)
7995
8020
  refresh = function() {
7996
- var rec = table && (editable ? table.getRecordAt(id) : table.getReadOnlyRecordAt(id)) || {};
7997
- render(content, rec, table, editable);
8021
+ render(content, id, table, editable);
7998
8022
  };
7999
8023
  refresh();
8000
8024
  if (ids && ids.length > 1) {
@@ -8033,7 +8057,8 @@
8033
8057
  tab.show();
8034
8058
  }
8035
8059
 
8036
- function render(el, rec, table, editable) {
8060
+ function render(el, recId, table, editable) {
8061
+ var rec = table && (editable ? table.getRecordAt(recId) : table.getReadOnlyRecordAt(recId)) || {};
8037
8062
  var tableEl = El('table').addClass('selectable'),
8038
8063
  rows = 0;
8039
8064
  // self.hide(); // clean up if panel is already open
@@ -8048,11 +8073,6 @@
8048
8073
  }
8049
8074
  });
8050
8075
 
8051
- // add new field form
8052
- if (editable) {
8053
- renderNewRow(tableEl, rec, table);
8054
- }
8055
-
8056
8076
  tableEl.appendTo(el);
8057
8077
  if (rows > 0) {
8058
8078
  // tableEl.appendTo(el);
@@ -8077,15 +8097,58 @@
8077
8097
  }
8078
8098
 
8079
8099
  if (editable) {
8100
+ // render "add field" button
8080
8101
  var line = El('div').appendTo(el);
8081
8102
  El('span').addClass('save-menu-btn').appendTo(line).on('click', async function(e) {
8103
+ // show "add field" dialog
8104
+ renderAddFieldPopup(recId, table);
8105
+ }).text('+ add field');
8106
+ }
8107
+ }
8108
+
8109
+ function renderAddFieldPopup(recId, table) {
8110
+ var popup = showPopupAlert('', 'Add field');
8111
+ var el = popup.container();
8112
+ el.addClass('option-menu');
8113
+ var html = `<input type="text" class="field-name text-input" placeholder="field name"><br>
8114
+ <input type="text" class="field-value text-input" placeholder="value"><br>
8115
+ <div tabindex="0" class="btn dialog-btn">Apply</div> <span class="inline-checkbox"><input type="checkbox" class="all" />assign value to all records</span>`;
8116
+ el.html(html);
8117
+
8118
+ var name = el.findChild('.field-name');
8119
+ name.node().focus();
8120
+ var val = el.findChild('.field-value');
8121
+ var box = el.findChild('.all');
8122
+ var btn = el.findChild('.btn').on('click', function() {
8123
+ var all = box.node().checked;
8124
+ var nameStr = name.node().value.trim();
8125
+ if (!nameStr) return;
8126
+ if (table.fieldExists(nameStr)) {
8127
+ name.node().value = '';
8128
+ return;
8129
+ }
8130
+ var valStr = val.node().value.trim();
8131
+ var value = parseUnknownType(valStr);
8132
+ // table.addField(nameStr, function(d) {
8133
+ // // parse each time to avoid multiple references to objects
8134
+ // return (all || d == rec) ? parseUnknownType(valStr) : null;
8135
+ // });
8082
8136
 
8083
- }).text('add field');
8084
- }
8085
- }
8086
-
8087
- function renderNewRow(el, rec, table) {
8137
+ var cmdStr = `-each "d['${nameStr}'] = `;
8138
+ if (!all) {
8139
+ cmdStr += `this.id != ${recId} ? null : `;
8140
+ }
8141
+ valStr = JSON.stringify(JSON.stringify(value));
8142
+ cmdStr = valStr.replace('"', cmdStr);
8088
8143
 
8144
+ gui.console.runMapshaperCommands(cmdStr, function(err) {
8145
+ if (!err) {
8146
+ popup.close();
8147
+ } else {
8148
+ console.error(err);
8149
+ }
8150
+ });
8151
+ });
8089
8152
  }
8090
8153
 
8091
8154
  function renderRow(table, rec, key, type, editable) {
@@ -8121,12 +8184,10 @@
8121
8184
  input.on('change', function(e) {
8122
8185
  var val2 = parser(input.value()),
8123
8186
  strval2 = formatInspectorValue(val2, type);
8124
- if (strval == strval2) {
8125
- // contents unchanged
8126
- } else if (val2 === null && type != 'object') { // allow null objects
8187
+ if (val2 === null && type != 'object') { // allow null objects
8127
8188
  // invalid value; revert to previous value
8128
8189
  input.value(strval);
8129
- } else {
8190
+ } else if (strval != strval2) {
8130
8191
  // field content has changed
8131
8192
  strval = strval2;
8132
8193
  gui.dispatchEvent('data_preupdate', {FID: currId}); // for undo/redo
@@ -8191,6 +8252,14 @@
8191
8252
  }
8192
8253
  };
8193
8254
 
8255
+ function parseUnknownType(str) {
8256
+ var val = inputParsers.number(str);
8257
+ if (val !== null) return val;
8258
+ val = inputParsers.object(str);
8259
+ if (val !== null) return val;
8260
+ return str;
8261
+ }
8262
+
8194
8263
  function getInputParser(type) {
8195
8264
  return inputParsers[type || 'multiple'];
8196
8265
  }