Comparing sensitive data, confidential files or internal emails?

Most legal and privacy policies prohibit uploading sensitive data online. Diffchecker Desktop ensures your confidential information never leaves your computer. Work offline and compare documents securely.

fc2

Created Diff never expires
16 removals
552 lines
15 additions
552 lines
<div id=deck deck_name="{{Deck}}"></div>



<!-- FC2 CONFIGURATION BEGIN -->
<!-- FC2 CONFIGURATION BEGIN -->
<script type="application/javascript">
<script type="application/javascript">
var config = {
var config = {
prompt: '[...]', // Prompt when no hint
prompt: '[...]', // Prompt when no hint
hint: '[%h]', // %h is replaced with hint text
hint: '[%h]', // %h is replaced with hint text
expose: {
expose: {
char: '!', // Char to mark exposed cloze
char: '!', // Char to mark exposed cloze
pos: 'begin', // Char pos: `pre`, `begin`, `end` or `post`
pos: 'begin', // Char pos: `pre`, `begin`, `end` or `post`
reverse: '{{Invert cloze hiding}}'.toString() // If true exposed clozes are hidden, others shown
reverse: '{{Invert cloze hiding}}'.toString() // If true exposed clozes are hidden, others shown
},
},
scroll: { // Valid values: `none`, `min`, `center`, `context`, `context-top` or `context-bottom`
scroll: { // Valid values: `none`, `min`, `center`, `context`, `context-top` or `context-bottom`
initial: 'center', // Scoll on initial show
initial: 'center', // Scoll on initial show
click: 'min', // Scroll on cloze click
click: 'min', // Scroll on cloze click
iterate: 'min' // Scroll on iteration
iterate: 'min' // Scroll on iteration
},
},
iteration: {
iteration: {
top: false, // Always start iteration from top
top: false, // Always start iteration from top
loop: true, // Restart from top/bottom from end
loop: true, // Restart from top/bottom from end
hide: false // Hide cloze iterated away from
hide: false // Hide cloze iterated away from
},
},
shortcuts: {
shortcuts: {
next: 'j', // Iterate to next cloze
next: 'j', // Iterate to next cloze
previous: 'h', // Iterate to previous cloze
previous: 'h', // Iterate to previous cloze
toggle_all: 'k' // Toggle all clozes and fields
toggle_all: 'k' // Toggle all clozes and fields
},
},
show: { // `false` means initially collapsed/hidden
show: { // `false` means initially collapsed/hidden
inactive: false, // Inactive clozes
inactive: false, // Inactive clozes
additional: false // Additional fields (Note, Mnemonics etc.)
additional: true // Additional fields (Note, Mnemonics etc.)
},
},
fields: {
fields: {
title: true, // Title area
title: true, // Title area
legends: [ ],
legends: [ ],
show_all_button: true, // Optional "show all" button at bottom of page
show_all_button: true, // Optional "show all" button at bottom of page
log: false // Debug information level (`false`, `'error'` or `true`)
log: false // Debug information level (`false`, `'error'` or `true`)
}
}
}
}
</script>
</script>
<!-- FC2 CONFIGURATION END -->
<!-- FC2 CONFIGURATION END -->





