Rox-Turbo commited on
Commit
19acf2d
·
verified ·
1 Parent(s): eafc3ee

Update private/admin/admin.js

Browse files
Files changed (1) hide show
  1. private/admin/admin.js +54 -131
private/admin/admin.js CHANGED
@@ -2103,30 +2103,23 @@ class AdminPanel {
2103
  return `<span class="math-inline math-fallback">${this.escapeHtmlDisplay(fallback)}</span>`;
2104
  }
2105
 
2106
- /**
2107
- * Parse markdown tables into HTML
2108
- * Optimized for performance with array building
2109
- * @private
2110
- */
2111
  _parseMarkdownTables(content, placeholders) {
2112
  if (!content) return content;
2113
 
2114
  const lines = content.split('\n');
2115
  const result = [];
2116
- const lineCount = lines.length;
2117
 
2118
- for (let i = 0; i < lineCount; i++) {
2119
  const line = lines[i];
2120
- const trimmed = line.trim();
2121
 
2122
- if (trimmed.startsWith('|') && trimmed.endsWith('|')) {
2123
  const nextLine = lines[i + 1];
2124
-
2125
  if (nextLine && /^\|[\s:|-]+\|$/.test(nextLine.trim())) {
2126
  const tableLines = [line];
2127
  let j = i + 1;
2128
 
2129
- while (j < lineCount && lines[j].trim().startsWith('|')) {
2130
  tableLines.push(lines[j]);
2131
  j++;
2132
  }
@@ -2136,76 +2129,52 @@ class AdminPanel {
2136
  const placeholder = `__TABLE_BLOCK_${placeholders.length}__`;
2137
  placeholders.push(tableHtml);
2138
  result.push(placeholder);
2139
- i = j - 1; // -1 because loop will increment
2140
  continue;
2141
  }
2142
  }
2143
  }
2144
 
2145
  result.push(line);
 
2146
  }
2147
 
2148
  return result.join('\n');
2149
  }
2150
 
2151
- /**
2152
- * Convert table lines to HTML
2153
- * Optimized with array building instead of string concatenation
2154
- * @private
2155
- */
2156
  _convertTableToHtml(lines) {
2157
  if (lines.length < 2) return null;
2158
 
2159
- // Extract cells (skip first and last empty cells from split)
2160
- const extractCells = (line) => {
2161
- const parts = line.split('|');
2162
- return parts.slice(1, -1).map(c => c.trim());
2163
- };
2164
-
2165
- const headerCells = extractCells(lines[0].trim());
2166
- if (headerCells.length === 0) return null;
2167
-
2168
- const headerCount = headerCells.length;
2169
 
2170
- // Parse alignments from separator
2171
- const sepCells = extractCells(lines[1].trim());
2172
- const aligns = sepCells.map(cell => {
2173
  if (cell.startsWith(':') && cell.endsWith(':')) return 'center';
2174
  if (cell.endsWith(':')) return 'right';
2175
  return 'left';
2176
  });
2177
 
2178
- // Build HTML using array
2179
- const htmlParts = ['<div class="table-wrapper"><table><thead><tr>'];
2180
-
2181
- // Header row
2182
- for (let i = 0; i < headerCount; i++) {
2183
- const align = aligns[i] || 'left';
2184
- const content = this._formatInlineContent(headerCells[i]);
2185
- htmlParts.push(`<th style="text-align:${align}">${content}</th>`);
2186
- }
2187
-
2188
- htmlParts.push('</tr></thead><tbody>');
2189
 
2190
- // Data rows (skip header and separator)
2191
  for (let i = 2; i < lines.length; i++) {
2192
- const cells = extractCells(lines[i]);
2193
- if (cells.length === 0) continue;
2194
-
2195
- htmlParts.push('<tr>');
2196
-
2197
- for (let j = 0; j < headerCount; j++) {
2198
- const align = aligns[j] || 'left';
2199
- const cellContent = cells[j] || '';
2200
- const content = this._formatInlineContent(cellContent);
2201
- htmlParts.push(`<td style="text-align:${align}">${content}</td>`);
2202
- }
2203
-
2204
- htmlParts.push('</tr>');
2205
  }
2206
 
2207
- htmlParts.push('</tbody></table></div>');
2208
- return htmlParts.join('');
2209
  }
