comparison src/formats/bbcode.js @ 46:ab2dc8736d88

fix paste html and cleanup
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 30 Aug 2022 14:33:27 -0600
parents 7491026f7623
children
comparison
equal deleted inserted replaced
45:bc1bce78276d 46:ab2dc8736d88
452 li: { 452 li: {
453 tags: { 453 tags: {
454 li: null 454 li: null
455 }, 455 },
456 isInline: false, 456 isInline: false,
457 closedBy: ['/ul', '/ol', '/list', '*', 'li'],
458 format: '[li]{0}[/li]', 457 format: '[li]{0}[/li]',
459 html: '<li>{0}</li>'
460 },
461 '*': {
462 isInline: false,
463 closedBy: ['/ul', '/ol', '/list', '*', 'li'],
464 html: '<li>{0}</li>' 458 html: '<li>{0}</li>'
465 }, 459 },
466 // END_COMMAND 460 // END_COMMAND
467 461
468 // START_COMMAND: Table 462 // START_COMMAND: Table
1241 if (currentTag()) { 1235 if (currentTag()) {
1242 currentTag().children.push(token); 1236 currentTag().children.push(token);
1243 } else { 1237 } else {
1244 output.push(token); 1238 output.push(token);
1245 } 1239 }
1246 },
1247 /**
1248 * Checks if this tag closes the current tag
1249 * @param {string} name
1250 * @return {Void}
1251 */
1252 closesCurrentTag = function (name) {
1253 return currentTag() &&
1254 (bbcode = bbcodeHandlers[currentTag().name]) &&
1255 bbcode.closedBy &&
1256 bbcode.closedBy.indexOf(name) > -1;
1257 }; 1240 };
1258 1241
1259 while ((token = toks.shift())) { 1242 while ((token = toks.shift())) {
1260 next = toks[0]; 1243 next = toks[0];
1261 1244
1282 } 1265 }
1283 } 1266 }
1284 1267
1285 switch (token.type) { 1268 switch (token.type) {
1286 case TOKEN_OPEN: 1269 case TOKEN_OPEN:
1287 // Check it this closes a parent,
1288 // e.g. for lists [*]one [*]two
1289 if (closesCurrentTag(token.name)) {
1290 openTags.pop();
1291 }
1292
1293 addTag(token); 1270 addTag(token);
1294 bbcode = bbcodeHandlers[token.name]; 1271 bbcode = bbcodeHandlers[token.name];
1295 1272
1296 // If this tag has a closing 1273 // If this tag has a closing
1297 // tag then it is open and has children so add it to the 1274 // tag then it is open and has children so add it to the
1298 // list of open tags. If has the closedBy property then 1275 // list of open tags. If has the closedBy property then
1299 // it is closed by other tags so include everything as 1276 // it is closed by other tags so include everything as
1300 // it's children until one of those tags is reached. 1277 // it's children until one of those tags is reached.
1301 if (bbcode && 1278 if (bbcode && hasTag(token.name, TOKEN_CLOSE, toks)) {
1302 (bbcode.closedBy ||
1303 hasTag(token.name, TOKEN_CLOSE, toks))) {
1304 openTags.push(token); 1279 openTags.push(token);
1305 } else { 1280 } else {
1306 token.type = TOKEN_CONTENT; 1281 token.type = TOKEN_CONTENT;
1307 } 1282 }
1308 break; 1283 break;
1309 1284
1310 case TOKEN_CLOSE: 1285 case TOKEN_CLOSE:
1311 // check if this closes the current tag,
1312 // e.g. [/list] would close an open [*]
1313 if (currentTag() && token.name !== currentTag().name &&
1314 closesCurrentTag('/' + token.name)) {
1315
1316 openTags.pop();
1317 }
1318
1319 // If this is closing the currently open tag just pop 1286 // If this is closing the currently open tag just pop
1320 // the close tag off the open tags array 1287 // the close tag off the open tags array
1321 if (currentTag() && token.name === currentTag().name) { 1288 if (currentTag() && token.name === currentTag().name) {
1322 currentTag().closing = token; 1289 currentTag().closing = token;
1323 openTags.pop(); 1290 openTags.pop();
1377 addTag(token); 1344 addTag(token);
1378 } 1345 }
1379 break; 1346 break;
1380 1347
1381 case TOKEN_NEWLINE: 1348 case TOKEN_NEWLINE:
1382 // handle things like
1383 // [*]list\nitem\n[*]list1
1384 // where it should come out as
1385 // [*]list\nitem[/*]\n[*]list1[/*]
1386 // instead of
1387 // [*]list\nitem\n[/*][*]list1[/*]
1388 if (currentTag() && next && closesCurrentTag(
1389 (next.type === TOKEN_CLOSE ? '/' : '') +
1390 next.name
1391 )) {
1392 // skip if the next tag is the closing tag for
1393 // the option tag, i.e. [/*]
1394 if (!(next.type === TOKEN_CLOSE &&
1395 next.name === currentTag().name)) {
1396 bbcode = bbcodeHandlers[currentTag().name];
1397
1398 if (bbcode && bbcode.breakAfter) {
1399 openTags.pop();
1400 } else if (bbcode &&
1401 bbcode.isInline === false &&
1402 base.opts.breakAfterBlock &&
1403 bbcode.breakAfter !== false) {
1404 openTags.pop();
1405 }
1406 }
1407 }
1408
1409 addTag(token); 1349 addTag(token);
1410 break; 1350 break;
1411 1351
1412 default: // content 1352 default: // content
1413 addTag(token); 1353 addTag(token);
1911 // Convert the tags children to BBCode 1851 // Convert the tags children to BBCode
1912 if (token.children) { 1852 if (token.children) {
1913 ret += convertToBBCode(token.children); 1853 ret += convertToBBCode(token.children);
1914 } 1854 }
1915 1855
1916 // add closing tag if not self closing 1856 if (breakEnd) {
1917 if (!bbcode.excludeClosing) { 1857 ret += '\n';
1918 if (breakEnd) { 1858 }
1919 ret += '\n'; 1859
1920 } 1860 ret += '[/' + token.name + ']';
1921
1922 ret += '[/' + token.name + ']';
1923 }
1924 1861
1925 if (breakAfter) { 1862 if (breakAfter) {
1926 ret += '\n'; 1863 ret += '\n';
1927 } 1864 }
1928 } else { 1865 } else {
2438 /** 2375 /**
2439 * Converts BBCode into HTML 2376 * Converts BBCode into HTML
2440 * 2377 *
2441 * @param {string} source 2378 * @param {string} source
2442 */ 2379 */
2443 function toHtml(source) { 2380 function toHtml(source, asFragment) {
2444 let parser = newBBCodeParser(base.editor); 2381 let parser = newBBCodeParser(base.editor);
2445 let html = parser.toHTML( 2382 let html = parser.toHTML(
2446 base.opts.bbcodeTrim ? source.trim() : source 2383 base.opts.bbcodeTrim ? source.trim() : source
2447 ); 2384 );
2385 if( asFragment )
2386 html = removeFirstLastDiv(html);
2448 return html; 2387 return html;
2449 } 2388 }
2450 2389
2451 /** 2390 /**
2452 * Converts HTML into BBCode 2391 * Converts HTML into BBCode
2456 * @param {!Document} [context] 2395 * @param {!Document} [context]
2457 * @param {!HTMLElement} [parent] 2396 * @param {!HTMLElement} [parent]
2458 * @return {string} 2397 * @return {string}
2459 * @private 2398 * @private
2460 */ 2399 */
2461 function toSource(asFragment) { 2400 function toSource(html, context, parent, asFragment) {
2462 return function(html, context, parent) { 2401 context = context || document;
2463 context = context || document; 2402
2464 2403 var bbcode, elements;
2465 var bbcode, elements; 2404 var containerParent = context.createElement('div');
2466 var containerParent = context.createElement('div'); 2405 var container = context.createElement('div');
2467 var container = context.createElement('div'); 2406 var parser = newBBCodeParser(base.editor);
2468 var parser = newBBCodeParser(base.editor); 2407
2469 2408 container.innerHTML = html;
2470 container.innerHTML = html; 2409 css(containerParent, 'visibility', 'hidden');
2471 css(containerParent, 'visibility', 'hidden'); 2410 containerParent.appendChild(container);
2472 containerParent.appendChild(container); 2411 context.body.appendChild(containerParent);
2473 context.body.appendChild(containerParent); 2412
2474 2413 if (asFragment) {
2475 if (asFragment) { 2414 // Add text before and after so removeWhiteSpace doesn't remove
2476 // Add text before and after so removeWhiteSpace doesn't remove 2415 // leading and trailing whitespace
2477 // leading and trailing whitespace 2416 containerParent.insertBefore(
2478 containerParent.insertBefore( 2417 context.createTextNode('#'),
2479 context.createTextNode('#'), 2418 containerParent.firstChild
2480 containerParent.firstChild 2419 );
2481 ); 2420 containerParent.appendChild(context.createTextNode('#'));
2482 containerParent.appendChild(context.createTextNode('#')); 2421 }
2483 } 2422
2484 2423 // Match parents white-space handling
2485 // Match parents white-space handling 2424 if (parent) {
2486 if (parent) { 2425 css(container, 'whiteSpace', css(parent, 'whiteSpace'));
2487 css(container, 'whiteSpace', css(parent, 'whiteSpace')); 2426 }
2488 } 2427
2489 2428 // Remove all nodes with sceditor-ignore class
2490 // Remove all nodes with sceditor-ignore class 2429 elements = container.getElementsByClassName('sceditor-ignore');
2491 elements = container.getElementsByClassName('sceditor-ignore'); 2430 while (elements.length) {
2492 while (elements.length) { 2431 elements[0].parentNode.removeChild(elements[0]);
2493 elements[0].parentNode.removeChild(elements[0]); 2432 }
2494 } 2433
2495 2434 dom.removeWhiteSpace(containerParent);
2496 dom.removeWhiteSpace(containerParent); 2435
2497 2436 bbcode = elementToBbcode(container);
2498 bbcode = elementToBbcode(container); 2437
2499 2438 context.body.removeChild(containerParent);
2500 context.body.removeChild(containerParent); 2439
2501 2440 bbcode = parser.toBBCode(bbcode, true);
2502 bbcode = parser.toBBCode(bbcode, true); 2441
2503 2442 if (base.opts.bbcodeTrim) {
2504 if (base.opts.bbcodeTrim) { 2443 bbcode = bbcode.trim();
2505 bbcode = bbcode.trim(); 2444 }
2506 } 2445
2507 2446 return bbcode;
2508 return bbcode;
2509 };
2510 } 2447 }
2511 2448
2512 base.toHtml = toHtml; 2449 base.toHtml = toHtml;
2513 base.toSource = toSource(false); 2450 base.toSource = toSource;
2514 base.fragmentToSource = toSource(true);
2515 2451
2516 return base; 2452 return base;
2517 }; 2453 };
2518 2454
2519 /** 2455 /**