overtype 1.1.1 → 1.1.4
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/README.md +28 -0
- package/dist/overtype.esm.js +133 -30
- package/dist/overtype.esm.js.map +2 -2
- package/dist/overtype.js +133 -30
- package/dist/overtype.js.map +2 -2
- package/dist/overtype.min.js +63 -54
- package/package.json +1 -1
- package/src/overtype.js +152 -13
- package/src/parser.js +3 -1
- package/src/styles.js +29 -20
package/dist/overtype.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* OverType v1.1.
|
|
2
|
+
* OverType v1.1.4
|
|
3
3
|
* A lightweight markdown editor library with perfect WYSIWYG alignment
|
|
4
4
|
* @license MIT
|
|
5
5
|
* @author Demo User
|
|
@@ -129,7 +129,7 @@ var OverType = (() => {
|
|
|
129
129
|
* @returns {string|null} Parsed code fence or null
|
|
130
130
|
*/
|
|
131
131
|
static parseCodeBlock(html) {
|
|
132
|
-
if (html.
|
|
132
|
+
if (html.match(/^```(\s*|\w*)$/)) {
|
|
133
133
|
return `<div><span class="code-fence">${html}</span></div>`;
|
|
134
134
|
}
|
|
135
135
|
return null;
|
|
@@ -1318,7 +1318,7 @@ ${blockSuffix}` : suffix;
|
|
|
1318
1318
|
const {
|
|
1319
1319
|
fontSize = "14px",
|
|
1320
1320
|
lineHeight = 1.6,
|
|
1321
|
-
fontFamily = "
|
|
1321
|
+
fontFamily = '"SF Mono", SFMono-Regular, Menlo, Monaco, "Cascadia Code", Consolas, "Roboto Mono", "Noto Sans Mono", "Droid Sans Mono", "Ubuntu Mono", "DejaVu Sans Mono", "Liberation Mono", "Courier New", Courier, monospace',
|
|
1322
1322
|
padding = "20px",
|
|
1323
1323
|
theme = null,
|
|
1324
1324
|
mobile = {}
|
|
@@ -1338,7 +1338,8 @@ ${blockSuffix}` : suffix;
|
|
|
1338
1338
|
return `
|
|
1339
1339
|
/* OverType Editor Styles */
|
|
1340
1340
|
.overtype-container {
|
|
1341
|
-
|
|
1341
|
+
display: grid !important;
|
|
1342
|
+
grid-template-rows: auto 1fr auto !important;
|
|
1342
1343
|
width: 100% !important;
|
|
1343
1344
|
height: 100% !important;
|
|
1344
1345
|
${themeVars ? `
|
|
@@ -1346,12 +1347,26 @@ ${blockSuffix}` : suffix;
|
|
|
1346
1347
|
${themeVars}` : ""}
|
|
1347
1348
|
}
|
|
1348
1349
|
|
|
1350
|
+
/* Auto-resize mode styles */
|
|
1351
|
+
.overtype-container.overtype-auto-resize {
|
|
1352
|
+
height: auto !important;
|
|
1353
|
+
grid-template-rows: auto auto auto !important;
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
.overtype-container.overtype-auto-resize .overtype-wrapper {
|
|
1357
|
+
height: auto !important;
|
|
1358
|
+
min-height: 60px !important;
|
|
1359
|
+
overflow: visible !important;
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1349
1362
|
.overtype-wrapper {
|
|
1350
1363
|
position: relative !important;
|
|
1351
1364
|
width: 100% !important;
|
|
1352
|
-
height: 100% !important;
|
|
1365
|
+
height: 100% !important; /* Take full height of grid cell */
|
|
1366
|
+
min-height: 60px !important; /* Minimum usable height */
|
|
1353
1367
|
overflow: hidden !important;
|
|
1354
1368
|
background: var(--bg-secondary, #ffffff) !important;
|
|
1369
|
+
grid-row: 2 !important; /* Always second row in grid */
|
|
1355
1370
|
}
|
|
1356
1371
|
|
|
1357
1372
|
/* Critical alignment styles - must be identical for both layers */
|
|
@@ -1366,6 +1381,8 @@ ${blockSuffix}` : suffix;
|
|
|
1366
1381
|
|
|
1367
1382
|
/* Font properties - any difference breaks alignment */
|
|
1368
1383
|
font-family: ${fontFamily} !important;
|
|
1384
|
+
font-synthesis: none !important; /* no faux bold/italic width drift */
|
|
1385
|
+
font-variant-ligatures: none !important; /* keep metrics stable for code */
|
|
1369
1386
|
font-size: var(--instance-font-size, ${fontSize}) !important;
|
|
1370
1387
|
line-height: var(--instance-line-height, ${lineHeight}) !important;
|
|
1371
1388
|
font-weight: normal !important;
|
|
@@ -1632,15 +1649,9 @@ ${blockSuffix}` : suffix;
|
|
|
1632
1649
|
}
|
|
1633
1650
|
|
|
1634
1651
|
/* Stats bar */
|
|
1635
|
-
.overtype-wrapper.with-stats {
|
|
1636
|
-
padding-bottom: 40px !important;
|
|
1637
|
-
}
|
|
1638
1652
|
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
bottom: 0 !important;
|
|
1642
|
-
left: 0 !important;
|
|
1643
|
-
right: 0 !important;
|
|
1653
|
+
/* Stats bar - positioned by grid, not absolute */
|
|
1654
|
+
.overtype-stats {
|
|
1644
1655
|
height: 40px !important;
|
|
1645
1656
|
padding: 0 20px !important;
|
|
1646
1657
|
background: #f8f9fa !important;
|
|
@@ -1651,24 +1662,24 @@ ${blockSuffix}` : suffix;
|
|
|
1651
1662
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
|
|
1652
1663
|
font-size: 0.85rem !important;
|
|
1653
1664
|
color: #666 !important;
|
|
1654
|
-
|
|
1665
|
+
grid-row: 3 !important; /* Always third row in grid */
|
|
1655
1666
|
}
|
|
1656
1667
|
|
|
1657
1668
|
/* Dark theme stats bar */
|
|
1658
|
-
.overtype-
|
|
1669
|
+
.overtype-container[data-theme="cave"] .overtype-stats {
|
|
1659
1670
|
background: var(--bg-secondary, #1D2D3E) !important;
|
|
1660
1671
|
border-top: 1px solid rgba(197, 221, 232, 0.1) !important;
|
|
1661
1672
|
color: var(--text, #c5dde8) !important;
|
|
1662
1673
|
}
|
|
1663
1674
|
|
|
1664
|
-
.overtype-
|
|
1675
|
+
.overtype-stats .overtype-stat {
|
|
1665
1676
|
display: flex !important;
|
|
1666
1677
|
align-items: center !important;
|
|
1667
1678
|
gap: 5px !important;
|
|
1668
1679
|
white-space: nowrap !important;
|
|
1669
1680
|
}
|
|
1670
1681
|
|
|
1671
|
-
.overtype-
|
|
1682
|
+
.overtype-stats .live-dot {
|
|
1672
1683
|
width: 8px !important;
|
|
1673
1684
|
height: 8px !important;
|
|
1674
1685
|
background: #4caf50 !important;
|
|
@@ -1681,11 +1692,6 @@ ${blockSuffix}` : suffix;
|
|
|
1681
1692
|
50% { opacity: 0.6; transform: scale(1.2); }
|
|
1682
1693
|
}
|
|
1683
1694
|
|
|
1684
|
-
/* Adjust textarea and preview for stats bar */
|
|
1685
|
-
.overtype-wrapper.with-stats .overtype-input,
|
|
1686
|
-
.overtype-wrapper.with-stats .overtype-preview {
|
|
1687
|
-
height: calc(100% - 40px) !important;
|
|
1688
|
-
}
|
|
1689
1695
|
|
|
1690
1696
|
/* Toolbar Styles */
|
|
1691
1697
|
.overtype-toolbar {
|
|
@@ -1696,6 +1702,9 @@ ${blockSuffix}` : suffix;
|
|
|
1696
1702
|
background: var(--toolbar-bg, var(--bg-primary, #f8f9fa));
|
|
1697
1703
|
overflow-x: auto;
|
|
1698
1704
|
-webkit-overflow-scrolling: touch;
|
|
1705
|
+
flex-shrink: 0;
|
|
1706
|
+
height: auto !important;
|
|
1707
|
+
grid-row: 1 !important; /* Always first row in grid */
|
|
1699
1708
|
}
|
|
1700
1709
|
|
|
1701
1710
|
.overtype-toolbar-button {
|
|
@@ -2247,8 +2256,16 @@ ${blockSuffix}` : suffix;
|
|
|
2247
2256
|
padding: "12px",
|
|
2248
2257
|
lineHeight: 1.5
|
|
2249
2258
|
},
|
|
2259
|
+
// Native textarea properties
|
|
2260
|
+
textareaProps: {},
|
|
2250
2261
|
// Behavior
|
|
2251
2262
|
autofocus: false,
|
|
2263
|
+
autoResize: false,
|
|
2264
|
+
// Auto-expand height with content
|
|
2265
|
+
minHeight: "100px",
|
|
2266
|
+
// Minimum height for autoResize mode
|
|
2267
|
+
maxHeight: null,
|
|
2268
|
+
// Maximum height for autoResize mode (null = unlimited)
|
|
2252
2269
|
placeholder: "Start typing...",
|
|
2253
2270
|
value: "",
|
|
2254
2271
|
// Callbacks
|
|
@@ -2365,9 +2382,6 @@ ${blockSuffix}` : suffix;
|
|
|
2365
2382
|
}
|
|
2366
2383
|
this.wrapper = document.createElement("div");
|
|
2367
2384
|
this.wrapper.className = "overtype-wrapper";
|
|
2368
|
-
if (this.options.showStats) {
|
|
2369
|
-
this.wrapper.classList.add("with-stats");
|
|
2370
|
-
}
|
|
2371
2385
|
if (this.options.fontSize) {
|
|
2372
2386
|
this.wrapper.style.setProperty("--instance-font-size", this.options.fontSize);
|
|
2373
2387
|
}
|
|
@@ -2382,19 +2396,47 @@ ${blockSuffix}` : suffix;
|
|
|
2382
2396
|
this.textarea.className = "overtype-input";
|
|
2383
2397
|
this.textarea.placeholder = this.options.placeholder;
|
|
2384
2398
|
this._configureTextarea();
|
|
2399
|
+
if (this.options.textareaProps) {
|
|
2400
|
+
Object.entries(this.options.textareaProps).forEach(([key, value]) => {
|
|
2401
|
+
if (key === "className" || key === "class") {
|
|
2402
|
+
this.textarea.className += " " + value;
|
|
2403
|
+
} else if (key === "style" && typeof value === "object") {
|
|
2404
|
+
Object.assign(this.textarea.style, value);
|
|
2405
|
+
} else {
|
|
2406
|
+
this.textarea.setAttribute(key, value);
|
|
2407
|
+
}
|
|
2408
|
+
});
|
|
2409
|
+
}
|
|
2385
2410
|
this.preview = document.createElement("div");
|
|
2386
2411
|
this.preview.className = "overtype-preview";
|
|
2387
2412
|
this.preview.setAttribute("aria-hidden", "true");
|
|
2388
2413
|
this.wrapper.appendChild(this.textarea);
|
|
2389
2414
|
this.wrapper.appendChild(this.preview);
|
|
2415
|
+
this.container.appendChild(this.wrapper);
|
|
2390
2416
|
if (this.options.showStats) {
|
|
2391
2417
|
this.statsBar = document.createElement("div");
|
|
2392
2418
|
this.statsBar.className = "overtype-stats";
|
|
2393
|
-
this.
|
|
2419
|
+
this.container.appendChild(this.statsBar);
|
|
2394
2420
|
this._updateStats();
|
|
2395
2421
|
}
|
|
2396
|
-
this.container.appendChild(this.wrapper);
|
|
2397
2422
|
this.element.appendChild(this.container);
|
|
2423
|
+
if (window.location.pathname.includes("demo.html")) {
|
|
2424
|
+
console.log("_createDOM completed:", {
|
|
2425
|
+
elementId: this.element.id,
|
|
2426
|
+
autoResize: this.options.autoResize,
|
|
2427
|
+
containerClasses: this.container.className,
|
|
2428
|
+
hasStats: !!this.statsBar,
|
|
2429
|
+
hasToolbar: this.options.toolbar
|
|
2430
|
+
});
|
|
2431
|
+
}
|
|
2432
|
+
if (this.options.autoResize) {
|
|
2433
|
+
this._setupAutoResize();
|
|
2434
|
+
} else {
|
|
2435
|
+
this.container.classList.remove("overtype-auto-resize");
|
|
2436
|
+
if (window.location.pathname.includes("demo.html")) {
|
|
2437
|
+
console.log("Removed auto-resize class from:", this.element.id);
|
|
2438
|
+
}
|
|
2439
|
+
}
|
|
2398
2440
|
}
|
|
2399
2441
|
/**
|
|
2400
2442
|
* Configure textarea attributes
|
|
@@ -2417,6 +2459,13 @@ ${blockSuffix}` : suffix;
|
|
|
2417
2459
|
if (this.options.autofocus) {
|
|
2418
2460
|
this.textarea.focus();
|
|
2419
2461
|
}
|
|
2462
|
+
if (this.options.autoResize) {
|
|
2463
|
+
if (!this.container.classList.contains("overtype-auto-resize")) {
|
|
2464
|
+
this._setupAutoResize();
|
|
2465
|
+
}
|
|
2466
|
+
} else {
|
|
2467
|
+
this.container.classList.remove("overtype-auto-resize");
|
|
2468
|
+
}
|
|
2420
2469
|
this.updatePreview();
|
|
2421
2470
|
}
|
|
2422
2471
|
/**
|
|
@@ -2457,6 +2506,8 @@ ${blockSuffix}` : suffix;
|
|
|
2457
2506
|
while (currentDiv && currentDiv !== closeParent) {
|
|
2458
2507
|
if (currentDiv.tagName === "DIV") {
|
|
2459
2508
|
currentDiv.classList.add("code-block-line");
|
|
2509
|
+
const plainText = currentDiv.textContent;
|
|
2510
|
+
currentDiv.textContent = plainText;
|
|
2460
2511
|
}
|
|
2461
2512
|
currentDiv = currentDiv.nextElementSibling;
|
|
2462
2513
|
if (!currentDiv)
|
|
@@ -2541,6 +2592,9 @@ ${blockSuffix}` : suffix;
|
|
|
2541
2592
|
setValue(value) {
|
|
2542
2593
|
this.textarea.value = value;
|
|
2543
2594
|
this.updatePreview();
|
|
2595
|
+
if (this.options.autoResize) {
|
|
2596
|
+
this._updateAutoHeight();
|
|
2597
|
+
}
|
|
2544
2598
|
}
|
|
2545
2599
|
/**
|
|
2546
2600
|
* Focus the editor
|
|
@@ -2604,6 +2658,57 @@ ${blockSuffix}` : suffix;
|
|
|
2604
2658
|
`;
|
|
2605
2659
|
}
|
|
2606
2660
|
}
|
|
2661
|
+
/**
|
|
2662
|
+
* Setup auto-resize functionality
|
|
2663
|
+
* @private
|
|
2664
|
+
*/
|
|
2665
|
+
_setupAutoResize() {
|
|
2666
|
+
this.container.classList.add("overtype-auto-resize");
|
|
2667
|
+
this.previousHeight = null;
|
|
2668
|
+
this._updateAutoHeight();
|
|
2669
|
+
this.textarea.addEventListener("input", () => this._updateAutoHeight());
|
|
2670
|
+
window.addEventListener("resize", () => this._updateAutoHeight());
|
|
2671
|
+
}
|
|
2672
|
+
/**
|
|
2673
|
+
* Update height based on scrollHeight
|
|
2674
|
+
* @private
|
|
2675
|
+
*/
|
|
2676
|
+
_updateAutoHeight() {
|
|
2677
|
+
if (!this.options.autoResize)
|
|
2678
|
+
return;
|
|
2679
|
+
const textarea = this.textarea;
|
|
2680
|
+
const preview = this.preview;
|
|
2681
|
+
const wrapper = this.wrapper;
|
|
2682
|
+
const computed = window.getComputedStyle(textarea);
|
|
2683
|
+
const paddingTop = parseFloat(computed.paddingTop);
|
|
2684
|
+
const paddingBottom = parseFloat(computed.paddingBottom);
|
|
2685
|
+
const scrollTop = textarea.scrollTop;
|
|
2686
|
+
textarea.style.setProperty("height", "auto", "important");
|
|
2687
|
+
let newHeight = textarea.scrollHeight;
|
|
2688
|
+
if (this.options.minHeight) {
|
|
2689
|
+
const minHeight = parseInt(this.options.minHeight);
|
|
2690
|
+
newHeight = Math.max(newHeight, minHeight);
|
|
2691
|
+
}
|
|
2692
|
+
let overflow = "hidden";
|
|
2693
|
+
if (this.options.maxHeight) {
|
|
2694
|
+
const maxHeight = parseInt(this.options.maxHeight);
|
|
2695
|
+
if (newHeight > maxHeight) {
|
|
2696
|
+
newHeight = maxHeight;
|
|
2697
|
+
overflow = "auto";
|
|
2698
|
+
}
|
|
2699
|
+
}
|
|
2700
|
+
const heightPx = newHeight + "px";
|
|
2701
|
+
textarea.style.setProperty("height", heightPx, "important");
|
|
2702
|
+
textarea.style.setProperty("overflow-y", overflow, "important");
|
|
2703
|
+
preview.style.setProperty("height", heightPx, "important");
|
|
2704
|
+
preview.style.setProperty("overflow-y", overflow, "important");
|
|
2705
|
+
wrapper.style.setProperty("height", heightPx, "important");
|
|
2706
|
+
textarea.scrollTop = scrollTop;
|
|
2707
|
+
preview.scrollTop = scrollTop;
|
|
2708
|
+
if (this.previousHeight !== newHeight) {
|
|
2709
|
+
this.previousHeight = newHeight;
|
|
2710
|
+
}
|
|
2711
|
+
}
|
|
2607
2712
|
/**
|
|
2608
2713
|
* Show or hide stats bar
|
|
2609
2714
|
* @param {boolean} show - Whether to show stats
|
|
@@ -2613,13 +2718,11 @@ ${blockSuffix}` : suffix;
|
|
|
2613
2718
|
if (show && !this.statsBar) {
|
|
2614
2719
|
this.statsBar = document.createElement("div");
|
|
2615
2720
|
this.statsBar.className = "overtype-stats";
|
|
2616
|
-
this.
|
|
2617
|
-
this.wrapper.classList.add("with-stats");
|
|
2721
|
+
this.container.appendChild(this.statsBar);
|
|
2618
2722
|
this._updateStats();
|
|
2619
2723
|
} else if (!show && this.statsBar) {
|
|
2620
2724
|
this.statsBar.remove();
|
|
2621
2725
|
this.statsBar = null;
|
|
2622
|
-
this.wrapper.classList.remove("with-stats");
|
|
2623
2726
|
}
|
|
2624
2727
|
}
|
|
2625
2728
|
/**
|