2210
 
2211
  _initCodeCopyButtons() {
@@ -3155,110 +3124,64 @@ class AdminPanel {
3155
  return `<span style="padding:2px 6px;background:rgba(102, 126, 234, 0.1);border-radius:4px;font-family:'Times New Roman',Georgia,serif;font-style:italic;">${this.escapeHtml(rendered)}</span>`;
3156
  }
3157
 
3158
- /**
3159
- * Parse markdown tables for PDF
3160
- * Optimized with array building and cleaner logic
3161
- * @private
3162
- */
3163
  _parseMarkdownTablesForPdf(content) {
3164
  if (!content) return content;
3165
-
3166
  const lines = content.split('\n');
3167
  const result = [];
3168
- const lineCount = lines.length;
3169
- const separatorRegex = /^\|[\s:|-]+\|$/;
3170
 
3171
- for (let i = 0; i < lineCount; i++) {
3172
  const line = lines[i];
3173
- const trimmed = line.trim();
3174
-
3175
- if (trimmed.startsWith('|') && trimmed.endsWith('|')) {
3176
  const nextLine = lines[i + 1];
3177
-
3178
- if (nextLine && separatorRegex.test(nextLine.trim())) {
3179
  const tableLines = [line];
3180
  let j = i + 1;
3181
-
3182
- while (j < lineCount && lines[j].trim().startsWith('|')) {
3183
  tableLines.push(lines[j]);
3184
  j++;
3185
  }
3186
-
3187
  result.push(this._convertTableToHtmlForPdf(tableLines));
3188
- i = j - 1; // -1 because loop will increment
3189
  continue;
3190
  }
3191
  }
3192
-
3193
  result.push(line);
 
3194
  }
3195
-
3196
  return result.join('\n');
3197
  }
3198
 
3199
- /**
3200
- * Convert table lines to HTML for PDF
3201
- * Optimized with array building instead of string concatenation
3202
- * @private
3203
- */
3204
  _convertTableToHtmlForPdf(lines) {
3205
  if (lines.length < 2) return lines.join('\n');
3206
 
3207
- // Extract cells (skip first and last empty cells from split)
3208
- const extractCells = (line) => {
3209
- const parts = line.split('|');
3210
- return parts.slice(1, -1).map(c => c.trim());
3211
- };
3212
-
3213
- // Parse alignments from separator
3214
- const sepCells = extractCells(lines[1]);
3215
- const aligns = sepCells.map(cell => {
3216
- if (cell.startsWith(':') && cell.endsWith(':')) return 'center';
3217
- if (cell.endsWith(':')) return 'right';
3218
  return 'left';
3219
  });
3220
 
3221
- // Parse header
3222
- const headerCells = extractCells(lines[0]);
3223
- const headerCount = headerCells.length;
3224
-
3225
- // Build HTML using array
3226
- const htmlParts = [
3227
- '<table style="width:100%;border-collapse:collapse;margin:20px 0;border-radius:12px;overflow:hidden;box-shadow:0 4px 12px rgba(0,0,0,0.1);">',
3228
- '<thead><tr style="background:linear-gradient(135deg, #667eea 0%, #764ba2 100%);">'
3229
- ];
3230
-
3231
- // Header row
3232
- for (let i = 0; i < headerCount; i++) {
3233
- const align = aligns[i] || 'left';
3234
- const content = this._formatInlineContentForPdf(headerCells[i]);
3235
- htmlParts.push(
3236
- `<th style="text-align:${align};padding:14px 16px;color:#ffffff;font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:0.5px;border:none;">${content}</th>`
3237
- );
3238
- }
3239
-
3240
- htmlParts.push('</tr></thead><tbody>');
3241
-
3242
- // Data rows (skip header and separator)
3243
  for (let i = 2; i < lines.length; i++) {
3244
- const cells = extractCells(lines[i]);
3245
  const rowBg = (i - 2) % 2 === 0 ? '#ffffff' : '#f8fafc';
3246
-
3247
- htmlParts.push(`<tr style="background:${rowBg};">`);
3248
-
3249
- for (let j = 0; j < headerCount && j < cells.length; j++) {
3250
- const align = aligns[j] || 'left';
3251
- const content = this._formatInlineContentForPdf(cells[j]);
3252
- htmlParts.push(
3253
- `<td style="text-align:${align};padding:14px 16px;border-bottom:1px solid #e2e8f0;color:#2d3748;font-size:14px;">${content}</td>`
3254
- );
3255
- }
3256
-
3257
- htmlParts.push('</tr>');
3258
  }
3259
-
3260
- htmlParts.push('</tbody></table>');
3261
- return htmlParts.join('');
3262
  }
3263
 
3264
  // Format inline content for PDF (bold, italic, code, underline)
 
2103
  return `<span class="math-inline math-fallback">${this.escapeHtmlDisplay(fallback)}</span>`;
2104
  }
