امروز میخواهم درباره یک ویرایشگر متن غنی (Rich Text Editor) صحبت کنم که به صورت یک فایل HTML مستقل کار میکند. این پروژه که “Nash” نام دارد، یک راهحل هوشمندانه برای ایجاد محتوای وب است که بدون نیاز به نرمافزار یا سرویسهای خارجی کار میکند.
نکات کلیدی این پروژه:
- ویرایشگر کاملاً مستقل که فقط به یک مرورگر وب نیاز دارد
- امکان ذخیره و ویرایش آفلاین محتوا
- رابط کاربری ساده و کاربرپسند
- قابلیت اشتراک محتوا
این پروژه نشان میدهد که با استفاده از ویژگی contenteditable در HTML، میتوانیم یک ویرایشگر متن غنی بسازیم که قابلیتهایی مانند تغییر اندازه فونت، رنگ متن، و اضافه کردن تصاویر را فراهم کند.
نکات فنی جالب:
- استفاده از CSS Variables برای تمهای مختلف
- پشتیبانی از حالت تیره (Dark Mode)
- مدیریت هوشمندانه DOM برای عملکرد بهتر
- ذخیرهسازی خودکار محتوا
این پروژه یک مثال عالی از قدرت HTML و JavaScript است که نشان میدهد چگونه میتوان با ابزارهای پایه، یک محصول مفید و کاربردی ایجاد کرد.
آیا شما هم تجربه کار با ویرایشگرهای متن غنی دارید؟ نظرات و تجربیات خود را در بخش کامنتها با ما به اشتراک بگذارید.
منبع: https://keepworking.github.io/nash/
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>👋 Hello, This is Nash</title> <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22100%22%20height%3D%22100%22%20viewBox%3D%220%200%20100%20100%22%3E%0A%20%20%3Crect%20width%3D%22100%22%20height%3D%22100%22%20rx%3D%2220%22%20fill%3D%22black%22%2F%3E%0A%20%20%3Ctext%20x%3D%2250%25%22%20y%3D%2250%25%22%20font-size%3D%2260%22%20font-weight%3D%22bold%22%20text-anchor%3D%22middle%22%20fill%3D%22white%22%20font-family%3D%22Arial%2C%20sans-serif%22%20dominant-baseline%3D%22central%22%3EN.%3C%2Ftext%3E%0A%3C%2Fsvg%3E"> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cstyle%3E%0A%20%20%20%20%20%20%20%20%3Aroot%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20--page-bg-color%3A%20%23f8f9fa%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20--page-text-color%3A%20%23333%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20--control-bg-color%3A%20%23f8f9fa%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20--control-text-color%3A%20buttontext%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20--control-hover-bg-color%3A%20%23f0f0f0%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20--control-hover-text-color%3A%20%23bbb%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20--note-bg-color%3A%20%23fff%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20--note-placeholer-color%3A%20%23bbb%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20--note-link-color%3A%20%23616161%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20--attribution-color%3A%20%23bbb%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20text%20background%20colors%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20--note-text-color-1%3A%20%23000000%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20black%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20--note-text-color-2%3A%20%23FF3B30%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20red%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20--note-text-color-3%3A%20%23FF9500%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20orange%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20--note-text-color-4%3A%20%23FFCC00%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20yellow%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20--note-text-color-5%3A%20%234CD964%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20green%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20--note-text-color-6%3A%20%235AC8FA%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20light-blue%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20--note-text-color-7%3A%20%23007AFF%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20dark-blue%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20--note-text-color-8%3A%20%235856D6%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20violet%20*%2F%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20highlight%20background%20colors%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20--note-highlight-color-1%3A%20%23FCECEC%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20red%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20--note-highlight-color-2%3A%20%23FFECEB%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20orange%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20--note-highlight-color-3%3A%20%23FFF8E1%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20yellow%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20--note-highlight-color-4%3A%20%23F1FAE5%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20green%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20--note-highlight-color-5%3A%20%23E6F9F0%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20light-blue%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20--note-highlight-color-6%3A%20%23E8F0FE%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20violet%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20--note-highlight-color-7%3A%20%23E7F0FF%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20dark-blue%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20--note-highlight-color-8%3A%20%23F3E8FF%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20purple%20*%2F%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F*%20dark%20mode%20*%2F%0A%20%20%20%20%20%20%20%20%40media%20(prefers-color-scheme%3A%20dark)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Aroot%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--page-bg-color%3A%20%233a3a3a%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--page-text-color%3A%20%23ddd%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--control-bg-color%3A%20%23444%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--control-text-color%3A%20%23aaa%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--control-hover-bg-color%3A%20%23666%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--control-hover-text-color%3A%20%23eee%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--note-bg-color%3A%20%23333%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--note-placeholder-color%3A%20%23555%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F*%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20TODO%3A%20choose%20nicer%20colers%20%3A-)%0A%20%20%20%20%20%20%20%20%20%20%20%20*%2F%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20text%20background%20colors%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--note-text-color-1%3A%20%23FAFAFA%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20black%20%2F%20white%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--note-text-color-2%3A%20%23FF3B30%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20red%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--note-text-color-3%3A%20%23FF9500%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20orange%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--note-text-color-4%3A%20%23FFCC00%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20yellow%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--note-text-color-5%3A%20%234CD964%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20green%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--note-text-color-6%3A%20%235AC8FA%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20light-blue%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--note-text-color-7%3A%20%23007AFF%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20dark-blue%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--note-text-color-8%3A%20%235856D6%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20violet%20*%2F%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20highlight%20background%20colors%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--note-highlight-color-1%3A%20hsl(0%2050%25%2030%25)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20red%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--note-highlight-color-2%3A%20hsl(30%2050%25%2030%25)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20orange%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--note-highlight-color-3%3A%20hsl(45%2050%25%2030%25)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20yellow%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--note-highlight-color-4%3A%20hsl(120%2050%25%2030%25)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20green%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--note-highlight-color-5%3A%20hsl(240%2070%25%2040%25)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20light-blue%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--note-highlight-color-6%3A%20hsl(300%2070%25%2040%25)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20violet%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--note-highlight-color-7%3A%20hsl(240%2050%25%2030%25)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20dark-blue%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--note-highlight-color-8%3A%20hsl(330%2050%25%2030%25)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20purple%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20body%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20font-family%3A%20'Arial'%2C%20sans-serif%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20background-color%3A%20var(--page-bg-color)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3A%20var(--page-text-color)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20margin%3A%200%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20padding%3A%2040px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20display%3A%20flex%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20flex-direction%3A%20column%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20align-items%3A%20center%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20.editor-container%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20width%3A%20100%25%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20max-width%3A%20800px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20background%3A%20var(--note-bg-color)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20padding%3A%2030px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20border-radius%3A%2012px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20box-shadow%3A%200px%205px%2015px%20rgba(0%2C%200%2C%200%2C%200.1)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20.file-title%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20font-size%3A%2028px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20font-weight%3A%20bold%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20margin-bottom%3A%2015px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20padding%3A%200px%2015px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20outline%3A%20none%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20border%3A%20none%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20width%3A%20100%25%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20background%3A%20transparent%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20.file-title%3Aempty%3A%3Abefore%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20content%3A%20%22Write%20your%20title%20here...%22%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3A%20var(--note-placeholder-color)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20display%3A%20block%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%23toolbar%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20position%3A%20sticky%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20position%3A%20-webkit-sticky%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20gap%3A%208px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20top%3A%205px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20padding%3A%200%2010px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20z-index%3A%209999%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20background-color%3A%20var(--control-bg-color)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20border-radius%3A%2012px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20display%3A%20flex%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20flex-wrap%3A%20wrap%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20justify-content%3A%20flex-start%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20align-items%3A%20center%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%23toolbar%20%23splitbar%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20margin-left%3A%20auto%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%23toolbar%20input%5Btype%3D%22file%22%5D%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20display%3A%20none%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%0A%20%20%20%20%20%20%20%20%23toolbar%20button%2C%0A%20%20%20%20%20%20%20%20%23toolbar%20label%2C%0A%20%20%20%20%20%20%20%20%23toolbar%20select%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20padding%3A%208px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20border%3A%20none%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20background%3A%20none%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3A%20var(--control-text-color)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20font-size%3A%2016px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20cursor%3A%20pointer%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20transition%3A%20opacity%200.2s%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%23toolbar%20button%3Ahover%2C%0A%20%20%20%20%20%20%20%20%23toolbar%20label%3Ahover%2C%0A%20%20%20%20%20%20%20%20%23toolbar%20select%3Ahover%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20background%3A%20var(--control-hover-bg-color)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20border-color%3A%20var(--control-hover-text-color)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3A%20var(--control-hover-text-color)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F*%20Dropdown%20container%20*%2F%0A%20%20%20%20%20%20%20%20.dropdown%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20position%3A%20relative%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20display%3A%20inline-block%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F*%20Dropdown%20button%20style%20*%2F%0A%20%20%20%20%20%20%20%20.dropdown%3Ebutton%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20padding%3A%206px%2010px%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F*%20Dropdown%20content%20(hidden%20by%20default)%20*%2F%0A%20%20%20%20%20%20%20%20.dropdown-content%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20display%3A%20none%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20position%3A%20absolute%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20top%3A%20110%25%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20right%3A%200%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20background%3A%20var(--control-bg-color)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20border%3A%201px%20solid%20var(--control-bg-color)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3A%20var(--control-text-color)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20padding%3A%208px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20border-radius%3A%204px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20box-shadow%3A%200%202px%206px%20rgba(0%2C%200%2C%200%2C%200.15)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20z-index%3A%2010%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F*%20Show%20dropdown%20when%20.show%20is%20added%20*%2F%0A%20%20%20%20%20%20%20%20.dropdown-content.show%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20display%3A%20block%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F*%20Grid%20of%20swatches%20*%2F%0A%20%20%20%20%20%20%20%20.swatch-grid%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20display%3A%20grid%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20grid-template-columns%3A%20repeat(auto-fill%2C%2024px)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20gap%3A%206px%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20.color-swatch%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20width%3A%2024px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20height%3A%2024px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20border%3A%20none%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20border-radius%3A%2050%25%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20cursor%3A%20pointer%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20transition%3A%20transform%200.2s%2C%20box-shadow%200.2s%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20.color-swatch%3Ahover%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20transform%3A%20scale(1.1)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20box-shadow%3A%200%200%204px%20rgba(0%2C%200%2C%200%2C%200.3)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%23saveDropdown%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20width%3A%20200px%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%23saveDropdown%20button%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20width%3A%20100%25%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20text-align%3A%20left%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F*%20%ED%8E%B8%EC%A7%91%20%EC%98%81%EC%97%AD%20*%2F%0A%20%20%20%20%20%20%20%20%23editor%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20border-radius%3A%2012px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20padding%3A%2015px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20min-height%3A%20250px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20outline%3A%20none%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20font-size%3A%2016px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20line-height%3A%201.6%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F*%20background%3A%20%23f4f4f4%3B%20*%2F%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%23editor%20p%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20margin-top%3A%200.5em%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20margin-bottom%3A%200.5em%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%23editor%20a%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3A%20var(--note-link-color)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20text-decoration%3A%20none%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20font-weight%3A%20800%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20transition%3A%20all%200.2s%20ease-in-out%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20border-bottom%3A%202px%20solid%20transparent%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%23editor%20a%3Ahover%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20border-bottom%3A%202px%20solid%20var(--note-link-color)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3A%20var(--note-link-color)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%23editor%20a%3A%3Abefore%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20content%3A%20%22%F0%9F%94%97%22%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%0A%20%20%20%20%20%20%20%20%23editor%3Aempty%3A%3Abefore%2C%0A%20%20%20%20%20%20%20%20%23editor%20p%3Aempty%3A%3Abefore%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20content%3A%20%22Write%20your%20note%20here...%22%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3A%20var(--note-placeholder-color)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20display%3A%20block%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%23footer%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20text-align%3A%20center%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20margin-top%3A%2020px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3A%20var(--attribution-color)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%23footer%20a%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20text-decoration%3A%20none%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3A%20var(--attribution-color)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20img%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20max-width%3A%20100%25%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20height%3A%20auto%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20display%3A%20block%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20margin%3A%2010px%200%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20border-radius%3A%2012px%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20.thin-line%3A%3Abefore%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20content%3A%20%22%22%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20display%3A%20block%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20width%3A%20100%25%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20height%3A%201px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20background-color%3A%20var(--control-bg-color)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3A%20var(--control-text-color)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20margin%3A%2010px%200%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%40media%20print%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20.no-print%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20display%3A%20none%20!important%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20.editor-container%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20width%3A%20100%25%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20max-width%3A%20100%25%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20box-shadow%3A%20none%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%3C%2Fstyle%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<style>" title="<style>" /> </head> <body> <div class="editor-container"> <div id="filename" contenteditable="plaintext-only" class="file-title">👋 Hello, This is Nash</div> <div id="toolbar" class="no-print"> <button onclick="changeBlock('h1')">XL</button> <button onclick="changeBlock('h2')">L</button> <button onclick="changeBlock('p')">M</button> <button onclick="changeBlock('small')">S</button> <button onclick="applyFormat('strong')"><b>B</b></button> <button onclick="applyFormat('em')"><i>I</i></button> <button onclick="applyFormat('u')"><u>U</u></button> <button onclick="applyURL()">🔗</button> <label for="imageUpload">📷</label> <input type="file" id="imageUpload" accept="image/*" onchange="insertImage(event)"> <div class="dropdown"> <button onclick="toggleDropdown('textColorDropdown')">Color</button> <div id="textColorDropdown" class="dropdown-content"> <div class="swatch-grid"> <button class="color-swatch" style="background: var(--note-text-color-1);" onmousedown="event.preventDefault();" onclick="applyTextColor('1'); toggleDropdown('textColorDropdown')"></button> <button class="color-swatch" style="background: var(--note-text-color-2);" onmousedown="event.preventDefault();" onclick="applyTextColor('2'); toggleDropdown('textColorDropdown')"></button> <button class="color-swatch" style="background: var(--note-text-color-3);" onmousedown="event.preventDefault();" onclick="applyTextColor('3'); toggleDropdown('textColorDropdown')"></button> <button class="color-swatch" style="background: var(--note-text-color-4);" onmousedown="event.preventDefault();" onclick="applyTextColor('4'); toggleDropdown('textColorDropdown')"></button> <button class="color-swatch" style="background: var(--note-text-color-5);" onmousedown="event.preventDefault();" onclick="applyTextColor('5'); toggleDropdown('textColorDropdown')"></button> <button class="color-swatch" style="background: var(--note-text-color-6);" onmousedown="event.preventDefault();" onclick="applyTextColor('6'); toggleDropdown('textColorDropdown')"></button> <button class="color-swatch" style="background: var(--note-text-color-7);" onmousedown="event.preventDefault();" onclick="applyTextColor('7'); toggleDropdown('textColorDropdown')"></button> <button class="color-swatch" style="background: var(--note-text-color-8);" onmousedown="event.preventDefault();" onclick="applyTextColor('8'); toggleDropdown('textColorDropdown')"></button> </div> </div> </div> <!-- Highlight Color Dropdown --> <div class="dropdown"> <button onclick="toggleDropdown('highlightDropdown')">Highlight</button> <div id="highlightDropdown" class="dropdown-content"> <div class="swatch-grid"> <button class="color-swatch" style="background: var(--note-highlight-color-1);" onmousedown="event.preventDefault();" onclick="applyHighlightColor('1'); toggleDropdown('highlightDropdown')"></button> <button class="color-swatch" style="background: var(--note-highlight-color-2);" onmousedown="event.preventDefault();" onclick="applyHighlightColor('2'); toggleDropdown('highlightDropdown')"></button> <button class="color-swatch" style="background: var(--note-highlight-color-3);" onmousedown="event.preventDefault();" onclick="applyHighlightColor('3'); toggleDropdown('highlightDropdown')"></button> <button class="color-swatch" style="background: var(--note-highlight-color-4);" onmousedown="event.preventDefault();" onclick="applyHighlightColor('4'); toggleDropdown('highlightDropdown')"></button> <button class="color-swatch" style="background: var(--note-highlight-color-5);" onmousedown="event.preventDefault();" onclick="applyHighlightColor('5'); toggleDropdown('highlightDropdown')"></button> <button class="color-swatch" style="background: var(--note-highlight-color-6);" onmousedown="event.preventDefault();" onclick="applyHighlightColor('6'); toggleDropdown('highlightDropdown')"></button> <button class="color-swatch" style="background: var(--note-highlight-color-7);" onmousedown="event.preventDefault();" onclick="applyHighlightColor('7'); toggleDropdown('highlightDropdown')"></button> <button class="color-swatch" style="background: var(--note-highlight-color-8);" onmousedown="event.preventDefault();" onclick="applyHighlightColor('8'); toggleDropdown('highlightDropdown')"></button> </div> </div> </div> <div id="splitbar">|</div> <!-- Block conversion --> <div class="dropdown"> <button onclick="toggleDropdown('saveDropdown')">💾</button> <div id="saveDropdown" class="dropdown-content"> <button onclick="toggleDropdown('saveDropdown'); exportToFile(true, true)">Save</button> <button onclick="toggleDropdown('saveDropdown'); exportToFile(false, true)">Share</button> <button onclick="toggleDropdown('saveDropdown'); exportToFile(true, false)">Save as Read-Only</button> <button onclick="toggleDropdown('saveDropdown'); exportToFile(false, false)">Share as Read-Only</button> </div> </div> </div> <div id="editorContainer" class="thin-line"> <div id="editor" contenteditable="true"> <h1>What's this?</h1> <p>Nash is a standalone <strong><span style="background-color: var(--note-highlight-color-2);">note as HTML</span></strong>.</p> <p>Nash does not require any other software or services.</p><small>Actually, this requires a web browser, but it's usually all installed.</small> <p>You can save this note and edit it offline.</p> <h1>Where do I use this?</h1> <p> <img src="https://www.w3schools.com/html/img_chania.jpg" alt="Flowers in Chania" width="460" height="345"> </p><small>I have a pizza photo that I like in the gallery, so I'm attaching it.</small> <p>You can create static blogging or single-page content.</p> <p>If you deliver it by messenger, you can watch it as a preview, so you can write long content and share it with others.</p> <h1>Inspiration</h1> <p>I used to implement a feature with a single HTML to POC a simple idea.</p> <p>Unexpectedly, I realized that there are many things I can do with a single HTML, so I thought I could create a document file that works without separate services and software like Notion or Word. This is my first attempt.</p> <p><br></p> <h1>Get a empty note</h1> <p>You can go to an empty page through the following link.</p> <p><a href="https://keepworking.github.io/nash/nash.html">https://keepworking.github.io/nash/nash.html</a> </p> <p><br></p> <h1>Nash is an open source.</h1> <p>Please feel free to modify and use it.</p> </div> </div> <div id="footer"> <small><a href="https://github.com/keepworking/nash">nash@github</a></small> </div> </div> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%3E%0A%0A%20%20%20%20%20%20%20%20function%20setEditMode(editMode)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20editor%20%3D%20document.getElementById(%22editor%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20toolbar%20%3D%20document.getElementById(%22toolbar%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20filename%20%3D%20document.getElementById(%22filename%22)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(editMode)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20editor.contentEditable%20%3D%20%22true%22%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20filename.contentEditable%20%3D%20%22plaintext-only%22%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20toolbar.style.display%20%3D%20%22flex%22%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20editor.contentEditable%20%3D%20%22false%22%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20filename.contentEditable%20%3D%20%22false%22%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20toolbar.style.display%20%3D%20%22none%22%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20async%20function%20exportToFile(save%2C%20editMode)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20filename%20%3D%20document.getElementById(%22filename%22).innerText.trim()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!filename)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20alert(%22title%20is%20empty!%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20filename%20%3D%20filename.endsWith(%22.html%22)%20%3F%20filename%20%3A%20filename%20%2B%20%22.html%22%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(editMode%20%3D%3D%3D%20false)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20setEditMode(false)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20content%20%3D%20document.documentElement.outerHTML%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20blob%20%3D%20new%20Blob(%5B%22%3C!DOCTYPE%20html%3E%5Cn%22%20%2B%20content%5D%2C%20%7B%20type%3A%20%22text%2Fhtml%22%20%7D)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20file%20%3D%20new%20File(%5Bblob%5D%2C%20filename%2C%20%7B%20type%3A%20%22text%2Fhtml%22%20%7D)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(editMode%20%3D%3D%3D%20false)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20setEditMode(true)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(save%20%3D%3D%20false%20%26%26%20navigator.canShare%20%26%26%20navigator.canShare(%7B%20files%3A%20%5Bfile%5D%20%7D))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20await%20navigator.share(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20files%3A%20%5Bfile%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20title%3A%20filename%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20text%3A%20%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20catch%20(error)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.error(%22share%20failed%3A%22%2C%20error)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20a%20%3D%20document.createElement(%22a%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a.href%20%3D%20URL.createObjectURL(blob)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a.download%20%3D%20filename%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a.click()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20URL.revokeObjectURL(a.href)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20function%20insertImage(event)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20file%20%3D%20event.target.files%5B0%5D%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(file)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20reader%20%3D%20new%20FileReader()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20reader.onload%20%3D%20function%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20img%20%3D%20document.createElement(%22img%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20img.src%20%3D%20e.target.result%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20document.querySelector(%22%23editor%22).appendChild(img)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20reader.readAsDataURL(file)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Toggle%20dropdown%20visibility%0A%20%20%20%20%20%20%20%20function%20toggleDropdown(id)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20dropdown%20%3D%20document.getElementById(id)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(dropdown.classList.contains('show'))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20dropdown.classList.remove('show')%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Close%20any%20open%20dropdowns%20first%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20document.querySelectorAll('.dropdown-content').forEach(el%20%3D%3E%20el.classList.remove('show'))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20dropdown.classList.add('show')%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Close%20dropdowns%20if%20clicking%20outside%0A%20%20%20%20%20%20%20%20document.addEventListener('click'%2C%20function%20(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!e.target.closest('.dropdown'))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20document.querySelectorAll('.dropdown-content').forEach(el%20%3D%3E%20el.classList.remove('show'))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D)%3B%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Helper%3A%20Place%20the%20caret%20at%20a%20given%20element%20and%20offset.%0A%20%20%20%20%20%20%20%20function%20setCaret(el%2C%20pos)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20selection%20%3D%20window.getSelection()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20range%20%3D%20document.createRange()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20range.setStart(el%2C%20pos)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20range.collapse(true)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20selection.removeAllRanges()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20selection.addRange(range)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Wrap%20only%20the%20selected%20portions%20of%20text%20nodes.%0A%20%20%20%20%20%20%20%20%2F%2F%20If%20selection%20is%20entirely%20within%20one%20text%20node%2C%20process%20it%20directly.%0A%20%20%20%20%20%20%20%20function%20wrapRangeText(range%2C%20tagName%2C%20style%2C%20hook)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20textNodes%20%3D%20%5B%5D%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(range.commonAncestorContainer.nodeType%20%3D%3D%3D%20Node.TEXT_NODE)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20textNodes.push(range.commonAncestorContainer)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20walker%20%3D%20document.createTreeWalker(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20range.commonAncestorContainer%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20NodeFilter.SHOW_TEXT%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20acceptNode%3A%20function%20(node)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20range.intersectsNode(node)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3F%20NodeFilter.FILTER_ACCEPT%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3A%20NodeFilter.FILTER_REJECT%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20node%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20while%20(node%20%3D%20walker.nextNode())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20textNodes.push(node)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20textNodes.forEach(function%20(textNode)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20start%20%3D%200%2C%20end%20%3D%20textNode.textContent.length%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(textNode%20%3D%3D%3D%20range.startContainer)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20start%20%3D%20range.startOffset%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(textNode%20%3D%3D%3D%20range.endContainer)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20end%20%3D%20range.endOffset%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(start%20%3E%3D%20end)%20return%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20parent%20%3D%20textNode.parentNode%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20wrapper%20%3D%20document.createElement(tagName)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(style)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20wrapper.style.cssText%20%3D%20style%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(hook)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20hook(wrapper)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20wrapper.textContent%20%3D%20textNode.textContent.substring(start%2C%20end)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20frag%20%3D%20document.createDocumentFragment()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20beforeText%20%3D%20textNode.textContent.substring(0%2C%20start)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20afterText%20%3D%20textNode.textContent.substring(end)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(beforeText)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20frag.appendChild(document.createTextNode(beforeText))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20frag.appendChild(wrapper)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(afterText)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20frag.appendChild(document.createTextNode(afterText))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20parent.replaceChild(frag%2C%20textNode)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Basic%20inline%20formatting%3A%20wraps%20the%20selection%20in%20the%20specified%20tag.%0A%20%20%20%20%20%20%20%20function%20applyFormat(tagName)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20selection%20%3D%20window.getSelection()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!selection.rangeCount%20%7C%7C%20selection.isCollapsed)%20return%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20range%20%3D%20selection.getRangeAt(0)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20editor%20%3D%20document.getElementById('editor')%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!editor.contains(range.commonAncestorContainer))%20return%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20wrapRangeText(range%2C%20tagName)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20selection.removeAllRanges()%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Apply%20inline%20style%20(e.g.%2C%20font-size%2C%20text%20color%2C%20background%20color)%20by%20wrapping%20the%20selection%20in%20a%20%3Cspan%3E.%0A%20%20%20%20%20%20%20%20function%20applyStyle(styleString)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20selection%20%3D%20window.getSelection()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!selection.rangeCount%20%7C%7C%20selection.isCollapsed)%20return%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20range%20%3D%20selection.getRangeAt(0)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20editor%20%3D%20document.getElementById('editor')%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!editor.contains(range.commonAncestorContainer))%20return%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20wrapRangeText(range%2C%20'span'%2C%20styleString)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20selection.removeAllRanges()%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Apply%20inline%20url%20%0A%20%20%20%20%20%20%20%20function%20applyURL()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20selection%20%3D%20window.getSelection()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!selection.rangeCount%20%7C%7C%20selection.isCollapsed)%20return%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20range%20%3D%20selection.getRangeAt(0)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20editor%20%3D%20document.getElementById('editor')%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!editor.contains(range.commonAncestorContainer))%20return%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20url%20%3D%20prompt(%22URL%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!url)%20return%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20wrapRangeText(range%2C%20'a'%2C%20null%2C%20function%20(element)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20element.href%20%3D%20url%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20selection.removeAllRanges()%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Called%20by%20the%20text%20size%20dropdown.%0A%20%20%20%20%20%20%20%20function%20applyTextSize(size)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!size)%20return%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20applyStyle(%22font-size%3A%20%22%20%2B%20size%20%2B%20%22%3B%22)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Called%20when%20a%20text%20color%20swatch%20is%20clicked.%0A%20%20%20%20%20%20%20%20function%20applyTextColor(color)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!color)%20return%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20applyStyle(%22color%3A%20var(--note-text-color-%22%20%2B%20color%20%2B%20%22)%3B%22)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Called%20when%20a%20highlight%20(background%20color)%20swatch%20is%20clicked.%0A%20%20%20%20%20%20%20%20function%20applyHighlightColor(color)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!color)%20return%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20applyStyle(%22background-color%3A%20var(--note-highlight-color-%22%20%2B%20color%20%2B%20%22)%3B%22)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Convert%20the%20current%20block%20(direct%20child%20of%20%23editor)%20to%20the%20chosen%20tag.%0A%20%20%20%20%20%20%20%20function%20changeBlock(tag)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20selection%20%3D%20window.getSelection()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!selection.rangeCount)%20return%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20node%20%3D%20selection.anchorNode%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20editor%20%3D%20document.getElementById('editor')%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20while%20(node%20%26%26%20node.parentNode%20!%3D%3D%20editor)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20node%20%3D%20node.parentNode%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!node%20%7C%7C%20node%20%3D%3D%3D%20editor)%20return%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20newBlock%20%3D%20document.createElement(tag)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20while%20(node.firstChild)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20node.firstChild.nodeType%20%3D%3D%3D%20Node.ELEMENT_NODE%20%26%26%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20node.firstChild.matches('p')%20%26%26%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tag.match(%2F%5EH%5B1-6%5D%24%2F)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20let%20child%20%3D%20node.firstChild%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20while%20(child.firstChild)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20newBlock.appendChild(child.firstChild)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20node.removeChild(child)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20newBlock.appendChild(node.firstChild)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20editor.replaceChild(newBlock%2C%20node)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20range%20%3D%20document.createRange()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20range.selectNodeContents(newBlock)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20range.collapse(false)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20selection.removeAllRanges()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20selection.addRange(range)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Splits%20the%20current%20block%20at%20the%20caret.%0A%20%20%20%20%20%20%20%20function%20splitBlock()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20editor%20%3D%20document.getElementById('editor')%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20selection%20%3D%20window.getSelection()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!selection.rangeCount)%20return%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20range%20%3D%20selection.getRangeAt(0)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20block%20%3D%20range.startContainer%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20while%20(block%20%26%26%20block.parentNode%20!%3D%3D%20editor)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20block%20%3D%20block.parentNode%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!block)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20p%20%3D%20document.createElement('p')%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20p.innerHTML%20%3D%20'%3Cwp-br%3E'%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20editor.appendChild(p)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20setCaret(p%2C%200)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20afterRange%20%3D%20range.cloneRange()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20afterRange.setStart(range.endContainer%2C%20range.endOffset)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20afterRange.setEndAfter(block.lastChild%20%7C%7C%20block)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20afterContent%20%3D%20afterRange.cloneContents()%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20isAtEnd%20%3D%20!Array.from(afterContent.childNodes).some(n%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20(n.nodeType%20%3D%3D%3D%20Node.ELEMENT_NODE)%20%7C%7C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(n.nodeType%20%3D%3D%3D%20Node.TEXT_NODE%20%26%26%20n.textContent.trim())%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(isAtEnd)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20newBlock%20%3D%20document.createElement('p')%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20newBlock.innerHTML%20%3D%20'%3Cwp-br%3E'%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(block.nextSibling)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20editor.insertBefore(newBlock%2C%20block.nextSibling)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20editor.appendChild(newBlock)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20setCaret(newBlock%2C%200)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20newBlock%20%3D%20document.createElement('p')%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20extractRange%20%3D%20range.cloneRange()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20extractRange.setEndAfter(block.lastChild%20%7C%7C%20block)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20extracted%20%3D%20extractRange.extractContents()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!extracted.childNodes.length)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20newBlock.innerHTML%20%3D%20'%3Cwp-br%3E'%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20newBlock.appendChild(extracted)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(block.nextSibling)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20editor.insertBefore(newBlock%2C%20block.nextSibling)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20editor.appendChild(newBlock)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20setCaret(newBlock%2C%200)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!block.textContent.trim()%20%26%26%20!block.querySelector('img%2C%20video%2C%20iframe%2C%20embed%2C%20object'))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20block.innerHTML%20%3D%20'%3Cwp-br%3E'%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Normalize%20stray%20text%20nodes%20and%20nested%20blocks.%0A%20%20%20%20%20%20%20%20function%20normalizeEditor()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20editor%20%3D%20document.getElementById('editor')%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20Array.from(editor.childNodes).forEach(node%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(node.nodeType%20%3D%3D%3D%20Node.TEXT_NODE%20%26%26%20node.textContent.trim())%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20p%20%3D%20document.createElement('p')%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20p.textContent%20%3D%20node.textContent%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20editor.replaceChild(p%2C%20node)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20editor.querySelectorAll('p%20p%2C%20h1%20p%2C%20h2%20p%2C%20h3%20p%2C%20h4%20p%2C%20h5%20p%2C%20h6%20p%2C%20p%20font%2C%20small%20p').forEach(nested%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20parent%20%3D%20nested.parentNode%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20while%20(nested.firstChild)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20parent.insertBefore(nested.firstChild%2C%20nested)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20parent.removeChild(nested)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Normalize%20stray%20text%20nodes%20and%20nested%20blocks.%0A%20%20%20%20%20%20%20%20function%20cleanEditor()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20editor%20%3D%20document.getElementById('editor')%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(editor.firstChild%20%26%26%20%5B%22H1%22%2C%20%22H2%22%2C%20%22H3%22%2C%20%22H4%22%2C%20%22H5%22%2C%20%22H6%22%2C%20%22P%22%5D.includes(editor.firstChild.nodeName))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(editor.innerHTML.trim()%20%3D%3D%3D%20%22%22%20%7C%7C%20editor.innerHTML.trim()%20%3D%3D%3D%20%22%3Cwp-br%3E%22)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20editor.innerHTML%20%3D%20%22%3Cwp-p%3E%3C%2Fwp-p%3E%22%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20function%20updateTitle()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20let%20filename%20%3D%20document.getElementById(%22filename%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(filename.innerHTML%20%3D%3D%3D%20%22%3Cwp-br%3E%22)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20filename.innerHTML%20%3D%20%22%22%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20document.title%20%3D%20filename.innerHTML.trim()%20%7C%7C%20%22Nash%20%3A%20Note%20as%20HTML%22%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20function%20keydownHandler(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(e.key%20%3D%3D%3D%20'Enter'%20%26%26%20!e.shiftKey)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20e.preventDefault()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20splitBlock()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20((e.ctrlKey%20%7C%7C%20e.metaKey)%20%26%26%20(e.key%20%3D%3D%3D%20'z'%20%7C%7C%20e.key%20%3D%3D%3D%20'y'))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20e.preventDefault()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20function%20clickHandler(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20target%20%3D%20e.target.closest(%22a%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(!target%20%7C%7C%20!document.getElementById(%22editorContainer%22).contains(target))%20return%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20e.preventDefault()%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20userConfirmed%20%3D%20confirm(%60%22%24%7Btarget.href%7D%22%20open%20this%20url%3F%60)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(userConfirmed)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20window.open(target.href%2C%20%22_blank%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20function%20unloadHandler(e)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(document.getElementById(%22editor%22).contentEditable%20!%3D%3D%20%22true%22)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20e.preventDefault()%0A%20%20%20%20%20%20%20%20%20%20%20%20e.returnValue%20%3D%20''%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%0A%20%20%20%20%20%20%20%20editor%20%3D%20document.getElementById('editor')%3B%0A%20%20%20%20%20%20%20%20filename%20%3D%20document.getElementById('filename')%3B%0A%0A%20%20%20%20%20%20%20%20editor.addEventListener('keydown'%2C%20keydownHandler)%3B%0A%20%20%20%20%20%20%20%20editor.addEventListener('click'%2C%20clickHandler)%3B%0A%20%20%20%20%20%20%20%20editor.addEventListener('blur'%2C%20normalizeEditor)%3B%0A%20%20%20%20%20%20%20%20editor.addEventListener(%22input%22%2C%20cleanEditor)%3B%0A%20%20%20%20%20%20%20%20editor.addEventListener(%22focus%22%2C%20cleanEditor)%3B%0A%0A%20%20%20%20%20%20%20%20filename.addEventListener(%22input%22%2C%20updateTitle)%3B%0A%0A%20%20%20%20%20%20%20%20window.addEventListener(%22beforeunload%22%2C%20unloadHandler)%3B%0A%0A%20%20%20%20%20%20%20%20updateTitle()%3B%0A%0A%20%20%20%20%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" /> </body> </html>