Skip to content

Commit

Permalink
add search functionality + many small fixes
Browse files Browse the repository at this point in the history
data-related changes:

- use lzma instead of gzip, b/c it provides way better compression.
  and merge all ayat parts into one (one imlaai & one uthmani).
  use `-1e`, as it's the lowest level that provides the highest possible
  compression for both of these files.

- remove the space after alef+fatha+waw+fatha in the data itself not code.
  see: aliftype/quran-data#17

interactivity fixes:

- remove the hash params when clicking "New".
  hash params are most likely introduced by the app itself not the user;
  the user would generally use the search params (if at all).

style fixes:

- improve the dropdown list in darkmode on Blink-based browsers.
- fix the top margin inside the options dialog.
- fix the top padding of #selectors.
- fix the margin-bottom of #title.
- fix the almost invisible selection color in darkmode.
- fix tafsirhint end-of-ayah sign having a help cursor.
- fix tafsir fonts.
- show texts in a local font, then swap when the remote fonts load.

code fixes:

- load goatcounter from javascript, b/c if it's in the html, the page
  waits for it to load (or fail) before executing any javascript.

- rename all suar_* constants to sura_*.

- various code improvements and general clean up.
  • Loading branch information
noureddin committed Jul 16, 2024
1 parent 3dcd75c commit 6b3cc36
Show file tree
Hide file tree
Showing 35 changed files with 495 additions and 212 deletions.
32 changes: 18 additions & 14 deletions .index.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

<div id="options" class="contentcontainer">

<hr id="guide">
<!-- <hr id="guide"> -->

<div id="darkmode_option" class="option maybe-inline">
<label for="darkmode_input">الوضع الليلي؟&ensp;</label><input id="darkmode_input" type="checkbox" onchange="change_dark()">
Expand Down Expand Up @@ -130,16 +130,12 @@

<div>
<label for="sura_bgn">من<span class="sura">&nbsp;سورة</span>:&thinsp;</label>
<select id="sura_bgn">
<<!!sh -c 'i=0; cat res/suar-names | while read sura; do printf "<option value=%s>%s</option>" $i "$sura"; i=$((i + 1)); done | sed "1s/>/ selected>/" | tr -d "\n"'>>
</select>&thinsp;<label for="aaya_bgn"><span class="aaya">الآية:&thinsp;</span></label><select id="aaya_bgn"></select>
<select id="sura_bgn"></select>&thinsp;<label for="aaya_bgn"><span class="aaya">الآية:&thinsp;</span></label><select id="aaya_bgn"></select>&thinsp;<button class="search">🔍<span class="srcttl"> ابحث</span></button>
</div>

<div>
<label for="sura_end">إلى<span class="sura">&nbsp;سورة</span>:&thinsp;</label>
<select id="sura_end">
<<!!sh -c 'i=0; cat res/suar-names | while read sura; do printf "<option value=%s>%s</option>" $i "$sura"; i=$((i + 1)); done | sed "1s/>/ selected>/" | tr -d "\n"'>>
</select>&thinsp;<label for="aaya_end"><span class="aaya">الآية:&thinsp;</span></label><select id="aaya_end"></select>
<select id="sura_end"></select>&thinsp;<label for="aaya_end"><span class="aaya">الآية:&thinsp;</span></label><select id="aaya_end"></select>&thinsp;<button class="search">🔍<span class="srcttl"> ابحث</span></button>
</div>

<button title="حدد ما تريد مراجعته أو تسميعه، ثم اضغط على هذا الزر." id="ok">ابدأ</button>
Expand Down Expand Up @@ -193,23 +189,31 @@
<circle cx="105" cy="350" r="35" id="T" /><text x="880" y="350" style="visibility: hidden; opacity: 0">مد حركتين</text>
</svg>

<div id="tvc"><!-- tafsir-view container -->
<div id="tv"></div><!-- tafsir-view -->
<svg id="tvx" viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg"><!-- tafsir-view close-button -->
<div id="tvc" class="popup"><!-- tafsir-view container -->
<div id="tv" class="pc"></div><!-- tafsir-view -->
<svg class="x" viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg"><!-- tafsir-view close-button -->
<circle cx="5" cy="5" r="5" />
<line x1="2" y1="2" x2="8" y2="8" stroke-width="1.25" />
<line x1="8" y1="2" x2="2" y2="8" stroke-width="1.25" />
</svg>
</div>