2105
 
 
 
 
 
 
2106
  _parseMarkdownTables(content, placeholders) {
2107
  if (!content) return content;
2108
 
2109
  const lines = content.split('\n');
2110
  const result = [];
2111
+ let i = 0;
2112
 
2113
+ while (i < lines.length) {
2114
  const line = lines[i];
 
2115
 
2116
+ if (line.trim().startsWith('|') && line.trim().endsWith('|')) {
2117
  const nextLine = lines[i + 1];
 
2118
  if (nextLine && /^\|[\s:|-]+\|$/.test(nextLine.trim())) {
2119
  const tableLines = [line];
2120
  let j = i + 1;
2121
 
2122
+ while (j < lines.length && lines[j].trim().startsWith('|')) {
2123
  tableLines.push(lines[j]);
2124
  j++;
2125
  }
 
2129
  const placeholder = `__TABLE_BLOCK_${placeholders.length}__`;
2130
  placeholders.push(tableHtml);
2131
  result.push(placeholder);
2132
+ i = j;
2133
  continue;
2134
  }
2135
  }
2136
  }
2137
 
2138
  result.push(line);
2139
+ i++;
2140
  }
2141
 
2142
  return result.join('\n');
2143
  }
2144
 
 
 
 
 
 
2145
  _convertTableToHtml(lines) {
2146
  if (lines.length < 2) return null;
2147
 
2148
+ const headerLine = lines[0].trim();
2149
+ const headerCells = headerLine.split('|').filter(c => c.trim()).map(c => c.trim());
 
 
 
 
 
 
 
 
2150
 
2151
+ const separatorLine = lines[1].trim();
2152
+ const aligns = separatorLine.split('|').filter(c => c.trim()).map(c => {
2153
+ const cell = c.trim();
2154
  if (cell.startsWith(':') && cell.endsWith(':')) return 'center';
2155
  if (cell.endsWith(':')) return 'right';
2156
  return 'left';
2157
  });
2158
 
2159
+ let html = '<div class="table-wrapper"><table><thead><tr>';
2160
+ headerCells.forEach((h, i) => {
2161
+ html += `<th style="text-align:${aligns[i] || 'left'}">${this._formatInlineContent(h)}</th>`;
2162
+ });
2163
+ html += '</tr></thead><tbody>';
 
 
 
 
 
 
2164
 
 
2165
  for (let i = 2; i < lines.length; i++) {
2166
+ const cells = lines[i].split('|').filter(c => c !== '').map(c => c.trim());
2167
+ html += '<tr>';
2168
+ cells.forEach((c, j) => {
2169
+ if (c !== undefined) {
2170
+ html += `<td style="text-align:${aligns[j] || 'left'}">${this._formatInlineContent(c)}</td>`;
2171
+ }
2172
+ });
2173
+ html += '</tr>';
 
 
 
 
 
2174
  }
2175
 
2176
+ html += '</tbody></table></div>';
2177
+ return html;
2178
  }
