diff options
-rwxr-xr-x | components/post-preview.sh | 6 | ||||
-rw-r--r-- | header.sh | 8 | ||||
-rwxr-xr-x | index.sh | 14 | ||||
-rwxr-xr-x | nav.sh | 9 | ||||
-rwxr-xr-x | pages/article.sh | 2 | ||||
-rwxr-xr-x | pages/home.sh | 15 | ||||
-rw-r--r-- | static/key-press.mp3 | bin | 0 -> 2632 bytes | |||
-rw-r--r-- | static/manifest.json | 15 | ||||
-rw-r--r-- | static/navigator.js | 87 | ||||
-rw-r--r-- | static/styles.css | 30 | ||||
-rwxr-xr-x | utils/parse-article-content.sh | 62 | ||||
-rwxr-xr-x | utils/parse-article.sh | 4 |
12 files changed, 226 insertions, 26 deletions
diff --git a/components/post-preview.sh b/components/post-preview.sh index dbbf663..2708060 100755 --- a/components/post-preview.sh +++ b/components/post-preview.sh @@ -1,13 +1,13 @@ #!/bin/bash -source $SCRIPT_DIR/utils/parse-article.sh +DO_NOT_PROCESS_HTML=true source $SCRIPT_DIR/utils/parse-article.sh cat <<POST <section class="post-preview"> <div class="post-header-preview"> - <h5 class="post-title">$ stat -c "%w" \\<br/> > $ARTICLE_FILE</h5> + <h5 class="post-title">$ stat -c "%w" \\<br/> > $ARTICLE_FILE_SANITIZED</h5> <small>$ARTICLE_BYTES</small> <br/> - <time>$(stat --format="Criado em: %w" $ARTICLE_FILE)</time> + <time>$ARTICLE_TIME</time> <ul class="tags"> $( @@ -21,18 +21,18 @@ cat <<HEADER </style> <script type="text/javascript"> - let mobileText = '$HEADER_TITLE_MOBILE'; - let desktopText = '$HEADER_TITLE'; + let mobileText = '${HEADER_TITLE_MOBILE//\\/\\\\}'; + let desktopText = '${HEADER_TITLE//\\/\\\\}'; </script> <script type="text/javascript" src="/static/header.js"></script> <script type="text/javascript" src="/static/navigator.js"></script> <header id="top-header"> <h1 id="header-title" class="desktop header-title"> - $ <span class="text">${HEADER_TITLE/;/<br\/>$ }<br/></span> + $ <span class="text">${HEADER_TITLE//;/<br\/>$ }<br/></span> </h1> <h1 id="header-title-mobile" class="mobile header-title"> - $ <span class="text">${HEADER_TITLE_MOBILE/;/<br\/>$ }<br/></span> + $ <span class="text">${HEADER_TITLE_MOBILE//;/<br\/>$ }<br/></span> </h1> </header> HEADER @@ -10,7 +10,7 @@ source ./config.sh RESPONSE_CONTENT_TYPE="text/html" STATUS=200 -HEADER_TITLE='cd programadores/;cd Jefferson\\ Julio/;source jefferson.sh' +HEADER_TITLE='cd programadores/;cd Jefferson\ Julio/;source jefferson.sh' HEADER_TITLE_MOBILE="$HEADER_TITLE" urldecode() { : "${*//+/ }"; echo -e "${_//%/\\x}"; } @@ -23,6 +23,10 @@ strip-html-tags () { echo "$1" | sed 's/<[^>]*>//g' } +sanitize-filename () { + echo "${1// /\\ }" +} + html () { cat <<HTML <html lang="pt-br"> @@ -62,8 +66,8 @@ router () { ;; /$ARTICLES_PATH*.txt) ARTICLE_FILE=.$REQUEST_URI - HEADER_TITLE="ARTICLE_FILE=$ARTICLE_FILE source pages/article.sh" - HEADER_TITLE_MOBILE="export ARTICLE_FILE=$ARTICLE_FILE;source pages/article.sh" + HEADER_TITLE="ARTICLE_FILE=$(sanitize-filename "$ARTICLE_FILE");source pages/article.sh" + HEADER_TITLE_MOBILE="ARTICLE_FILE=$(sanitize-filename "$ARTICLE_FILE");source pages/article.sh" BODY=$(source ./pages/article.sh) ;; /json) @@ -78,8 +82,8 @@ JSON ;; *) STATUS=404 - HEADER_TITLE="REQUEST_FILE=.$REQUEST_URI source page.sh" - HEADER_TITLE_MOBILE="export REQUEST_FILE=.$REQUEST_URI;source page.sh" + HEADER_TITLE="REQUEST_FILE=.$(sanitize-filename "$REQUEST_URI");source page.sh" + HEADER_TITLE_MOBILE="$HEADER_TITLE" BODY="<p class='err-404'>404: .$REQUEST_URI: Arquivo ou diretório inexistente</p>" ;; esac @@ -8,13 +8,10 @@ cat <<NAV display: inline-flex; background-color: var(--primary-fg); height: 40px; - width: 100%; + width: calc(100% - 50px); align-items: center; - } - - .nav-header { - padding-left: 25px; - padding-right: 25px; + margin-left: 25px; + margin-right: 25px; } .nav-header a { diff --git a/pages/article.sh b/pages/article.sh index b50d922..59a33b6 100755 --- a/pages/article.sh +++ b/pages/article.sh @@ -14,7 +14,7 @@ cat <<ARTICLE <article class="container"> <section> <div class="post-header"> - <h4 class="post-title">$ stat -c "%s %w %z" \\ <br/> > $ARTICLE_FILE</h4> + <h4 class="post-title">$ stat -c "%s %w %z" \\ <br/> > $ARTICLE_FILE_SANITIZED</h4> <small>$ARTICLE_BYTES</small> <br/> <time>$ARTICLE_TIME</time> <br/> diff --git a/pages/home.sh b/pages/home.sh index c9a9966..02adf53 100755 --- a/pages/home.sh +++ b/pages/home.sh @@ -13,8 +13,19 @@ WELCOME print-all-articles () { # Find all articles and sort by date of creation - for i in $(find $ARTICLES_PATH -type f -name '*.txt' -printf "%T@ %p\n" | sort -rn | cut -b 23-); do - ARTICLE_FILE="${i/* /}" source $SCRIPT_DIR/components/post-preview.sh + IFS=';' read -ra ARTICLE_LIST <<< "$( + find $ARTICLES_PATH \ + -type f \ + -name '*.txt' \ + -printf "%T@ %p\n" | + sort -rn | + cut -b 23- | + sed 's/^ //g' | + tr '\n' ';' + )" + + for i in "${ARTICLE_LIST[@]}"; do + ARTICLE_FILE="$i" source $SCRIPT_DIR/components/post-preview.sh done } diff --git a/static/key-press.mp3 b/static/key-press.mp3 Binary files differnew file mode 100644 index 0000000..c52f485 --- /dev/null +++ b/static/key-press.mp3 diff --git a/static/manifest.json b/static/manifest.json new file mode 100644 index 0000000..b700497 --- /dev/null +++ b/static/manifest.json @@ -0,0 +1,15 @@ +{ + "name": "jefferson.sh", + "short_name": "jefferson.sh", + "description": "Blog do Jefferson", + "icons": [ + { + "src": "static/favicon.png", + "sizes": "192x192", + "type": "image/png" + } + ], + "display": "fullscreen", + "start_url": "/", + "orientation": "portrait" +} diff --git a/static/navigator.js b/static/navigator.js new file mode 100644 index 0000000..a4385fa --- /dev/null +++ b/static/navigator.js @@ -0,0 +1,87 @@ +let pageTransitionLock = false; +let pageTransitionAnimating = false; +let pageTransitionCleared = false; + +function bindAllRelativeAnchors() { + document.querySelectorAll('a[href^="/"]:not([navigator-bind])').forEach((el) => { + el.setAttribute('navigator-bind', 'true'); + el.addEventListener('click', (e) => { + e.preventDefault(); + goToPage((new URL(e.target.href)).pathname); + }); + }); +} + +function showContentIfPageIsLoaded () { + if (!pageTransitionLock) { + showContent(() => { + pageTransitionAnimating = false; + bindAllRelativeAnchors(); + }); + } +} + +function goToPage(url, cb) { + if (pageTransitionLock) return; + pageTransitionLock = true; + pageTransitionAnimating = true; + pageTransitionCleared = false; + + let footerCommandPrompt = document.querySelector('#footer-command-prompt .text'); + history.pushState({date: "new url -> " + url}, url, url); + + fetch(url).then((response) => { + response.text().then(html => { + let parser = new DOMParser(); + let htmlDOM = parser.parseFromString(html, 'text/html'); + + let mainContainer = document.querySelector('main'); + + function swapHTMLContent() { + if (!pageTransitionCleared) { + window.requestAnimationFrame(swapHTMLContent); + return; + } + + mainContainer.innerHTML = ''; + mainContainer.innerHTML = htmlDOM.querySelector('main').innerHTML; + if (headerAnimationTerminated) showContent(bindAllRelativeAnchors); + pageTransitionLock = false; + } + + swapHTMLContent(); + }); + }); + + typingAnimation( + footerCommandPrompt, + 'clear', + 0, + () => { + clearHeaderTerminal(() => { + hideContent(); + pageTransitionCleared = true; + footerCommandPrompt.innerHTML = ''; + if (url == "/") { + headerTerminalExecute( + "source jefferson.sh", + "source jefferson.sh", + showContentIfPageIsLoaded, + ); + } else if (url == "/contato") { + headerTerminalExecute( + "source pages/contato.sh", + "source pages/contato.sh", + showContentIfPageIsLoaded, + ); + } else if (url.match(/\/artigos/)) { + headerTerminalExecute( + `ARTICLE_FILE=.${decodeURI(url).replace(' ', '\\ ')};source pages/article.sh`, + `ARTICLE_FILE=.${decodeURI(url).replace(' ', '\\ ')};source pages/article.sh`, + showContentIfPageIsLoaded, + ); + } + }); + } + ); +} diff --git a/static/styles.css b/static/styles.css index e84dc56..d45bdd1 100644 --- a/static/styles.css +++ b/static/styles.css @@ -275,7 +275,7 @@ header > h2 { } .pad-left, .pad-right { - width: 215px; + width: 180px; } } @@ -347,13 +347,37 @@ header > h2 { border-radius: 8px; } ::-webkit-scrollbar-thumb:hover{ - background: var(--primary-bg); + background: #059233; } ::-webkit-scrollbar-track{ background: var(--primary-bg); border-radius: 7px; } -::-webkit-scrollbar-track:hover { +*::selection { background: var(--primary-fg); + color: var(--primary-bg); +} + +*::-moz-selection { + background: var(--primary-fg); + color: var(--primary-bg); +} + +pre { + counter-reset: line; + display: block; + border: 1px solid; + padding: 4px; +} + +code { + counter-increment: line; +} + +code:before { + content: counter(line); + margin-right: 8px; + margin-left: 4px; + -webkit-user-select: none; } diff --git a/utils/parse-article-content.sh b/utils/parse-article-content.sh new file mode 100755 index 0000000..40593c5 --- /dev/null +++ b/utils/parse-article-content.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +# Skip file metadata, first 3 lines + +sanitize-html-entities () { + echo "$1" | + sed 's/</\</g' | + sed 's/>/\>/g' +} + +parse-article-content-file () { + local PRE_TAG= + local IGNORE_NEXT_PRE_TAG= + local INSIDE_PRE_TAG= + local CONTENT + local TLINE= + + while IFS= read -r line; do + TLINE="$line" + + if [ -z "$INSIDE_PRE_TAG" ]; then + echo "$line" | grep '<pre role="code"' > /dev/null + if [ $? -eq 0 ]; then + PRE_TAG=$line + INSIDE_PRE_TAG=1 + TLINE="$line <!-- code-start -->" + fi + else + echo "$line" | grep '<pre' > /dev/null + if [ "$?" -eq 0 ]; then + IGNORE_NEXT_PRE_TAG=1 + TLINE="<code>$(sanitize-html-entities "$line")</code>" + fi + + echo "$line" | grep '</pre>' > /dev/null + if [ $? -eq 0 ]; then + if [ -n "$IGNORE_NEXT_PRE_TAG" ]; then + IGNORE_NEXT_PRE_TAG="" + TLINE="<code>$(sanitize-html-entities "$line")</code>" + else + INSIDE_PRE_TAG="" + PRE_TAG="" + TLINE="$line<!-- code-end -->" + fi + else + TLINE="<code>$(sanitize-html-entities "$line")</code>" + fi + + fi + + CONTENT="${CONTENT} +$TLINE" + done <<< $(echo "$ARTICLE_FILE_CONTENT" | tail -n +3) + + echo "$CONTENT" +} + +if [ "$DO_NOT_PROCESS_HTML" = "true" ]; then + ARTICLE_CONTENT=$(echo "$ARTICLE_FILE_CONTENT" | tail -n +3) +else + ARTICLE_CONTENT=$(parse-article-content-file) +fi diff --git a/utils/parse-article.sh b/utils/parse-article.sh index c3e540a..b64c0ff 100755 --- a/utils/parse-article.sh +++ b/utils/parse-article.sh @@ -1,6 +1,7 @@ #!/bin/bash ARTICLE_TITLE=$(basename "$ARTICLE_FILE") +ARTICLE_FILE_SANITIZED="$(sanitize-filename "$ARTICLE_FILE")" # Pick all file content ARTICLE_FILE_CONTENT=$(cat "$ARTICLE_FILE") @@ -8,8 +9,7 @@ ARTICLE_FILE_CONTENT=$(cat "$ARTICLE_FILE") # The first 3 lines of the file are metadata information ARTICLE_METADATA=$(echo "$ARTICLE_FILE_CONTENT" | head -n 3) -# Skip file metadata, first 3 lines -ARTICLE_CONTENT=$(echo "$ARTICLE_FILE_CONTENT" | tail -n +3) +source $SCRIPT_DIR/utils/parse-article-content.sh # Tags are placed on the first line of the file, delimited by commas IFS=',' read -ra ARTICLE_TAGS <<< "$(echo "$ARTICLE_METADATA" | head -n 1)" |