<div id="sxc" class="popup"><!-- search container -->
<div id="sx" class="pc"><!-- search -->
<div id="sxi"><select id="sura_sx"></select><input id="sxq"></div>
<div id="sxr"></div><!-- search results -->
</div>
<svg class="x" viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg"><!-- search close-button -->
<circle cx="5" cy="5" r="5" />
<line x1="2" y1="2" x2="8" y2="8" stroke-width="1.25" />
<line x1="8" y1="2" x2="2" y2="8" stroke-width="1.25" />
</svg>
</div>

<script>window.goatcounter={path:location.href.replace(/[?#].*/,''),allow_frame:true}</script>
<!-- privacy-friendly statistics, no tracking of personal data, no need for GDPR consent; see goatcounter.com -->
<script data-goatcounter="https://recite.goatcounter.com/count"
async src="//gc.zgo.at/count.js"></script>
</div>
</div>

<script><<!!cat .scripts.gen.min.js>></script>

</body>
</html>
1 change: 1 addition & 0 deletions .lzma-d-min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .scripts.gen.min.js

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions .scripts.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
'use strict'

<<!!cat a.gen.js>>
<<!!cat mappings.js>>
<<!!cat tajlorligilumi.js>>
<<!!cat data.gen.js>>
<<!!cat versligilumi.js>>

// from: https://github.com/mathusummut/confetti.js. Copyright (c) 2018 MathuSum Mut. MIT License
<<!!cat res/confetti.min.js>>

<<!!#cat test.js>>
// remove the '#' in the previous line to perform the tests

<<!!cat tafsir.js>>
<<!!cat search.js>>
<<!!cat javascript.js>>

// gunzipSync from fflate with a few modifications (check .g.ts)
// MIT License; original source: https://github.com/101arrowz/fflate
<<!!cat .g.js>>

// lmza-d-min.js from LZMA-JS by Nathan Rugg; v2.3.0; License: MIT.
// https://github.com/LZMA-JS/LZMA-JS/blob/master/src/lzma-d-min.js
<<!!cat .lzma-d-min.js>>

<<!!cat z.js>>

window.goatcounter = { path: location.href.replace(/[?#].*/,''), allow_frame: true }
// privacy-friendly statistics, no tracking of personal data, no need for GDPR consent; see goatcounter.com
document.body.append(make_elem('script', { data: { goatcounter: 'https://recite.goatcounter.com/count' }, async: true, src: '//gc.zgo.at/count.js' }))
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@ index.html: .index.html .scripts.gen.min.js style.min.css .minify.pl

%.min.css: %.css
$C "$<" > "$@"
# cat "$<" > "$@"

%.min.js: %.js
$J "$<" > "$@"

%.gen.js: %.js
$P "$<" > "$@"

.scripts.gen.min.js: .scripts.js .g.js a.gen.js mappings.js tafsir.js tajlorligilumi.js data.gen.js versligilumi.js res/confetti.min.js javascript.js z.js
.scripts.gen.min.js: .scripts.js .g.js a.gen.js mappings.js tafsir.js search.js tajlorligilumi.js data.gen.js versligilumi.js res/confetti.min.js javascript.js z.js
$P "$<" | perl -CDAS -pe 's/const +say += +console\.log//' | $J | perl -pe 's/;?\s*\Z//' > "$@"
# $P "$<" > "$@"

Expand Down
45 changes: 35 additions & 10 deletions a.gen.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
// with similar names, eg scroll_to_top. I also use it for variables and consts.
// The only exception is the Q* shorthand functions defined next.

// const say = console.log
const range = (i) => [...Array(i).keys()]

// Q*, el_*
Expand All @@ -16,6 +15,27 @@ Element.prototype.Q = Element.prototype.querySelector
Element.prototype.Qall = Element.prototype.querySelectorAll
// Element.prototype.Qid = Element.prototype.getElementById

function make_elem (tag, opts={}) {
const el = document.createElement(tag)
for (let opt in opts)
if (opt === 'data')
for (let k in opts[opt])
el.dataset[k] = opts[opt][k]
else
el[opt] = opts[opt]
return el
}

function make_svgelem (tag, attrs={}, opts={}) {
const el = document.createElementNS("http://www.w3.org/2000/svg", tag)
for (let attr in attrs)
el.setAttribute(attr, attrs[attr])
return el
}

const spinner = make_svgelem('svg', { id: 'spinner-svg', viewBox: '0 0 100 100' })
spinner.appendChild(make_svgelem('circle', { id: 'spinner', cx: 50, cy: 50, r: 35, fill: 'none', 'stroke-width': '10', 'stroke-dasharray': '40 30' }))

const L = location
const S = localStorage
// defaults are not stored:
Expand Down Expand Up @@ -100,7 +120,12 @@ const el_J = Qid("J")
const el_T = Qid("T")
const el_tvc = Qid("tvc")
const el_tv = Qid("tv")
const el_tvx = Qid("tvx")
const el_sxc = Qid("sxc")
const el_sx = Qid("sx")
const el_sxi = Qid("sxi")
const el_sura_sx = Qid("sura_sx")
const el_sxq = Qid("sxq")
const el_sxr = Qid("sxr")


const __scroll_top = (el) => el.scrollTo({ top: 0 })
Expand Down Expand Up @@ -143,8 +168,8 @@ const toascii = (n) => // convert numerals to ASCII
.replace(/٨/g, '8')
.replace(/٩/g, '9')

const sura_bgn_length = () => el_sura_bgn.value === '' ? 0 : suar_length[+el_sura_bgn.value]
const sura_end_length = () => el_sura_end.value === '' ? 0 : suar_length[+el_sura_end.value]
const sura_bgn_length = () => el_sura_bgn.value === '' ? 0 : sura_length[+el_sura_bgn.value]
const sura_end_length = () => el_sura_end.value === '' ? 0 : sura_length[+el_sura_end.value]
const sura_bgn_val = () => el_sura_bgn.value === '' ? '' : +el_sura_bgn.value
const sura_end_val = () => el_sura_end.value === '' ? '' : +el_sura_end.value
const aaya_bgn_val = () => el_aaya_bgn.value === '' ? '' : +el_aaya_bgn.value
Expand Down Expand Up @@ -278,8 +303,8 @@ function valid_inputs (sura_bgn, aaya_bgn, sura_end, aaya_end) { // {{{
sura_end !== '' && aaya_end !== '' &&
sura_bgn <= sura_end &&
(aaya_bgn <= aaya_end || sura_bgn < sura_end) &&
1 <= aaya_bgn && aaya_bgn <= suar_length[sura_bgn] &&
1 <= aaya_end && aaya_end <= suar_length[sura_end]
1 <= aaya_bgn && aaya_bgn <= sura_length[sura_bgn] &&
1 <= aaya_end && aaya_end <= sura_length[sura_end]
)
} // }}}

Expand Down Expand Up @@ -435,10 +460,10 @@ function make_title (sura_bgn, aaya_bgn, sura_end, aaya_end) { // {{{
aaya_bgn = +aaya_bgn
sura_end = +sura_end
aaya_end = +aaya_end
const s_bgn_len = suar_length[sura_bgn - 1]
const s_end_len = suar_length[sura_end - 1]
const s_bgn_txt = suar_name[sura_bgn - 1]
const s_end_txt = suar_name[sura_end - 1]
const s_bgn_len = sura_length[sura_bgn - 1]
const s_end_len = sura_length[sura_end - 1]
const s_bgn_txt = sura_name[sura_bgn - 1]
const s_end_txt = sura_name[sura_end - 1]
// converts to Eastern Arabic numerals, and state the first and last in words
const a_bgn_txt = aaya_bgn === 1? 'الأولى' : aaya_bgn === s_bgn_len? toarab(aaya_bgn) + nbsp+'الأخيرة' : toarab(aaya_bgn)
const a_end_txt = aaya_end === 1? 'الأولى' : aaya_end === s_end_len? toarab(aaya_end) + nbsp+'الأخيرة' : toarab(aaya_end)
Expand Down
38 changes: 29 additions & 9 deletions a.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
// with similar names, eg scroll_to_top. I also use it for variables and consts.
// The only exception is the Q* shorthand functions defined next.

// const say = console.log
const range = (i) => [...Array(i).keys()]

// Q*, el_*
Expand All @@ -16,6 +15,27 @@ Element.prototype.Q = Element.prototype.querySelector
Element.prototype.Qall = Element.prototype.querySelectorAll
// Element.prototype.Qid = Element.prototype.getElementById

function make_elem (tag, opts={}) {
const el = document.createElement(tag)
for (let opt in opts)
if (opt === 'data')
for (let k in opts[opt])
el.dataset[k] = opts[opt][k]
else
el[opt] = opts[opt]
return el
}

function make_svgelem (tag, attrs={}, opts={}) {
const el = document.createElementNS("http://www.w3.org/2000/svg", tag)
for (let attr in attrs)
el.setAttribute(attr, attrs[attr])
return el
}

const spinner = make_svgelem('svg', { id: 'spinner-svg', viewBox: '0 0 100 100' })
spinner.appendChild(make_svgelem('circle', { id: 'spinner', cx: 50, cy: 50, r: 35, fill: 'none', 'stroke-width': '10', 'stroke-dasharray': '40 30' }))

const L = location
const S = localStorage
// defaults are not stored:
Expand Down Expand Up @@ -74,8 +94,8 @@ const toascii = (n) => // convert numerals to ASCII
.replace(/٨/g, '8')
.replace(/٩/g, '9')

const sura_bgn_length = () => el_sura_bgn.value === '' ? 0 : suar_length[+el_sura_bgn.value]
const sura_end_length = () => el_sura_end.value === '' ? 0 : suar_length[+el_sura_end.value]
const sura_bgn_length = () => el_sura_bgn.value === '' ? 0 : sura_length[+el_sura_bgn.value]
const sura_end_length = () => el_sura_end.value === '' ? 0 : sura_length[+el_sura_end.value]
const sura_bgn_val = () => el_sura_bgn.value === '' ? '' : +el_sura_bgn.value
const sura_end_val = () => el_sura_end.value === '' ? '' : +el_sura_end.value
const aaya_bgn_val = () => el_aaya_bgn.value === '' ? '' : +el_aaya_bgn.value
Expand Down Expand Up @@ -209,8 +229,8 @@ function valid_inputs (sura_bgn, aaya_bgn, sura_end, aaya_end) { // {{{
sura_end !== '' && aaya_end !== '' &&
sura_bgn <= sura_end &&
(aaya_bgn <= aaya_end || sura_bgn < sura_end) &&
1 <= aaya_bgn && aaya_bgn <= suar_length[sura_bgn] &&
1 <= aaya_end && aaya_end <= suar_length[sura_end]
1 <= aaya_bgn && aaya_bgn <= sura_length[sura_bgn] &&
1 <= aaya_end && aaya_end <= sura_length[sura_end]
)
} // }}}

Expand Down Expand Up @@ -366,10 +386,10 @@ function make_title (sura_bgn, aaya_bgn, sura_end, aaya_end) { // {{{
aaya_bgn = +aaya_bgn
sura_end = +sura_end
aaya_end = +aaya_end
const s_bgn_len = suar_length[sura_bgn - 1]
const s_end_len = suar_length[sura_end - 1]
const s_bgn_txt = suar_name[sura_bgn - 1]
const s_end_txt = suar_name[sura_end - 1]
const s_bgn_len = sura_length[sura_bgn - 1]
const s_end_len = sura_length[sura_end - 1]
const s_bgn_txt = sura_name[sura_bgn - 1]
const s_end_txt = sura_name[sura_end - 1]
// converts to Eastern Arabic numerals, and state the first and last in words
const a_bgn_txt = aaya_bgn === 1? 'الأولى' : aaya_bgn === s_bgn_len? toarab(aaya_bgn) + nbsp+'الأخيرة' : toarab(aaya_bgn)
const a_end_txt = aaya_end === 1? 'الأولى' : aaya_end === s_end_len? toarab(aaya_end) + nbsp+'الأخيرة' : toarab(aaya_end)
Expand Down
Loading

0 comments on commit 6b3cc36

Please sign in to comment.