<!-- Title field at top of page -->
<!-- Title field at top of page -->
{{#Title}}<div id="fc2-title">{{Title}}</div>{{/Title}}
{{#Title}}<div id="fc2-title">{{Title}}</div>{{/Title}}


<!-- Scrollable area of the screen, required but can be styled/layouted differently -->
<!-- Scrollable area of the screen, required but can be styled/layouted differently -->
<div id="fc2-viewport">
<div id="fc2-viewport">
<!-- Main content field, required but can be styled/layouted differently -->
<!-- Main content field, required but can be styled/layouted differently -->
<div id="fc2-content" class="linkRender">{{cloze:Text}}<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div>
<div id="fc2-content" class="linkRender">{{cloze:Text}}</div>
<div id="fc2-content-placeholder">This note type requires <code>nested cloze support</code> and <code>increased meta data</code> features from the Anki 2.1.56+ backend (Anki desktop 2.1.56+, AnkiDroid 2.16alpha93+ with `Use new backend` enabled and AnkiMobile 2.0.88+).</div>
<div id="fc2-content-placeholder">This note type requires <code>nested cloze support</code> and <code>increased meta data</code> features from the Anki 2.1.56+ backend (Anki desktop 2.1.56+, AnkiDroid 2.16alpha93+ with `Use new backend` enabled and AnkiMobile 2.0.88+).</div>


<!-- Additional fields, delete to remove from the cards -->
<!-- Additional fields, delete to remove from the cards -->
<div id="fc2-additional">
{{#Extra}}
<div id="fc2-extra-header" class="fc2-additional-header"></div>
<div id="fc2-extra-content" class="fc2-additional-content">{{Extra}}</div>
{{/Extra}}
{{#Source}}
<gr><br>Source: {{Source}} </gr>
{{/Source}}
<p class=footer>{{clickable:Tags}}</p>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
</div>
</div>
</div>
</div>






<!-- FC2 FUNCTIONALITY - DO NOT EDIT BELOW THIS POINT -->
<!-- FC2 FUNCTIONALITY - DO NOT EDIT BELOW THIS POINT -->
<!-- nav bars -->
<!-- nav bars -->
<div id="fc2-nav-toggle-all"></div>
<div id="fc2-nav-toggle-all"></div>
<div id="fc2-nav-prev-cloze"></div>
<div id="fc2-nav-prev-cloze"></div>
<div id="fc2-nav-next-cloze"></div>
<div id="fc2-nav-next-cloze"></div>
<!-- card meta data -->
<!-- card meta data -->
<div id="fc2-meta-type">{{Type}}</div>
<div id="fc2-meta-type">{{Type}}</div>
<div id="fc2-meta-card">{{Card}}</div>
<div id="fc2-meta-card">{{Card}}</div>
<div id="fc2-meta-tags">{{Tags}}</div>
<div id="fc2-meta-tags">{{Tags}}</div>
<div id="fc2-meta-deck">{{Deck}}</div>
<div id="fc2-meta-deck">{{Deck}}</div>
<div id="fc2-meta-subdeck">{{Subdeck}}</div>
<div id="fc2-meta-subdeck">{{Subdeck}}</div>
<div id="fc2-meta-flag">{{CardFlag}}</div>
<div id="fc2-meta-flag">{{CardFlag}}</div>
<script type="application/javascript">
<script type="application/javascript">
var fc2
var fc2
(function () {
(function () {
'use strict';
'use strict';


function logger(element, lvl) {
function logger(element, lvl) {
let log = ((_) => { });
let log = ((_) => { });
if (lvl && element) {
if (lvl && element) {
if (lvl === true) {
if (lvl === true) {
log = ((str, args) => {
log = ((str, args) => {
if (log.element.hidden)
if (log.element.hidden)
log.element.hidden = false;
log.element.hidden = false;
let msg = str;
let msg = str;
if (typeof (args) === 'object') {
if (typeof (args) === 'object') {
for (let i = 0; i < args.length; i++) {
for (let i = 0; i < args.length; i++) {
msg += i ? ', ' : ': ';
msg += i ? ', ' : ': ';
if (typeof (args[i]) == 'object')
if (typeof (args[i]) == 'object')
msg += JSON.stringify(args[i]);
msg += JSON.stringify(args[i]);
else if (typeof (args[i]) == 'string')
else if (typeof (args[i]) == 'string')
msg += `"${args[i]}"`;
msg += `"${args[i]}"`;
else
else
msg += args[i];
msg += args[i];
}
}
}
}
else if (args)
else if (args)
msg += `: ${args}`;
msg += `: ${args}`;
log.element.innerText += `${msg}\n`;
log.element.innerText += `${msg}\n`;
log.element.scrollTop = log.element.scrollHeight;
log.element.scrollTop = log.element.scrollHeight;
});
});
}
}
window.onerror = (emsg, _src, _ln, _col, err) => {
window.onerror = (emsg, _src, _ln, _col, err) => {
if (log.element.hidden)
if (log.element.hidden)
log.element.hidden = false;
log.element.hidden = false;
log.element.innerText += `error ${emsg}:\n${err.stack}\n`;
log.element.innerText += `error ${emsg}:\n${err.stack}\n`;
log.element.scrollTop = log.element.scrollHeight;
log.element.scrollTop = log.element.scrollHeight;
return true;
return true;
};
};
log.element = element;
log.element = element;
log.element.hidden = true;
log.element.hidden = true;
}
}
return log;
return log;
}
}


class Searcher {
class Searcher {
constructor(element, prefix, logger = (() => { })) {
constructor(element, prefix, logger = (() => { })) {
logger('searcher.constructor()');
logger('searcher.constructor()');
this.element = element, this.log = logger;
this.element = element, this.log = logger;
this.matches = [], this.index = -1, this.sstr = '';
this.matches = [], this.index = -1, this.sstr = '';
this.class_ = {
this.class_ = {
match: prefix + 'search-match',
match: prefix + 'search-match',
matches: prefix + 'search-matches'
matches: prefix + 'search-matches'
};
};
const panel = document.createElement('div');
const panel = document.createElement('div');
panel.id = `${prefix}search-panel`;
panel.id = `${prefix}search-panel`;
panel.hidden = true;
panel.hidden = true;
panel.innerHTML = `<input type="text" id="${prefix}search-field" placeholder="Search for text"/><div id="${prefix}search-btn" tabindex="0">Search</div>`;
panel.innerHTML = `<input type="text" id="${prefix}search-field" placeholder="Search for text"/><div id="${prefix}search-btn" tabindex="0">Search</div>`;
this.panel = element.parentElement.insertBefore(panel, this.element.nextElementSibling);
this.panel = element.parentElement.insertBefore(panel, this.element.nextElementSibling);
this.field = document.getElementById(`${prefix}search-field`);
this.field = document.getElementById(`${prefix}search-field`);
this.field.addEventListener('keydown', (evt) => {
this.field.addEventListener('keydown', (evt) => {
if (evt.key === 'Enter') {
if (evt.key === 'Enter') {
this.search();
this.search();
this.button.focus();
this.button.focus();
if (!document.documentElement.classList.contains('mobile'))
if (!document.documentElement.classList.contains('mobile'))
this.field.focus();
this.field.focus();
}
}
else if (evt.key === 'Escape')
else if (evt.key === 'Escape')
return;
return;
evt.stopPropagation();
evt.stopPropagation();
});
});
this.button = document.getElementById(`${prefix}search-btn`);
this.button = document.getElementById(`${prefix}search-btn`);
this.button.onclick = (evt) => { this.search(); };
this.button.onclick = (evt) => { this.search(); };
this.field.onfocus = (evt) => { this.field.select(); };
this.field.onfocus = (evt) => { this.field.select(); };
}
}
search() {
search() {
this.log('searcher.search');
this.log('searcher.search');
if (!this.field?.value) {
if (!this.field?.value) {
this.clear();
this.clear();
return;
return;
}
}
if (this.field.value !== this.sstr) {
if (this.field.value !== this.sstr) {
this.clear();
this.clear();
this.sstr = this.field.value;
this.sstr = this.field.value;
this.highlight(RegExp(this.sstr.replace(/[.*+?^${}()|[\]\\]/g, "\\/*--###JS###--*/"), 'gi'));
this.highlight(RegExp(this.sstr.replace(/[.*+?^${}()|[\]\\]/g, "\\/*--###JS###--*/"), 'gi'));
}
}
if (this.matches?.length) {
if (this.matches?.length) {
if (this.index >= 0)
if (this.index >= 0)
this.matches[this.index].classList.replace(this.class_.match, this.class_.matches);
this.matches[this.index].classList.replace(this.class_.match, this.class_.matches);
this.index = this.index < this.matches.length - 1
this.index = this.index < this.matches.length - 1
? this.index + 1
? this.index + 1
: 0;
: 0;
this.matches[this.index].classList.replace(this.class_.matches, this.class_.match);
this.matches[this.index].classList.replace(this.class_.matches, this.class_.match);
this.matches[this.index].scrollIntoView({ behavior: 'auto', block: 'center', inline: 'nearest' });
this.matches[this.index].scrollIntoView({ behavior: 'auto', block: 'center', inline: 'nearest' });
}
}
}
}
highlight(re) {
highlight(re) {
this.log('searcher.highlight');
this.log('searcher.highlight');
const txt = this.element.textContent;
const txt = this.element.textContent;
const rct = this.element.getBoundingClientRect();
const rct = this.element.getBoundingClientRect();
const stl = getComputedStyle(this.element);
const stl = getComputedStyle(this.element);
const offset = {
const offset = {
top: this.element.scrollTop - rct.top - parseFloat(stl.marginTop),
top: this.element.scrollTop - rct.top - parseFloat(stl.marginTop),
left: this.element.scrollLeft - rct.left - parseFloat(stl.marginLeft)
left: this.element.scrollLeft - rct.left - parseFloat(stl.marginLeft)
};
};
const sel = window.getSelection();
const sel = window.getSelection();
sel.removeAllRanges();
sel.removeAllRanges();
let match, sstr = this.field.value;
let match, sstr = this.field.value;
while (match = re.exec(txt)) {
while (match = re.exec(txt)) {
const itr = nd_itr(this.element);
const itr = nd_itr(this.element);
let index = 0;
let index = 0;
let res = itr.next();
let res = itr.next();
while (!res.done) {
while (!res.done) {
let rng;
let rng;
if (match.index >= index && match.index < index + res.value.length) {
if (match.index >= index && match.index < index + res.value.length) {
rng = new Range();
rng = new Range();
rng.setStart(res.value, match.index - index);
rng.setStart(res.value, match.index - index);
}
}
if (match.index + sstr.length >= index &&
if (match.index + sstr.length >= index &&
match.index + sstr.length <= index + res.value.length &&
match.index + sstr.length <= index + res.value.length &&
rng) {
rng) {
rng.setEnd(res.value, match.index + sstr.length - index);
rng.setEnd(res.value, match.index + sstr.length - index);
sel.addRange(rng);
sel.addRange(rng);
for (const rect of rng.getClientRects()) {
for (const rect of rng.getClientRects()) {
const light = document.createElement('DIV');
const light = document.createElement('DIV');
this.element.appendChild(light);
this.element.appendChild(light);
light.classList.add(this.class_.matches);
light.classList.add(this.class_.matches);
light.style.top = rect.y + offset.top + 'px';
light.style.top = rect.y + offset.top + 'px';
light.style.left = rect.x + offset.left + 'px';
light.style.left = rect.x + offset.left + 'px';
light.style.height = rect.height + 'px';
light.style.height = rect.height + 'px';
light.style.width = rect.width + 'px';
light.style.width = rect.width + 'px';
this.matches.push(light);
this.matches.push(light);
}
}
}
}
index += res.value.length;
index += res.value.length;
res = itr.next();
res = itr.next();
}
}
}
}
sel.removeAllRanges();
sel.removeAllRanges();
function* nd_itr(nd) {
function* nd_itr(nd) {
for (const cnd of nd.childNodes) {
for (const cnd of nd.childNodes) {
if (cnd.nodeType === Node.TEXT_NODE)
if (cnd.nodeType === Node.TEXT_NODE)
yield cnd;
yield cnd;
else
else
yield* nd_itr(cnd);
yield* nd_itr(cnd);
}
}
}
}
}
}
clear() {
clear() {
this.log('searcher.clear');
this.log('searcher.clear');
for (const el of this.matches)
for (const el of this.matches)
el.remove();
el.remove();
this.index = -1, this.sstr = '', this.matches = [];
this.index = -1, this.sstr = '', this.matches = [];
}
}
focus() {
focus() {
this.log('searcher.focus');
this.log('searcher.focus');
this.hidden = false;
this.hidden = false;
this.field.focus();
this.field.focus();
}
}
get hidden() { return this.panel.hidden; }
get hidden() { return this.panel.hidden; }
set hidden(hide) { if (this.panel.hidden = hide)
set hidden(hide) { if (this.panel.hidden = hide)
this.clear(); }
this.clear(); }
}
}


function ancestor(descendant, selector) {
function ancestor(descendant, selector) {
while (descendant && !descendant.matches(selector))
while (descendant && !descendant.matches(selector))
descendant = descendant.parentElement;
descendant = descendant.parentElement;
return descendant;
return descendant;
}
}


class FC2 {
class FC2 {
constructor() {
constructor() {
this.listeners = false;
this.listeners = false;
}
}
load(config, side) {
load(config, side) {
this.viewport = document.getElementById('fc2-viewport');
this.viewport = document.getElementById('fc2-viewport');
let elm = document.getElementById('fc2-log-panel');
let elm = document.getElementById('fc2-log-panel');
if (!elm && config.fields?.log) {
if (!elm && config.fields?.log) {
elm = document.createElement('pre');
elm = document.createElement('pre');
elm.id = 'fc2-log-panel';
elm.id = 'fc2-log-panel';
elm.hidden = true;
elm.hidden = true;
elm = this.viewport.parentElement.appendChild(elm);
elm = this.viewport.parentElement.appendChild(elm);
}
}
this.log = logger(elm, config.fields?.log);
this.log = logger(elm, config.fields?.log);
this.cfg = config;
this.cfg = config;
this.cfg.front = side === 'front';
this.cfg.front = side === 'front';
this.content = document.getElementById('fc2-content');
this.content = document.getElementById('fc2-content');
this.current = this.content.querySelector('.cloze');
this.current = this.content.querySelector('.cloze');
if (this.current.dataset.ordinal === undefined)
if (this.current.dataset.ordinal === undefined)
return;
return;
this.search = new Searcher(this.viewport, 'fc2-', this.log);
this.search = new Searcher(this.viewport, 'fc2-', this.log);
this.ordinal || (this.ordinal = parseInt(this.current.dataset.ordinal));
this.ordinal || (this.ordinal = parseInt(this.current.dataset.ordinal));
this.content.parentElement.classList.remove(this.cfg.front ? 'back' : 'front');
this.content.parentElement.classList.remove(this.cfg.front ? 'back' : 'front');
this.content.parentElement.classList.add(this.cfg.front ? 'front' : 'back');
this.content.parentElement.classList.add(this.cfg.front ? 'front' : 'back');
const tags = document.getElementById('fc2-meta-tags').innerText.split(' ');
const tags = document.getElementById('fc2-meta-tags').innerText.split(' ');
for (const tag of tags) {
for (const tag of tags) {
if (!tag.startsWith('fc2.'))
if (!tag.startsWith('fc2.'))
continue;
continue;
const parts = tag.slice(4).split('.');
const parts = tag.slice(4).split('.');
const tag_side = ['front', 'back'].includes(parts[0]) ? parts.shift() : undefined;
const tag_side = ['front', 'back'].includes(parts[0]) ? parts.shift() : undefined;
if (tag_side && tag_side !== side || this.cfg[parts[0]]?.[parts[1]] === undefined)
if (tag_side && tag_side !== side || this.cfg[parts[0]]?.[parts[1]] === undefined)
continue;
continue;
this.cfg[parts[0]][parts[1]] = typeof (this.cfg[parts[0]][parts[1]]) === 'boolean'
this.cfg[parts[0]][parts[1]] = typeof (this.cfg[parts[0]][parts[1]]) === 'boolean'
? parts[2] === 'true'
? parts[2] === 'true'
: parts.slice(2);
: parts.slice(2);
}
}
let title = document.getElementById('fc2-title');
let title = document.getElementById('fc2-title');
if (!title && this.cfg.fields?.title) {
if (!title && this.cfg.fields?.title) {
let titles;
let titles;
const h1 = this.content.querySelector('h1');
const h1 = this.content.querySelector('h1');
if (h1) {
if (h1) {
titles = h1.innerText;
titles = h1.innerText;
h1.remove();
h1.remove();
}
}
else
else
titles = document.getElementById('fc2-meta-subdeck')?.innerText;
titles = document.getElementById('fc2-meta-subdeck')?.innerText;
if (titles) {
if (titles) {
title = document.createElement('div');
title = document.createElement('div');
title.id = 'fc2-title';
title.id = 'fc2-title';
title.innerText = titles;
title.innerText = titles;
this.viewport.insertAdjacentElement('beforebegin', title);
this.viewport.insertAdjacentElement('beforebegin', title);
}
}
}
}
const expose = this.generate_expose();
const expose = this.generate_expose();
let active_seen = false;
let active_seen = false;
this.content.querySelectorAll('.cloze-inactive, .cloze').forEach(((cloze) => {
this.content.querySelectorAll('.cloze-inactive, .cloze').forEach(((cloze) => {
const active = cloze.classList.contains('cloze');
const active = cloze.classList.contains('cloze');
active_seen || (active_seen = active);
active_seen || (active_seen = active);
const exposed = expose(cloze);
const exposed = expose(cloze);
if (!active && (exposed || cloze.querySelector('.cloze'))) {
if (!active && (exposed || cloze.querySelector('.cloze'))) {
cloze.classList.remove('cloze-inactive');
cloze.classList.remove('cloze-inactive');
return;
return;
}
}
cloze.dataset.hint = this.cfg.front && active && cloze.innerHTML !== '[...]'
cloze.dataset.hint = this.cfg.front && active && cloze.innerHTML !== '[...]'
? this.cfg.hint.replace('%h', cloze.innerHTML.slice(1, cloze.innerHTML.length - 1)) || ""
? this.cfg.hint.replace('%h', cloze.innerHTML.slice(1, cloze.innerHTML.length - 1)) || ""
: this.cfg.prompt;
: this.cfg.prompt;
if (active && this.cfg.front ||
if (active && this.cfg.front ||
!active && (!this.cfg.show.inactive ||
!active && (!this.cfg.show.inactive ||
this.cfg.show.inactive === 'preceding' && active_seen))
this.cfg.show.inactive === 'preceding' && active_seen))
this.hide(cloze);
this.hide(cloze);
}));
}));
if (!this.cfg.show.additional)
if (!this.cfg.show.additional)
this.viewport.querySelectorAll('.fc2-additional-content')
this.viewport.querySelectorAll('.fc2-additional-content')
.forEach(nd => nd.hidden = true);
.forEach(nd => nd.hidden = true);
if (this.cfg.fields?.legends?.length) {
if (this.cfg.fields?.legends?.length) {
const footer = document.createElement('div');
const footer = document.createElement('div');
footer.id = 'fc2-footer';
footer.id = 'fc2-footer';
this.viewport.insertAdjacentElement('afterend', footer);
this.viewport.insertAdjacentElement('afterend', footer);
for (const legend of this.cfg.fields.legends) {
for (const legend of this.cfg.fields.legends) {
const row = document.createElement('div');
const row = document.createElement('div');
row.className = 'fc2-legends';
row.className = 'fc2-legends';
footer.appendChild(row);
footer.appendChild(row);
for (const itm of legend) {
for (const itm of legend) {
let cell = document.createElement('div');
let cell = document.createElement('div');
cell.innerHTML = itm;
cell.innerHTML = itm;
cell = cell.firstElementChild;
cell = cell.firstElementChild;
if (!cell)
if (!cell)
continue;
continue;
cell.className = 'fc2-legend';
cell.className = 'fc2-legend';
row.appendChild(cell);
row.appendChild(cell);
}
}
}
}
}
}
if (this.cfg.fields?.show_all_button) {
if (this.cfg.fields?.show_all_button) {
const btn = document.createElement('button');
const btn = document.createElement('button');
btn.id = "fc2-show-all-btn";
btn.id = "fc2-show-all-btn";
btn.innerText = "Show all";
btn.innerText = "Show all";
this.viewport.insertAdjacentElement('afterend', btn);
this.viewport.insertAdjacentElement('afterend', btn);
}
}
if (this.cfg.front)
if (this.cfg.front)
this.viewport.onscroll = (_evt) => sessionStorage.setItem('fc2_scroll_top', this.viewport.scrollTop.toString());
this.viewport.onscroll = (_evt) => sessionStorage.setItem('fc2_scroll_top', this.viewport.scrollTop.toString());
if (!this.listeners) {
if (!this.listeners) {
document.addEventListener("click", this.mouse.bind(this));
document.addEventListener("click", this.mouse.bind(this));
document.addEventListener("keydown", this.keyboard.bind(this));
document.addEventListener("keydown", this.keyboard.bind(this));
this.listeners = true;
this.listeners = true;
}
}
this.content.style.display = 'block';
this.content.style.display = 'block';
document.getElementById('fc2-content-placeholder').remove();
document.getElementById('fc2-content-placeholder').remove();
window.requestAnimationFrame(() => this.scroll_to({ scroll: this.cfg.scroll.initial }));
window.requestAnimationFrame(() => this.scroll_to({ scroll: this.cfg.scroll.initial }));
}
}
generate_expose() {
generate_expose() {
this.log('generate_expose');
this.log('generate_expose');
let expose_;
let expose_;
if (this.cfg.expose.pos === 'pre') {
if (this.cfg.expose.pos === 'pre') {
expose_ = (el) => {
expose_ = (el) => {
if (el.previousSibling?.data?.endsWith(this.cfg.expose.char)) {
if (el.previousSibling?.data?.endsWith(this.cfg.expose.char)) {
el.previousSibling.data = el.previousSibling.data.slice(0, -1);
el.previousSibling.data = el.previousSibling.data.slice(0, -1);
return true;
return true;
}
}
return false;
return false;
};
};
}
}
else if (this.cfg.expose.pos === 'post') {
else if (this.cfg.expose.pos === 'post') {
expose_ = (el) => {
expose_ = (el) => {
if (el.nextSibling?.data?.startsWith(this.cfg.expose.char)) {
if (el.nextSibling?.data?.startsWith(this.cfg.expose.char)) {
el.nextSibling.data = el.nextSibling.data.substring(1);
el.nextSibling.data = el.nextSibling.data.substring(1);
return true;
return true;
}
}
return false;
return false;
};
};
}
}
else if (this.cfg.expose.pos === 'end') {
else if (this.cfg.expose.pos === 'end') {
expose_ = (el) => {
expose_ = (el) => {
if (el.dataset.cloze?.endsWith(this.cfg.expose.char)) {
if (el.dataset.cloze?.endsWith(this.cfg.expose.char)) {
el.dataset.cloze = el.dataset.cloze.slice(0, -1);
el.dataset.cloze = el.dataset.cloze.slice(0, -1);
return true;
return true;
}
}
else if (el.lastChild?.data?.endsWith(this.cfg.expose.char)) {
else if (el.lastChild?.data?.endsWith(this.cfg.expose.char)) {
el.lastChild.data = el.lastChild.data.slice(0, -1);
el.lastChild.data = el.lastChild.data.slice(0, -1);
return true;
return true;
}
}
return false;
return false;
};
};
}
}
else {
else {
expose_ = (el) => {
expose_ = (el) => {
if (el.dataset.cloze?.startsWith(this.cfg.expose.char)) {
if (el.dataset.cloze?.startsWith(this.cfg.expose.char)) {
el.dataset.cloze = el.dataset.cloze.substring(1);
el.dataset.cloze = el.dataset.cloze.substring(1);
return true;
return true;
}
}
else if (el.firstChild?.data?.startsWith(this.cfg.expose.char)) {
else if (el.firstChild?.data?.startsWith(this.cfg.expose.char)) {
el.firstChild.data = el.firstChild.data.substring(1);
el.firstChild.data = el.firstChild.data.substring(1);
return true;
return true;
}
}
return false;
return false;
};
};
}
}
return this.cfg.expose.reverse ? (el) => { return !expose_(el); } : expose_;
return this.cfg.expose.reverse ? (el) => { return !expose_(el); } : expose_;
}
}
show(el) {
show(el) {
this.log('show', el.tagName);
this.log('show', el.tagName);
if (!el?.classList.contains('hide'))
if (!el?.classList.contains('hide'))
return;
return;
el.classList.remove('hide');
el.classList.remove('hide');
el.innerHTML = el.dataset.cloze;
el.innerHTML = el.dataset.cloze;
for (const child of el.querySelectorAll(':scope .cloze, :scope .cloze-inactive')) {
for (const child of el.querySelectorAll(':scope .cloze, :scope .cloze-inactive')) {
if (child.dataset.hint === undefined)
if (child.dataset.hint === undefined)
child.dataset.hint = '';
child.dataset.hint = '';
this.hide(child);
this.hide(child);
}
}
}
}
hide(el) {
hide(el) {
this.log('hide');
this.log('hide');
if (el?.classList.contains('hide'))
if (el?.classList.contains('hide'))
return;
return;
el.classList.add('hide');
el.classList.add('hide');
if (!this.search.hidden)
if (!this.search.hidden)
this.search.hidden = true;
this.search.hidden = true;
if (el.dataset.cloze === undefined)
if (el.dataset.cloze === undefined)
el.dataset.cloze = el.innerHTML;
el.dataset.cloze = el.innerHTML;
el.innerHTML = el.dataset.hint;
el.innerHTML = el.dataset.hint;
}
}
iter(fwd) {
iter(fwd) {
this.log('iter');
this.log('iter');
const els = this.content.querySelectorAll('.cloze');
const els = this.content.querySelectorAll('.cloze');
let nxt;
let nxt;
if (this.current?.classList.contains('hide'))
if (this.current?.classList.contains('hide'))
nxt = this.current;
nxt = this.current;
if (fwd && this.current === els[els.length - 1])
if (fwd && this.current === els[els.length - 1])
nxt = this.cfg.iteration.loop ? els[0] : this.current;
nxt = this.cfg.iteration.loop ? els[0] : this.current;
else if (!fwd && this.current === els[0])
else if (!fwd && this.current === els[0])
nxt = this.cfg.iteration.loop ? els[els.length - 1] : this.current;
nxt = this.cfg.iteration.loop ? els[els.length - 1] : this.current;
for (let i = 0; !nxt && i < els.length; i++) {
for (let i = 0; !nxt && i < els.length; i++) {
if (els[i] === this.current)
if (els[i] === this.current)
nxt = els[i + (fwd ? 1 : -1)];
nxt = els[i + (fwd ? 1 : -1)];
}
}
if (nxt !== this.current && this.cfg.iteration.hide)
if (nxt !== this.current && this.cfg.iteration.hide)
this.hide(this.current);
this.hide(this.current);
this.show(this.current = nxt);
this.show(this.current = nxt);
this.scroll_to({ scroll: this.cfg.scroll.iterate, cloze: this.current });
this.scroll_to({ scroll: this.cfg.scroll.iterate, cloze: this.current });
}
}
toggle_cloze(cloze) {
toggle_cloze(cloze) {
this.log('toggle_cloze');
this.log('toggle_cloze');
const show = cloze.classList.contains('hide');
const show = cloze.classList.contains('hide');
if (show)
if (show)
this.show(cloze);
this.show(cloze);
else
else
this.hide(cloze);
this.hide(cloze);
return show;
return show;
}
}
toggle_field(field) {
toggle_field(field) {
this.log('toggle_field');
this.log('toggle_field');
const fld = ancestor(field, '.fc2-additional-content') ||
const fld = ancestor(field, '.fc2-additional-content') ||
ancestor(field, '.fc2-additional-header').nextElementSibling;
ancestor(field, '.fc2-additional-header').nextElementSibling;
if (fld)
if (fld)
fld.hidden = !fld.hidden;
fld.hidden = !fld.hidden;
}
}
toggle_all(show = undefined) {
toggle_all(show = undefined) {
this.log('toggle_all');
this.log('toggle_all');
if (show === true || this.search.hidden ||
if (show === true || this.search.hidden ||
show === undefined &&
show === undefined &&
this.content.querySelector('.cloze.hide, .cloze-inactive.hide, .fc2-additional-content[hidden]')) {
this.content.querySelector('.cloze.hide, .cloze-inactive.hide, .fc2-additional-content[hidden]')) {
this.content.querySelectorAll('.cloze.hide, .cloze-inactive.hide')
this.content.querySelectorAll('.cloze.hide, .cloze-inactive.hide')
.forEach(el => { this.show(el); });
.forEach(el => { this.show(el); });
this.viewport.querySelectorAll('.fc2-additional-content[hidden]')
this.viewport.querySelectorAll('.fc2-additional-content[hidden]')
.forEach(el => { el.hidden = false; });
.forEach(el => { el.hidden = false; });
this.search.hidden = false;
this.search.hidden = false;
return true;
return true;
}
}
else {
else {
this.content.querySelectorAll('.cloze:not(.hide), .cloze-inactive:not(.hide)')
this.content.querySelectorAll('.cloze:not(.hide), .cloze-inactive:not(.hide)')
.forEach(el => { this.hide(el); });
.forEach(el => { this.hide(el); });
this.viewport.querySelectorAll('.fc2-additional-content:not([hidden])')
this.viewport.querySelectorAll('.fc2-additional-content:not([hidden])')
.forEach(el => { el.hidden = true; });
.forEach(el => { el.hidden = true; });
this.search.hidden = true;
this.search.hidden = true;
return false;
return false;
}
}
}
}
scroll_to(opts) {
scroll_to(opts) {
this.log('scroll_to');
this.log('scroll_to');
if (!this.cfg.front) {
if (!this.cfg.front) {
const scroll_top = parseFloat(sessionStorage.getItem('fc2_scroll_top'));
const scroll_top = parseFloat(sessionStorage.getItem('fc2_scroll_top'));
if (!isNaN(scroll_top)) {
if (!isNaN(scroll_top)) {
sessionStorage.removeItem('fc2_scroll_top');
sessionStorage.removeItem('fc2_scroll_top');
this.viewport.scrollTop = scroll_top;
this.viewport.scrollTop = scroll_top;
}
}
}
}
if (opts.scroll === 'none')
if (opts.scroll === 'none')
return;
return;
let first, last;
let first, last;
if (opts.cloze)
if (opts.cloze)
first = last = opts.cloze;
first = last = opts.cloze;
else {
else {
const active = this.content.querySelectorAll('.cloze');
const active = this.content.querySelectorAll('.cloze');
first = active[0];
first = active[0];
last = active[active.length - 1];
last = active[active.length - 1];
}
}
const offset = this.viewport.getBoundingClientRect().top;
const offset = this.viewport.getBoundingClientRect().top;
const line_height = (style) => {
const line_height = (style) => {
this.log(' line_height');
this.log(' line_height');
return parseInt(style.height) + parseInt(style.marginTop) + parseInt(style.marginBottom)
return parseInt(style.height) + parseInt(style.marginTop) + parseInt(style.marginBottom)
|| parseInt(style.lineHeight)
|| parseInt(style.lineHeight)
|| 20;
|| 20;
};
};
const vp_height = this.viewport.clientHeight;
const vp_height = this.viewport.clientHeight;
const cloze_top = (first.getBoundingClientRect().top - offset) - line_height(window.getComputedStyle(first?.previousElementSibling || first, ':before')) + 3;
const cloze_top = (first.getBoundingClientRect().top - offset) - line_height(window.getComputedStyle(first?.previousElementSibling || first, ':before')) + 3;
let top;
let top;
const bottom = (last.getBoundingClientRect().bottom - offset) + line_height(window.getComputedStyle(last?.nextElementSibling || last, ':after')) + 3;
const bottom = (last.getBoundingClientRect().bottom - offset) + line_height(window.getComputedStyle(last?.nextElementSibling || last, ':after')) + 3;
let y = 0;
let y = 0;
if (opts.scroll?.slice(0, 7) === 'context') {
if (opts.scroll?.slice(0, 7) === 'context') {
top = 0;
top = 0;
let section, section_seen, cloze_seen;
let section, section_seen, cloze_seen;
const sections = this.content.querySelectorAll('hr, h1, h2, h3, h4, h5, h6, .cloze');
const sections = this.content.querySelectorAll('hr, h1, h2, h3, h4, h5, h6, .cloze');
for (let i = 0; i < sections.length; i++) {
for (let i = 0; i < sections.length; i++) {
cloze_seen || (cloze_seen = sections[i].tagName === 'SPAN');
cloze_seen || (cloze_seen = sections[i].tagName === 'SPAN');
section_seen || (section_seen = sections[i].tagName !== 'SPAN');
section_seen || (section_seen = sections[i].tagName !== 'SPAN');
if (!cloze_seen)
if (!cloze_seen)
section = sections[i];
section = sections[i];
if (cloze_seen && (section || section_seen))
if (cloze_seen && (section || section_seen))
break;
break;
}
}
if (section) {
if (section) {
top = section.tagName === 'HR'
top = section.tagName === 'HR'
? (section.getBoundingClientRect().bottom - offset)
? (section.getBoundingClientRect().bottom - offset)
: (section.getBoundingClientRect().top - offset) - 5;
: (section.getBoundingClientRect().top - offset) - 5;
}
}
else if (!section_seen) {
else if (!section_seen) {
const all = this.content.querySelectorAll('.cloze, .cloze-inactive');
const all = this.content.querySelectorAll('.cloze, .cloze-inactive');
for (let i = 1; i < all.length; i++) {
for (let i = 1; i < all.length; i++) {
if (all[i] === this.current) {
if (all[i] === this.current) {
top = (all[i - 1].getBoundingClientRect().top - offset) - 5;
top = (all[i - 1].getBoundingClientRect().top - offset) - 5;
break;
break;
}
}
}
}
}
}
}
}
else
else
top = cloze_top;
top = cloze_top;
if (['center', 'context', 'context-bottom'].includes(opts.scroll)) {
if (['center', 'context', 'context-bottom'].includes(opts.scroll)) {
if (bottom - top <= vp_height)
if (bottom - top <= vp_height)
opts.scroll === 'context-bottom'
opts.scroll === 'context-bottom'
? y = bottom - vp_height
? y = bottom - vp_height
: y = top + (bottom - top) / 2 - vp_height / 2;
: y = top + (bottom - top) / 2 - vp_height / 2;
else if (this.cfg.front)
else if (this.cfg.front)
y = top;
else
y = bottom - cloze_top <= vp_height
? bottom - vp_height
: cloze_top;
}
else {
if (cloze_top < 0 || bottom - top >= vp_height)
y = cloze_top;
else if (bot