Page Menu
Home
Sealhub
Search
Configure Global Search
Log In
Files
F12656123
markdown-textarea.stimulus.ts
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
5 KB
Referenced Files
None
Subscribers
None
markdown-textarea.stimulus.ts
View Options
/* eslint-disable @typescript-eslint/no-misused-promises */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-explicit-any */
import
{
Controller
}
from
"stimulus"
;
import
type
{
default
as
simplemde
}
from
"simplemde"
;
const
CSS_ID
=
"simplemde-css"
;
const
JS_ID
=
"simplemde-js"
;
declare
const
SimpleMDE
:
simplemde
;
export
default
class
MarkdownTextarea
extends
Controller
<
HTMLTextAreaElement
>
{
sm
:
simplemde
;
checkboxHandler
:
(
this
:
HTMLElement
,
ev
:
Event
)
=>
any
;
resizeObserver
:
ResizeObserver
;
intersectionObserver
:
IntersectionObserver
;
mdeStarted
=
false
;
addCSS
()
{
const
tag
=
document
.
querySelector
(
`head #
${
CSS_ID
}
`
);
if
(
!
tag
)
{
const
link
=
document
.
createElement
(
"link"
);
link
.
setAttribute
(
"rel"
,
"stylesheet"
);
link
.
setAttribute
(
"type"
,
"text/css"
);
link
.
setAttribute
(
"id"
,
CSS_ID
);
link
.
setAttribute
(
"href"
,
"/dist/simplemde.min.css"
);
document
.
head
.
appendChild
(
link
);
}
}
async
addJS
()
{
return
new
Promise
<
void
>
((
resolve
,
reject
)
=>
{
const
once_loaded
=
(
e
:
MouseEvent
)
=>
{
(
e
.
target
as
HTMLScriptElement
).
setAttribute
(
"loaded"
,
"true"
);
resolve
();
};
try
{
const
tag
=
document
.
querySelector
(
`head #
${
JS_ID
}
`
);
if
(
!
tag
)
{
const
script
=
document
.
createElement
(
"script"
);
script
.
setAttribute
(
"id"
,
JS_ID
);
script
.
setAttribute
(
"src"
,
"/dist/simplemde.min.js"
);
script
.
addEventListener
(
"load"
,
once_loaded
);
document
.
head
.
appendChild
(
script
);
}
else
{
if
(
tag
.
getAttribute
(
"loaded"
)
==
"true"
)
{
resolve
();
}
else
{
tag
.
addEventListener
(
"load"
,
once_loaded
);
}
}
}
catch
(
e
)
{
reject
(
e
);
}
});
}
handleResize
()
{
this
.
sm
.
codemirror
.
refresh
();
}
async
connect
()
{
console
.
log
(
"Markdown connect!"
,
this
.
element
);
if
(
this
.
element
.
parentNode
?
.
querySelector
(
".editor-toolbar"
))
{
//already loaded, quit;
return
;
}
this
.
addCSS
();
await
this
.
addJS
();
const
component_block
=
this
.
isInsideComponentBlock
();
// some offloading of starting the MDE, because it is slow on Chrome
if
(
component_block
)
{
if
(
this
.
isHiddenBlock
())
{
const
handler
=
()
=>
{
this
.
getCheckboxThatShowsBlock
()
?
.
removeEventListener
(
"change"
,
handler
);
setTimeout
(()
=>
this
.
init
(),
1
);
};
this
.
getCheckboxThatShowsBlock
()
?
.
addEventListener
(
"change"
,
handler
);
}
else
{
await
this
.
init
();
}
}
else
{
await
this
.
init
();
}
}
async
startMDE
()
{
if
(
this
.
mdeStarted
)
{
return
;
}
this
.
sm
=
new
(
SimpleMDE
as
any
)({
element
:
this
.
element
,
autoDownloadFontAwesome
:
false
,
spellChecker
:
false
,
hideIcons
:
[
"image"
,
"preview"
,
"side-by-side"
],
status
:
[
"words"
],
autosave
:
{
enabled
:
false
},
forceSync
:
true
,
// for autosubmit to work
initialValue
:
this
.
element
.
value
,
})
as
simplemde
;
// this.element.closest(".grow-wrap").setAttribute("data-turbo-permanent", "");
this
.
sm
.
codemirror
.
on
(
"change"
,
()
=>
{
this
.
element
.
dispatchEvent
(
new
Event
(
"input"
));
});
this
.
setupRefreshOnShow
();
this
.
resizeObserver
=
new
ResizeObserver
(()
=>
{
this
.
sm
.
codemirror
.
refresh
();
});
const
wrapper
=
(
this
.
sm
as
any
).
element
.
closest
(
".grow-wrap"
)
as
HTMLDivElement
;
this
.
resizeObserver
.
observe
(
wrapper
);
document
.
addEventListener
(
"turbo:before-morph-element"
,
function
(
event
:
BeforeUnloadEvent
)
{
const
target
=
event
.
target
as
HTMLDivElement
;
// disallow morphing, but allow removing
if
(
target
==
wrapper
&&
(
event
as
any
).
detail
.
newElement
!==
undefined
)
{
event
.
preventDefault
();
}
}
);
this
.
mdeStarted
=
true
;
}
async
init
()
{
this
.
intersectionObserver
=
new
IntersectionObserver
(
(
entries
)
=>
{
entries
.
forEach
((
entry
)
=>
{
if
(
entry
.
intersectionRatio
>
0.2
)
{
this
.
startMDE
();
}
});
},
{
root
:
this
.
element
.
closest
(
".component-arguments"
),
rootMargin
:
"0px"
,
threshold
:
0.25
,
}
);
this
.
intersectionObserver
.
observe
(
this
.
element
);
}
isHiddenBlock
()
{
return
!
this
.
getCheckboxThatShowsBlock
()
?
.
checked
;
}
isInsideComponentBlock
()
:
false
|
HTMLDivElement
{
return
this
.
element
.
closest
(
".jdd-editor__component-block"
)
as
|
HTMLDivElement
|
false
;
}
getCheckboxThatShowsBlock
()
:
HTMLInputElement
|
null
{
const
block
=
this
.
isInsideComponentBlock
();
if
(
!
block
)
{
return
null
;
}
return
block
.
querySelector
(
".component-collapse-toggle"
);
}
setupRefreshOnShow
()
{
this
.
checkboxHandler
=
(
e
)
=>
{
const
target
=
e
.
target
as
HTMLInputElement
;
if
(
target
.
checked
)
{
this
.
sm
.
codemirror
.
refresh
();
}
};
this
.
getCheckboxThatShowsBlock
()
?
.
addEventListener
(
"change"
,
this
.
checkboxHandler
);
}
disconnect
()
{
console
.
log
(
"disconnecting"
,
this
.
element
);
this
.
getCheckboxThatShowsBlock
()
?
.
removeEventListener
(
"change"
,
this
.
checkboxHandler
);
this
.
element
.
closest
(
".grow-wrap"
)
?
.
removeAttribute
(
"data-turbo-permanent"
);
this
.
resizeObserver
?
.
unobserve
((
this
.
sm
as
any
).
element
as
HTMLElement
);
this
.
sm
.
toTextArea
();
}
}
File Metadata
Details
Attached
Mime Type
text/x-java
Expires
Fri, Nov 28, 15:09 (1 d, 18 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1075932
Default Alt Text
markdown-textarea.stimulus.ts (5 KB)
Attached To
Mode
rJDDE jdd-editor
Attached
Detach File
Event Timeline
Log In to Comment