├── .babelrc ├── .gitignore ├── .jshintrc ├── .sass-cache └── 40ef6696ce83a3a06fade2e81111f51d28ff6f68 │ └── styles.scssc ├── 153.html ├── CNAME ├── CONTRIBUTING.md ├── README.md ├── ajax-loader.gif ├── android-icon-144x144.png ├── android-icon-192x192.png ├── android-icon-36x36.png ├── android-icon-48x48.png ├── android-icon-72x72.png ├── android-icon-96x96.png ├── api ├── searchApi.js └── word.js ├── apple-icon-114x114.png ├── apple-icon-120x120.png ├── apple-icon-144x144.png ├── apple-icon-152x152.png ├── apple-icon-180x180.png ├── apple-icon-57x57.png ├── apple-icon-60x60.png ├── apple-icon-72x72.png ├── apple-icon-76x76.png ├── apple-icon-precomposed.png ├── apple-icon.png ├── browserconfig.xml ├── build ├── bundle.935d01b59593a21c2947.js ├── bundle.js └── index.html ├── clear.html ├── create-directories.sh ├── createRoots.html ├── createbranches.html ├── crossReferenceCombiner.html ├── css └── layout.css ├── data ├── bible.js ├── crossReferences.js ├── extra-dictionary.js ├── greek4.js ├── hebrew-with-morph5.js ├── hebrew.js ├── hebrewWithoutPointing.js ├── kjvdwyer7.js ├── literalConsistent.js ├── literalConsistentExtra.js ├── morphology.js ├── strongs-dictionary.js ├── strongs-greek-dictionary.js ├── strongsObjectRoots.js ├── strongsObjectWithFamilies2.js └── web3.js ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon-96x96.png ├── favicon.ico ├── googlef41cf4fef494a76d.html ├── greekReplaceAccents.html ├── hebrew-test.html ├── help └── index.html ├── icon-128.png ├── index.html ├── javascripture.svg ├── lib ├── MorphCodes.js ├── MorphParse.js ├── json2.js ├── raphael-min.js └── raphael.pie.js ├── literalConsistentHebrew.html ├── manifest.json ├── ms-icon-144x144.png ├── ms-icon-150x150.png ├── ms-icon-310x310.png ├── ms-icon-70x70.png ├── package-lock.json ├── package.json ├── parsing.txt ├── pie.html ├── postcss.config.js ├── promo ├── large.png ├── marquee.png ├── screenshot.png └── small.png ├── redirect.html ├── root test.txt ├── src ├── actions │ └── index.js ├── app.js ├── components │ ├── _colors.scss │ ├── _dimensions.scss │ ├── add-column-button │ │ ├── index.js │ │ └── style.scss │ ├── bookmarks │ │ ├── bookmark.js │ │ ├── index.js │ │ └── styles.scss │ ├── cross-references │ │ ├── index.js │ │ └── styles.scss │ ├── dock │ │ ├── index.js │ │ └── style.scss │ ├── footer │ │ ├── index.js │ │ └── styles.scss │ ├── keyboard-shortcuts.js │ ├── reference-selector-mobile │ │ ├── index.js │ │ └── style.scss │ ├── reference-selector │ │ ├── book-control.js │ │ ├── index.js │ │ └── styles.scss │ ├── reference-wrapper │ │ ├── index.js │ │ └── style.scss │ ├── reference │ │ ├── bookmarker.js │ │ ├── chapter.js │ │ ├── index.js │ │ ├── single-reference.js │ │ ├── styles.scss │ │ ├── verse-number.js │ │ ├── verse.js │ │ ├── word-single.js │ │ └── word.js │ ├── remove-column-button │ │ ├── index.js │ │ └── style.scss │ ├── root.js │ ├── search │ │ ├── index.js │ │ ├── search-block.js │ │ ├── search-link.js │ │ └── styles.scss │ ├── strongs-color.js │ ├── svg │ │ ├── add.js │ │ ├── book.js │ │ ├── bookmark.js │ │ ├── cancel.js │ │ ├── cog.js │ │ ├── eye.js │ │ ├── picker.js │ │ ├── remove.js │ │ ├── search.js │ │ ├── sync-disabled.js │ │ └── sync.js │ ├── sync-button │ │ ├── index.js │ │ └── style.scss │ ├── tray-filter │ │ └── styles.scss │ ├── tray-list.js │ ├── trays │ │ ├── bookmarks.js │ │ ├── filter.js │ │ ├── goto.js │ │ ├── index.js │ │ ├── search.js │ │ ├── settings.js │ │ ├── styles.scss │ │ ├── tray-button.js │ │ ├── tray-list.js │ │ └── word.js │ ├── version-selector │ │ ├── index.js │ │ └── styles.scss │ ├── word-details │ │ ├── index.js │ │ ├── kjv-def.js │ │ ├── styles.scss │ │ └── word-block.js │ └── word-highlight │ │ └── index.js ├── containers │ ├── FilterTrayLink.js │ ├── book-control.js │ ├── bookmark.js │ ├── bookmarker.js │ ├── bookmarks.js │ ├── chapter.js │ ├── cross-references.js │ ├── keyboard-shortcuts.js │ ├── kjv-def.js │ ├── reference-wrapper.js │ ├── reference.js │ ├── root.js │ ├── search-block.js │ ├── search-link.js │ ├── search.js │ ├── single-reference.js │ ├── verse.js │ ├── version-selector.js │ ├── visible-trays.js │ ├── word-block.js │ ├── word-details.js │ ├── word-highlight.js │ └── word-single.js ├── index.js ├── lib │ ├── morphology.js │ ├── reference.js │ ├── strip-pointing.js │ ├── stylizer │ │ ├── README.md │ │ └── index.js │ └── word.js └── reducers │ ├── bookmarks.js │ ├── cross-references.js │ ├── current-reference.js │ ├── index.js │ ├── reference-selector-mobile.js │ ├── reference.js │ ├── scroll-chapter.js │ ├── search-advanced.js │ ├── search-form.js │ ├── search-results.js │ ├── search-select.js │ ├── search-terms.js │ ├── settings.js │ ├── trayVisibilityFilter.js │ ├── trays.js │ ├── version.js │ ├── word-details.js │ └── word-highlight.js ├── sw.js ├── todo ├── web.php ├── webpack.config.js ├── worker.html ├── workers └── worker.js └── xmltojson.html /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ "es2015", "stage-1", "stage-2", "react" ] 3 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | nbproject/ 3 | node_modules/ 4 | css/.sass_cache/ 5 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "boss": true, 3 | "curly": true, 4 | "eqeqeq": true, 5 | "eqnull": true, 6 | "expr": true, 7 | "immed": true, 8 | "noarg": true, 9 | "onevar": false, 10 | "trailing": true, 11 | "undef": true, 12 | "unused": true, 13 | 14 | "browser": true, 15 | "node": true, 16 | 17 | "globals" : { 18 | /* MOCHA */ 19 | "describe" : false, 20 | "it" : false, 21 | "before" : false, 22 | "beforeEach" : false, 23 | "after" : false, 24 | "afterEach" : false 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.sass-cache/40ef6696ce83a3a06fade2e81111f51d28ff6f68/styles.scssc: -------------------------------------------------------------------------------- 1 | 3.3.0.rc.5 (Maptastic Maple) 2 | ab27ddca68fb13f1584e6ad9a4471b27ee2403f3 3 | o:Sass::Tree::RootNode :@children[o:Sass::Tree::RuleNode: 4 | @rule[I" body:ET:@selector_source_rangeo:Sass::Source::Range :@start_poso:Sass::Source::Position: 5 | @linei: @offseti: @end_poso; ;i;i : 6 | @fileI"sass/styles.scss; T:@importero: Sass::Importers::Filesystem: 7 | @rootI"#/Users/ben/Sites/Javascripture; T:@same_name_warningso:Set: 8 | @hash{: 9 | @tabsi:@parsed_ruleso:"Sass::Selector::CommaSequence: @members[o:Sass::Selector::Sequence;[o:#Sass::Selector::SimpleSequence ;[o:Sass::Selector::Element : 10 | @name[I" body; T:@namespace0;i:@filenameI"; T: @subject0: @sourceso;;{:@source_rangeo; ; o; ;i;i;o; ;i;i 11 | ;@;0;i;!@;i;!@;[o:Sass::Tree::PropNode;[I"background; T: @valueo: Sass::Script::Tree::Literal;&o: Sass::Script::Value::String;&I" 12 | white; T: 13 | @type:identifier: @options{;i;$o; ; o; ;i;i;o; ;i;i;@ ;@;i:@prop_syntax:new;[;i;$o; ; o; ;i;i;o; ;i;i;@ ;@:@name_source_rangeo; ; @.;o; ;i;i;@ ;@:@value_source_rangeo; ; o; ;i;i;@/;@ ;@;+@(;i;$o; ; o; ;i;i;o; ;i;i ;@ ;@:@has_childrenT;+@(o:Sass::Tree::CommentNode 14 | ;&[I"+/*# sourceMappingURL=styles.css.map */; T;): normal;[;i ;+@(:@templateI"Kbody { 15 | background: white; } 16 | 17 | /*# sourceMappingURL=styles.css.map */ 18 | ; T;i;$o; ; o; ;i;i;o; ;i;i;@ ;@;0T;+@( -------------------------------------------------------------------------------- /153.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | javascripture.xyz -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to JavaScripture 2 | 3 | Thanks for your interest in contributing to JavaScripture. 4 | 5 | There are many ways to contribute – reporting bugs, feature suggestions, fixing bugs, submitting pull requests for enhancements. 6 | 7 | ## Reporting Bugs, Asking Questions, Sending Suggestions 8 | 9 | We'd love to hear about any issues you have or ideas for new features. You can just [file a GitHub issue](https://github.com/scruffian/Javascripture/issues/), or [contact me](http://ben.blog/contact). 10 | 11 | ## Running JavaScripture Locally 12 | 13 | If you’d like to contribute code, first, you will need to run JavaScripture locally. Here is the short version: 14 | 15 | 1. Make sure you have git, node and npm installed 16 | 2. Clone this repository locally with git@github.com:scruffian/Javascripture.git 17 | 3. Execute npm start to install packages and start the server 18 | 4. Open http://localhost:7777 in your browser. I find it best to work in Firefox in private mode to avoid caching issues. 19 | 20 | ## Pull Requests 21 | 22 | When you have a patch ready to submit in your local version you need to submit a pull request so it can be reviewed before being merged. Here is a typical workflow: 23 | 24 | 1. Make sure your local repo is up to date: `git pull` 25 | 2. Create a new branch locally and check it out: `git checkout -b branch-name" 26 | 3. Add the files you have changed: `git add filename.js` 27 | 4. Commit the files: `git commit -m "Commit message goes here" 28 | 5. Push your local branch to the remote server: `git push --set-upstream origin branch-name` 29 | 6. Open the repo and use the GUI to create and submit a pull request from this branch: https://github.com/scruffian/javascripture 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Javascripture 2 | A tool for studying scripture, written in Javascript (React and Redux) 3 | 4 | ## Principles 5 | 6 | Javascripture is agnostic; it's purpose is to make it easier to access bible data. Doctrine is not a consideration in the interface or the data. If there are mistakes in a translation, these are preserved. This is important because: 7 | 8 | - it means the tool can be useful to all bible students, not just those of a particular denomination 9 | - it helps to remove our own bias from our bible study 10 | 11 | However Javascripture is heavily geared towards a "bible only" approach to study. This means that, as much as is practical, extra-biblical data is removed to reveal the inspired word as close to how it was revealed. This means that: 12 | 13 | - accents and pointing are removed from the original text (as these are later additions) 14 | - human "definitions" (like Strong's) are removed, as these are merely interpretations 15 | 16 | Instead the emphasis is on making it as easy as possible to access the raw data. This is a fine line to tread. The intention is to encourage students to think critically, and make their own interpretation. This means also being critical of the data that is presented (e.g. not all cross references are helpful, not all "related words" are related). By removing things like Strong's definitions we hope to make students work harder to come to their own conclusions. 17 | 18 | The primary data points are: 19 | 20 | - The original text, keyed with Strongs numbers, making it easy to follow the translation. 21 | - The usage of a word; by surfacing where a word is used elsewhere we can find "single word quotations". 22 | - Related words; this is based on Strong's concordance and is not always accurate. 23 | - Cross references; this is data that has been collected through recieved wisdom and should be subject to scrutiny. 24 | 25 | ## Get involed 26 | 27 | To find out how to get involved with the project read the [CONTRIBUTING](./CONTRIBUTING.md) document. 28 | -------------------------------------------------------------------------------- /ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scruffian/javascripture/2087f36882a40be076b4012f08b7e4af36c86340/ajax-loader.gif -------------------------------------------------------------------------------- /android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scruffian/javascripture/2087f36882a40be076b4012f08b7e4af36c86340/android-icon-144x144.png -------------------------------------------------------------------------------- /android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scruffian/javascripture/2087f36882a40be076b4012f08b7e4af36c86340/android-icon-192x192.png -------------------------------------------------------------------------------- /android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scruffian/javascripture/2087f36882a40be076b4012f08b7e4af36c86340/android-icon-36x36.png -------------------------------------------------------------------------------- /android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scruffian/javascripture/2087f36882a40be076b4012f08b7e4af36c86340/android-icon-48x48.png -------------------------------------------------------------------------------- /android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scruffian/javascripture/2087f36882a40be076b4012f08b7e4af36c86340/android-icon-72x72.png -------------------------------------------------------------------------------- /android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scruffian/javascripture/2087f36882a40be076b4012f08b7e4af36c86340/android-icon-96x96.png -------------------------------------------------------------------------------- /api/word.js: -------------------------------------------------------------------------------- 1 | /*globals javascripture bible*/ 2 | javascripture.api.word = { 3 | getFamily: function ( strongsNumber ) { 4 | if ( javascripture.data.strongsObjectWithFamilies[ strongsNumber ] ) { 5 | return javascripture.data.strongsObjectWithFamilies[ strongsNumber ].family; 6 | } else { 7 | return strongsNumber; 8 | } 9 | } 10 | }; -------------------------------------------------------------------------------- /apple-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scruffian/javascripture/2087f36882a40be076b4012f08b7e4af36c86340/apple-icon-114x114.png -------------------------------------------------------------------------------- /apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scruffian/javascripture/2087f36882a40be076b4012f08b7e4af36c86340/apple-icon-120x120.png -------------------------------------------------------------------------------- /apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scruffian/javascripture/2087f36882a40be076b4012f08b7e4af36c86340/apple-icon-144x144.png -------------------------------------------------------------------------------- /apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scruffian/javascripture/2087f36882a40be076b4012f08b7e4af36c86340/apple-icon-152x152.png -------------------------------------------------------------------------------- /apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scruffian/javascripture/2087f36882a40be076b4012f08b7e4af36c86340/apple-icon-180x180.png -------------------------------------------------------------------------------- /apple-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scruffian/javascripture/2087f36882a40be076b4012f08b7e4af36c86340/apple-icon-57x57.png -------------------------------------------------------------------------------- /apple-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scruffian/javascripture/2087f36882a40be076b4012f08b7e4af36c86340/apple-icon-60x60.png -------------------------------------------------------------------------------- /apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scruffian/javascripture/2087f36882a40be076b4012f08b7e4af36c86340/apple-icon-72x72.png -------------------------------------------------------------------------------- /apple-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scruffian/javascripture/2087f36882a40be076b4012f08b7e4af36c86340/apple-icon-76x76.png -------------------------------------------------------------------------------- /apple-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scruffian/javascripture/2087f36882a40be076b4012f08b7e4af36c86340/apple-icon-precomposed.png -------------------------------------------------------------------------------- /apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scruffian/javascripture/2087f36882a40be076b4012f08b7e4af36c86340/apple-icon.png -------------------------------------------------------------------------------- /browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | #ffffff -------------------------------------------------------------------------------- /build/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Caching 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /clear.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /createRoots.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Javascripture 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 25 | 26 | 27 |
28 | 29 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /createbranches.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /crossReferenceCombiner.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /css/layout.css: -------------------------------------------------------------------------------- 1 | * { 2 | border: none; 3 | margin: 0; 4 | padding: 0; } 5 | 6 | body { 7 | background: #fff; 8 | color: #000; 9 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 10 | font-size: 100%; 11 | } 12 | 13 | a { 14 | color: #000; 15 | } 16 | 17 | .added { 18 | color: #aaa; font-style: italic; } 19 | 20 | input, select, button { 21 | border: 1px solid rgba(0, 0, 0, 0.3); 22 | border-radius: 5px; 23 | box-sizing: border-box; 24 | font-family: Helvetica, Arial, sans-serif; 25 | font-size: 14px; 26 | height: 40px; 27 | line-height: 1em; 28 | padding: 0; 29 | } 30 | 31 | @media ( min-width: 768px ) { 32 | input, select, button { 33 | font-size: 20px; 34 | } 35 | } 36 | input { 37 | text-indent: .3em; 38 | } 39 | input { 40 | width: 100%; 41 | } 42 | 43 | input[type=checkbox] { 44 | box-shadow: none; } 45 | 46 | input[type=reset] { 47 | background: none; 48 | border: none; 49 | color: #999; 50 | font-size: 14px; 51 | height: auto; 52 | line-height: 2; 53 | } 54 | 55 | select { 56 | /* Removes the default 103 | { this.pickerButton( 'word' ) } 104 | 105 | { this.props.searchAdvanced && ( 106 |
107 |
108 | 109 | 110 | { this.pickerButton( 'lemma' ) } 111 |
112 |
113 | 114 | 115 | { this.pickerButton( 'morph' ) } 116 |
117 |
118 | 124 |
125 |
126 | 134 |
135 |
136 | 137 |
138 |
139 | 140 |
141 |
142 | ) } 143 | { this.renderAdvanced() } 144 |
145 | 146 | 147 |
148 | 149 | { this.results() } 150 | 151 | ); 152 | } 153 | } 154 | 155 | Search.propTypes = {}; 156 | 157 | export default withStyles( styles )( Search ); 158 | -------------------------------------------------------------------------------- /src/components/search/search-block.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import React from 'react'; 3 | import PropTypes from 'prop-types'; 4 | import withStyles from 'isomorphic-style-loader/lib/withStyles'; 5 | 6 | // Internal dependencies 7 | import SearchLink from '../../containers/search-link'; 8 | import styles from './styles.scss'; 9 | 10 | class SearchBlock extends React.Component{ 11 | renderDetails() { 12 | return this.props.results.map( ( reference, index ) => { 13 | return ( 14 | 15 | ) 16 | } ); 17 | } 18 | 19 | render() { 20 | if ( ! this.props.results ) { 21 | return (
Loading…
); 22 | } 23 | 24 | if ( this.props.results.length === 0 || typeof this.props.results === 'string' ) { 25 | return ( 26 |
27 | No results. 28 |
29 | ); 30 | } 31 | 32 | return ( 33 |
34 |
    35 | { this.renderDetails() } 36 |
37 |
38 | ); 39 | } 40 | } 41 | 42 | SearchBlock.propTypes = {}; 43 | 44 | export default withStyles( styles )( SearchBlock ); 45 | -------------------------------------------------------------------------------- /src/components/search/search-link.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import React from 'react'; 3 | import PropTypes from 'prop-types'; 4 | import withStyles from 'isomorphic-style-loader/lib/withStyles'; 5 | import { Link } from 'react-router-dom'; 6 | 7 | // Internal dependencies 8 | import Verse from '../reference/verse'; 9 | import styles from './styles.scss'; 10 | import { createReferenceLink } from '../../lib/reference.js'; 11 | 12 | class SearchLink extends React.Component{ 13 | setCurrentVerse() { 14 | const { index } = this.props; 15 | this.props.setCurrentVerse( index ); 16 | } 17 | 18 | expandedSearchResults( reference ) { 19 | if ( ! javascripture.data.kjv[ reference.book ][ reference.chapter - 1 ] || ! javascripture.data.kjv[ reference.book ][ reference.chapter - 1 ][ reference.verse - 1 ] ) { 20 | console.log( 'found a non-existent verse', reference ); 21 | return null; 22 | } 23 | 24 | const verseData = javascripture.data.kjv[ reference.book ][ reference.chapter - 1 ][ reference.verse - 1 ]; 25 | return (
26 | 27 |
); 28 | } 29 | 30 | render() { 31 | const { reference, index } = this.props, 32 | className = this.props.isActive ? styles.activeReference : null; 33 | 34 | return ( 35 |
  • 36 | this.setCurrentVerse( false ) }> 37 | { index + 1 }. { reference.book } { reference.chapter }:{ reference.verse } 38 | 39 | { this.props.expandedSearchResults && this.expandedSearchResults( reference ) } 40 |
  • 41 | ); 42 | } 43 | } 44 | 45 | SearchLink.propTypes = {}; 46 | 47 | export default withStyles( styles )( SearchLink ); 48 | -------------------------------------------------------------------------------- /src/components/search/styles.scss: -------------------------------------------------------------------------------- 1 | .search { 2 | fieldset { 3 | margin: 5px; 4 | position: relative; 5 | } 6 | 7 | select { 8 | height: 1em; 9 | line-height: 1em; 10 | } 11 | } 12 | 13 | .picker-button { 14 | border-top-left-radius: 0; 15 | border-bottom-left-radius: 0; 16 | padding: 0 10px; 17 | position: absolute; 18 | right: 0; 19 | top: 0; 20 | } 21 | 22 | .header { 23 | background: darken( grey, 20); 24 | border-bottom: 1px solid white; 25 | color: white; 26 | padding: .2em; 27 | position: relative; 28 | } 29 | 30 | .remove { 31 | cursor: pointer; 32 | padding: 8px; 33 | position: absolute; 34 | right: 0; 35 | top: 0; 36 | } 37 | 38 | .results { 39 | line-height: 1.4; 40 | list-style: none; 41 | 42 | li { 43 | padding-left: .5em; 44 | } 45 | a { 46 | color: black; 47 | display: inline-block; 48 | text-decoration: none; 49 | } 50 | } 51 | 52 | .hidden { 53 | display: none; 54 | } 55 | 56 | .no-results { 57 | padding: .5em; 58 | } 59 | 60 | .active-reference { 61 | background: lighten( lightblue, 10 ); 62 | } 63 | 64 | $trayWidth: 320px; 65 | $width: 70px; 66 | $padding: 10px; 67 | a.clear-all { 68 | background: lightblue; 69 | color: #fff; 70 | display: block; 71 | padding: $padding; 72 | position: fixed; 73 | bottom: 55px; 74 | left: $trayWidth - $width - $padding * 2; 75 | cursor: pointer; 76 | text-align: right; 77 | text-decoration: none; 78 | width: $width; 79 | } 80 | 81 | .advanced { 82 | cursor: pointer; 83 | text-align: right; 84 | a { 85 | color: #aaa; 86 | } 87 | } 88 | 89 | .verse { 90 | font-size: 12px; 91 | } 92 | -------------------------------------------------------------------------------- /src/components/strongs-color.js: -------------------------------------------------------------------------------- 1 | import { getFamily } from '../lib/word'; 2 | 3 | var getStrongsColor = function( lemma, lightness ) { 4 | var strongsInt = parseInt( lemma ); 5 | if ( isNaN ( strongsInt ) ) { 6 | strongsInt = 0; 7 | } 8 | var theSizeOfAColorSegment = 360 / 8000, 9 | hue = Math.floor( strongsInt * theSizeOfAColorSegment ), 10 | staturation = '50%'; 11 | return 'hsl( ' + hue + ',' + staturation + ', ' + lightness + ' )'; 12 | }; 13 | 14 | var getStrongsColorWithSettings = function( strongsNumber, lightness, highlightWordsWith ) { 15 | var hightlightFamilies = highlightWordsWith === 'family', 16 | classInt; 17 | if ( hightlightFamilies ) { 18 | classInt = parseFloat( strongsNumber.substring( 1, strongsNumber.length ), 10 ); 19 | } else { 20 | classInt = parseInt( strongsNumber.substring( 1, strongsNumber.length ), 10 ); 21 | } 22 | 23 | return getStrongsColor( classInt, lightness ); 24 | }; 25 | 26 | var getClassNameWithSettings = function( strongsNumber, lightness, highlightWordsWith ) { 27 | if ( highlightWordsWith === 'family' ) { 28 | return getFamily( strongsNumber ); 29 | } else { 30 | return strongsNumber; 31 | } 32 | }; 33 | 34 | var getHue = function( strongsInt ) { 35 | var theSizeOfAColorSegment = 360 / 8000; //8000 different words 36 | return strongsInt * theSizeOfAColorSegment; 37 | }; 38 | 39 | var getHighlight = function ( strongsNumber, lightness, highlightWordsWith ) { 40 | var newColor = getStrongsColorWithSettings( strongsNumber, lightness, highlightWordsWith ); 41 | var className = getClassNameWithSettings( strongsNumber, lightness, highlightWordsWith ); 42 | return '.' + className + ' {color:#fff !important;background:' + newColor + ' !important;}'; 43 | }; 44 | 45 | var getHighlightBorder = function ( strongsNumber, lightness, highlightWordsWith ) { 46 | var newColor = getStrongsColorWithSettings( strongsNumber, lightness, highlightWordsWith ); 47 | var className = getClassNameWithSettings( strongsNumber, lightness, highlightWordsWith ); 48 | return '.' + className + ' {outline: 3px solid ' + newColor + ' !important;}'; 49 | }; 50 | 51 | module.exports = { 52 | get: getStrongsColor, 53 | getHighlight: getHighlight, 54 | getHighlightBorder: getHighlightBorder, 55 | }; 56 | -------------------------------------------------------------------------------- /src/components/svg/add.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import React from 'react'; 3 | 4 | const Add = ( { fill } ) => ( 5 | 6 | 7 | 8 | ); 9 | 10 | export default Add; 11 | -------------------------------------------------------------------------------- /src/components/svg/book.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import React from 'react'; 3 | 4 | const Book = ( { fill }) => ( 5 | 6 | 7 | 8 | ); 9 | 10 | export default Book; 11 | -------------------------------------------------------------------------------- /src/components/svg/bookmark.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import React from 'react'; 3 | 4 | const Bookmark = ( { fill } ) => ( 5 | 6 | 7 | 8 | ); 9 | 10 | export default Bookmark; 11 | -------------------------------------------------------------------------------- /src/components/svg/cancel.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import React from 'react'; 3 | 4 | const Cancel = ( { fill } ) => ( 5 | 6 | 7 | 8 | ); 9 | 10 | export default Cancel; 11 | -------------------------------------------------------------------------------- /src/components/svg/cog.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import React from 'react'; 3 | 4 | const Cog = ( { fill } ) => ( 5 | 6 | 7 | 8 | ); 9 | 10 | export default Cog; 11 | -------------------------------------------------------------------------------- /src/components/svg/eye.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import React from 'react'; 3 | 4 | const Eye = ( { fill } ) => ( 5 | 6 | 7 | 8 | ); 9 | 10 | export default Eye; 11 | -------------------------------------------------------------------------------- /src/components/svg/picker.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import React from 'react'; 3 | 4 | const Picker = ( { fill }) => ( 5 | 6 | 7 | 8 | ); 9 | 10 | export default Picker; 11 | -------------------------------------------------------------------------------- /src/components/svg/remove.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import React from 'react'; 3 | 4 | const Remove = ( { fill } ) => ( 5 | 6 | 7 | 8 | ); 9 | 10 | export default Remove; 11 | -------------------------------------------------------------------------------- /src/components/svg/search.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import React from 'react'; 3 | 4 | const Search = ( { fill } ) => ( 5 | 6 | 7 | 8 | ); 9 | 10 | export default Search; 11 | -------------------------------------------------------------------------------- /src/components/svg/sync-disabled.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import React from 'react'; 3 | 4 | const SyncDisabled = ( { fill } ) => ( 5 | 6 | 7 | 8 | ); 9 | 10 | export default SyncDisabled; 11 | -------------------------------------------------------------------------------- /src/components/svg/sync.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import React from 'react'; 3 | 4 | const Sync = ( { fill } ) => ( 5 | 6 | 7 | 8 | ); 9 | 10 | export default Sync; 11 | -------------------------------------------------------------------------------- /src/components/sync-button/index.js: -------------------------------------------------------------------------------- 1 | // External 2 | import React from 'react'; 3 | import { connect } from 'react-redux'; 4 | 5 | // Internal 6 | import { settingsChange } from '../../actions'; 7 | import SyncSvg from '../svg/sync'; 8 | import SyncDisabledSvg from '../svg/sync-disabled'; 9 | import styles from './style.scss'; 10 | import withStyles from 'isomorphic-style-loader/lib/withStyles'; 11 | 12 | const fill = '#333333'; 13 | 14 | class SyncButton extends React.Component{ 15 | changeSync = () => { 16 | this.props.settingsChange( 'inSync', ! this.props.inSync ); 17 | }; 18 | 19 | render() { 20 | return ( 21 | 24 | ); 25 | } 26 | } 27 | 28 | const mapStateToProps = ( { settings }, ownProps ) => { 29 | return { 30 | inSync: settings.inSync, 31 | }; 32 | }; 33 | 34 | const mapDispatchToProps = ( dispatch, ownProps ) => { 35 | return { 36 | settingsChange: ( settingName, settingValue ) => { 37 | dispatch( settingsChange( settingName, settingValue ) ) 38 | } 39 | }; 40 | }; 41 | 42 | export default connect( 43 | mapStateToProps, 44 | mapDispatchToProps, 45 | )( withStyles( styles )( SyncButton ) ); 46 | 47 | -------------------------------------------------------------------------------- /src/components/sync-button/style.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scruffian/javascripture/2087f36882a40be076b4012f08b7e4af36c86340/src/components/sync-button/style.scss -------------------------------------------------------------------------------- /src/components/tray-filter/styles.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scruffian/javascripture/2087f36882a40be076b4012f08b7e4af36c86340/src/components/tray-filter/styles.scss -------------------------------------------------------------------------------- /src/components/tray-list.js: -------------------------------------------------------------------------------- 1 | // External 2 | import React from 'react'; 3 | import PropTypes from 'prop-types'; 4 | import withStyles from 'isomorphic-style-loader/lib/withStyles'; 5 | 6 | // Internal 7 | import styles from './trays/styles.scss'; 8 | import WordTray from '../components/trays/word'; 9 | import GotoTray from '../components/trays/goto'; 10 | import SearchTray from '../components/trays/search'; 11 | import BookmarksTray from '../components/trays/bookmarks'; 12 | import SettingsTray from '../components/trays/settings'; 13 | 14 | function getComponent( componentString ) { 15 | switch ( componentString ) { 16 | case 'WordTray': 17 | return 18 | 19 | case 'GotoTray': 20 | return 21 | 22 | case 'SearchTray': 23 | return 24 | 25 | case 'BookmarksTray': 26 | return 27 | 28 | case 'SettingsTray': 29 | return 30 | } 31 | } 32 | 33 | const TrayList = ( { trays, filter, onTrayClick } ) => { 34 | return ( 35 |
    36 | { trays.map( tray => 37 |
    42 | { getComponent( tray.component ) } 43 |
    44 | ) } 45 |
    46 | ); 47 | }; 48 | 49 | TrayList.propTypes = { 50 | trays: PropTypes.arrayOf(PropTypes.shape({ 51 | id: PropTypes.string.isRequired, 52 | visible: PropTypes.bool.isRequired, 53 | text: PropTypes.string.isRequired 54 | }).isRequired).isRequired 55 | }; 56 | 57 | export default withStyles( styles )( TrayList ); 58 | -------------------------------------------------------------------------------- /src/components/trays/bookmarks.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import React from 'react'; 3 | import PropTypes from 'prop-types'; 4 | import withStyles from 'isomorphic-style-loader/lib/withStyles'; 5 | 6 | // Internal dependencies 7 | import BookMarks from '../../containers/bookmarks'; 8 | import CrossReferences from '../../containers/cross-references'; 9 | import styles from './styles.scss'; 10 | 11 | const BookmarksTray = ( props ) => ( 12 |
    13 |
    14 | 15 | 16 |
    17 |
    18 | ); 19 | 20 | BookmarksTray.propTypes = {}; 21 | 22 | export default withStyles( styles )( BookmarksTray ); 23 | -------------------------------------------------------------------------------- /src/components/trays/filter.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import React from 'react'; 3 | import PropTypes from 'prop-types'; 4 | import withStyles from 'isomorphic-style-loader/lib/withStyles'; 5 | 6 | // Internal dependencies 7 | import styles from './styles.scss'; 8 | 9 | const TrayFilter = ( { active, children, activate, hideAll } ) => { 10 | let classeName = styles.trayFilter; 11 | if ( active ) { 12 | classeName = styles.active 13 | } 14 | 15 | return ( 16 | { 18 | event.preventDefault() 19 | if ( active ) { 20 | hideAll(); 21 | } else { 22 | activate(); 23 | } 24 | } } 25 | > 26 | { children } 27 | 28 | ); 29 | }; 30 | 31 | TrayFilter.propTypes = { 32 | active: PropTypes.bool.isRequired, 33 | children: PropTypes.node.isRequired, 34 | activate: PropTypes.func.isRequired, 35 | hideAll: PropTypes.func.isRequired 36 | }; 37 | 38 | export default withStyles( styles )( TrayFilter ); -------------------------------------------------------------------------------- /src/components/trays/goto.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import React from 'react'; 3 | import PropTypes from 'prop-types'; 4 | import withStyles from 'isomorphic-style-loader/lib/withStyles'; 5 | 6 | // Internal dependencies 7 | import ReferenceSelector from '../reference-selector'; 8 | import styles from './styles.scss'; 9 | 10 | const GotoTray = () => ( 11 |
    12 | 13 |
    14 | ); 15 | 16 | GotoTray.propTypes = {}; 17 | 18 | export default withStyles( styles )( GotoTray ); 19 | -------------------------------------------------------------------------------- /src/components/trays/index.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import React from 'react'; 3 | import withStyles from 'isomorphic-style-loader/lib/withStyles'; 4 | 5 | // Internal dependencies 6 | import styles from './styles.scss'; 7 | 8 | const Trays = ( { children } ) => ( 9 |
    10 | { children } 11 |
    12 | ) 13 | 14 | export default withStyles( styles )( Trays ); 15 | -------------------------------------------------------------------------------- /src/components/trays/search.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import React from 'react'; 3 | import PropTypes from 'prop-types'; 4 | import withStyles from 'isomorphic-style-loader/lib/withStyles'; 5 | 6 | // Internal dependencies 7 | import Search from '../../containers/search'; 8 | import styles from './styles.scss'; 9 | 10 | const SearchTray = () => ( 11 |
    12 |
    13 | 14 |
    15 |
    16 |
    17 | ); 18 | 19 | SearchTray.propTypes = {}; 20 | 21 | export default withStyles( styles )( SearchTray ); 22 | -------------------------------------------------------------------------------- /src/components/trays/settings.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import { connect } from 'react-redux'; 3 | import React from 'react'; 4 | import PropTypes from 'prop-types'; 5 | import withStyles from 'isomorphic-style-loader/lib/withStyles'; 6 | 7 | // Internal dependencies 8 | import { settingsChange } from '../../actions'; 9 | import styles from './styles.scss'; 10 | 11 | class SettingsTray extends React.Component{ 12 | changeSetting = ( event ) => { 13 | this.props.settingsChange( event.target.name, event.target.value ); 14 | event.target.blur(); 15 | }; 16 | 17 | changeCheckboxSetting = ( event ) => { 18 | this.props.settingsChange( event.target.name, event.target.checked ); 19 | event.target.blur(); 20 | }; 21 | 22 | render() { 23 | return ( 24 |
    25 |
    26 |
    27 |
    28 |

    Help

    29 |

    Having problems? Email for help!

    30 |
    31 |
      32 |
    • To find out about a word, click on it
    • 33 |
    34 |
    35 |

    Keyboard shortcuts

    36 |
      37 |
    • Go to a reference: just start typing
    • 38 |
    • Next reference: =
    • 39 |
    • Previous reference: -
    • 40 |
    • Jump to chapter: type a number
    • 41 |
    42 |
    43 |
    44 |
    45 | 46 |
    47 |
    48 |
    49 |

    Settings

    50 |
    51 |
      52 |
    • 53 | 54 | 63 |
    • 64 |
    • 65 | 66 | 81 |
    • 82 |
    • 83 | 84 | 91 |
    • 92 |
    • 93 | 94 | 98 |
    • 99 |
    • 100 | 103 |
    • 104 |
    • 105 | 108 |
    • 109 |
    110 |
    111 |
    112 |
    113 |
    114 |
    115 |

    Built in Firefox. Tested in Chrome.

    116 |
    117 |
    118 | ); 119 | } 120 | } 121 | 122 | SettingsTray.propTypes = {}; 123 | 124 | const SettingsTrayWithStyles = withStyles( styles )( SettingsTray ); 125 | 126 | // set up global - to be deleted 127 | javascripture.state = {}; 128 | 129 | const mapStateToProps = ( state, ownProps ) => { 130 | // remove this line 131 | javascripture.state.settings = state.settings; 132 | 133 | return { 134 | bookmarks: state.bookmarks, 135 | settings: state.settings 136 | }; 137 | }; 138 | 139 | const mapDispatchToProps = ( dispatch, ownProps ) => { 140 | return { 141 | settingsChange: ( settingName, settingValue ) => { 142 | dispatch( settingsChange( settingName, settingValue ) ) 143 | } 144 | } 145 | }; 146 | 147 | export default connect( 148 | mapStateToProps, 149 | mapDispatchToProps 150 | )( SettingsTrayWithStyles ); 151 | -------------------------------------------------------------------------------- /src/components/trays/styles.scss: -------------------------------------------------------------------------------- 1 | .tray { 2 | background: rgba( 255, 255, 255, .9 ); 3 | box-shadow: 0 0 5px 0 rgba( 0, 0, 0 , .5 ); 4 | overflow: scroll; 5 | position: fixed; 6 | bottom: 3.5em; 7 | left: 0; 8 | top: 0; 9 | width: 320px; 10 | z-index: 10; 11 | } 12 | 13 | .visible { 14 | display: block; 15 | } 16 | 17 | .hidden { 18 | display: none; 19 | } 20 | 21 | .trayFilter { 22 | display: inline-block; 23 | cursor: pointer; 24 | margin: 0; 25 | padding: 1em 0; 26 | text-align: center; 27 | width: 20%; 28 | 29 | &:hover { 30 | background: rgba( 150, 230, 230, 0.2 ); 31 | } 32 | } 33 | 34 | .active { 35 | composes: trayFilter; 36 | background: rgba( 150, 230, 230, 0.3 ); 37 | } 38 | 39 | .help-panel { 40 | padding: .5em; 41 | } 42 | 43 | .settings-li { 44 | margin-bottom: 1em; 45 | 46 | label { 47 | display: block; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/components/trays/tray-button.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class Search extends React.Component{ 4 | handleClick: function() { 5 | this.props.onChangeDisplayState( this.props.target ); 6 | }, 7 | 8 | render: function() { 9 | var className = this.props.open ? 'open' : ''; 10 | return ( 11 | 15 | ); 16 | } 17 | } 18 | 19 | export default Search; 20 | -------------------------------------------------------------------------------- /src/components/trays/tray-list.js: -------------------------------------------------------------------------------- 1 | // External 2 | import React from 'react'; 3 | import PropTypes from 'prop-types'; 4 | import withStyles from 'isomorphic-style-loader/lib/withStyles'; 5 | 6 | // Internal 7 | import styles from './styles.scss'; 8 | import WordTray from './word'; 9 | import GotoTray from './goto'; 10 | import SearchTray from './search'; 11 | import BookmarksTray from './bookmarks'; 12 | import SettingsTray from './settings'; 13 | 14 | function getComponent( componentString ) { 15 | switch ( componentString ) { 16 | case 'WordTray': 17 | return 18 | 19 | case 'GotoTray': 20 | return 21 | 22 | case 'SearchTray': 23 | return 24 | 25 | case 'BookmarksTray': 26 | return 27 | 28 | case 'SettingsTray': 29 | return 30 | } 31 | } 32 | 33 | class TrayList extends React.Component{ 34 | render() { 35 | const { trays, filter, onTrayClick } = this.props; 36 | 37 | return ( 38 |
    39 | { trays.map( tray => 40 |
    44 | { getComponent( tray.component ) } 45 |
    46 | ) } 47 |
    48 | ); 49 | } 50 | }; 51 | 52 | TrayList.propTypes = { 53 | trays: PropTypes.arrayOf(PropTypes.shape({ 54 | id: PropTypes.string.isRequired, 55 | visible: PropTypes.bool.isRequired, 56 | text: PropTypes.string.isRequired 57 | }).isRequired).isRequired 58 | }; 59 | 60 | export default withStyles( styles )( TrayList ); 61 | -------------------------------------------------------------------------------- /src/components/trays/word.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import React from 'react'; 3 | import PropTypes from 'prop-types'; 4 | import withStyles from 'isomorphic-style-loader/lib/withStyles'; 5 | 6 | // Internal dependencies 7 | import WordDetails from '../../containers/word-details'; 8 | import styles from './styles.scss'; 9 | 10 | const WordTray = () => ( 11 |
    12 |
    13 | 14 |
    15 |
    16 | ); 17 | 18 | WordTray.propTypes = {}; 19 | 20 | export default withStyles( styles )( WordTray ); 21 | -------------------------------------------------------------------------------- /src/components/version-selector/index.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import React from 'react'; 3 | import PropTypes from 'prop-types'; 4 | import mousetrap from 'mousetrap'; 5 | 6 | // Internal dependencies 7 | import AddColumnButton from '../add-column-button'; 8 | import ReferenceSelectorMobile from '../reference-selector-mobile'; 9 | import RemoveColumnButton from '../remove-column-button'; 10 | import SyncButton from '../sync-button'; 11 | import withStyles from 'isomorphic-style-loader/lib/withStyles'; 12 | import { createReferenceLink } from '../../lib/reference.js'; 13 | 14 | // Component variables 15 | let lastTimeStamp = 0; 16 | 17 | // Internal dependencies 18 | import styles from './styles.scss'; 19 | 20 | class VersionSelector extends React.Component{ 21 | state = { 22 | reference: this.props.value, 23 | }; 24 | 25 | changeVersion = ( event ) => { 26 | this.props.changeVersion( event.target.name, event.target.value ); 27 | event.target.blur(); 28 | }; 29 | 30 | change = ( event ) => { 31 | this.setState( { 32 | reference: event.target.value, 33 | } ); 34 | }; 35 | 36 | goToReference = ( event ) => { 37 | event.preventDefault(); 38 | const reference = bible.parseReference( this.refs.referenceInput.value ); 39 | reference.book = bible.Data.books[reference.bookID - 1][0]; 40 | if ( this.props.index === 0 ) { 41 | window.location.hash = createReferenceLink( reference ); 42 | } else { 43 | this.props.setReference( reference, this.props.index ); 44 | } 45 | this.refs.referenceInput.blur(); 46 | }; 47 | 48 | componentWillReceiveProps( nextProps ) { 49 | if ( this.refs.referenceInput ) { 50 | //this.refs.referenceInput.value = nextProps.value; 51 | this.setState( { 52 | reference: nextProps.value, 53 | } ); 54 | } 55 | } 56 | 57 | goToReferenceField = ( event ) => { 58 | event.preventDefault(); 59 | this.refs.referenceInput.focus(); 60 | this.refs.referenceInput.selectionStart = this.refs.referenceInput.selectionEnd = 0; 61 | //this.refs.referenceInput.value = event.key; 62 | this.setState( { 63 | reference: event.key, 64 | } ); 65 | } 66 | 67 | componentDidMount() { 68 | if ( this.props.index === 0 ) { 69 | mousetrap.bind( [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' ], this.goToReferenceField ); 70 | } 71 | } 72 | 73 | componentWillUnmount() { 74 | if ( this.props.index === 0 ) { 75 | mousetrap.unbind( [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' ], this.goToReferenceField ); 76 | } 77 | } 78 | 79 | renderInput() { 80 | return ( 81 | 82 | 83 | 84 | 85 | ); 86 | } 87 | 88 | renderSelect() { 89 | const value = this.props.references[ this.props.index ].version ? this.props.references[ this.props.index ].version : ''; 90 | return ( 91 | 97 | ); 98 | } 99 | 100 | render() { 101 | return ( 102 |
    103 | { ( this.props.index === 0 || ! this.props.inSync ) && this.renderInput() } 104 | { this.renderSelect() } 105 | { this.props.index === 0 ? : } 106 | { this.props.last && } 107 | 108 | 109 | ); 110 | } 111 | } 112 | 113 | VersionSelector.propTypes = {}; 114 | 115 | export default withStyles( styles )( VersionSelector ); 116 | -------------------------------------------------------------------------------- /src/components/version-selector/styles.scss: -------------------------------------------------------------------------------- 1 | @import '../_dimensions.scss'; 2 | 3 | .version-selector { 4 | display: flex; 5 | } 6 | 7 | .version-selector-flexible { 8 | display: flex; 9 | flex-basis: 0; 10 | flex-grow: 1; 11 | margin-right: -1px; 12 | max-width: $total-column-width; 13 | } 14 | 15 | .form-field, .left-version, .right-version { 16 | box-sizing: border-box; 17 | flex-grow: 1; 18 | 19 | } 20 | 21 | .right-version { 22 | border-radius: 0; 23 | } 24 | 25 | .inputWrapper { 26 | display: flex; 27 | flex-grow: 4; 28 | height: 20px; 29 | position: relative; 30 | } 31 | 32 | .input { 33 | border-radius: 0; 34 | border-right: 0; 35 | flex-grow: 1; 36 | } 37 | 38 | .left-version, .right-version, .input { 39 | @media ( max-width: 399px ) { 40 | border-top: 0; 41 | border-radius: 0; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/components/word-details/index.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import React from 'react'; 3 | import PropTypes from 'prop-types'; 4 | import withStyles from 'isomorphic-style-loader/lib/withStyles'; 5 | 6 | // Internal dependencies 7 | import styles from './styles.scss'; 8 | import WordBlock from '../../containers/word-block'; 9 | 10 | class WordDetails extends React.Component{ 11 | render() { 12 | if ( this.props.words.length ) { 13 | return ( 14 |
    15 | { this.props.words.map( ( wordDetails, index ) => { 16 | return ( 17 | 18 | ); 19 | } ) } 20 | Clear all 21 |
    22 | ); 23 | } 24 | 25 | return (
    Select a word to show more details about it here.
    ); 26 | } 27 | } 28 | 29 | WordDetails.propTypes = {}; 30 | 31 | export default withStyles( styles )( WordDetails ); 32 | -------------------------------------------------------------------------------- /src/components/word-details/kjv-def.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import React from 'react'; 3 | import PropTypes from 'prop-types'; 4 | import withStyles from 'isomorphic-style-loader/lib/withStyles'; 5 | 6 | // Internal dependencies 7 | import styles from './styles.scss'; 8 | 9 | class KJVDef extends React.Component{ 10 | searchWord = () => { 11 | const searchParameters = { 12 | clusivity: 'exclusive', 13 | language: 'kjv', 14 | version: 'kjv', 15 | lemma: this.props.strongsNumber, 16 | range: 'verse', 17 | word: this.props.word, 18 | morph: '', 19 | }; 20 | 21 | this.props.addSearch( searchParameters, 'search' ); 22 | }; 23 | 24 | render() { 25 | return { this.props.word }; 26 | } 27 | } 28 | 29 | KJVDef.propTypes = {}; 30 | 31 | export default withStyles( styles )( KJVDef ); 32 | -------------------------------------------------------------------------------- /src/components/word-details/styles.scss: -------------------------------------------------------------------------------- 1 | .title { 2 | cursor: pointer; 3 | font-weight: 100; 4 | margin: 0 !important; 5 | padding: 5px !important; 6 | position: relative; 7 | } 8 | 9 | .fake-link { 10 | cursor: pointer; 11 | text-decoration: underline; 12 | } 13 | 14 | .remove { 15 | color: #fff; 16 | padding: 8px; 17 | position: absolute; 18 | top: 0; 19 | right: 0; 20 | } 21 | 22 | .visible { 23 | display: block; 24 | } 25 | 26 | .hidden { 27 | display: none; 28 | } 29 | 30 | $trayWidth: 320px; 31 | $width: 70px; 32 | $padding: 10px; 33 | a.clear-all { 34 | background: lightblue; 35 | color: #fff; 36 | display: block; 37 | padding: $padding; 38 | position: fixed; 39 | bottom: 55px; 40 | left: $trayWidth - $width - $padding * 2; 41 | cursor: pointer; 42 | text-align: right; 43 | text-decoration: none; 44 | width: $width; 45 | } 46 | 47 | .word-block { 48 | padding: .5em; 49 | } 50 | 51 | .strongs-number-title { 52 | display: inline-block; 53 | width: 85px; 54 | } 55 | 56 | .found-in-extra { 57 | color: #999; 58 | cursor: pointer; 59 | float: right; 60 | text-decoration: none; 61 | } 62 | -------------------------------------------------------------------------------- /src/components/word-highlight/index.js: -------------------------------------------------------------------------------- 1 | // External dependencies 2 | import React from 'react'; 3 | import PropTypes from 'prop-types'; 4 | 5 | import { getHighlight, getHighlightBorder } from '../strongs-color.js'; 6 | 7 | class WordHighlight extends React.Component{ 8 | render() { 9 | return ( 10 | 23 | ); 24 | } 25 | } 26 | 27 | WordHighlight.propTypes = {}; 28 | 29 | export default WordHighlight; 30 | -------------------------------------------------------------------------------- /src/containers/FilterTrayLink.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux' 2 | import some from 'lodash/some'; 3 | 4 | import { setTrayVisibilityFilter } from '../actions' 5 | import TrayLink from '../components/trays/filter' 6 | 7 | const mapStateToProps = ( state, ownProps ) => { 8 | return { 9 | active: state.trays.some( tray => { 10 | return ( tray.id === ownProps.filter && tray.visible ); 11 | } ) 12 | } 13 | }; 14 | 15 | const mapDispatchToProps = ( dispatch, ownProps ) => { 16 | return { 17 | activate: () => { 18 | dispatch( setTrayVisibilityFilter( ownProps.filter ) ) 19 | }, 20 | hideAll: () => { 21 | dispatch( setTrayVisibilityFilter( 'SHOW_NONE' ) ) 22 | } 23 | } 24 | }; 25 | 26 | const TrayFilter = connect( 27 | mapStateToProps, 28 | mapDispatchToProps 29 | )( TrayLink ) 30 | 31 | export default TrayFilter; 32 | -------------------------------------------------------------------------------- /src/containers/book-control.js: -------------------------------------------------------------------------------- 1 | // External 2 | import { connect } from 'react-redux'; 3 | import { push } from 'connected-react-router' 4 | 5 | // Internal 6 | import BookControl from '../components/reference-selector/book-control'; 7 | 8 | const mapDispatchToProps = ( dispatch, ownProps ) => { 9 | return { 10 | goToReference: ( path ) => { 11 | dispatch( push( path ) ); 12 | } 13 | } 14 | }; 15 | 16 | const BookControlContainer = connect( 17 | null, 18 | mapDispatchToProps 19 | )( BookControl ) 20 | 21 | export default BookControlContainer; 22 | -------------------------------------------------------------------------------- /src/containers/bookmark.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { removeBookmark } from '../actions'; 3 | import BookMark from '../components/bookmarks/bookmark'; 4 | 5 | const mapDispatchToProps = ( dispatch, ownProps ) => { 6 | return { 7 | removeBookmark: ( reference ) => { 8 | dispatch( removeBookmark( reference ) ) 9 | }, 10 | } 11 | }; 12 | 13 | const BookMarkContainer = connect( 14 | null, 15 | mapDispatchToProps 16 | )( BookMark ) 17 | 18 | export default BookMarkContainer; 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/containers/bookmarker.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | 3 | import { addBookmark, setTrayVisibilityFilter } from '../actions'; 4 | import BookMarker from '../components/reference/bookmarker'; 5 | 6 | const mapDispatchToProps = ( dispatch, ownProps ) => { 7 | return { 8 | addBookmark: () => { 9 | dispatch( setTrayVisibilityFilter( 'bookmarks' ) ); 10 | dispatch( addBookmark( ownProps ) ); 11 | }, 12 | 13 | } 14 | }; 15 | 16 | const BookMarkerContainer = connect( 17 | null, 18 | mapDispatchToProps 19 | )( BookMarker ) 20 | 21 | export default BookMarkerContainer; 22 | -------------------------------------------------------------------------------- /src/containers/bookmarks.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { removeBookmark } from '../actions'; 3 | import BookMarks from '../components/bookmarks'; 4 | 5 | const mapStateToProps = ( state, ownProps ) => { 6 | return { 7 | bookmarks: state.bookmarks 8 | }; 9 | }; 10 | 11 | const BookMarksContainer = connect( 12 | mapStateToProps, 13 | )( BookMarks ) 14 | 15 | export default BookMarksContainer; 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/containers/chapter.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | 3 | import Chapter from '../components/reference/chapter'; 4 | 5 | const mapStateToProps = ( state, ownProps ) => { 6 | return { 7 | reference: state.reference, 8 | inSync: state.settings.inSync, 9 | } 10 | }; 11 | 12 | const ChapterContainer = connect( 13 | mapStateToProps 14 | )( Chapter ) 15 | 16 | export default ChapterContainer; 17 | -------------------------------------------------------------------------------- /src/containers/cross-references.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import some from 'lodash/some'; 3 | 4 | import { showCrossReferences } from '../actions'; 5 | import CrossReferences from '../components/cross-references'; 6 | 7 | const mapStateToProps = ( state, ownProps ) => { 8 | return { 9 | reference: state.crossReferences 10 | }; 11 | }; 12 | 13 | const mapDispatchToProps = ( dispatch, ownProps ) => { 14 | return { 15 | showCrossReferences: ( reference ) => { 16 | dispatch( showCrossReferences( reference ) ); 17 | } 18 | } 19 | }; 20 | 21 | const CrossReferencesContainer = connect( 22 | mapStateToProps, 23 | mapDispatchToProps 24 | )( CrossReferences ) 25 | 26 | export default CrossReferencesContainer; 27 | -------------------------------------------------------------------------------- /src/containers/keyboard-shortcuts.js: -------------------------------------------------------------------------------- 1 | // External 2 | import { connect } from 'react-redux'; 3 | import find from 'lodash/find'; 4 | import isEqual from 'lodash/isEqual'; 5 | 6 | // Internal 7 | import KeyboardShortcuts from '../components/keyboard-shortcuts'; 8 | import { goToReference, goToNextCurrentVerse, goToPreviousCurrentVerse } from '../actions' 9 | 10 | function getCurrentReferenceOffset( searchResults, currentReference, offset ) { 11 | const currentSearchResults = find( searchResults, searchResult => { 12 | return isEqual( searchResult.terms, currentReference.terms ); 13 | } ) ; 14 | 15 | if ( currentSearchResults ) { 16 | return currentSearchResults.results[ currentReference.activeReference + offset ]; 17 | } 18 | 19 | return null; 20 | }; 21 | 22 | const mapStateToProps = ( { searchResults, currentReference, reference } ) => { 23 | return { 24 | nextReference: getCurrentReferenceOffset( searchResults, currentReference, 1 ), 25 | previousReference: getCurrentReferenceOffset( searchResults, currentReference, -1 ), 26 | reference: reference, 27 | } 28 | }; 29 | 30 | const mapDispatchToProps = ( dispatch ) => { 31 | return { 32 | markNextCurrentReference: () => { 33 | dispatch( goToNextCurrentVerse() ); 34 | }, 35 | markPreviousCurrentReference: () => { 36 | dispatch( goToPreviousCurrentVerse() ); 37 | }, 38 | goToReference: ( reference ) => { 39 | goToReference( reference ); 40 | } 41 | } 42 | }; 43 | 44 | const KeyboardShortcutsContainer = connect( 45 | mapStateToProps, 46 | mapDispatchToProps, 47 | )( KeyboardShortcuts ) 48 | 49 | export default KeyboardShortcutsContainer; 50 | -------------------------------------------------------------------------------- /src/containers/kjv-def.js: -------------------------------------------------------------------------------- 1 | // External 2 | import { connect } from 'react-redux'; 3 | 4 | // Internal 5 | import { addSearch, setTrayVisibilityFilter } from '../actions'; 6 | import KJVDef from '../components/word-details/kjv-def'; 7 | 8 | const mapDispatchToProps = ( dispatch, ownProps ) => { 9 | return { 10 | addSearch: ( terms ) => { 11 | dispatch( addSearch( terms, 'search' ) ); 12 | dispatch( setTrayVisibilityFilter( 'search' ) ) 13 | } 14 | } 15 | }; 16 | 17 | const KJVDefContainer = connect( 18 | null, 19 | mapDispatchToProps 20 | )( KJVDef ) 21 | 22 | export default KJVDefContainer; 23 | -------------------------------------------------------------------------------- /src/containers/reference-wrapper.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import ReferenceWrapper from '../components/reference-wrapper'; 3 | 4 | const mapStateToProps = ( { reference, settings }, ownProps ) => { 5 | return { 6 | inSync: settings.inSync, 7 | references: reference, 8 | } 9 | }; 10 | 11 | const ReferenceWrapperContainer = connect( 12 | mapStateToProps, 13 | )( ReferenceWrapper ) 14 | 15 | export default ReferenceWrapperContainer; 16 | -------------------------------------------------------------------------------- /src/containers/reference.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { setScrollChapter } from '../actions'; 3 | import Reference from '../components/reference'; 4 | 5 | 6 | const mapStateToProps = ( state, ownProps ) => { 7 | return { 8 | inSync: state.settings.inSync, 9 | } 10 | }; 11 | 12 | const mapDispatchToProps = ( dispatch, ownProps ) => { 13 | return { 14 | setScrollChapter: ( book, chapter, index ) => { 15 | dispatch( setScrollChapter( book, chapter, index ) ); 16 | }, 17 | setScrollChapterPrevious: ( book, chapter, index ) => { 18 | const currentChapter = bible.parseReference( book + ' ' + chapter ); 19 | const prevChapter = currentChapter.prevChapter(); 20 | if ( prevChapter ) { 21 | dispatch( setScrollChapter( prevChapter.bookName, prevChapter.chapter1, index ) ); 22 | } 23 | }, 24 | } 25 | }; 26 | 27 | const ReferenceContainer = connect( 28 | mapStateToProps, 29 | mapDispatchToProps 30 | )( Reference ) 31 | 32 | export default ReferenceContainer; 33 | -------------------------------------------------------------------------------- /src/containers/root.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import Root from '../components/root'; 3 | 4 | const mapStateToProps = ( state, ownProps ) => { 5 | return { 6 | settings: state.settings, 7 | }; 8 | }; 9 | 10 | const RootContainer = connect( 11 | mapStateToProps 12 | )( Root ); 13 | 14 | export default Root; 15 | -------------------------------------------------------------------------------- /src/containers/search-block.js: -------------------------------------------------------------------------------- 1 | // External 2 | import { connect } from 'react-redux'; 3 | import find from 'lodash/find'; 4 | import isEqual from 'lodash/isEqual'; 5 | 6 | // Internal 7 | import SearchBlock from '../components/search/search-block'; 8 | import { setCurrentVerse } from '../actions'; 9 | 10 | function getSearchResults( searchResults, terms ) { 11 | const searchResultsData = searchResults.find( searchResult => isEqual( searchResult.terms, terms ) ); 12 | 13 | if ( searchResultsData ) { 14 | return searchResultsData.results; 15 | } 16 | } 17 | 18 | const mapStateToProps = ( state, ownProps ) => { 19 | return { 20 | results: getSearchResults( state.searchResults, ownProps.terms ) 21 | }; 22 | }; 23 | 24 | const mapDispatchToProps = ( dispatch, ownProps ) => { 25 | return { 26 | setCurrentVerse: ( index ) => { 27 | dispatch( setCurrentVerse( ownProps.terms, index ) ); 28 | }, 29 | } 30 | }; 31 | 32 | const SearchBlockContainer = connect( 33 | mapStateToProps, 34 | mapDispatchToProps 35 | )( SearchBlock ) 36 | 37 | export default SearchBlockContainer; 38 | -------------------------------------------------------------------------------- /src/containers/search-link.js: -------------------------------------------------------------------------------- 1 | // External 2 | import { connect } from 'react-redux'; 3 | import find from 'lodash/find'; 4 | import isEqual from 'lodash/isEqual'; 5 | 6 | // Internal 7 | import SearchLink from '../components/search/search-link'; 8 | import { setCurrentVerse } from '../actions'; 9 | 10 | function isActive( currentReference, ownProps ) { 11 | if( ownProps.terms === currentReference.terms && currentReference.activeReference === ownProps.index ) { 12 | return true; 13 | } 14 | 15 | return false; 16 | } 17 | 18 | const mapStateToProps = ( state, ownProps ) => { 19 | return { 20 | isActive: isActive( state.currentReference, ownProps ), 21 | expandedSearchResults: state.settings.expandedSearchResults, 22 | }; 23 | }; 24 | 25 | const mapDispatchToProps = ( dispatch, ownProps ) => { 26 | return { 27 | setCurrentVerse: ( index ) => { 28 | dispatch( setCurrentVerse( ownProps.terms, index ) ); 29 | }, 30 | } 31 | }; 32 | 33 | const SearchLinkContainer = connect( 34 | mapStateToProps, 35 | mapDispatchToProps 36 | )( SearchLink ) 37 | 38 | export default SearchLinkContainer; 39 | -------------------------------------------------------------------------------- /src/containers/search.js: -------------------------------------------------------------------------------- 1 | // External 2 | import { connect } from 'react-redux'; 3 | 4 | // Internal 5 | import { 6 | addSearch, 7 | clearAll, 8 | removeSearch, 9 | toggleSearch, 10 | closeAdvancedSearch, 11 | openAdvancedSearch, 12 | settingsChange, 13 | activateSearchSelect, 14 | updateSearchForm, 15 | clearSearchForm, 16 | } from '../actions' 17 | import Search from '../components/search'; 18 | 19 | const mapStateToProps = ( state, ownProps ) => { 20 | return { 21 | searchAdvanced: state.searchAdvanced, 22 | searchTerms: state.searchTerms, 23 | settings: state.settings, 24 | searchForm: state.searchForm, 25 | }; 26 | }; 27 | 28 | const mapDispatchToProps = ( dispatch, ownProps ) => { 29 | javascripture.reactHelpers.dispatch = dispatch; 30 | return { 31 | updateSearchForm: ( name, value ) => { 32 | dispatch( updateSearchForm( name, value ) ); 33 | }, 34 | addSearch: ( terms ) => { 35 | dispatch( addSearch( terms, 'search' ) ); 36 | dispatch( clearSearchForm() ); 37 | }, 38 | removeSearch: ( terms ) => { 39 | dispatch( removeSearch( terms ) ); 40 | }, 41 | toggleSearch: ( terms ) => { 42 | dispatch( toggleSearch( terms ) ); 43 | }, 44 | clearAllSearch: () => { 45 | dispatch( clearAll() ); 46 | }, 47 | openAdvancedSearch: () => { 48 | dispatch( openAdvancedSearch() ); 49 | }, 50 | closeAdvancedSearch: () => { 51 | dispatch( closeAdvancedSearch() ); 52 | }, 53 | expandSearchResults: () => { 54 | dispatch( settingsChange( 'expandedSearchResults', true ) ); 55 | }, 56 | collapseSearchResults: () => { 57 | dispatch( settingsChange( 'expandedSearchResults', false ) ); 58 | }, 59 | activateSearchSelect: ( mode ) => { 60 | dispatch( activateSearchSelect( mode ) ); 61 | }, 62 | clearSearchForm: () => { 63 | dispatch( clearSearchForm() ); 64 | }, 65 | } 66 | }; 67 | 68 | const SearchContainer = connect( 69 | mapStateToProps, 70 | mapDispatchToProps 71 | )( Search ) 72 | 73 | export default SearchContainer; 74 | -------------------------------------------------------------------------------- /src/containers/single-reference.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { addNextChapter, addPreviousChapter } from '../actions'; 3 | import SingleReference from '../components/reference/single-reference'; 4 | 5 | const mapStateToProps = ( state, ownProps ) => { 6 | return { 7 | scrollChapter: state.scrollChapter 8 | } 9 | }; 10 | 11 | const mapDispatchToProps = ( dispatch, ownProps ) => { 12 | return { 13 | addPreviousChapter: () => { 14 | dispatch( addPreviousChapter( ownProps.reference ) ); 15 | }, 16 | addNextChapter: () => { 17 | dispatch( addNextChapter( ownProps.reference ) ); 18 | } 19 | } 20 | }; 21 | 22 | const SingleReferenceContainer = connect( 23 | mapStateToProps, 24 | mapDispatchToProps 25 | )( SingleReference ) 26 | 27 | export default SingleReferenceContainer; 28 | -------------------------------------------------------------------------------- /src/containers/verse.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import Verse from '../components/reference/verse'; 3 | 4 | const mapStateToProps = ( state, ownProps ) => { 5 | return { 6 | references: state.references 7 | } 8 | }; 9 | 10 | const VerseContainer = connect( 11 | mapStateToProps 12 | )( Verse ) 13 | 14 | export default VerseContainer; 15 | -------------------------------------------------------------------------------- /src/containers/version-selector.js: -------------------------------------------------------------------------------- 1 | // External 2 | import { connect } from 'react-redux'; 3 | import find from 'lodash/find'; 4 | import isEqual from 'lodash/isEqual'; 5 | 6 | // Internal 7 | import VersionSelector from '../components/version-selector'; 8 | import { changeVersion, setReference, setScrollChapter } from '../actions' 9 | 10 | const getReferenceValue = ( state, index ) => { 11 | const chapter = ( state.scrollChapter[ index ] && state.scrollChapter[ index ].chapter ) ? state.scrollChapter[ index ].chapter : state.reference[ index ].chapter; 12 | const book = ( state.scrollChapter[ index ] && state.scrollChapter[ index ].book ) ? state.scrollChapter[ index ].book : state.reference[ index ].book; 13 | 14 | return book + ' ' + chapter; 15 | }; 16 | 17 | const mapStateToProps = ( state, ownProps ) => { 18 | return { 19 | inSync: state.settings.inSync, 20 | references: state.reference, 21 | value: getReferenceValue( state, ownProps.index ), 22 | } 23 | }; 24 | 25 | const mapDispatchToProps = ( dispatch, ownProps ) => { 26 | return { 27 | changeVersion: ( index, version ) => { 28 | dispatch( changeVersion( index, version ) ); 29 | }, 30 | setReference: ( reference, index ) => { 31 | dispatch( setReference( reference, index ) ); 32 | dispatch( setScrollChapter( reference.book, reference.chapter, index ) ); 33 | }, 34 | } 35 | }; 36 | 37 | const VersionSelectorContainer = connect( 38 | mapStateToProps, 39 | mapDispatchToProps 40 | )( VersionSelector ) 41 | 42 | export default VersionSelectorContainer; 43 | -------------------------------------------------------------------------------- /src/containers/visible-trays.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import findIndex from 'lodash/findIndex'; 3 | import { toggleTray } from '../actions' 4 | import TrayList from '../components/trays/tray-list'; 5 | 6 | const mapStateToProps = ( state ) => { 7 | return { 8 | trays: state.trays, 9 | filter: state.trayVisibilityFilter, 10 | } 11 | } 12 | 13 | const mapDispatchToProps = ( dispatch ) => { 14 | return { 15 | onTrayClick: ( id ) => { 16 | dispatch( toggleTray( id ) ) 17 | }, 18 | } 19 | } 20 | 21 | const VisibleTrayList = connect( 22 | mapStateToProps, 23 | mapDispatchToProps 24 | )( TrayList ) 25 | 26 | export default VisibleTrayList 27 | -------------------------------------------------------------------------------- /src/containers/word-block.js: -------------------------------------------------------------------------------- 1 | // External 2 | import { connect } from 'react-redux'; 3 | 4 | // Internal 5 | import WordBlock from '../components/word-details/word-block'; 6 | import { addWord, removeSearch, removeWord, settingsChange, toggleWord } from '../actions' 7 | 8 | const mapStateToProps = ( state, ownProps ) => { 9 | return { 10 | settings: state.settings, 11 | }; 12 | }; 13 | 14 | const mapDispatchToProps = ( dispatch, ownProps ) => { 15 | return { 16 | addWord: ( strongsNumber ) => { 17 | dispatch( addWord( { 18 | strongsNumber: strongsNumber, 19 | open: true, 20 | morphology: null, 21 | version: ownProps.version, 22 | } ) ); 23 | }, 24 | 25 | removeWord: ( lemma, version ) => { 26 | const searchParameters = { 27 | clusivity: 'exclusive', 28 | version: version, 29 | lemma: lemma, 30 | range: 'verse', 31 | }; 32 | 33 | dispatch( removeWord( lemma ) ); 34 | dispatch( removeSearch( searchParameters ) ); 35 | }, 36 | 37 | toggleWord: () => { 38 | dispatch( toggleWord( ownProps.strongsNumber ) ); 39 | }, 40 | 41 | expandSearchResults: () => { 42 | dispatch( settingsChange( 'expandedSearchResults', true ) ); 43 | }, 44 | 45 | collapseSearchResults: () => { 46 | dispatch( settingsChange( 'expandedSearchResults', false ) ); 47 | }, 48 | 49 | } 50 | }; 51 | 52 | const WordBlockContainer = connect( 53 | mapStateToProps, 54 | mapDispatchToProps, 55 | )( WordBlock ) 56 | 57 | export default WordBlockContainer; 58 | -------------------------------------------------------------------------------- /src/containers/word-details.js: -------------------------------------------------------------------------------- 1 | // External 2 | import { connect } from 'react-redux'; 3 | 4 | // Internal 5 | import WordDetails from '../components/word-details'; 6 | import { addWord, clearAll, removeWord } from '../actions' 7 | 8 | const mapStateToProps = ( state, ownProps ) => { 9 | return { 10 | words: state.wordDetails 11 | } 12 | }; 13 | 14 | const mapDispatchToProps = ( dispatch, ownProps ) => { 15 | return { 16 | addWord: ( lemma, open, morphology, version ) => { 17 | dispatch( addWord( { lemma, open, morphology, version } ) ); 18 | }, 19 | 20 | clearAll: () => { 21 | dispatch( clearAll() ); 22 | }, 23 | 24 | removeWord: ( lemma ) => { 25 | dispatch( removeWord( lemma ) ); 26 | }, 27 | } 28 | }; 29 | 30 | const WordDetailsContainer = connect( 31 | mapStateToProps, 32 | mapDispatchToProps 33 | )( WordDetails ) 34 | 35 | export default WordDetailsContainer; 36 | -------------------------------------------------------------------------------- /src/containers/word-highlight.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import WordHighlight from '../components/word-highlight'; 3 | 4 | const mapStateToProps = ( state, ownProps ) => { 5 | return { 6 | wordHighlight: state.wordHighlight, 7 | settings: state.settings, 8 | searchSelect: state.searchSelect, 9 | } 10 | }; 11 | 12 | const WordHighlightContainer = connect( 13 | mapStateToProps 14 | )( WordHighlight ) 15 | 16 | export default WordHighlightContainer; 17 | -------------------------------------------------------------------------------- /src/containers/word-single.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import { 3 | addWord, 4 | deactivateSearchSelect, 5 | removeWordHighlight, 6 | setWordHighlight, 7 | setTrayVisibilityFilter, 8 | updateSearchForm, 9 | appendToSearchForm 10 | } from '../actions'; 11 | import WordSingle from '../components/reference/word-single'; 12 | 13 | const mapStateToProps = ( state, ownProps ) => { 14 | return { 15 | highlighted: state.wordHighlight, 16 | searchSelect: state.searchSelect, 17 | settings: state.settings, 18 | } 19 | }; 20 | 21 | const mapDispatchToProps = ( dispatch, ownProps ) => { 22 | return { 23 | highlightOn: () => { 24 | dispatch( setWordHighlight( ownProps.lemma.split(' ') ) ) 25 | }, 26 | highlightOff: () => { 27 | dispatch( removeWordHighlight( ownProps.lemma.split( ' ' ) ) ) 28 | }, 29 | selectSearchTerm: ( name, value ) => { 30 | dispatch( appendToSearchForm( name, value ) ); 31 | dispatch( updateSearchForm( 'version', ownProps.language ) ); 32 | dispatch( deactivateSearchSelect() ); 33 | }, 34 | addWord: () => { 35 | dispatch( setTrayVisibilityFilter( 'word' ) ); 36 | 37 | ownProps.lemma && ownProps.lemma.split( ' ' ).map( strongsNumber => { 38 | if ( strongsNumber === "G3588" ) { 39 | return; 40 | } 41 | 42 | dispatch( addWord( { 43 | strongsNumber, 44 | open: true, 45 | morphology: ownProps.morph, 46 | version: ownProps.language, 47 | } ) ); 48 | } ); 49 | }, 50 | } 51 | }; 52 | 53 | const WordSingleContainer = connect( 54 | mapStateToProps, 55 | mapDispatchToProps 56 | )( WordSingle ) 57 | 58 | export default WordSingleContainer; 59 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * External dependencies 3 | */ 4 | import React from 'react'; 5 | import { render } from 'react-dom'; 6 | 7 | import App from './app'; 8 | 9 | let ContentRoot = render( , document.getElementById('content') ); 10 | 11 | if (module.hot) { 12 | module.hot.accept( './app', () => { 13 | const NextRootContainer = require('./app').default; 14 | ContentRoot = render( , document.getElementById('content') ); 15 | } ); 16 | }; 17 | 18 | window.updateAppComponent = ( key, value ) => { 19 | // Update state of topmost parent when this method is called 20 | const newState = {}; 21 | newState[ key ] = value; 22 | ContentRoot.setState( newState ); 23 | }; 24 | -------------------------------------------------------------------------------- /src/lib/morphology.js: -------------------------------------------------------------------------------- 1 | export default function (morph, includeLinks, lemma ) { 2 | if (includeLinks === undefined) { 3 | includeLinks = 'noLinks'; 4 | } 5 | var language = 'greek'; 6 | if ( lemma.substring( 0, 1 ) === "H" ) { 7 | language = 'hebrew'; 8 | } 9 | var morphologyDictionary = javascripture.data.morphology, 10 | markup = '', 11 | gender, 12 | morphArray, 13 | number, 14 | Case, 15 | person, 16 | Person, 17 | case2, 18 | mood, 19 | voice, 20 | tense, 21 | partOfSpeech; 22 | if (morph !== undefined) { 23 | //hebrew 24 | if (morphologyDictionary.hebrew[morph] !== undefined) { 25 | markup += morphologyDictionary.hebrew[morph]; 26 | } else { 27 | if ( 'hebrew' === language ) { 28 | const morphParseObject = new MorphParse(); 29 | if ( 'undefined' !== typeof morphParseObject.Parse( morph ) ) { 30 | markup += morphParseObject.Parse( 'H' + morph ); // The morphology API expexts the morph to be prepended with an H 31 | } 32 | } else { 33 | 34 | //greek 35 | morphArray = morph.split('-'); 36 | partOfSpeech = morphArray[0]; 37 | markup += morphologyDictionary.greek.partOfSpeech[partOfSpeech] + ' '; 38 | Case = morphArray[1]; 39 | if (partOfSpeech === 'V') { //for verbs 40 | if (Case !== undefined) { 41 | if (morphologyDictionary.greek.Case[Case] !== undefined) { 42 | markup += morphologyDictionary.greek.Case[Case] + ' '; 43 | } else { 44 | if (parseInt(Case[0], 10) > 0) { // second future, second aorist and second perfect 45 | tense = Case[0] + Case[1]; 46 | voice = Case[2]; 47 | mood = Case[3]; 48 | } else { 49 | tense = Case[0]; 50 | voice = Case[1]; 51 | mood = Case[2]; 52 | } 53 | markup += morphologyDictionary.greek.Case.tense[tense] + ' '; 54 | markup += morphologyDictionary.greek.Case.voice[voice] + ' '; 55 | if ( includeLinks === 'withLinks' ) { 56 | markup += ' 0 ) { 87 | Person = morphArray[1][0]; 88 | Case = morphArray[1][1]; 89 | number = morphArray[1][2]; 90 | gender = morphArray[1][3]; 91 | } else { 92 | Case = morphArray[1][0]; 93 | number = morphArray[1][1]; 94 | gender = morphArray[1][2]; 95 | } 96 | 97 | if ( typeof Person !== 'undefined' ) { 98 | markup += morphologyDictionary.greek.person[Person] + ' '; 99 | } 100 | markup += morphologyDictionary.greek.Case[Case] + ' '; 101 | markup += morphologyDictionary.greek.number[number] + ' '; 102 | if ( gender ) { 103 | markup += morphologyDictionary.greek.gender[gender]; 104 | } 105 | } 106 | } 107 | } 108 | } 109 | } 110 | } 111 | return markup; 112 | }; 113 | -------------------------------------------------------------------------------- /src/lib/reference.js: -------------------------------------------------------------------------------- 1 | export const createReferenceLink = ( reference ) => { 2 | return '/' + reference.book + '/' + reference.chapter + '/' + reference.verse; 3 | }; 4 | 5 | export const getLanguageFromVersion = ( book, version ) => { 6 | if ( version === 'original' || version === 'lc' ) { 7 | return bible.Data.otBooks.indexOf( book ) > -1 ? 'hebrew' : 'greek'; 8 | } 9 | 10 | return version; 11 | }; 12 | -------------------------------------------------------------------------------- /src/lib/strip-pointing.js: -------------------------------------------------------------------------------- 1 | const stripPointing = ( word ) => { 2 | return word.replace(/֑/gi,'') 3 | .replace(/֓/gi,'') 4 | .replace(/֕/gi,'') 5 | .replace(/֖/gi,'') 6 | .replace(/֘/gi,'') 7 | .replace(/֙/gi,'') 8 | .replace(/֚/gi,'') 9 | .replace(/֛/gi,'') 10 | .replace(/֜/gi,'') 11 | .replace(/֝/gi,'') 12 | .replace(/֞/gi,'') 13 | .replace(/֟/gi,'') 14 | .replace(/֠/gi,'') 15 | .replace(/֡/gi,'') 16 | .replace(/֢/gi,'') 17 | .replace(/֣/gi,'') 18 | .replace(/֤/gi,'') 19 | .replace(/֥/gi,'') 20 | .replace(/֦/gi,'') 21 | .replace(/֧/gi,'') 22 | .replace(/֩/gi,'') 23 | .replace(/֪/gi,'') 24 | .replace(/֫/gi,'') 25 | .replace(/֬/gi,'') 26 | .replace(/֭/gi,'') 27 | .replace(/֮/gi,'') 28 | .replace(/֯/gi,'') 29 | .replace(/ֱ/gi,'') 30 | .replace(/ֲ/gi,'') 31 | .replace(/ֳ/gi,'') 32 | .replace(/ֵ/gi,'') 33 | .replace(/ֶ/gi,'') 34 | .replace(/ַ/gi,'') 35 | .replace(/ָ/gi,'') 36 | .replace(/ֹ/gi,'') 37 | .replace(/ֺ/gi,'') 38 | .replace(/ֻ/gi,'') 39 | .replace(/ּ/gi,'') 40 | .replace(/ֽ/gi,'') 41 | .replace(/־/gi,'') 42 | .replace(/׀/gi,'') 43 | .replace(/ׂ/gi,'') 44 | .replace(/׃/gi,'') 45 | .replace(/ׄ/gi,'') 46 | .replace(/ׇ/gi,'') 47 | .replace(/ׁ/gi,'') 48 | .replace(/ִ/gi,'') 49 | .replace(/ְ/,'') 50 | //new ones 51 | .replace(/ְ/,'') 52 | .replace(/ְ/,'') 53 | .replace(/ְ/,'') 54 | .replace(/֗/,'') 55 | .replace(/ְ/,'') 56 | .replace(/ְ/,'') 57 | .replace(/֔/,'') 58 | .replace(/ְ/,'') 59 | .replace(/ְ/,'') 60 | .replace(/֨/,'') 61 | .replace(/֑/,'') 62 | .replace(/֗/,'') 63 | .replace(/֨/,'') 64 | .replace(/֔/,''); 65 | //.replace(/\//,''); 66 | }; 67 | 68 | export default stripPointing; -------------------------------------------------------------------------------- /src/lib/stylizer/README.md: -------------------------------------------------------------------------------- 1 | Stylizer 2 | ======== 3 | 4 | `Stylizer` is a very simple library that is used in conjunction with the [isomorphic style loader](https://github.com/kriasoft/isomorphic-style-loader/) for Webpack and [React](https://facebook.github.io/react/). This loader picks up the output of previous loaders (usually a CSS loader) and injects the CSS into the page. `Stylizer` simplifies the use of this loader with React applications. 5 | 6 | To be more specific, `Stylizer` provides the function specified via the `onInsertCss` prop to all child components. It makes use of the [React context](https://facebook.github.io/react/docs/context.html) so you don't have to pass this function down manually at every level in the component tree. Each component should be decorated with the `withStyles` higher-order component provided by the loader. 7 | 8 | 9 | ### Client-side 10 | 11 | You should use the provided `insertCss()` function when rendering on the client: 12 | 13 | ``` 14 | import Stylizer, { insertCss } from 'lib/stylizer'; 15 | ... 16 | 17 | function render() { 18 | ... 19 | 20 | ReactDOM.render( 21 | 22 | 23 | 24 | 25 | , 26 | document.getElementById( 'content' ) 27 | ); 28 | } 29 | ``` 30 | 31 | 32 | ### Server-side 33 | 34 | It's your responsibility to provide a function to retrieve the styles when rendering on the server. You'll then have to inject these styles in the template of your page: 35 | 36 | ``` 37 | import curry from 'lodash/curry'; 38 | import Stylizer, { addCss } from 'lib/stylizer'; 39 | ... 40 | 41 | function render() { 42 | ... 43 | 44 | const css = []; 45 | 46 | const content = renderToString( 47 | 48 | 49 | 50 | 51 | 52 | ); 53 | 54 | response.send( template( { content, css: css.join( '' ) } ) ); 55 | } 56 | ``` 57 | 58 | 59 | ### Components 60 | 61 | Any component with styles should be wrapped with the `withStyles` function. The latter will retrieve the function provided to `Stylizer` from the React context and use it to aggregate all the styles: 62 | 63 | ``` 64 | import React from 'react'; 65 | import styles from './styles.scss'; 66 | import withStyles from 'isomorphic-style-loader/lib/withStyles'; 67 | 68 | const MyComponent = React.createClass( { 69 | render() { 70 | return ( 71 |
    72 |

    Hello world!

    73 |
    74 | ); 75 | } 76 | } ); 77 | 78 | export default withStyles( styles )( MyComponent ); 79 | ``` -------------------------------------------------------------------------------- /src/lib/stylizer/index.js: -------------------------------------------------------------------------------- 1 | import { Children, Component } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | class Stylizer extends Component { 5 | static propTypes = { 6 | children: PropTypes.element.isRequired, 7 | onInsertCss: PropTypes.func.isRequired 8 | }; 9 | 10 | static childContextTypes = { 11 | insertCss: PropTypes.func.isRequired 12 | }; 13 | 14 | getChildContext() { 15 | return { insertCss: this.props.onInsertCss }; 16 | } 17 | 18 | render() { 19 | return Children.only( this.props.children ); 20 | } 21 | } 22 | 23 | export default Stylizer; 24 | 25 | export function addCss( css, styles ) { 26 | css.push( styles._getCss() ); 27 | } 28 | 29 | export function insertCss( styles ) { 30 | return styles._insertCss(); 31 | } 32 | -------------------------------------------------------------------------------- /src/lib/word.js: -------------------------------------------------------------------------------- 1 | export const getFamily = ( strongsNumber ) => { 2 | if ( javascripture.data.strongsObjectWithFamilies[ strongsNumber ] ) { 3 | return javascripture.data.strongsObjectWithFamilies[ strongsNumber ].family; 4 | } else { 5 | return strongsNumber; 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /src/reducers/bookmarks.js: -------------------------------------------------------------------------------- 1 | const bookmarks = ( state = [], action ) => { 2 | switch ( action.type ) { 3 | case 'ADD_BOOKMARK': 4 | const newState = state.filter( reference => { 5 | return ! ( reference.book === action.reference.book && 6 | reference.chapter === action.reference.chapter && 7 | reference.verse === action.reference.verse ); 8 | } ) 9 | 10 | newState.push( action.reference ); 11 | return newState; 12 | 13 | case 'REMOVE_BOOKMARK': 14 | return state.filter( reference => { 15 | return ! ( reference.book === action.reference.book && 16 | reference.chapter === action.reference.chapter && 17 | reference.verse === action.reference.verse ); 18 | } ); 19 | 20 | default: 21 | return state; 22 | } 23 | } 24 | 25 | export default bookmarks; 26 | -------------------------------------------------------------------------------- /src/reducers/cross-references.js: -------------------------------------------------------------------------------- 1 | const crossReferences = ( state = '', action ) => { 2 | switch ( action.type ) { 3 | case 'SHOW_CROSS_REFERENCES': 4 | return action.reference; 5 | 6 | default: 7 | return state; 8 | } 9 | } 10 | 11 | export default crossReferences; 12 | -------------------------------------------------------------------------------- /src/reducers/current-reference.js: -------------------------------------------------------------------------------- 1 | import findIndex from 'lodash/findIndex'; 2 | import isEqual from 'lodash/isEqual'; 3 | 4 | const currentReference = ( state = {}, action ) => { 5 | switch ( action.type ) { 6 | case 'SET_CURRENT_VERSE': 7 | return { 8 | terms: action.terms, 9 | activeReference: action.index 10 | }; 11 | 12 | case 'GO_TO_NEXT_CURRENT_VERSE': 13 | return Object.assign( {}, state, { 14 | activeReference: state.activeReference + 1 15 | } ); 16 | 17 | case 'GO_TO_PREVIOUS_CURRENT_VERSE': 18 | return Object.assign( {}, state, { 19 | activeReference: state.activeReference - 1 20 | } ); 21 | 22 | case 'CLEAR_ALL': 23 | return []; 24 | 25 | default: 26 | return state; 27 | } 28 | } 29 | 30 | export default currentReference; 31 | -------------------------------------------------------------------------------- /src/reducers/index.js: -------------------------------------------------------------------------------- 1 | import bookmarks from './bookmarks'; 2 | import reference from './reference'; 3 | import referenceSelectorMobile from './reference-selector-mobile'; 4 | import scrollChapter from './scroll-chapter'; 5 | import searchAdvanced from './search-advanced'; 6 | import searchForm from './search-form'; 7 | import searchResults from './search-results'; 8 | import searchSelect from './search-select'; 9 | import searchTerms from './search-terms'; 10 | import settings from './settings'; 11 | import trays from './trays'; 12 | import wordDetails from './word-details'; 13 | import wordHighlight from './word-highlight'; 14 | import crossReferences from './cross-references'; 15 | import currentReference from './current-reference'; 16 | import version from './version'; 17 | 18 | const app = { 19 | bookmarks, 20 | crossReferences, 21 | currentReference, 22 | reference, 23 | referenceSelectorMobile, 24 | scrollChapter, 25 | searchAdvanced, 26 | searchForm, 27 | searchResults, 28 | searchSelect, 29 | searchTerms, 30 | settings, 31 | trays, 32 | version, 33 | wordDetails, 34 | wordHighlight, 35 | }; 36 | 37 | export default app; 38 | -------------------------------------------------------------------------------- /src/reducers/reference-selector-mobile.js: -------------------------------------------------------------------------------- 1 | const initialState = [ { 2 | open: false, 3 | bookIndex: null, 4 | bookName: null, 5 | }, { 6 | open: false, 7 | bookIndex: null, 8 | bookName: null, 9 | } ]; 10 | 11 | const openState = { 12 | open: true, 13 | bookIndex: null, 14 | bookName: null, 15 | }; 16 | 17 | const referenceSelectorMobile = ( state = initialState, action ) => { 18 | switch ( action.type ) { 19 | case 'CLOSE_REFERENCE_SELECTOR_MOBILE': 20 | return state.map( () => { 21 | return { 22 | open: false, 23 | bookIndex: null, 24 | bookName: null, 25 | }; 26 | } ); 27 | 28 | case 'TOGGLE_REFERENCE_SELECTOR_MOBILE': 29 | const newState = state.map( () => { 30 | return { 31 | open: false, 32 | bookIndex: null, 33 | bookName: null, 34 | }; 35 | } ); 36 | 37 | newState[ action.index ].open = ! state[ action.index ].open; 38 | return newState; 39 | 40 | case 'REFERENCE_SELECTOR_MOBILE_SET_BOOK': 41 | const setBookState = [ ...state ]; 42 | setBookState[ action.index ].bookName = action.bookName; 43 | setBookState[ action.index ].bookIndex = action.bookIndex; 44 | 45 | return setBookState; 46 | 47 | case 'ADD_COLUMN': 48 | const addedState = [ ...state ]; 49 | addedState.push( { 50 | open: false, 51 | bookIndex: null, 52 | bookName: null, 53 | } ); 54 | return addedState; 55 | 56 | case 'REMOVE_COLUMN': 57 | const removedState = [ ...state ]; 58 | removedState.splice( action.index, 1 ); 59 | return removedState; 60 | 61 | default: 62 | return state; 63 | } 64 | } 65 | 66 | export default referenceSelectorMobile; 67 | -------------------------------------------------------------------------------- /src/reducers/reference.js: -------------------------------------------------------------------------------- 1 | import { LOCATION_CHANGE } from 'connected-react-router'; 2 | import { REHYDRATE } from 'redux-persist/lib/constants' 3 | import { isMatch } from 'lodash'; 4 | 5 | const getRandomReference = function() { 6 | var bookNumber = Math.floor(Math.random() * bible.Data.books.length), 7 | chapterNumber = Math.floor(Math.random() * bible.Data.verses[bookNumber].length), 8 | numberOfVerses = bible.Data.verses[bookNumber][chapterNumber], 9 | verseNumber = Math.floor(Math.random() * numberOfVerses), 10 | referenceObject = {}; 11 | referenceObject.book = bible.Data.books[bookNumber][0]; 12 | referenceObject.chapter = chapterNumber + 1; 13 | referenceObject.verse = verseNumber + 1; 14 | return referenceObject; 15 | }; 16 | 17 | if ( window.location.hash.length < 3 ) { 18 | const randomReference = getRandomReference(); 19 | window.location.hash = '#/' + randomReference.book + '/' + randomReference.chapter + '/' + randomReference.verse; 20 | } 21 | 22 | const getReferenceFromHash = function( hash, version ) { 23 | const reference = hash.split( '/' ); 24 | if ( ! reference[ 1 ] ) { 25 | return false; 26 | } 27 | 28 | const book = reference[ 1 ].replace( /\%20/gi, ' ' ), 29 | chapter = parseInt( reference[ 2 ] ), 30 | verse = reference[ 3 ] ? parseInt( reference[ 3 ] ) : 1; 31 | 32 | return { book, chapter, verse, version }; 33 | }; 34 | 35 | const getReferenceFromAction = ( reference, version ) => { 36 | const book = reference.book.replace( /\%20/gi, ' ' ), 37 | chapter = parseInt( reference.chapter ), 38 | verse = reference.verse ? parseInt( reference.verse ) : 1; 39 | 40 | return { book, chapter, verse, version }; 41 | } 42 | 43 | const getInitialState = () => { 44 | return [ getReferenceFromHash( window.location.hash, 'original' ), getReferenceFromHash( window.location.hash, 'kjv' ) ]; 45 | } 46 | 47 | const reference = ( state = getInitialState(), action ) => { 48 | switch ( action.type ) { 49 | case LOCATION_CHANGE: 50 | const reference = getReferenceFromHash( action.payload.location.hash, state[ 0 ].version ); 51 | if ( ! reference ) { 52 | return state; 53 | } 54 | const locationState = [ ...state ]; 55 | locationState[ 0 ] = reference; 56 | return locationState; 57 | 58 | case 'CHANGE_VERSION': 59 | const newState = [ ...state ]; 60 | const newReference = newState[ action.index ]; 61 | newReference.version = action.version; 62 | newState[ action.index ] = newReference; 63 | return newState; 64 | 65 | case 'SET_REFERENCE': 66 | const setReferenceState = [ ...state ]; 67 | setReferenceState[ action.index ] = getReferenceFromAction( action.reference, setReferenceState[ action.index ].version ); 68 | return setReferenceState; 69 | 70 | case 'ADD_COLUMN': 71 | const addedState = [ ...state ]; 72 | const numberOfColumns = state.length; 73 | const addedColumn = Object.assign( {}, state[ state.length - 1 ] ); 74 | addedState.push( addedColumn ); 75 | return addedState; 76 | 77 | case 'REMOVE_COLUMN': 78 | const removedState = [ ...state ]; 79 | removedState.splice( action.index, 1 ); 80 | return removedState; 81 | 82 | default: 83 | return state; 84 | } 85 | } 86 | 87 | export default reference; 88 | -------------------------------------------------------------------------------- /src/reducers/scroll-chapter.js: -------------------------------------------------------------------------------- 1 | import { LOCATION_CHANGE } from 'connected-react-router'; 2 | 3 | const initialState = [{},{}]; 4 | 5 | const getReferenceFromHash = function( hash ) { 6 | const reference = hash.split( '/' ); 7 | if ( ! reference[ 1 ] ) { 8 | return false; 9 | } 10 | 11 | const book = reference[ 1 ].replace( /\%20/gi, ' ' ), 12 | chapter = parseInt( reference[ 2 ] ), 13 | verse = 1; 14 | 15 | return { book, chapter, verse }; 16 | } 17 | 18 | const scrollChapter = ( state = initialState, action ) => { 19 | switch ( action.type ) { 20 | case LOCATION_CHANGE: 21 | const locationState = [ ...state ], 22 | reference = getReferenceFromHash( action.payload.location.hash ); 23 | locationState[ 0 ] = reference; 24 | 25 | return locationState; 26 | 27 | case 'SET_SCROLL_CHAPTER': 28 | const newState = [ ...state], 29 | book = action.book, 30 | chapter = action.chapter, 31 | index = action.index; 32 | 33 | newState[ index ] = { book, chapter }; 34 | return newState; 35 | 36 | case 'REMOVE_COLUMN': 37 | const removedState = [ ...state ]; 38 | removedState.splice( action.index, 1 ); 39 | return removedState; 40 | 41 | default: 42 | return state; 43 | } 44 | } 45 | 46 | export default scrollChapter; 47 | -------------------------------------------------------------------------------- /src/reducers/search-advanced.js: -------------------------------------------------------------------------------- 1 | const searchAdvanced = ( state = false, action ) => { 2 | switch ( action.type ) { 3 | case 'OPEN_ADVANCED_SEARCH': 4 | return true; 5 | 6 | case 'CLOSE_ADVANCED_SEARCH': 7 | return false; 8 | 9 | default: 10 | return state; 11 | } 12 | } 13 | 14 | export default searchAdvanced; 15 | -------------------------------------------------------------------------------- /src/reducers/search-form.js: -------------------------------------------------------------------------------- 1 | const initialState = { 2 | word: '', 3 | lemma: '', 4 | morph: '', 5 | version: 'kjv', 6 | clusivity: 'exclusive', 7 | range: 'verse', 8 | strict: false, 9 | }; 10 | 11 | const searchForm = ( state = initialState, action ) => { 12 | switch ( action.type ) { 13 | case 'UPDATE_SEARCH_FORM': 14 | const updatedSearchForm = { ...state }; 15 | updatedSearchForm[ action.name ] = action.value.trimStart(); 16 | return updatedSearchForm; 17 | 18 | case 'APPEND_TO_SEARCH_FORM': 19 | const appendedSearchForm = { ...state }; 20 | appendedSearchForm[ action.name ] = ( appendedSearchForm[ action.name ] + ' ' + action.value ).trimStart(); 21 | return appendedSearchForm; 22 | 23 | case 'CLEAR_SEARCH_FORM': 24 | return { ...initialState }; 25 | 26 | default: 27 | return state; 28 | } 29 | } 30 | 31 | export default searchForm; 32 | -------------------------------------------------------------------------------- /src/reducers/search-results.js: -------------------------------------------------------------------------------- 1 | import findIndex from 'lodash/findIndex'; 2 | import isEqual from 'lodash/isEqual'; 3 | 4 | const searchResults = ( state = [], action ) => { 5 | let newState, 6 | getCurrentVersePosition, 7 | reference; 8 | 9 | switch ( action.type ) { 10 | case 'ADD_SEARCH_RESULTS': 11 | const searchResultsPosition = findIndex( state, searchTerm => { 12 | return isEqual( searchTerm.terms, action.terms ); 13 | } ); 14 | newState = [ ...state ]; 15 | if ( searchResultsPosition > -1 ) { 16 | newState[ searchResultsPosition ] = { 17 | results: action.results.length > 0 ? action.results : 'No results', 18 | terms: newState[ searchResultsPosition ].terms, 19 | }; 20 | 21 | return newState; 22 | } 23 | 24 | return [ 25 | ...newState, 26 | { 27 | results: action.results.length > 0 ? action.results : 'No results', 28 | terms: action.terms, 29 | } 30 | ]; 31 | 32 | case 'REMOVE_SEARCH': 33 | return state.filter( searchTerm => { 34 | return ! isEqual( searchTerm.terms, action.terms ); 35 | } ); 36 | 37 | case 'CLEAR_ALL': 38 | return []; 39 | 40 | default: 41 | return state; 42 | } 43 | } 44 | 45 | export default searchResults; 46 | -------------------------------------------------------------------------------- /src/reducers/search-select.js: -------------------------------------------------------------------------------- 1 | const searchSelect = ( state = null, action ) => { 2 | switch ( action.type ) { 3 | case 'ACTIVATE_SEARCH_SELECT': 4 | return action.target; 5 | 6 | case 'DEACTIVATE_SEARCH_SELECT': 7 | return null; 8 | 9 | default: 10 | return state; 11 | } 12 | } 13 | 14 | export default searchSelect; 15 | -------------------------------------------------------------------------------- /src/reducers/search-terms.js: -------------------------------------------------------------------------------- 1 | import clone from 'lodash/clone'; 2 | import findIndex from 'lodash/findIndex'; 3 | import isEqual from 'lodash/isEqual'; 4 | import isMatch from 'lodash/isMatch'; 5 | 6 | const searchTerms = ( state = [], action ) => { 7 | let newState, 8 | getCurrentVersePosition, 9 | reference; 10 | 11 | switch ( action.type ) { 12 | case 'ADD_SEARCH': 13 | const termPosition = findIndex( state, searchTerm => isEqual( searchTerm.terms, action.terms ) ); 14 | newState = state.map( searchTerm => { 15 | return { 16 | open: false, 17 | results: searchTerm.results, 18 | terms: searchTerm.terms, 19 | }; 20 | } ); 21 | 22 | if ( termPosition > -1 ) { 23 | newState[ termPosition ].open = true; 24 | return [ ...newState ]; 25 | } 26 | 27 | return [ 28 | ...newState, 29 | { 30 | open: true, 31 | results: 'Searching…', 32 | terms: action.terms, 33 | } 34 | ]; 35 | 36 | case 'TOGGLE_SEARCH': 37 | const toggleWordPosition = findIndex( state, word => isEqual( word.terms, action.terms ) ); 38 | if ( toggleWordPosition > -1 ) { // This should always be the case 39 | newState = [ ...state ]; 40 | 41 | newState[ toggleWordPosition ] = { 42 | open: ! state[ toggleWordPosition ].open, 43 | results: state[ toggleWordPosition ].results, 44 | terms: state[ toggleWordPosition ].terms, 45 | }; 46 | 47 | return newState; 48 | } 49 | 50 | return state; 51 | 52 | case 'REMOVE_SEARCH': 53 | return state.filter( word => { 54 | return word.terms !== action.terms; 55 | } ); 56 | 57 | case 'CLEAR_ALL': 58 | return []; 59 | 60 | default: 61 | return state; 62 | } 63 | } 64 | 65 | export default searchTerms; 66 | -------------------------------------------------------------------------------- /src/reducers/settings.js: -------------------------------------------------------------------------------- 1 | const initialState = { 2 | fontSize: "100%", 3 | fontFamily: "'Helvetica Neue', Helvetica, Arial, sans-serif", 4 | highlightWordsWith: "same", 5 | referencePicker: "select", 6 | subdue: "50%", 7 | inSync: true, 8 | expandedSearchResults: false, 9 | type: "SETTINGS_CHANGE", 10 | } 11 | 12 | export default ( state = initialState, action ) => { 13 | let settings; 14 | switch ( action.type ) { 15 | case 'SETTINGS_CHANGE': 16 | settings = Object.assign( {}, state, action ); 17 | break; 18 | 19 | default: 20 | settings = state; 21 | break; 22 | } 23 | 24 | javascripture.state.settings = settings; 25 | return settings; 26 | } 27 | -------------------------------------------------------------------------------- /src/reducers/trayVisibilityFilter.js: -------------------------------------------------------------------------------- 1 | import { LOCATION_CHANGE } from 'connected-react-router'; 2 | 3 | const trayVisibilityFilter = ( state = 'goto', action ) => { 4 | switch ( action.type ) { 5 | case 'SET_TRAY_VISIBILITY_FILTER': 6 | return action.filter; 7 | 8 | case LOCATION_CHANGE: 9 | if ( window.innerWidth < 600 ) { 10 | return 'SHOW_NONE'; 11 | } 12 | 13 | default: 14 | return state; 15 | } 16 | } 17 | 18 | export default trayVisibilityFilter 19 | -------------------------------------------------------------------------------- /src/reducers/trays.js: -------------------------------------------------------------------------------- 1 | import { LOCATION_CHANGE } from 'connected-react-router'; 2 | 3 | const initalState = [ 4 | { 5 | visible: true, 6 | id: 'goto', 7 | text: 'Go to', 8 | component: 'GotoTray' 9 | }, 10 | { 11 | visible: false, 12 | id: 'word', 13 | text: 'Word Details', 14 | component: 'WordTray' 15 | }, 16 | { 17 | visible: false, 18 | id: 'search', 19 | text: 'Search', 20 | component: 'SearchTray' 21 | }, 22 | { 23 | visible: false, 24 | id: 'bookmarks', 25 | text: 'Bookmarks', 26 | component: 'BookmarksTray' 27 | }, 28 | { 29 | visible: false, 30 | id: 'settings', 31 | text: 'Settings', 32 | component: 'SettingsTray' 33 | } 34 | ]; 35 | 36 | const trays = ( state = initalState, action ) => { 37 | switch ( action.type ) { 38 | case 'SET_TRAY_VISIBILITY_FILTER': 39 | return state.map( tray => { 40 | if ( action.filter === tray.id ) { 41 | tray.visible = true; 42 | } else { 43 | tray.visible = false; 44 | } 45 | return tray; 46 | } ); 47 | 48 | case LOCATION_CHANGE: 49 | if ( window.innerWidth < 600 ) { 50 | return state.map( tray => { 51 | tray.visible = false; 52 | return tray; 53 | } ); 54 | } 55 | return state; 56 | 57 | default: 58 | return state; 59 | } 60 | } 61 | 62 | export default trays; 63 | -------------------------------------------------------------------------------- /src/reducers/version.js: -------------------------------------------------------------------------------- 1 | const version = ( state = { left: 'original', right: 'kjv' }, action ) => { 2 | let returnState; 3 | switch ( action.type ) { 4 | default: 5 | returnState = state; 6 | break; 7 | } 8 | 9 | javascripture.state.version = returnState; 10 | return returnState; 11 | } 12 | 13 | export default version; 14 | -------------------------------------------------------------------------------- /src/reducers/word-details.js: -------------------------------------------------------------------------------- 1 | import clone from 'lodash/clone'; 2 | import findIndex from 'lodash/findIndex'; 3 | 4 | const wordDetails = ( state = [], action ) => { 5 | let newState, 6 | getCurrentVersePosition, 7 | reference; 8 | 9 | switch ( action.type ) { 10 | case 'ADD_WORD': 11 | const wordPosition = findIndex( state, word => word.strongsNumber === action.strongsNumber ); 12 | newState = state.map( word => { 13 | return { 14 | strongsNumber: word.strongsNumber, 15 | open: false, 16 | morphology: word.morphology, 17 | version: word.version, 18 | }; 19 | } ); 20 | 21 | if ( wordPosition > -1 ) { 22 | newState[ wordPosition ] = { 23 | strongsNumber: action.strongsNumber, 24 | open: action.open, 25 | morphology: action.morphology, 26 | version: action.version, 27 | }; 28 | 29 | return newState; 30 | } 31 | 32 | return [ 33 | ...newState, 34 | { 35 | strongsNumber: action.strongsNumber, 36 | open: action.open, 37 | morphology: action.morphology, 38 | version: action.version, 39 | } 40 | ]; 41 | 42 | case 'TOGGLE_WORD': 43 | const toggleWordPosition = findIndex( state, word => word.strongsNumber === action.strongsNumber ); 44 | if ( toggleWordPosition > -1 ) { // This should always be the case 45 | newState = [ ...state ]; 46 | 47 | newState[ toggleWordPosition ] = { 48 | strongsNumber: state[ toggleWordPosition ].strongsNumber, 49 | open: ! state[ toggleWordPosition ].open, 50 | morphology: state[ toggleWordPosition ].morphology, 51 | version: state[ toggleWordPosition ].version, 52 | }; 53 | 54 | return newState; 55 | } 56 | 57 | return state; 58 | 59 | case 'REMOVE_WORD': 60 | return state.filter( word => { 61 | return word.strongsNumber !== action.strongsNumber; 62 | } ); 63 | 64 | case 'CLEAR_ALL': 65 | return []; 66 | 67 | default: 68 | return state; 69 | } 70 | } 71 | 72 | export default wordDetails; 73 | -------------------------------------------------------------------------------- /src/reducers/word-highlight.js: -------------------------------------------------------------------------------- 1 | import difference from 'lodash/difference'; 2 | 3 | const wordHighlight = ( state = [], action ) => { 4 | switch ( action.type ) { 5 | case 'SET_WORD_HIGHLIGHT': 6 | return [ ...state.concat( action.word ) ]; 7 | case 'REMOVE_WORD_HIGHLIGHT': 8 | return difference( state, action.word ); 9 | default: 10 | return state 11 | } 12 | } 13 | 14 | export default wordHighlight; 15 | -------------------------------------------------------------------------------- /sw.js: -------------------------------------------------------------------------------- 1 | var cache = 'javascripture.20'; // search summary highlighting 2 | 3 | self.addEventListener('install', function(e) { 4 | e.waitUntil( caches.open( cache ).then(function(cache) { 5 | return cache.addAll([ 6 | '/', 7 | '/index.html', 8 | '/css/layout.css', 9 | '/manifest.json', 10 | '/javascripture.svg', 11 | //libs 12 | 'lib/MorphCodes.js', 13 | 'lib/MorphParse.js', 14 | 15 | //data 16 | 'data/bible.js', 17 | 'data/extra-dictionary.js', 18 | 'data/strongs-dictionary.js', 19 | 'data/strongs-greek-dictionary.js', 20 | 'data/kjvdwyer7.js', 21 | 'data/web3.js', 22 | 'data/strongsObjectWithFamilies2.js', 23 | 'data/hebrew.js', 24 | 'data/greek4.js', 25 | 'data/crossReferences.js', 26 | 'data/morphology.js', 27 | 'data/literalConsistent.js', 28 | 'data/literalConsistentExtra.js', 29 | 30 | //api - so that search works offline? 31 | 'api/searchApi.js', 32 | 33 | //modules 34 | 'build/bundle.js', 35 | 36 | //workers 37 | 'workers/worker.js', 38 | ]); 39 | 40 | })); 41 | }); 42 | 43 | self.addEventListener('fetch', function(event) { 44 | event.respondWith( 45 | caches.match(event.request).then(function(response) { 46 | return response || fetch(event.request); 47 | }) 48 | ); 49 | }); 50 | 51 | // Delete unused cache 52 | self.addEventListener('activate', function( event ) { 53 | const channel = new BroadcastChannel('sw-messages'); 54 | channel.addEventListener('message', event => { 55 | channel.postMessage( { versionNumber: cache } ); 56 | }); 57 | 58 | var cacheWhitelist = [ cache ]; 59 | event.waitUntil( 60 | caches.keys().then(function( keyList ) { 61 | return Promise.all(keyList.map(function( key ) { 62 | if (cacheWhitelist.indexOf( key ) === -1) { 63 | return caches.delete( key ); 64 | } 65 | })); 66 | }) 67 | ); 68 | }); 69 | -------------------------------------------------------------------------------- /todo: -------------------------------------------------------------------------------- 1 | // todo 2 | - fixing caching 3 | - make errors work better 4 | - set up a stable alternative site 5 | - improve mobile ui 6 | - browser cache 7 | - simplify word/word-single 8 | - gaps between words like there in 9 | - add to home screen 10 | 11 | found a non-existent verse 12 | Object { book: "Isaiah", chapter: 32, verse: 19 } 13 | 14 | 15 | 16 | - creating a new literal consistent translation 17 | - remove + from lemma 18 | - strip accents from greek? 19 | - fix greek roots 20 | - move word details to right 21 | - show the verse text with the search results 22 | 23 | data 24 | _____ 25 | 26 | - generate the strongs hebrew dictionary 27 | - generate kjv and put it in the repo 28 | - generate the greek and put it in the repo 29 | - look at getting ESV and NET 30 | - put strongs roots and families in repo 31 | - put WEB in repo? 32 | - cross references in repo 33 | 34 | 35 | 36 | 37 | //javascripture bugs 38 | ________________________________________ 39 | 40 | //scrolling deferred object 41 | 42 | 43 | number of refs found when searching 44 | keyboard shortcuts 45 | 46 | 47 | search for H232 48 | 49 | H01657 is a root of H0566 50 | acts 7:20 - word for take up is missing... 51 | G2470 is a root of G2471 52 | H02620 not related to H0982 53 | fix color changer 54 | search for G18 G2041 - why isn't 2 Tim 3:1 in the list? 55 | search for "change" broken 56 | H5214 57 | luke 8:25 - afrai 58 | link definitions to usage 59 | G96 is a root of G1381 60 | 61 | luke 6:41 - KJV/ 62 | mark 9:43 63 | 64 | 65 | beth-lehem 66 | G2928 is root of G4032 67 | H05797 is related to H01162 (via micah 5:3) 68 | H0748 is a root of H0724 69 | 70 | //javascripture features 71 | ________________________________________ 72 | highlight family or word 73 | autocomplete 74 | list of all heberew forms so can give consistent translation? 75 | soft hyphen 76 | show history 77 | use intersecting bubbles to show what words appear in all X passages and with words 78 | graphs for chapters and words 79 | word density 80 | change strict to exact 81 | find strange translations 82 | history - which passges you look up more and less 83 | back button 84 | make it more like a game - but what are achievements 85 | show greek/hebrew word in word tree 86 | judges 11:14 - H05314 - should be something else - breath not soul 87 | 88 | 89 | How to get the length of a JSON object 90 | ________________________________________ 91 | Hebrw morphology 92 | 93 | 1.tree empty 94 | 2.call function with stem 95 | 3.if is stem in not already in tree then 96 | 4.add stem to tree as empty object 97 | 5.loop through all relationships to stem 98 | 6.for each one go to step 2 99 | 100 | Occourances for simon: 101 | word frequence analysis 102 | 103 | -------------------------------------------------------------------------------- /web.php: -------------------------------------------------------------------------------- 1 | 1 ) ? ", \r\n":""; 10 | echo "[\r\n"; 11 | $all_verses = mysql_fetch_array(mysql_query( 'SELECT MAX(verse) FROM gen WHERE chapter = ' . $chapter ) )[0] + 1; 12 | for($verse=1;$verse<$all_verses;$verse++) { 13 | echo ( $verse > 1 ) ? ", \r\n":""; 14 | echo "["; 15 | $query = 'SELECT * FROM gen WHERE chapter = ' . $chapter . ' AND verse = ' . $verse . ' ORDER BY WordSeqNumber'; 16 | 17 | $result = mysql_query( $query ); 18 | $word = 1; 19 | while( $words = mysql_fetch_array( $result ) ) { 20 | echo ( $word > 1 ) ? ",":""; 21 | echo "["; 22 | echo "'" . addslashes( $words['pre'] . $words['word'] . $words['post'] ) . "'"; 23 | if ( $words['OrigWordLanguage'] == 'G' && $words['DictEntryNumber'] != 0 ) { 24 | echo ",'" . $words['OrigWordLanguage'] . $words['DictEntryNumber'] . "'"; 25 | } 26 | echo "]"; 27 | $word++; 28 | } 29 | echo "]"; 30 | } 31 | echo "\r\n]"; 32 | } 33 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * External dependencies 3 | */ 4 | var webpack = require( 'webpack' ), 5 | autoprefixer = require( 'autoprefixer' ), 6 | NODE_ENV = process.env.NODE_ENV || 'development', 7 | path = require( 'path' ); 8 | 9 | const CleanWebpackPlugin = require('clean-webpack-plugin'); 10 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 11 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin') 12 | 13 | var config = { 14 | mode: NODE_ENV, 15 | entry: { 16 | 'bundle' : [ 17 | './src' 18 | ] 19 | }, 20 | 21 | output: { 22 | path: path.join( __dirname, 'build' ), 23 | publicPath: '/build/', 24 | filename: '[name].js', 25 | devtoolModuleFilenameTemplate: 'app:///[resource-path]' 26 | }, 27 | 28 | module: { 29 | rules: [ 30 | { 31 | test: /\.jsx?$/, 32 | loader: 'babel-loader', 33 | exclude: /node_modules/, 34 | include: path.join( __dirname, '/src' ) 35 | }, 36 | { 37 | test: /\.json$/, 38 | loader: 'json-loader' 39 | }, 40 | { 41 | test: /\.scss$/, 42 | loaders: [ 43 | 'isomorphic-style-loader', 44 | 'css-loader?modules&importLoaders=1&localIdentName=[path][local]&camelCase=dashes&sourceMap', 45 | 'postcss-loader', 46 | 'sass-loader?sourceMap' 47 | ] 48 | } 49 | ], 50 | }, 51 | resolve: { 52 | extensions: [ '.json', '.js', '.jsx' ] 53 | }, 54 | node: { 55 | console: false, 56 | process: true, 57 | global: true, 58 | Buffer: true, 59 | __filename: 'mock', 60 | __dirname: 'mock', 61 | fs: 'empty' 62 | }, 63 | plugins: [ 64 | new webpack.DefinePlugin( { 65 | 'process.env': { 66 | NODE_ENV: JSON.stringify( NODE_ENV ), 67 | BROWSER: JSON.stringify( true ) 68 | } 69 | } ), 70 | ] 71 | }; 72 | 73 | if ( process.env.NODE_ENV !== 'production' ) { 74 | // Switches loaders to debug mode. This is required to make CSS hot reloading works correctly (see 75 | // http://bit.ly/1VTOHrK for more information). 76 | //config.debug = true; 77 | 78 | // Enables source maps 79 | config.devtool = 'eval'; 80 | 81 | config.devServer = { 82 | hot: true, 83 | port: 7777, 84 | historyApiFallback: true 85 | }; 86 | 87 | /*config.module.rules.unshift( { 88 | test: /\.jsx?$/, 89 | loader: 'react-hot-loader/webpack', 90 | include: path.join( __dirname, '/src' ), 91 | exclude: /node_modules/, 92 | } );*/ 93 | } 94 | 95 | if ( NODE_ENV === 'production' ) { 96 | config.optimization = {}; 97 | config.optimization.minimizer = [ 98 | new UglifyJsPlugin() 99 | ]; 100 | /*config.plugins.push( 101 | new webpack.optimize.UglifyJsPlugin( { 102 | output: { 103 | comments: false 104 | }, 105 | compress: { 106 | warnings: false 107 | } 108 | } ) 109 | );*/ 110 | } 111 | 112 | module.exports = config; -------------------------------------------------------------------------------- /worker.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /workers/worker.js: -------------------------------------------------------------------------------- 1 | var javascripture = {}; 2 | javascripture.data = {}; 3 | javascripture.data.kjv = {}; 4 | javascripture.data.web = {}; 5 | javascripture.data.greek = {}; 6 | javascripture.data.hebrew = {}; 7 | javascripture.api = {}; 8 | self.postMessage( { task: 'loading', html: 'loading KJV' } ); 9 | importScripts('../data/kjvdwyer7.js'); 10 | self.postMessage( { task: 'loading', html: 'loading WEB' } ); 11 | importScripts('../data/web3.js'); 12 | self.postMessage( { task: 'loading', html: 'loading Hebrew' } ); 13 | importScripts('../data/hebrew.js'); 14 | self.postMessage( { task: 'loading', html: 'loading Greek' } ); 15 | importScripts('../data/greek4.js'); 16 | 17 | importScripts('../data/bible.js'); 18 | self.postMessage( { task: 'loading', html: 'loading Strongs' } ); 19 | importScripts('../data/strongsObjectWithFamilies2.js'); 20 | 21 | self.postMessage( { task: 'loading', html: 'loading API' } ); 22 | importScripts('../api/searchApi.js'); 23 | self.postMessage( { task: 'loading', html: 'loading complete!' } ); 24 | self.addEventListener('message', function( e ) { 25 | var result; 26 | 27 | if ( e.data.task === 'search' || e.data.task === 'word' ) { 28 | result = javascripture.api.search.getReferences( e.data.parameters ); 29 | } 30 | 31 | if ( result ) { 32 | self.postMessage( { 33 | task: e.data.task, 34 | parameters: e.data.parameters, 35 | result: result 36 | } ); 37 | } 38 | 39 | }, false); 40 | --------------------------------------------------------------------------------