Mercurial Hosting > sceditor
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 /** |