diff --git a/css/TCS_components.css b/css/TCS_components.css index d25c931..17cf59a 100644 --- a/css/TCS_components.css +++ b/css/TCS_components.css @@ -7,14 +7,14 @@ /* simple tags styles */ #TCS_main { - width:100%; + width: 100%; max-width: 1200px; display: flex; - flex-wrap:wrap !important; - + flex-wrap: wrap !important; + padding: 0.5em 0.5em; - + color: var(--SEARCH_COLOR); background-color: var(--PRIMARY_BKG); border: 2px solid var(--TIER_COLOR); @@ -32,7 +32,7 @@ */ @media screen and (max-width: 799px) { #TCS_main { - + font-size: var(--MOBILE_FONT-SIZE); font-weight: var(--MOBILE_FONT-WEIGHT); } @@ -48,7 +48,7 @@ #TCS_bricksWrapper { - display:flex; + display: flex; padding-bottom: 0px; overflow: hidden; white-space: nowrap; @@ -58,19 +58,19 @@ #TCS_backArrow { - width:60%; - height:60%; + width: 60%; + height: 60%; - padding:0px; - margin:auto 0px auto 0px; - background-color:var(--BRICK_ACTIVE); - -webkit-mask: url(../img/arrow.svg) no-repeat 50% 50%; + padding: 0px; + margin: auto 0px auto 0px; + background-color: var(--BRICK_ACTIVE); + -webkit-mask: url(../img/arrow.svg) no-repeat 50% 50%; mask: url(../img/arrow.svg) no-repeat 50% 50%; } #TCS_searchInput { - + align-self: flex-end; padding: 10px 0px 0px 1px; @@ -78,12 +78,13 @@ box-sizing: border-box; border: none; outline: none; - + cursor: text; + opacity: 1; color: var(--SEARCH_COLOR); - background-color: var(--SEARCH_BKG); + background-color: var(--SEARCH_BKG); } .input { @@ -110,10 +111,10 @@ button.TCS_searchButton { display: inline-flex; margin: auto 0px auto auto; - padding:0px; - border:0; + padding: 0px; + border: 0; - opacity:0.5; + opacity: 0.5; background-image: url("../img/search.svg"); background-repeat: no-repeat; @@ -122,14 +123,20 @@ button.TCS_searchButton { background-color: transparent; cursor: pointer; - height:25px; - width:25px; - max-width:25px; + + height: 25px; + width: 25px; + max-width: 25px; } button.TCS_searchButton:hover { opacity: 1; - } +} + + + + + @@ -143,9 +150,9 @@ ul.TCS_bricks { padding: 0px 0px 7px 0px; margin: 0px 0px 0px 0px; - + text-align: center; - + text-decoration: none; color: var(--BRICK_TEXT); font-family: var(--PRIMARY_FONT-FAMILY); @@ -153,7 +160,6 @@ ul.TCS_bricks { font-weight: var(--PRIMARY_FONT-WEIGHT); cursor: pointer; - } @@ -165,11 +171,11 @@ ul.TCS_bricks li { box-sizing: border-box; flex-wrap: nowrap; - + margin: 10px 6px 0px 0px; padding: 0.5em 0.5em 0.6em 0.5em; border-radius: 3px; - + } @@ -189,14 +195,14 @@ ul.TCS_bricks li { font-size: var(--SMALL_FONT-SIZE); font-weight: var(--SMALL_FONT-WEIGHT); - height:min-content; + height: min-content; padding: 6px 5px 5px 5px !important; margin: 0px 6px 0px 0px; letter-spacing: 0.07em; } - + .TCS_inactive { @@ -211,14 +217,16 @@ ul.TCS_bricks li { hr.TCS_hr { margin: auto 0px 0px 2px; + cursor: pointer; + border-bottom: 7px dashed var(--BRICK_BASE); - + transform: translateY(-45%); border-top: none; border-left: none; border-right: none; - + } @@ -228,23 +236,24 @@ hr.TCS_hr { overflow: visible; - height:25px !important; + height: 25px !important; width: 25px !important; transform: translate(15px, 5px); - background-color:var(--TIER_COLOR); - -webkit-mask: url(../img/icon.svg) no-repeat 50% 50%; + background-color: var(--TIER_COLOR); + -webkit-mask: url(../img/icon.svg) no-repeat 50% 50%; mask: url(../img/icon.svg) no-repeat 50% 50%; - + cursor: pointer; + } @media screen and (min-width:500px) and (max-width: 699px) { - + .TCS_tierIcon { - + transform: translate(10px, 5px); } } @@ -254,9 +263,9 @@ hr.TCS_hr { // */ @media screen and (max-width: 499px) { - + .TCS_tierIcon { - + transform: translate(5px, 5px); } } \ No newline at end of file diff --git a/css/TCS_globals.css b/css/TCS_globals.css index 873b904..9555b31 100644 --- a/css/TCS_globals.css +++ b/css/TCS_globals.css @@ -1,8 +1,8 @@ /* GLOBAL VARIABLES */ :root { - - --BRICK_BASE: rgb(1, 102, 255); + --BRICK_BASE: blue; + --BRICK_POST: rgb(1, 102, 255); --BRICK_ACTIVE: green; --BRICK_ACTIVE_LIGHT: rgb(6, 158, 6); diff --git a/css/TCS_styles.css b/css/TCS_styles.css index 5db41c7..4cd7f59 100644 --- a/css/TCS_styles.css +++ b/css/TCS_styles.css @@ -7,15 +7,25 @@ /* * */ - - * {margin:0; padding:0;} + +* { + margin: 0; + padding: 0; +} + +body.searchWaiting * { + + cursor: wait !important; +} + + .TCS_blogPost { - display:block; + display: block; - color:var(--HOVER_COLOR); + color: var(--HOVER_COLOR); width: 100%; padding: 20px 0px 0px 0px; @@ -30,81 +40,82 @@ .TCS_blogPost:hover { - + background-color: var(--TAB_BEHIND); - border-color:var(--BKG_COLOR); - - } + border-color: var(--BKG_COLOR); + +} .TCS_galleryButton { - - border-radius: 22px; - border: solid; - border-width:5px; - background-color:var(--BRICK_ACTIVE); - border-color: var(--BRICK_ACTIVE_LIGHT); - - color:rgb(216, 223, 226); - padding: 12px 14px 12px 14px; - - width:max-content; - height:min-content; - - margin: 0px auto 0px auto; - - cursor: pointer; - font-family: var(--PRIMARY_FONT-FAMILY); - font-size: 1em; + border-radius: 22px; + border: solid; + border-width: 5px; + background-color: var(--BRICK_ACTIVE); + border-color: var(--BRICK_ACTIVE_LIGHT); - line-height:1em; - font-weight: 400; - text-decoration: none; - text-align: center; + + color: rgb(216, 223, 226); + padding: 12px 14px 12px 14px; + + width: max-content; + height: min-content; + + margin: 0px auto 0px auto; + + cursor: pointer; + + font-family: var(--PRIMARY_FONT-FAMILY); + font-size: 1em; + + line-height: 1em; + font-weight: 400; + text-decoration: none; + text-align: center; } .TCS_galleryButton:hover { - - color:white; - padding:12px; - background-color:var(--BRICK_ACTIVE_LIGHT); + color: white; + padding: 12px; + + background-color: var(--BRICK_ACTIVE_LIGHT); border-color: var(--BRICK_ACTIVE); font-weight: 600; - } +} .TCS_galleryButton a { - - color:white; + + color: white; text-decoration: none; } .TCS_postUrl { - display:block; + display: block; margin: 15px auto 0 auto; text-align: center; - width:65%; + width: 65%; border-radius: 5%; - background-color:white; - padding:10px; + background-color: white; + padding: 10px; } .TCS_table .TCS_postUrl { - width:90% !important; - padding:0px !important; + width: 90% !important; + padding: 0px !important; } .TCS_caption { @@ -112,21 +123,21 @@ display: block; overflow-x: hidden; - + margin: 0px auto 0px auto; - width:80%; + width: 80%; padding: 12px; - background-color:var(--CAPTION_BKG); - color:var(--CAPTION_COLOR); - - font-family:var(--CAPTION_FONT_FAMILY); + background-color: var(--CAPTION_BKG); + color: var(--CAPTION_COLOR); + + font-family: var(--CAPTION_FONT_FAMILY); font-weight: 600; - + letter-spacing: 0.015em; - + border-radius: 10px; } @@ -136,7 +147,7 @@ color: var(--DATE_COLOR); background-color: var(--DATE_BKG); - width:min-content; + width: min-content; margin: 5px 20px 0px auto; @@ -148,44 +159,45 @@ .TCS_table { - display:table !important; - width:65%; - margin:0px auto 0px auto; + display: table !important; + width: 100%; + margin: 0px auto 0px auto; background-color: white; - padding:10px; - border-radius:10px; + padding: 10px; + border-radius: 10px; } .TCS_table table { - width:100%; - margin:0px; + width: 100%; + margin: 0px; text-align: center; } .TCS_table tr { - height: 100px!important; + height: 100px !important; } + .TCS_table td { - width:50%; + width: 50%; padding: 4px; background-size: contain; background-position: center; - + } .TCS_table td img { - width:100%; + width: 100%; } .TCS_blogPost .TCS_bricks { - - cursor:default; + + cursor: pointer; margin: 0px 0px 20px 20px; - + text-decoration: none; color: var(--BRICK_TEXT); @@ -200,7 +212,7 @@ .TCS_blogPost .TCS_bricks li { - + background-color: var(--BRICK_BASE); letter-spacing: 0.05em; text-decoration: none; @@ -208,18 +220,18 @@ .TCS_hidden { - display:none !important; + display: none !important; } .TCS_showing { - display:block !important; + display: block !important; } /* * FLEXBOX styles */ - .row { +.row { display: inline-flex; justify-content: left; flex-direction: row; @@ -249,6 +261,7 @@ ._15 { flex: 1.5; } + ._2 { flex: 2; } diff --git a/js/TagCloudSearch_HTML.js b/js/TagCloudSearch_HTML.js index 6ca7e03..b38b0c5 100644 --- a/js/TagCloudSearch_HTML.js +++ b/js/TagCloudSearch_HTML.js @@ -7,7 +7,8 @@ import { searchButtonListener_callback, resetSearch, clickBrick_tier, - addSearchText } from "./TagCloudSearch_UI.js" + addSearchText, + } from "./TagCloudSearch_UI.js" @@ -113,7 +114,6 @@ import { searchButtonListener_callback, searchBar.innerHTML = (message == null) ? "" : message; searchBar.classList.add("welcome"); searchBar.focus(); - } } diff --git a/js/TagCloudSearch_INIT.js b/js/TagCloudSearch_INIT.js index aba0a1e..ac5f2cf 100644 --- a/js/TagCloudSearch_INIT.js +++ b/js/TagCloudSearch_INIT.js @@ -23,7 +23,7 @@ import { validateTAGS } from "./TagCloudSearch_IO.js"; // GLOBAL DATA STRUCTURES // */ -export const MAX_TAG_LENGTH = 16; // chars +export const MAX_TAG_LENGTH = 15; // chars /* * TOTAL_TAGS = [][] @@ -150,6 +150,8 @@ function initTags(TCS_main) { } /* +// BUILD THE SEARCH BAR / BUTTON / START BRICKS +// // div -- TCS_main // - div TCS_tier // -- wrapper @@ -198,6 +200,7 @@ function initSearchBar(TCS_main) { searchButton.classList.add("column"); searchButton.classList.add("_1"); searchButton.classList.add("TCS_searchButton"); + searchButton.id = "TCS_searchBarButton"; newTier.appendChild( searchButton ); @@ -213,20 +216,23 @@ function initSearchBar(TCS_main) { // searchBar.addEventListener("keydown", (pressEvent) => { + // get the specific key + let key = pressEvent.keyCode || pressEvent.charCode; + // is the search text already too long? // stop adding new chars and return if (searchBar.innerHTML.length >= MAX_TAG_LENGTH) { - // get the specific key - let key = pressEvent.keyCode || pressEvent.charCode; if (( key == 8 ) || ( key == 46 )) { // backspace / delete return true; - + } else { pressEvent.preventDefault(); return false; } + } + return true; }); @@ -280,6 +286,11 @@ function setSearchWelcome(searchBar) { } + + + + + /* * */ diff --git a/js/TagCloudSearch_IO.js b/js/TagCloudSearch_IO.js index ea162a7..a3f7251 100644 --- a/js/TagCloudSearch_IO.js +++ b/js/TagCloudSearch_IO.js @@ -92,11 +92,11 @@ export async function sendSearchToServer() { if (fetchError == null) { console.log("TCS ERROR in sendSearchToServer: fetchError == null"); - console.log("RESPONSE=" + response.body); + if (response != null) console.log("RESPONSE=" + response.body); } else { console.log("TCS ERROR in sendSearchToServer: " + SEARCH_URL); - console.log("RESPONSE=" + response.body); + if (response!= null) console.log("RESPONSE=" + response.tcs_message); console.error( fetchError ); } return; diff --git a/js/TagCloudSearch_UI.js b/js/TagCloudSearch_UI.js index 2f7b470..e7236d0 100644 --- a/js/TagCloudSearch_UI.js +++ b/js/TagCloudSearch_UI.js @@ -27,6 +27,7 @@ import { sendSearchToServer } from "./TagCloudSearch_IO.js" * clear the SEARCH_TAGS * clear the search bricks * reset the search bar + * reset the cursor to default pointer */ export function resetSearch() { @@ -38,10 +39,8 @@ export function resetSearch() { clearTierBricks(); } - - // change the cursor back - document.body.style.cursor = "default"; + normalCursor(); } @@ -78,7 +77,7 @@ export function removeTierBricks() { * [1][second tier of tags added, tag, tag...] */ export const newTagsListener_callback = (rawTags) => { - + // did the search come up empty? if (rawTags == null || rawTags.length == 0) { return; @@ -105,6 +104,7 @@ export const newTagsListener_callback = (rawTags) => { newTier = createBricksTier(index + 1, newTags) TCS_main.appendChild(newTier) + } @@ -321,8 +321,24 @@ export function searchBarListener_callback( wrapper, theUL, searchBar, pressEven } - if (trimText != "") { + + if (trimText != "") { // trimText contains search bar input from user + +// 11/2022 +// trying to catch invalid input into search bar +// one step towards preventing SQL injection attack +// be careful not to reject tags containing a space ' ' +// + + if (! (isAlphaNum(trimText))) { + searchBar.innerHTML = ""; + pressEvent.preventDefault(); + alert("Only letters and numbers allowed in TCS search"); + return false; + } + + // WE GOT ONE! if ( addBrickToSearch( theUL, trimText) ) { @@ -403,7 +419,7 @@ export function searchButtonListener_callback(searchBar, event) { } // change the cursor - document.body.style.cursor = "wait"; + waitCursor(); // SEND THE SEARCH! // search for everything in SEARCH_TAGS @@ -420,10 +436,6 @@ export function searchButtonListener_callback(searchBar, event) { - - - - ///////////////////////////////////////////////////////////////////////////////////// // add a new tag to SEARCH_TAGS if it doesn't exist already @@ -446,6 +458,49 @@ export function addSearchText(theText) { } + + + + +///////////////////////////////////////////////////////////////////////////////////// +// CHANGE THE CURSOR TO WAIT DURING SEARCH AND BACK AGAIN +// +// 1/2023 -- this is still a work in progress +// +//////////////////////////////////////////////////////////////////////////////////// + +function waitCursor() { + + document.body.classList.add('searchWaiting'); + + // have to force the button + let searchButton = document.getElementById("TCS_searchBarButton"); + searchButton.style.cursor = "wait"; +} + + +function normalCursor() { + + document.body.classList.remove('searchWaiting'); + + // have to force the button + let searchButton = document.getElementById("TCS_searchBarButton"); + searchButton.style.cursor = "pointer"; +} + + + + +/* + * does the search bar input contain only valid alphanumeric chars + */ +function isAlphaNum( text ) { + + const letterNumber = /^[0-9a-zA-Z\s]+$/; + return (text.match( letterNumber )); +} + + /* * */