Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Shaoxuan He
web-shell
Commits
a827d16a
Commit
a827d16a
authored
Dec 14, 2022
by
HSX
Browse files
without localstorage
parent
1986670d
Changes
2
Show whitespace changes
Inline
Side-by-side
index.html
View file @
a827d16a
...
@@ -6,23 +6,21 @@
...
@@ -6,23 +6,21 @@
<meta
http-equiv=
"X-UA-Compatible"
content=
"IE=edge"
>
<meta
http-equiv=
"X-UA-Compatible"
content=
"IE=edge"
>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
>
<title>
TODO List
</title>
<title>
TODO List
</title>
<script
src=
"
??????
"
type=
"module"
></script>
<script
src=
"
index.js
"
type=
"module"
></script>
<link
rel=
"stylesheet"
href=
"
??????
"
>
<link
rel=
"stylesheet"
href=
"
index.css
"
>
</head>
</head>
<body>
<body>
<!-- shell command input part -->
<!-- shell command input part -->
<div>
<div>
<input
id=
"input-??????"
placeholder=
"??????"
></input>
<input
id=
"input-todo"
placeholder=
"Title Content DueDate"
></input>
<!-- this is optional: -->
<!-- <button id="btn-??????">??????</button> -->
</div>
</div>
<!-- todo card display part -->
<!-- todo card display part -->
<div
id=
"list-
??????
"
>
<div
id=
"list-
todo
"
>
<div
id=
"todo-
1
"
x-resolved=
"1"
>
<div
id=
"todo-
0
"
x-resolved=
"1"
>
<strong>
title
</strong>
<strong>
title
</strong>
<span>
(id=
1
)
</span>
<span>
(id=
0
)
</span>
<p>
<p>
content
content
</p>
</p>
...
...
index.js
View file @
a827d16a
// @ts-check
// @ts-check
import
{
format
}
from
'
https://esm.run/date-fns
'
;
/// <reference path="./shim.d.ts" />
/// <reference path="./date-fns.d.ts" />
import
{
format
,
compareAsc
,
parse
}
from
'
https://esm.run/date-fns
'
;
/**
/**
* @param {Date} from
* @param {Date} from
...
@@ -15,6 +18,8 @@ function getTimeDiffString(from, to) {
...
@@ -15,6 +18,8 @@ function getTimeDiffString(from, to) {
return
"
not implemented
"
;
return
"
not implemented
"
;
}
}
var
id
=
1
;
/**
/**
* @param {number} id
* @param {number} id
* @param {string} title
* @param {string} title
...
@@ -25,42 +30,59 @@ function addTodoToDOM(id, title, content, deadline) {
...
@@ -25,42 +30,59 @@ function addTodoToDOM(id, title, content, deadline) {
// bonus: save all todos into localStorage
// bonus: save all todos into localStorage
const
newId
=
"
todo-
"
+
id
;
const
newId
=
"
todo-
"
+
id
;
const
todoElem
=
document
.
createElement
(
"
???
"
);
const
todoElem
=
document
.
createElement
(
"
div
"
);
const
todoTitleElem
=
document
.
createElement
(
"
???
"
);
const
todoTitleElem
=
document
.
createElement
(
"
strong
"
);
const
todoContentElem
=
document
.
createElement
(
"
???
"
);
const
todoContentElem
=
document
.
createElement
(
"
p
"
);
const
todoDeadlineElem
=
document
.
createElement
(
"
???
"
);
const
todoDeadlineElem
=
document
.
createElement
(
"
i
"
);
todoElem
.
id
=
newId
;
todoElem
.
id
=
newId
;
todoTitleElem
.
textContent
=
??
?;
todoTitleElem
.
textContent
=
title
;
todoContentElem
.
textContent
=
content
;
const
formatdate
=
format
(
deadline
,
'
yyyy/MM/dd
'
);
todoDeadlineElem
.
textContent
=
formatdate
;
...
todoElem
.
appendChild
(
todoTitleElem
);
todoElem
.
appendChild
(
todoContentElem
);
todoElem
.
appendChild
(
todoDeadlineElem
);
const
parentElem
=
document
.
getElementById
(
"
???
"
);
const
parentElem
=
document
.
getElementById
(
"
list-todo
"
);
if
(
!
parentElem
)
{
if
(
!
parentElem
)
{
alert
(
"
Failed to get input element
"
);
alert
(
"
Failed to get input element
"
);
return
;
return
;
}
}
parentElem
.
appendChild
(
??
?
);
parentElem
.
appendChild
(
todoElem
);
}
}
/**
/**
* @param {number} id
* @param {number} id
*/
*/
function
resolveTodo
(
id
)
{
function
resolveTodo
(
id
)
{
const
todo
=
document
.
getElementById
(
"
todo-
"
+
??
?
);
const
todo
=
document
.
getElementById
(
"
todo-
"
+
id
);
if
(
!
todo
)
{
if
(
!
todo
)
{
return
;
return
;
}
}
todo
.
setAttribute
(
"
x-resolved
"
,
"
1
"
);
todo
.
setAttribute
(
"
x-resolved
"
,
"
1
"
);
todo
.
style
.
color
=
"
???
"
;
// set color to gray
todo
.
style
.
color
=
"
gray
"
;
// set color to gray
}
function
deleteTodo
(
id
)
{
const
todo
=
document
.
getElementById
(
"
todo-
"
+
id
);
if
(
!
todo
)
{
return
;
}
if
(
todo
.
parentNode
)
{
todo
.
parentNode
.
removeChild
(
todo
);
}
}
}
/**
/**
* @param {number} id
* @param {number} id
*/
*/
function
updateOverdueStatus
(
id
)
{
function
updateOverdueStatus
(
id
)
{
const
todo
=
document
.
getElementById
(
"
todo-
"
+
??
?
);
const
todo
=
document
.
getElementById
(
"
todo-
"
+
id
);
if
(
!
todo
)
{
if
(
!
todo
)
{
return
;
return
;
}
}
...
@@ -68,28 +90,31 @@ function updateOverdueStatus(id) {
...
@@ -68,28 +90,31 @@ function updateOverdueStatus(id) {
return
;
return
;
}
}
const
todoDeadlineElemSet
=
todo
.
getElementsByTagName
(
"
???
"
);
// ref: index.html example todo div
var
currentDate
=
new
Date
();
const
todoDeadlineElemSet
=
todo
.
getElementsByTagName
(
"
i
"
);
// ref: index.html example todo div
if
(
todoDeadlineElemSet
.
length
!==
1
)
{
if
(
todoDeadlineElemSet
.
length
!==
1
)
{
alert
(
"
Failed to get deadline element: unexpected number of <
???
> elements
"
);
alert
(
"
Failed to get deadline element: unexpected number of <
i
> elements
"
);
}
}
const
todoDeadline
=
todoDeadlineElemSet
[
0
].
??
?;
// get text content of element
const
todoDeadline
=
todoDeadlineElemSet
[
0
].
textContent
;
// get text content of element
const
deadline
=
??
?;
// use date-fns here to parse date string
if
(
!
todoDeadline
)
{
if
(
deadline
>
??
?)
{
return
;
todo
.
style
.
??
?
=
"
???
"
;
// set color to red
}
const
deadline
=
parse
(
todoDeadline
,
'
yyyy/MM/dd
'
,
currentDate
);
// use date-fns here to parse date string
if
(
compareAsc
(
deadline
,
currentDate
)
===
-
1
)
{
todo
.
style
.
color
=
"
red
"
;
// set color to red
}
}
}
}
function
initializeTodoApp
()
{
function
initializeTodoApp
()
{
// bonus: load all saved todos from localStorage
// bonus: load all saved todos from localStorage
const
addTodoRegex
=
/^add
(\w
+
)
????
????
$/
;
const
addTodoRegex
=
/^add
\s
+
(\w
+
)
\s
+
(\w
+
)\s
+
(\d
+
)\/(\d
+
)\/(\d
+
)
$/
;
const
modifyTodoRegex
=
??
?
;
const
modifyTodoRegex
=
/^modify
\s
+
(\d
+
)\s
+
(\w
+
)\s
*=
\s
*
(
.+
)
/
;
const
resolveTodoRegex
=
??
?
;
const
resolveTodoRegex
=
/^resolve
\s
+
(\d
+
)
/
;
const
deleteTodoRegex
=
??
?
;
const
deleteTodoRegex
=
/^delete
\s
+
(\d
+
)
/
;
const
updateTodoRegex
=
/^update
\s
*/
;
const
shellInputElem
=
/** @type {HTMLInputElement | null} */
(
document
.
getElementById
(
"
???
"
));
const
shellInputElem
=
/** @type {HTMLInputElement | null} */
(
document
.
getElementById
(
"
input-todo
"
));
if
(
shellInputElem
===
null
)
{
if
(
shellInputElem
===
null
)
{
alert
(
"
Failed to get input element
"
);
alert
(
"
Failed to get input element
"
);
return
;
return
;
...
@@ -98,11 +123,79 @@ function initializeTodoApp() {
...
@@ -98,11 +123,79 @@ function initializeTodoApp() {
// set event listener
// set event listener
shellInputElem
.
addEventListener
(
"
keyup
"
,
function
(
ev
)
{
shellInputElem
.
addEventListener
(
"
keyup
"
,
function
(
ev
)
{
if
(
ev
.
key
===
"
Enter
"
)
{
if
(
ev
.
key
===
"
Enter
"
)
{
const
inputContent
=
??
?
.
value
;
const
inputContent
=
shellInputElem
.
value
;
if
(
addTodoRegex
.
test
(
inputContent
))
{
if
(
addTodoRegex
.
test
(
inputContent
))
{
??
?
let
match
=
inputContent
.
match
(
addTodoRegex
);
}
else
if
(
??
?)
{
var
deadline
=
new
Date
();
??
?
if
(
!
match
||
match
.
length
!==
6
)
// immediately test the possible NULL variable
{
alert
(
"
add operation input format is wrong
"
);
return
;
}
deadline
.
setFullYear
(
parseInt
(
match
[
3
]),
parseInt
(
match
[
4
])
-
1
,
parseInt
(
match
[
5
]));
addTodoToDOM
(
id
++
,
match
[
1
],
match
[
2
],
deadline
);
}
else
if
(
modifyTodoRegex
.
test
(
inputContent
))
{
let
match
=
inputContent
.
match
(
modifyTodoRegex
);
if
(
!
match
||
match
.
length
!==
4
)
{
alert
(
"
modify operation input format is wrong
"
);
return
;
}
match
[
3
]
=
match
[
3
].
trim
();
// delete the front and back spaces
var
modifyElem
=
document
.
getElementById
(
"
todo-
"
+
match
[
1
]);
if
(
!
modifyElem
)
{
alert
(
"
Failed to get modify element
"
);
return
;
// to prevent future error
}
match
[
2
].
toLocaleLowerCase
();
// upper and lower input texts are both supported
if
(
match
[
2
]
===
"
title
"
)
{
const
elem
=
modifyElem
.
getElementsByTagName
(
"
strong
"
);
// getElementByTagName returns an array, so elem should be used with index
elem
[
0
].
textContent
=
match
[
3
];
}
else
if
(
match
[
2
]
===
"
content
"
)
{
const
elem
=
modifyElem
.
getElementsByTagName
(
"
p
"
);
elem
[
0
].
textContent
=
match
[
3
];
}
else
if
(
match
[
2
]
===
"
deadline
"
){
const
elem
=
modifyElem
.
getElementsByTagName
(
"
i
"
);
var
date
=
match
[
3
].
split
(
"
/
"
);
if
(
date
.
length
!==
3
)
{
alert
(
"
duedate input format is wrong
"
);
return
;
}
date
[
0
]
=
date
[
0
].
trim
();
// spaces are allowed in input date format " yyyy / MM / dd "
date
[
1
]
=
date
[
1
].
trim
();
date
[
2
]
=
date
[
2
].
trim
();
elem
[
0
].
textContent
=
date
[
0
]
+
"
/
"
+
date
[
1
]
+
"
/
"
+
date
[
2
];
}
}
else
if
(
resolveTodoRegex
.
test
(
inputContent
))
{
let
match
=
inputContent
.
match
(
resolveTodoRegex
);
if
(
!
match
||
match
.
length
!==
1
)
{
alert
(
"
Failed to get resolve element
"
);
return
;
}
resolveTodo
(
parseInt
(
match
[
0
]));
}
else
if
(
deleteTodoRegex
.
test
(
inputContent
))
{
let
match
=
inputContent
.
match
(
deleteTodoRegex
);
if
(
!
match
||
match
.
length
!==
1
)
{
alert
(
"
Failed to get delete element
"
);
return
;
}
deleteTodo
(
parseInt
(
match
[
0
]));
}
else
if
(
updateTodoRegex
.
test
(
inputContent
))
{
for
(
var
i
=
1
;
i
<
id
;
i
++
)
{
updateOverdueStatus
(
i
);
}
}
else
{
var
s
=
"
operation
\"
"
+
inputContent
.
split
(
"
"
)[
0
]
+
"
\"
is not supported
"
;
alert
(
s
);
}
}
}
}
})
})
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment