mirror of
https://github.com/aelve/guide.git
synced 2024-12-24 13:26:08 +03:00
Create some <textarea>s dynamically
Makes it quite a bit faster on Firefox (see #24)
This commit is contained in:
parent
e0ff916eea
commit
41230596bf
90
src/JS.hs
90
src/JS.hs
@ -44,6 +44,10 @@ allJSFunctions = JS . T.unlines . map fromJS $ [
|
||||
showOrHideHelp, showHelp, hideHelp,
|
||||
-- Misc
|
||||
createAjaxIndicator,
|
||||
autosizeTextarea,
|
||||
-- Creating parts of interface
|
||||
makeTraitEditor,
|
||||
makeItemNotesEditor,
|
||||
-- Add methods
|
||||
addCategory, addItem,
|
||||
addPro, addCon,
|
||||
@ -85,12 +89,16 @@ instance JSParams () where
|
||||
jsParams () = []
|
||||
instance ToJS a => JSParams [a] where
|
||||
jsParams = map toJS
|
||||
instance (ToJS a, ToJS b) => JSParams (a,b) where
|
||||
instance (ToJS a,ToJS b) => JSParams (a,b) where
|
||||
jsParams (a,b) = [toJS a, toJS b]
|
||||
instance (ToJS a, ToJS b, ToJS c) => JSParams (a,b,c) where
|
||||
instance (ToJS a,ToJS b,ToJS c) => JSParams (a,b,c) where
|
||||
jsParams (a,b,c) = [toJS a, toJS b, toJS c]
|
||||
instance (ToJS a, ToJS b, ToJS c, ToJS d) => JSParams (a,b,c,d) where
|
||||
instance (ToJS a,ToJS b,ToJS c,ToJS d) => JSParams (a,b,c,d) where
|
||||
jsParams (a,b,c,d) = [toJS a, toJS b, toJS c, toJS d]
|
||||
instance (ToJS a,ToJS b,ToJS c,ToJS d,ToJS e) => JSParams (a,b,c,d,e) where
|
||||
jsParams (a,b,c,d,e) = [toJS a, toJS b, toJS c, toJS d, toJS e]
|
||||
instance (ToJS a,ToJS b,ToJS c,ToJS d,ToJS e,ToJS f) => JSParams (a,b,c,d,e,f) where
|
||||
jsParams (a,b,c,d,e,f) = [toJS a, toJS b, toJS c, toJS d, toJS e, toJS f]
|
||||
|
||||
{- | This hacky class lets you construct and use Javascript functions; you give 'makeJSFunction' function name, function parameters, and function body, and you get a polymorphic value of type @JSFunction a => a@, which you can use either as a complete function definition (if you set @a@ to be @JS@), or as a function that you can give some parameters and it would return a Javascript call:
|
||||
|
||||
@ -283,6 +291,82 @@ createAjaxIndicator =
|
||||
$("#ajax-indicator").hide();
|
||||
|]
|
||||
|
||||
autosizeTextarea :: JSFunction a => a
|
||||
autosizeTextarea =
|
||||
makeJSFunction "autosizeTextarea" ["textareaNode"]
|
||||
[text|
|
||||
autosize(textareaNode);
|
||||
autosize.update(textareaNode);
|
||||
|]
|
||||
|
||||
makeTraitEditor :: JSFunction a => a
|
||||
makeTraitEditor =
|
||||
makeJSFunction "makeTraitEditor"
|
||||
["traitNode", "sectionNode", "textareaUid", "content", "itemId", "traitId"]
|
||||
[text|
|
||||
$(sectionNode).html("");
|
||||
area = $("<textarea>", {
|
||||
"autocomplete" : "off",
|
||||
"rows" : "5",
|
||||
"id" : textareaUid,
|
||||
"class" : "fullwidth",
|
||||
"text" : content })[0];
|
||||
area.onkeydown = function () {
|
||||
if (event.keyCode == 13) {
|
||||
submitTrait(traitNode, itemId, traitId, area.value);
|
||||
return false; } };
|
||||
br = $("<br>")[0];
|
||||
a = $("<a>", {
|
||||
"href" : "#",
|
||||
"text" : "cancel" })[0];
|
||||
a.onclick = function () {
|
||||
$(sectionNode).html("");
|
||||
switchSection(traitNode, "editable");
|
||||
return false; };
|
||||
cancelBtn = $("<span>", {"class":"text-button"})[0];
|
||||
$(cancelBtn).append(a);
|
||||
$(sectionNode).append(area, br, cancelBtn);
|
||||
|]
|
||||
|
||||
makeItemNotesEditor :: JSFunction a => a
|
||||
makeItemNotesEditor =
|
||||
makeJSFunction "makeItemNotesEditor"
|
||||
["notesNode", "sectionNode", "textareaUid", "content", "itemId"]
|
||||
[text|
|
||||
$(sectionNode).html("");
|
||||
area = $("<textarea>", {
|
||||
"autocomplete" : "off",
|
||||
"rows" : "10",
|
||||
"id" : textareaUid,
|
||||
"class" : "big fullwidth",
|
||||
"text" : content })[0];
|
||||
saveBtn = $("<input>", {
|
||||
"value" : "Save",
|
||||
"type" : "button" })[0];
|
||||
saveBtn.onclick = function () {
|
||||
submitItemNotes(notesNode, itemId, area.value); };
|
||||
// Can't use $()-generation here because then the <span> would have
|
||||
// to be cloned (since we're inserting it multiple times) and I don't
|
||||
// know how to do that.
|
||||
space = "<span style='margin-left:6px'></span>";
|
||||
cancelBtn = $("<input>", {
|
||||
"value" : "Cancel",
|
||||
"type" : "button" })[0];
|
||||
cancelBtn.onclick = function () {
|
||||
$(sectionNode).html("");
|
||||
switchSection(notesNode, "expanded"); };
|
||||
monospace = $("<input>", {
|
||||
"name" : "monospace",
|
||||
"type" : "checkbox" })[0];
|
||||
monospace.onchange = function () {
|
||||
setMonospace(area, monospace.checked); };
|
||||
monospaceLabel = $("<label>")[0];
|
||||
$(monospaceLabel).append(monospace, "monospace editor");
|
||||
$(sectionNode).append(
|
||||
area, saveBtn, $(space), cancelBtn, $(space),
|
||||
"Markdown", $(space), monospaceLabel);
|
||||
|]
|
||||
|
||||
-- | Create a new category.
|
||||
addCategory :: JSFunction a => a
|
||||
addCategory =
|
||||
|
44
src/View.hs
44
src/View.hs
@ -865,6 +865,7 @@ renderTrait :: MonadIO m => Uid Item -> Trait -> HtmlT m ()
|
||||
renderTrait itemId trait = do
|
||||
let thisId = "trait-" <> uidToText (trait^.uid)
|
||||
this = JS.selectId thisId
|
||||
editingSectionUid <- randomLongUid
|
||||
li_ [id_ thisId] $ do
|
||||
|
||||
sectionSpan "normal editable" [shown, noScriptShown] $ do
|
||||
@ -879,15 +880,17 @@ renderTrait itemId trait = do
|
||||
-- TODO: these 3 icons in a row don't look nice
|
||||
imgButton "delete trait" "/x.svg" [width_ "12"] $
|
||||
JS.deleteTrait (itemId, trait^.uid, this)
|
||||
textareaUid <- randomLongUid
|
||||
textButton "edit" $
|
||||
JS.switchSection (this, "editing" :: Text)
|
||||
JS.makeTraitEditor (this, JS.selectUid editingSectionUid,
|
||||
textareaUid,
|
||||
trait^.content.mdText,
|
||||
itemId, trait^.uid) <>
|
||||
JS.switchSection (this, "editing" :: Text) <>
|
||||
JS.autosizeTextarea [JS.selectUid textareaUid]
|
||||
|
||||
section "editing" [] $ do
|
||||
smallMarkdownEditor
|
||||
[rows_ "5"]
|
||||
(trait^.content)
|
||||
(\val -> JS.submitTrait (this, itemId, trait^.uid, val))
|
||||
(Just (JS.switchSection (this, "editable" :: Text)))
|
||||
section "editing" [uid_ editingSectionUid] $ do
|
||||
return ()
|
||||
|
||||
-- TODO: automatically provide links to modules in Markdown (and have a
|
||||
-- database of modules or something)
|
||||
@ -912,6 +915,7 @@ renderItemNotes :: MonadIO m => Item -> HtmlT m ()
|
||||
renderItemNotes item = do
|
||||
let thisId = "item-notes-" <> uidToText (item^.uid)
|
||||
this = JS.selectId thisId
|
||||
editingSectionUid <- randomLongUid
|
||||
div_ [id_ thisId, class_ "item-notes"] $ do
|
||||
|
||||
section "collapsed" [shown] $ do
|
||||
@ -929,12 +933,22 @@ renderItemNotes item = do
|
||||
renderTOC toc
|
||||
|
||||
section "expanded" [noScriptShown] $ do
|
||||
textareaUid <- randomLongUid
|
||||
contents <- if item^.notes == ""
|
||||
then liftIO $ T.readFile "static/item-notes-template.md"
|
||||
else return (item^.notes.mdText)
|
||||
let buttons = do
|
||||
textButton "collapse notes" $
|
||||
JS.switchSection (this, "collapsed" :: Text)
|
||||
emptySpan "1em"
|
||||
textButton "edit notes" $
|
||||
JS.switchSection (this, "editing" :: Text)
|
||||
JS.makeItemNotesEditor (
|
||||
this, JS.selectUid editingSectionUid,
|
||||
textareaUid,
|
||||
contents,
|
||||
item^.uid) <>
|
||||
JS.switchSection (this, "editing" :: Text) <>
|
||||
JS.autosizeTextarea [JS.selectUid textareaUid]
|
||||
buttons
|
||||
if item^.notes == ""
|
||||
then p_ "add something!"
|
||||
@ -944,16 +958,8 @@ renderItemNotes item = do
|
||||
-- the notes are closed (but don't scroll if it's already visible after
|
||||
-- the notes have been hidden)
|
||||
|
||||
section "editing" [] $ do
|
||||
contents <- if item^.notes == ""
|
||||
then liftIO $ renderMarkdownBlock <$>
|
||||
T.readFile "static/item-notes-template.md"
|
||||
else return (item^.notes)
|
||||
markdownEditor
|
||||
[rows_ "10"]
|
||||
contents
|
||||
(\val -> JS.submitItemNotes (this, item^.uid, val))
|
||||
(JS.switchSection (this, "expanded" :: Text))
|
||||
section "editing" [uid_ editingSectionUid] $
|
||||
return ()
|
||||
|
||||
-- TODO: a shortcut for editing (when you press Ctrl-something, whatever was
|
||||
-- selected becomes editable)
|
||||
@ -1049,7 +1055,7 @@ markdownEditor attr (view mdText -> s) submit cancel = do
|
||||
"Markdown"
|
||||
emptySpan "6px"
|
||||
-- TODO: this jumps around when there's a lot of text, need to somehow
|
||||
-- prevent jumping
|
||||
-- prevent jumping (and in JS.makeItemNotesEditor too)
|
||||
let checkHandler = fromJS $
|
||||
JS.setMonospace (JS.selectUid textareaUid, JS "this.checked")
|
||||
label_ $ do
|
||||
|
Loading…
Reference in New Issue
Block a user