2179
 
2180
  _initCodeCopyButtons() {
 
3124
  return `<span style="padding:2px 6px;background:rgba(102, 126, 234, 0.1);border-radius:4px;font-family:'Times New Roman',Georgia,serif;font-style:italic;">${this.escapeHtml(rendered)}</span>`;
3125
  }
3126
 
 
 
 
 
 
3127
  _parseMarkdownTablesForPdf(content) {
3128
  if (!content) return content;
 
3129
  const lines = content.split('\n');
3130
  const result = [];
3131
+ let i = 0;
 
3132
 
3133
+ while (i < lines.length) {
3134
  const line = lines[i];
3135
+ if (line.trim().startsWith('|') && line.trim().endsWith('|')) {
 
 
3136
  const nextLine = lines[i + 1];
3137
+ if (nextLine && /^\|[\s:|-]+\|$/.test(nextLine.trim())) {
 
3138
  const tableLines = [line];
3139
  let j = i + 1;
3140
+ while (j < lines.length && lines[j].trim().startsWith('|')) {
 
3141
  tableLines.push(lines[j]);
3142
  j++;
3143
  }
 
3144
  result.push(this._convertTableToHtmlForPdf(tableLines));
3145
+ i = j;
3146
  continue;
3147
  }
3148
  }
 
3149
  result.push(line);
3150
+ i++;
3151
  }
 
3152
  return result.join('\n');
3153
  }
3154
 
 
 
 
 
 
3155
  _convertTableToHtmlForPdf(lines) {
3156
  if (lines.length < 2) return lines.join('\n');
3157
 
3158
+ const sep = lines[1];
3159
+ const aligns = sep.split('|').filter(c => c.trim()).map(c => {
3160
+ const t = c.trim();
3161
+ if (t.startsWith(':') && t.endsWith(':')) return 'center';
3162
+ if (t.endsWith(':')) return 'right';
 
 
 
 
 
 
3163
  return 'left';
3164
  });
3165
 
3166
+ const headerCells = lines[0].split('|').filter(c => c.trim()).map(c => c.trim());
3167
+ let html = '<table style="width:100%;border-collapse:collapse;margin:20px 0;border-radius:12px;overflow:hidden;box-shadow:0 4px 12px rgba(0,0,0,0.1);"><thead><tr style="background:linear-gradient(135deg, #667eea 0%, #764ba2 100%);">';
3168
+ headerCells.forEach((h, i) => {
3169
+ html += `<th style="text-align:${aligns[i] || 'left'};padding:14px 16px;color:#ffffff;font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:0.5px;border:none;">${this._formatInlineContentForPdf(h)}</th>`;
3170
+ });
3171
+ html += '</tr></thead><tbody>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3172
  for (let i = 2; i < lines.length; i++) {
3173
+ const cells = lines[i].match(/\|([^|]*)/g)?.map(c => c.slice(1).trim()) || [];
3174
  const rowBg = (i - 2) % 2 === 0 ? '#ffffff' : '#f8fafc';
3175
+ html += `<tr style="background:${rowBg};">`;
3176
+ cells.forEach((c, j) => {
3177
+ if (c !== undefined) {
3178
+ html += `<td style="text-align:${aligns[j] || 'left'};padding:14px 16px;border-bottom:1px solid #e2e8f0;color:#2d3748;font-size:14px;">${this._formatInlineContentForPdf(c)}</td>`;
3179
+ }
3180
+ });
3181
+ html += '</tr>';
 
 
 
 
 
3182
  }
3183
+ html += '</tbody></table>';
3184
+ return html;
 
3185
  }
3186
 
3187
  // Format inline content for PDF (bold, italic, code, underline)