widetorah-embed 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +71 -231
- package/dist/embed.esm.js +39 -0
- package/dist/embed.min.js +36 -36
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -7,31 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
Embed WideTorah scripture widgets on any website. **Zero dependencies**, Shadow DOM style isolation, 3 built-in themes (light, dark, sepia), and automatic daily verse updates. Each widget includes a "Powered by WideTorah" backlink.
|
|
9
9
|
|
|
10
|
-
WideTorah covers the **Hebrew Bible (Tanakh)** — **24 books** (Torah: 5, Nevi'im: 21, Ketuvim: 13 by Jewish canon), **23,145 verses**, Hebrew Masoretic text, English translations (JPS, KJV), **54 parashot** (weekly Torah portions), **2,121 Talmud daf** (pages), and **3,901 Rashi commentaries** — all accessible via free public API.
|
|
11
|
-
|
|
12
10
|
> **Try the interactive widget builder at [widget.widetorah.com](https://widget.widetorah.com)**
|
|
13
11
|
|
|
14
|
-
<p align="center">
|
|
15
|
-
<img src="demo.gif" alt="widetorah-embed demo — Torah verse widget with Hebrew Masoretic text and English translation, light/dark/sepia themes" width="800">
|
|
16
|
-
</p>
|
|
17
|
-
|
|
18
|
-
## Table of Contents
|
|
19
|
-
|
|
20
|
-
- [Quick Start](#quick-start)
|
|
21
|
-
- [What You Can Do](#what-you-can-do)
|
|
22
|
-
- [Verse Card — Single Torah Verse Display](#verse-card--single-torah-verse-display)
|
|
23
|
-
- [Chapter Card — Full Chapter with Navigation](#chapter-card--full-chapter-with-navigation)
|
|
24
|
-
- [Comparison Card — Side-by-Side Verse Comparison](#comparison-card--side-by-side-verse-comparison)
|
|
25
|
-
- [Verse of the Day — Auto-Updating Daily Widget](#verse-of-the-day--auto-updating-daily-widget)
|
|
26
|
-
- [Search Box — Full-Text Torah Search](#search-box--full-text-torah-search)
|
|
27
|
-
- [Widget Options](#widget-options)
|
|
28
|
-
- [Themes](#themes)
|
|
29
|
-
- [CDN Options](#cdn-options)
|
|
30
|
-
- [Technical Details](#technical-details)
|
|
31
|
-
- [Learn More About the Torah](#learn-more-about-the-torah)
|
|
32
|
-
- [WideHoly Scripture Family](#wideholy-scripture-family)
|
|
33
|
-
- [License](#license)
|
|
34
|
-
|
|
35
12
|
## Quick Start
|
|
36
13
|
|
|
37
14
|
```html
|
|
@@ -42,258 +19,121 @@ WideTorah covers the **Hebrew Bible (Tanakh)** — **24 books** (Torah: 5, Nevi'
|
|
|
42
19
|
<script src="https://cdn.jsdelivr.net/npm/widetorah-embed@1/dist/embed.min.js"></script>
|
|
43
20
|
```
|
|
44
21
|
|
|
45
|
-
That's it. The widget
|
|
22
|
+
That's it. The widget will load, fetch the verse from the WideTorah API, and render it with full style isolation.
|
|
46
23
|
|
|
47
|
-
##
|
|
24
|
+
## Widget Types
|
|
48
25
|
|
|
49
|
-
|
|
26
|
+
| Type | Usage |
|
|
27
|
+
|------|-------|
|
|
28
|
+
| Verse Card | `<div data-widetorah="verse" data-ref="..." data-theme="light"></div>` |
|
|
29
|
+
| Chapter Card | `<div data-widetorah="chapter" data-ref="..."></div>` |
|
|
30
|
+
| Comparison Card | `<div data-widetorah="compare" data-a="..." data-b="..."></div>` |
|
|
31
|
+
| Verse of the Day | `<div data-widetorah="votd" data-theme="light"></div>` |
|
|
32
|
+
| Search Box | `<div data-widetorah="search" data-placeholder="..."></div>` |
|
|
50
33
|
|
|
51
|
-
|
|
34
|
+
## Widget Options
|
|
52
35
|
|
|
53
|
-
|
|
36
|
+
| Attribute | Values | Default | Description |
|
|
37
|
+
|-----------|--------|---------|-------------|
|
|
38
|
+
| `data-widetorah` | verse, chapter, person, compare, votd, search | required | Widget type |
|
|
39
|
+
| `data-ref` | "2:255" | — | Verse/chapter reference |
|
|
40
|
+
| `data-slug` | "moses", "paul" | — | Person slug (person widget only) |
|
|
41
|
+
| `data-a` | verse ref | — | First verse for comparison |
|
|
42
|
+
| `data-b` | verse ref | — | Second verse for comparison |
|
|
43
|
+
| `data-theme` | light, dark, sepia | light | Visual theme |
|
|
44
|
+
| `data-size` | default, compact | default | Widget size |
|
|
45
|
+
| `data-translation` | jps, etc. | jps | Translation code |
|
|
46
|
+
| `data-show-original` | true, false | false | Show original language text |
|
|
47
|
+
| `data-placeholder` | any string | "Search Torah…" | Search box placeholder |
|
|
54
48
|
|
|
55
|
-
|
|
56
|
-
|-------------|------|-------|
|
|
57
|
-
| JPS 1917 | `jps` | Traditional Jewish scholarly translation |
|
|
58
|
-
| King James Version | `kjv` | Widely recognized Christian translation |
|
|
49
|
+
## Themes
|
|
59
50
|
|
|
60
51
|
```html
|
|
61
|
-
<!--
|
|
62
|
-
<div data-widetorah="
|
|
63
|
-
data-ref="Genesis 1:1"
|
|
64
|
-
data-theme="light">
|
|
65
|
-
</div>
|
|
66
|
-
|
|
67
|
-
<!-- Deuteronomy 6:4 — The Shema (Hear O Israel) with Hebrew text -->
|
|
68
|
-
<div data-widetorah="verse"
|
|
69
|
-
data-ref="Deuteronomy 6:4"
|
|
70
|
-
data-translation="jps"
|
|
71
|
-
data-show-original="true"
|
|
72
|
-
data-theme="sepia">
|
|
73
|
-
</div>
|
|
52
|
+
<!-- Light (default) -->
|
|
53
|
+
<div data-widetorah="votd" data-theme="light"></div>
|
|
74
54
|
|
|
75
|
-
<!--
|
|
76
|
-
<div data-widetorah="
|
|
77
|
-
data-ref="Leviticus 19:18"
|
|
78
|
-
data-size="compact"
|
|
79
|
-
data-theme="dark">
|
|
80
|
-
</div>
|
|
55
|
+
<!-- Dark -->
|
|
56
|
+
<div data-widetorah="votd" data-theme="dark"></div>
|
|
81
57
|
|
|
82
|
-
|
|
58
|
+
<!-- Sepia (warm, book-like) -->
|
|
59
|
+
<div data-widetorah="votd" data-theme="sepia"></div>
|
|
83
60
|
```
|
|
84
61
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
| Attribute | Values | Default |
|
|
88
|
-
|-----------|--------|---------|
|
|
89
|
-
| `data-ref` | `"Book Chapter:Verse"` e.g. `Genesis 1:1` | required |
|
|
90
|
-
| `data-translation` | `jps`, `kjv` | `jps` |
|
|
91
|
-
| `data-show-original` | `true`, `false` | `false` (shows Hebrew with nikud) |
|
|
92
|
-
| `data-theme` | `light`, `dark`, `sepia` | `light` |
|
|
93
|
-
| `data-size` | `default`, `compact` | `default` |
|
|
94
|
-
|
|
95
|
-
Learn more: [Torah Verse Lookup — widetorah.com](https://widetorah.com) · [The Shema — Deuteronomy 6:4](https://widetorah.com) · [Aseret HaDibrot — Ten Commandments](https://widetorah.com)
|
|
96
|
-
|
|
97
|
-
### Chapter Card — Full Chapter with Navigation
|
|
98
|
-
|
|
99
|
-
A Chapter Card renders all verses in a chapter with previous/next navigation. The Torah's 929 chapters range from 9 verses (Genesis 25) to 91 verses (Psalms 119 in the Ketuvim). Chapter Cards display the parashah name when the chapter falls within the standard weekly reading cycle.
|
|
62
|
+
## CDN Options
|
|
100
63
|
|
|
101
|
-
|
|
64
|
+
### jsDelivr (recommended — global CDN, auto-updates with npm)
|
|
102
65
|
|
|
103
66
|
```html
|
|
104
|
-
<!-- Genesis Chapter 1 — Bereishit parashah, creation account -->
|
|
105
|
-
<div data-widetorah="chapter"
|
|
106
|
-
data-ref="Genesis 1"
|
|
107
|
-
data-theme="light">
|
|
108
|
-
</div>
|
|
109
|
-
|
|
110
|
-
<!-- Exodus Chapter 20 — Yitro parashah, Ten Commandments -->
|
|
111
|
-
<div data-widetorah="chapter"
|
|
112
|
-
data-ref="Exodus 20"
|
|
113
|
-
data-translation="jps"
|
|
114
|
-
data-theme="sepia">
|
|
115
|
-
</div>
|
|
116
|
-
|
|
117
|
-
<!-- Psalms Chapter 119 — Longest chapter in Tanakh, 176 verses -->
|
|
118
|
-
<div data-widetorah="chapter"
|
|
119
|
-
data-ref="Psalms 119"
|
|
120
|
-
data-show-original="true"
|
|
121
|
-
data-theme="dark">
|
|
122
|
-
</div>
|
|
123
|
-
|
|
124
67
|
<script src="https://cdn.jsdelivr.net/npm/widetorah-embed@1/dist/embed.min.js"></script>
|
|
125
68
|
```
|
|
126
69
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
### Comparison Card — Side-by-Side Verse Comparison
|
|
130
|
-
|
|
131
|
-
Compare any two verses from across the Tanakh — useful for showing how the same theme appears in Torah law, prophetic books, and Ketuvim wisdom literature, or for displaying how different translations render a Hebrew hapax legomenon (a word appearing only once in the entire text).
|
|
132
|
-
|
|
133
|
-
The Tanakh has extensive internal cross-references — for example, 2 Kings 19 and Isaiah 37 are nearly identical chapters, and Chronicles often parallels Samuel and Kings. The Comparison Card makes these parallels visible.
|
|
70
|
+
### R2 CDN (widetorah.com hosted)
|
|
134
71
|
|
|
135
72
|
```html
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
data-a="Exodus 20:2"
|
|
139
|
-
data-b="Deuteronomy 5:6"
|
|
140
|
-
data-theme="light">
|
|
141
|
-
</div>
|
|
142
|
-
|
|
143
|
-
<!-- Compare two messianic prophecies: Isaiah 9:6 vs Isaiah 53:3 -->
|
|
144
|
-
<div data-widetorah="compare"
|
|
145
|
-
data-a="Isaiah 9:6"
|
|
146
|
-
data-b="Isaiah 53:3"
|
|
147
|
-
data-show-original="true"
|
|
148
|
-
data-theme="sepia">
|
|
149
|
-
</div>
|
|
73
|
+
<script src="https://cdn.widetorah.com/embed.min.js"></script>
|
|
74
|
+
```
|
|
150
75
|
|
|
151
|
-
|
|
152
|
-
<div data-widetorah="compare"
|
|
153
|
-
data-a="Proverbs 3:5"
|
|
154
|
-
data-b="Ecclesiastes 12:13"
|
|
155
|
-
data-translation="jps"
|
|
156
|
-
data-theme="dark">
|
|
157
|
-
</div>
|
|
76
|
+
### npm (for bundlers)
|
|
158
77
|
|
|
159
|
-
|
|
78
|
+
```bash
|
|
79
|
+
npm install widetorah-embed
|
|
160
80
|
```
|
|
161
81
|
|
|
162
|
-
|
|
82
|
+
```javascript
|
|
83
|
+
import 'widetorah-embed';
|
|
84
|
+
```
|
|
163
85
|
|
|
164
|
-
|
|
86
|
+
## Examples
|
|
165
87
|
|
|
166
|
-
|
|
88
|
+
### Verse of the Day
|
|
167
89
|
|
|
168
90
|
```html
|
|
169
|
-
<!-- Verse of the Day — full size, light theme -->
|
|
170
91
|
<div data-widetorah="votd" data-theme="light"></div>
|
|
171
|
-
|
|
172
|
-
<!-- Verse of the Day — dark theme -->
|
|
173
|
-
<div data-widetorah="votd" data-theme="dark"></div>
|
|
174
|
-
|
|
175
|
-
<!-- Verse of the Day — sepia, evokes the feel of a parchment scroll -->
|
|
176
|
-
<div data-widetorah="votd" data-theme="sepia"></div>
|
|
177
|
-
|
|
178
|
-
<!-- Compact for narrow sidebars (verse + reference only) -->
|
|
179
|
-
<div data-widetorah="votd" data-theme="light" data-size="compact"></div>
|
|
180
|
-
|
|
181
92
|
<script src="https://cdn.jsdelivr.net/npm/widetorah-embed@1/dist/embed.min.js"></script>
|
|
182
93
|
```
|
|
183
94
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
### Search Box — Full-Text Torah Search
|
|
187
|
-
|
|
188
|
-
Embed a full-text search box that queries all 23,145 verses in both JPS and KJV translations, plus 3,901 Rashi commentaries. Results appear as the user types with book, chapter, and verse reference. Hebrew transliteration search is also supported — searching "shema" returns Deuteronomy 6:4 even without a Hebrew keyboard.
|
|
95
|
+
### Verse with Original Language
|
|
189
96
|
|
|
190
97
|
```html
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
data-
|
|
194
|
-
data-theme="light">
|
|
195
|
-
</div>
|
|
196
|
-
|
|
197
|
-
<!-- Hebrew-aware search placeholder -->
|
|
198
|
-
<div data-widetorah="search"
|
|
199
|
-
data-placeholder="Search in Hebrew or English…"
|
|
98
|
+
<div data-widetorah="verse"
|
|
99
|
+
data-ref="1:1"
|
|
100
|
+
data-show-original="true"
|
|
200
101
|
data-theme="sepia">
|
|
201
102
|
</div>
|
|
202
|
-
|
|
203
|
-
<!-- Dark theme search -->
|
|
204
|
-
<div data-widetorah="search"
|
|
205
|
-
data-placeholder="Find a verse or commentary…"
|
|
206
|
-
data-theme="dark">
|
|
207
|
-
</div>
|
|
208
|
-
|
|
209
103
|
<script src="https://cdn.jsdelivr.net/npm/widetorah-embed@1/dist/embed.min.js"></script>
|
|
210
104
|
```
|
|
211
105
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
## Widget Options
|
|
215
|
-
|
|
216
|
-
All widget types share these common attributes:
|
|
217
|
-
|
|
218
|
-
| Attribute | Values | Default | Description |
|
|
219
|
-
|-----------|--------|---------|-------------|
|
|
220
|
-
| `data-widetorah` | `verse`, `chapter`, `compare`, `votd`, `search` | required | Widget type |
|
|
221
|
-
| `data-ref` | `"Book Chapter:Verse"` e.g. `Genesis 1:1` | — | Verse or chapter reference |
|
|
222
|
-
| `data-a` | verse reference | — | First verse for comparison |
|
|
223
|
-
| `data-b` | verse reference | — | Second verse for comparison |
|
|
224
|
-
| `data-theme` | `light`, `dark`, `sepia` | `light` | Visual theme |
|
|
225
|
-
| `data-size` | `default`, `compact` | `default` | Compact suits sidebars under 300px |
|
|
226
|
-
| `data-translation` | `jps`, `kjv` | `jps` | English translation |
|
|
227
|
-
| `data-show-original` | `true`, `false` | `false` | Show Hebrew Masoretic text with nikud |
|
|
228
|
-
| `data-placeholder` | any string | `"Search Torah…"` | Placeholder for search widget |
|
|
229
|
-
|
|
230
|
-
## Themes
|
|
231
|
-
|
|
232
|
-
WideTorah widgets support 3 themes:
|
|
233
|
-
|
|
234
|
-
```html
|
|
235
|
-
<!-- Light — white background, dark text, indigo/purple accent -->
|
|
236
|
-
<div data-widetorah="votd" data-theme="light"></div>
|
|
237
|
-
|
|
238
|
-
<!-- Dark — dark background, light text, indigo accent -->
|
|
239
|
-
<div data-widetorah="votd" data-theme="dark"></div>
|
|
240
|
-
|
|
241
|
-
<!-- Sepia — warm parchment background, brown text — evokes a Torah scroll -->
|
|
242
|
-
<div data-widetorah="votd" data-theme="sepia"></div>
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
All themes are self-contained inside Shadow DOM — they never affect or inherit from your site's CSS.
|
|
246
|
-
|
|
247
|
-
## CDN Options
|
|
248
|
-
|
|
249
|
-
### jsDelivr (recommended — global CDN, auto-updates with npm)
|
|
106
|
+
### Compact Verse of the Day (sidebar use)
|
|
250
107
|
|
|
251
108
|
```html
|
|
109
|
+
<div data-widetorah="votd" data-theme="light" data-size="compact"></div>
|
|
252
110
|
<script src="https://cdn.jsdelivr.net/npm/widetorah-embed@1/dist/embed.min.js"></script>
|
|
253
111
|
```
|
|
254
112
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
```html
|
|
258
|
-
<script src="https://cdn.jsdelivr.net/npm/widetorah-embed@1.0.1/dist/embed.min.js"></script>
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
### R2 CDN (widetorah.com hosted)
|
|
113
|
+
### Search Box
|
|
262
114
|
|
|
263
115
|
```html
|
|
264
|
-
<
|
|
116
|
+
<div data-widetorah="search" data-placeholder="Search Torah…"></div>
|
|
117
|
+
<script src="https://cdn.jsdelivr.net/npm/widetorah-embed@1/dist/embed.min.js"></script>
|
|
265
118
|
```
|
|
266
119
|
|
|
267
|
-
|
|
120
|
+
## Technical Details
|
|
268
121
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
122
|
+
- **Shadow DOM**: Complete style isolation — no CSS conflicts with your site
|
|
123
|
+
- **Zero dependencies**: No jQuery, React, or any external library
|
|
124
|
+
- **System fonts**: No Google Fonts request — loads instantly
|
|
125
|
+
- **CORS**: WideTorah API has CORS enabled for all origins
|
|
126
|
+
- **Caching**: Verse of the Day cached in localStorage (refreshes daily)
|
|
127
|
+
- **MutationObserver**: Works with dynamically added elements (SPAs)
|
|
128
|
+
- **Bundle size**: ~5KB gzipped
|
|
272
129
|
|
|
273
|
-
|
|
274
|
-
import 'widetorah-embed';
|
|
275
|
-
```
|
|
130
|
+
## Learn More About Torah
|
|
276
131
|
|
|
277
|
-
|
|
132
|
+
Visit [widetorah.com](https://widetorah.com) — WideTorah is a comprehensive Torah reference with full text, translations, and study tools.
|
|
278
133
|
|
|
279
|
-
- **
|
|
280
|
-
- **
|
|
281
|
-
- **
|
|
282
|
-
- **System fonts**: No Google Fonts request — widgets use the system font stack and load instantly.
|
|
283
|
-
- **CORS**: WideTorah API has CORS enabled for all origins — no proxy needed.
|
|
284
|
-
- **Caching**: Verse of the Day cached in localStorage, refreshes daily at midnight UTC.
|
|
285
|
-
- **MutationObserver**: Works with dynamically added elements (React, Vue, Angular SPAs).
|
|
286
|
-
- **Bundle size**: ~5KB gzipped.
|
|
287
|
-
- **Accent color**: Indigo (`#6366F1`) — matches the WideTorah brand.
|
|
288
|
-
- **API base**: `https://widetorah.com/api/v1/` — free, no authentication required.
|
|
289
|
-
|
|
290
|
-
## Learn More About the Torah
|
|
291
|
-
|
|
292
|
-
- **Browse**: [All 24 Tanakh Books — widetorah.com](https://widetorah.com) · [Five Books of Moses](https://widetorah.com) · [Nevi'im — Prophets](https://widetorah.com) · [Ketuvim — Writings](https://widetorah.com)
|
|
293
|
-
- **Study**: [54 Parashot — Weekly Torah Portions](https://widetorah.com/parashot/) · [Rashi Commentaries — 3,901 entries](https://widetorah.com) · [Talmud Daf Yomi — 2,121 pages](https://widetorah.com)
|
|
294
|
-
- **Reference**: [Hebrew-English Tanakh](https://widetorah.com) · [JPS Translation Guide](https://widetorah.com/translations/) · [Masoretic Text Explained](https://widetorah.com)
|
|
295
|
-
- **Tools**: [Torah Verse Lookup](https://widetorah.com) · [Parashah Calendar](https://widetorah.com/parashot/) · [Widget Builder](https://widget.widetorah.com)
|
|
296
|
-
- **API**: [REST API Docs](https://widetorah.com/developers/) · [OpenAPI Spec](https://widetorah.com/api/openapi.json)
|
|
134
|
+
- **API docs**: [widetorah.com/developers/](https://widetorah.com/developers/)
|
|
135
|
+
- **Widget builder**: [widget.widetorah.com](https://widget.widetorah.com)
|
|
136
|
+
- **npm package**: [npmjs.com/package/widetorah-embed](https://www.npmjs.com/package/widetorah-embed)
|
|
297
137
|
|
|
298
138
|
## WideHoly Scripture Family
|
|
299
139
|
|
|
@@ -301,15 +141,15 @@ Part of [WideHoly](https://wideholy.com) — Scripture for everyone.
|
|
|
301
141
|
|
|
302
142
|
| Site | Domain | Scripture |
|
|
303
143
|
|------|--------|-----------|
|
|
304
|
-
| WideBible | [widebible.com](https://widebible.com) |
|
|
305
|
-
| WideQuran | [widequran.com](https://widequran.com) |
|
|
306
|
-
| **WideTorah** | [widetorah.com](https://widetorah.com) |
|
|
307
|
-
| WideGita | [widegita.com](https://widegita.com) |
|
|
308
|
-
| WideSutra | [widesutra.com](https://widesutra.com) |
|
|
309
|
-
| WideHoly | [wideholy.com](https://wideholy.com) |
|
|
144
|
+
| **WideBible** | [widebible.com](https://widebible.com) | Bible verses, chapters, people |
|
|
145
|
+
| **WideQuran** | [widequran.com](https://widequran.com) | Quran verses, surahs |
|
|
146
|
+
| **WideTorah** | [widetorah.com](https://widetorah.com) | Torah verses, portions |
|
|
147
|
+
| **WideGita** | [widegita.com](https://widegita.com) | Bhagavad Gita verses |
|
|
148
|
+
| **WideSutra** | [widesutra.com](https://widesutra.com) | Buddhist sutras, teachings |
|
|
149
|
+
| **WideHoly** | [wideholy.com](https://wideholy.com) | Multi-religion scripture hub |
|
|
310
150
|
|
|
311
151
|
## License
|
|
312
152
|
|
|
313
153
|
MIT — see [LICENSE](./LICENSE).
|
|
314
154
|
|
|
315
|
-
Built with
|
|
155
|
+
Built with ❤️ by [WideHoly](https://wideholy.com).
|
package/dist/embed.esm.js
CHANGED
|
@@ -518,6 +518,31 @@ function bindCopyButton(btn, text) {
|
|
|
518
518
|
});
|
|
519
519
|
}
|
|
520
520
|
|
|
521
|
+
// src/rich-snippets.ts
|
|
522
|
+
function injectQuotation(data, domain, siteName) {
|
|
523
|
+
if (document.querySelector("script[data-wide-snippet]")) return;
|
|
524
|
+
const jsonLd = {
|
|
525
|
+
"@context": "https://schema.org",
|
|
526
|
+
"@type": "Quotation",
|
|
527
|
+
text: data.text,
|
|
528
|
+
spokenByCharacter: data.reference,
|
|
529
|
+
isPartOf: {
|
|
530
|
+
"@type": "Book",
|
|
531
|
+
name: data.book
|
|
532
|
+
},
|
|
533
|
+
contributor: {
|
|
534
|
+
"@type": "Organization",
|
|
535
|
+
name: siteName,
|
|
536
|
+
url: `https://${domain}`
|
|
537
|
+
}
|
|
538
|
+
};
|
|
539
|
+
const script = document.createElement("script");
|
|
540
|
+
script.type = "application/ld+json";
|
|
541
|
+
script.setAttribute("data-wide-snippet", "true");
|
|
542
|
+
script.textContent = JSON.stringify(jsonLd);
|
|
543
|
+
document.head.appendChild(script);
|
|
544
|
+
}
|
|
545
|
+
|
|
521
546
|
// src/widgets/verse.ts
|
|
522
547
|
function parseRef(ref) {
|
|
523
548
|
const withBook = ref.match(/^(.+?)\s+(\d+):(\d+)$/);
|
|
@@ -595,6 +620,20 @@ function initVerseWidget(el, config) {
|
|
|
595
620
|
const verse = "results" in data && Array.isArray(data.results) ? data.results[0] : data;
|
|
596
621
|
if (!verse || !verse.text) throw new Error("No verse found");
|
|
597
622
|
renderVerseWidget(container, verse, el, config);
|
|
623
|
+
if (el.dataset.noSnippet !== "true") {
|
|
624
|
+
const parsed = parseRef(verse.reference || ref);
|
|
625
|
+
const bookName = (parsed == null ? void 0 : parsed.book) || verse.book || config.scriptureLabel;
|
|
626
|
+
injectQuotation(
|
|
627
|
+
{
|
|
628
|
+
text: verse.text,
|
|
629
|
+
reference: verse.reference || ref,
|
|
630
|
+
translation: verse.translation || config.defaultTranslation,
|
|
631
|
+
book: bookName
|
|
632
|
+
},
|
|
633
|
+
config.domain,
|
|
634
|
+
config.name
|
|
635
|
+
);
|
|
636
|
+
}
|
|
598
637
|
}).catch(() => {
|
|
599
638
|
renderError(
|
|
600
639
|
container,
|
package/dist/embed.min.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* widetorah-embed v1.0.0 | MIT | https://widget.widetorah.com */
|
|
2
|
-
"use strict";(()=>{var
|
|
2
|
+
"use strict";(()=>{var f={site:"widetorah",name:"WideTorah",domain:"widetorah.com",apiBase:"https://widetorah.com/api/v1/torah",votdEndpoint:"https://widetorah.com/api/v1/verse-of-the-day/",searchPath:"/search/",accent:"#2563EB",attribute:"data-widetorah",religion:"judaism",scriptureLabel:"Torah",defaultTranslation:"jps"};function C(t){return`
|
|
3
3
|
:host {
|
|
4
4
|
display: block;
|
|
5
5
|
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
|
|
@@ -441,42 +441,42 @@
|
|
|
441
441
|
color: var(--muted);
|
|
442
442
|
margin: 2px 0 0 0;
|
|
443
443
|
}
|
|
444
|
-
`}function
|
|
444
|
+
`}function u(t,e){let r=t.attachShadow({mode:"open"}),n=document.createElement("style");return n.textContent=C(e.accent),r.appendChild(n),r}function m(t,e,r){let n=e.dataset.theme||"light",o=e.dataset.size||"default",s=document.createElement("div");return s.className=["wide-widget",r].filter(Boolean).join(" "),s.setAttribute("data-theme",n),s.setAttribute("data-size",o),t.appendChild(s),s}function h(t){t.innerHTML=`
|
|
445
445
|
<div class="wide-loading">
|
|
446
446
|
<span class="wide-spinner"></span>
|
|
447
447
|
Loading\u2026
|
|
448
448
|
</div>
|
|
449
|
-
`}function
|
|
449
|
+
`}function p(t,e,r){t.innerHTML=`
|
|
450
450
|
<div class="wide-error">
|
|
451
451
|
<p>${e}</p>
|
|
452
452
|
<a href="https://${r.domain}" target="_blank" rel="noopener">
|
|
453
453
|
Visit ${r.name}
|
|
454
454
|
</a>
|
|
455
455
|
</div>
|
|
456
|
-
`}var
|
|
457
|
-
<div class="wide-ribbon${
|
|
458
|
-
<p class="wide-verse-text${
|
|
459
|
-
${
|
|
456
|
+
`}var b='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>',w='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>',E='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>',L='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>';function g(t){return`<span class="wide-powered">Powered by <a href="https://${t.domain}" target="_blank" rel="noopener">${t.name}</a></span>`}function k(t,e){t.addEventListener("click",()=>{var r;(r=navigator.clipboard)==null||r.writeText(e).then(()=>{t.innerHTML=`${E} Copied!`,setTimeout(()=>{t.innerHTML=`${w} Copy`},2e3)}).catch(()=>{let n=document.createElement("textarea");n.value=e,n.style.position="fixed",n.style.opacity="0",document.body.appendChild(n),n.select(),document.execCommand("copy"),document.body.removeChild(n),t.innerHTML=`${E} Copied!`,setTimeout(()=>{t.innerHTML=`${w} Copy`},2e3)})})}function S(t,e,r){if(document.querySelector("script[data-wide-snippet]"))return;let n={"@context":"https://schema.org","@type":"Quotation",text:t.text,spokenByCharacter:t.reference,isPartOf:{"@type":"Book",name:t.book},contributor:{"@type":"Organization",name:r,url:`https://${e}`}},o=document.createElement("script");o.type="application/ld+json",o.setAttribute("data-wide-snippet","true"),o.textContent=JSON.stringify(n),document.head.appendChild(o)}function M(t){let e=t.match(/^(.+?)\s+(\d+):(\d+)$/);if(e)return{book:e[1],chapter:e[2],verse:e[3]};let r=t.match(/^(\d+):(\d+)$/);return r?{book:"",chapter:r[1],verse:r[2]}:null}function N(t,e,r){let n=M(e);if(!n)return"";let o=new URLSearchParams;return n.book&&o.set("book",n.book),o.set("chapter",n.chapter),o.set("verse",n.verse),r&&o.set("translation",r),`${t.apiBase}/verses/?${o.toString()}`}function O(t,e,r,n){let o=r.dataset.size==="compact",s=r.dataset.showOriginal==="true",a=e.reference||r.dataset.ref||"",i=e.translation||n.defaultTranslation,d=e.url||`https://${n.domain}`,c=s&&e.original_text?`<p class="wide-original" lang="${e.original_language||""}">${e.original_text}</p>`:"";t.innerHTML=`
|
|
457
|
+
<div class="wide-ribbon${o?" compact":""}">
|
|
458
|
+
<p class="wide-verse-text${o?" compact":""}">${e.text}</p>
|
|
459
|
+
${c}
|
|
460
460
|
</div>
|
|
461
|
-
<div class="wide-body${
|
|
461
|
+
<div class="wide-body${o?" compact":""}">
|
|
462
462
|
<div class="wide-meta">
|
|
463
463
|
<span class="wide-ref">${a}</span>
|
|
464
|
-
<span class="wide-badge">${
|
|
464
|
+
<span class="wide-badge">${i.toUpperCase()}</span>
|
|
465
465
|
</div>
|
|
466
466
|
</div>
|
|
467
|
-
<div class="wide-actions${
|
|
467
|
+
<div class="wide-actions${o?" compact":""}">
|
|
468
468
|
<a class="wide-link" href="${d}" target="_blank" rel="noopener">
|
|
469
|
-
Read on ${n.name} ${
|
|
469
|
+
Read on ${n.name} ${b}
|
|
470
470
|
</a>
|
|
471
471
|
<button class="wide-copy-btn" type="button">
|
|
472
|
-
${
|
|
472
|
+
${w} Copy
|
|
473
473
|
</button>
|
|
474
474
|
</div>
|
|
475
475
|
${g(n)}
|
|
476
|
-
`;let
|
|
476
|
+
`;let l=t.querySelector(".wide-copy-btn");l&&k(l,`${e.text} \u2014 ${a}`)}function H(t,e){let r=u(t,e),n=m(r,t);h(n);let o=t.dataset.ref||"",s=t.dataset.translation||e.defaultTranslation;if(!o){p(n,"Missing data-ref attribute.",e);return}let a=N(e,o,s);if(!a){p(n,`Could not parse reference: "${o}"`,e);return}fetch(a).then(i=>{if(!i.ok)throw new Error(`HTTP ${i.status}`);return i.json()}).then(i=>{let d="results"in i&&Array.isArray(i.results)?i.results[0]:i;if(!d||!d.text)throw new Error("No verse found");if(O(n,d,t,e),t.dataset.noSnippet!=="true"){let c=M(d.reference||o),l=(c==null?void 0:c.book)||d.book||e.scriptureLabel;S({text:d.text,reference:d.reference||o,translation:d.translation||e.defaultTranslation,book:l},e.domain,e.name)}}).catch(()=>{p(n,`Could not load "${o}". Visit ${e.name} to read scripture.`,e)})}function U(t){let e=t.match(/^(.+?)\s+(\d+)$/);if(e)return{book:e[1],chapter:e[2]};let r=t.match(/^(\d+)$/);return r?{book:"",chapter:r[1]}:null}function A(t,e){let r=t.split(/\s+/);return r.length<=e?t:r.slice(0,e).join(" ")+"\u2026"}function B(t,e){let r=u(t,e),n=m(r,t);h(n);let o=t.dataset.ref||"";if(!o){p(n,"Missing data-ref attribute.",e);return}let s=U(o);if(!s){p(n,`Could not parse chapter reference: "${o}"`,e);return}let a=s.book?`${e.apiBase}/chapters/${encodeURIComponent(s.book)}/${s.chapter}/`:`${e.apiBase}/chapters/${s.chapter}/`;fetch(a).then(i=>{if(!i.ok)throw new Error(`HTTP ${i.status}`);return i.json()}).then(i=>{var v;let d=i.title||i.name||o,c=i.book_name||i.book||"",l=i.summary||i.description||"",y=(v=i.verse_count)!=null?v:Array.isArray(i.verses)?i.verses.length:null,$=i.url||`https://${e.domain}`,x=l?A(l,100):"";n.innerHTML=`
|
|
477
477
|
<div class="wide-body">
|
|
478
478
|
<div class="wide-meta">
|
|
479
|
-
${
|
|
479
|
+
${c?`<span class="wide-badge">${c}</span>`:""}
|
|
480
480
|
${y!=null?`<span class="wide-stat">${y} verses</span>`:""}
|
|
481
481
|
</div>
|
|
482
482
|
<h3 class="wide-title">${d}</h3>
|
|
@@ -484,81 +484,81 @@
|
|
|
484
484
|
</div>
|
|
485
485
|
<div class="wide-actions">
|
|
486
486
|
<a class="wide-link" href="${$}" target="_blank" rel="noopener">
|
|
487
|
-
Read full chapter on ${e.name} ${
|
|
487
|
+
Read full chapter on ${e.name} ${b}
|
|
488
488
|
</a>
|
|
489
489
|
</div>
|
|
490
490
|
${g(e)}
|
|
491
|
-
`}).catch(()=>{
|
|
491
|
+
`}).catch(()=>{p(n,`Could not load chapter "${o}". Visit ${e.name} to read scripture.`,e)})}function q(t,e){let r=t.split(/\s+/);return r.length<=e?t:r.slice(0,e).join(" ")+"\u2026"}function V(t,e){let r=u(t,e),n=m(r,t);h(n);let o=t.dataset.slug||"";if(!o){p(n,"Missing data-slug attribute.",e);return}let s=`${e.apiBase}/people/${encodeURIComponent(o)}/`;fetch(s).then(a=>{if(!a.ok)throw new Error(`HTTP ${a.status}`);return a.json()}).then(a=>{var x,v;let i=a.name||a.full_name||o,d=a.era||a.period||"",c=a.bio||a.description||"",l=(v=(x=a.verse_count)!=null?x:a.mentioned_verses)!=null?v:null,y=a.url||`https://${e.domain}/people/${o}/`,$=c?q(c,150):"";n.innerHTML=`
|
|
492
492
|
<div class="wide-person-header">
|
|
493
493
|
<div class="wide-person-icon">${L}</div>
|
|
494
494
|
<div>
|
|
495
|
-
<p class="wide-person-name">${
|
|
495
|
+
<p class="wide-person-name">${i}</p>
|
|
496
496
|
${d?`<p class="wide-person-era">${d}</p>`:""}
|
|
497
497
|
</div>
|
|
498
498
|
</div>
|
|
499
499
|
<div class="wide-body">
|
|
500
500
|
<div class="wide-meta">
|
|
501
|
-
${
|
|
501
|
+
${l!=null?`<span class="wide-stat">${l} verses</span>`:""}
|
|
502
502
|
</div>
|
|
503
503
|
${$?`<p class="wide-summary">${$}</p>`:""}
|
|
504
504
|
</div>
|
|
505
505
|
<div class="wide-actions">
|
|
506
506
|
<a class="wide-link" href="${y}" target="_blank" rel="noopener">
|
|
507
|
-
Learn more on ${e.name} ${
|
|
507
|
+
Learn more on ${e.name} ${b}
|
|
508
508
|
</a>
|
|
509
509
|
</div>
|
|
510
510
|
${g(e)}
|
|
511
|
-
`}).catch(()=>{
|
|
511
|
+
`}).catch(()=>{p(n,`Could not load "${o}". Visit ${e.name} for biblical figures.`,e)})}function Q(t){let e=new URLSearchParams,r=t.match(/^(.+?)\s+(\d+):(\d+)$/);if(r)return e.set("book",r[1]),e.set("chapter",r[2]),e.set("verse",r[3]),e;let n=t.match(/^(\d+):(\d+)$/);return n&&(e.set("chapter",n[1]),e.set("verse",n[2])),e}async function D(t,e){var i,d;let r=Q(e),n=`${t.apiBase}/verses/?${r.toString()}`,o=await fetch(n);if(!o.ok)throw new Error(`HTTP ${o.status}`);let s=await o.json(),a=(d=(i=s.results)==null?void 0:i[0])!=null?d:s;if(!(a!=null&&a.text))throw new Error("No verse data");return{text:a.text,reference:a.reference||e,url:a.url}}function z(t,e){let r=u(t,e),n=m(r,t);h(n);let o=t.dataset.a||"",s=t.dataset.b||"";if(!o||!s){p(n,"Missing data-a or data-b attributes.",e);return}Promise.all([D(e,o),D(e,s)]).then(([a,i])=>{let d=`https://${e.domain}/compare/`;n.innerHTML=`
|
|
512
512
|
<div class="wide-compare-grid">
|
|
513
513
|
<div class="wide-compare-col">
|
|
514
514
|
<p class="wide-compare-label">${a.reference}</p>
|
|
515
515
|
<p class="wide-compare-text">${a.text}</p>
|
|
516
516
|
</div>
|
|
517
517
|
<div class="wide-compare-col">
|
|
518
|
-
<p class="wide-compare-label">${
|
|
519
|
-
<p class="wide-compare-text">${
|
|
518
|
+
<p class="wide-compare-label">${i.reference}</p>
|
|
519
|
+
<p class="wide-compare-text">${i.text}</p>
|
|
520
520
|
</div>
|
|
521
521
|
</div>
|
|
522
522
|
<div class="wide-actions">
|
|
523
523
|
<a class="wide-link" href="${d}" target="_blank" rel="noopener">
|
|
524
|
-
Compare on ${e.name} ${
|
|
524
|
+
Compare on ${e.name} ${b}
|
|
525
525
|
</a>
|
|
526
526
|
</div>
|
|
527
527
|
${g(e)}
|
|
528
|
-
`}).catch(()=>{
|
|
528
|
+
`}).catch(()=>{p(n,`Could not load comparison. Visit ${e.name} to compare scripture.`,e)})}var _="wide_votd_";function W(){return new Date().toISOString().slice(0,10)}function G(t){try{let e=`${_}${t}`,r=localStorage.getItem(e);if(!r)return null;let n=JSON.parse(r);return n.date!==W()?(localStorage.removeItem(e),null):n.data}catch(e){return null}}function F(t,e){try{let r=`${_}${t}`;localStorage.setItem(r,JSON.stringify({date:W(),data:e}))}catch(r){}}function R(t,e){let r=u(t,e),n=m(r,t);h(n);let o=t.dataset.size==="compact";function s(i){let d=i.translation||e.defaultTranslation,c=i.url||`https://${e.domain}`;n.innerHTML=`
|
|
529
529
|
<div class="wide-accent-bar"></div>
|
|
530
|
-
<div class="wide-ribbon${
|
|
531
|
-
<p class="wide-verse-text${
|
|
530
|
+
<div class="wide-ribbon${o?" compact":""}">
|
|
531
|
+
<p class="wide-verse-text${o?" compact":""}">${i.text}</p>
|
|
532
532
|
</div>
|
|
533
|
-
<div class="wide-body${
|
|
533
|
+
<div class="wide-body${o?" compact":""}">
|
|
534
534
|
<div class="wide-meta">
|
|
535
|
-
<span class="wide-ref">${
|
|
535
|
+
<span class="wide-ref">${i.reference}</span>
|
|
536
536
|
<span class="wide-badge">${d.toUpperCase()}</span>
|
|
537
537
|
<span class="wide-badge">Verse of the Day</span>
|
|
538
538
|
</div>
|
|
539
539
|
</div>
|
|
540
|
-
<div class="wide-actions${
|
|
541
|
-
<a class="wide-link" href="${
|
|
542
|
-
More at ${e.name} ${
|
|
540
|
+
<div class="wide-actions${o?" compact":""}">
|
|
541
|
+
<a class="wide-link" href="${c}" target="_blank" rel="noopener">
|
|
542
|
+
More at ${e.name} ${b}
|
|
543
543
|
</a>
|
|
544
544
|
<button class="wide-copy-btn" type="button">
|
|
545
|
-
${
|
|
545
|
+
${w} Copy
|
|
546
546
|
</button>
|
|
547
547
|
</div>
|
|
548
548
|
${g(e)}
|
|
549
|
-
`;let
|
|
549
|
+
`;let l=n.querySelector(".wide-copy-btn");l&&k(l,`${i.text} \u2014 ${i.reference}`)}let a=G(e.site);if(a){s(a);return}fetch(e.votdEndpoint).then(i=>{if(!i.ok)throw new Error(`HTTP ${i.status}`);return i.json()}).then(i=>{if(!(i!=null&&i.text))throw new Error("No VOTD data");F(e.site,i),s(i)}).catch(()=>{p(n,`Could not load verse of the day. Visit ${e.name} for daily scripture.`,e)})}function I(t,e){let r=u(t,e),n=m(r,t),o=t.dataset.placeholder||`Search ${e.scriptureLabel}\u2026`;n.innerHTML=`
|
|
550
550
|
<div class="wide-search-wrap">
|
|
551
551
|
<form class="wide-search-form" action="https://${e.domain}${e.searchPath}" method="get" target="_blank">
|
|
552
552
|
<input
|
|
553
553
|
class="wide-search-input"
|
|
554
554
|
type="search"
|
|
555
555
|
name="q"
|
|
556
|
-
placeholder="${
|
|
557
|
-
aria-label="${
|
|
556
|
+
placeholder="${o}"
|
|
557
|
+
aria-label="${o}"
|
|
558
558
|
autocomplete="off"
|
|
559
559
|
/>
|
|
560
560
|
<button class="wide-search-btn" type="submit">Search</button>
|
|
561
561
|
</form>
|
|
562
562
|
</div>
|
|
563
563
|
${g(e)}
|
|
564
|
-
`}function T(t,e,r){switch(e){case"verse":
|
|
564
|
+
`}function T(t,e,r){switch(e){case"verse":H(t,r);break;case"chapter":B(t,r);break;case"person":V(t,r);break;case"compare":z(t,r);break;case"votd":R(t,r);break;case"search":I(t,r);break;default:break}}function P(t){document.querySelectorAll(`[${t.attribute}]`).forEach(r=>{if(r.shadowRoot)return;let n=r.dataset[t.attribute.replace("data-","")];n&&T(r,n,t)})}(function(){let e=f;document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>P(e)):P(e),new MutationObserver(n=>{n.forEach(o=>{o.addedNodes.forEach(s=>{var i;if(s.nodeType!==Node.ELEMENT_NODE)return;let a=s;if(a.hasAttribute(e.attribute)&&!a.shadowRoot){let d=a.dataset[e.attribute.replace("data-","")];d&&T(a,d,e)}(i=a.querySelectorAll)==null||i.call(a,`[${e.attribute}]`).forEach(d=>{if(!d.shadowRoot){let c=d.dataset[e.attribute.replace("data-","")];c&&T(d,c,e)}})})})}).observe(document.body||document.documentElement,{childList:!0,subtree:!0})})();})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "widetorah-embed",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Embed WideTorah scripture widgets on any website. Lightweight (~5KB gzipped), zero dependencies, Shadow DOM isolation, 3 themes (light/dark/sepia).",
|
|
5
5
|
"main": "dist/embed.min.js",
|
|
6
6
|
"module": "dist/embed.esm.js",
|
|
@@ -35,4 +35,4 @@
|
|
|
35
35
|
"publishConfig": {
|
|
36
36
|
"access": "public"
|
|
37
37
|
}
|
|
38
|
-
}
|
|
38
|
+
}
|