- // ==UserScript==
- // @name Cleanreads
- // @namespace http://hermanfassett.me
- // @version 1.4
- // @description Cleanreads userscript for Goodreads.com
- // @author Herman Fassett
- // @match https://www.goodreads.com/*
- // @grant GM_addStyle
- // ==/UserScript==
-
- GM_addStyle( `
- .contentComment { padding: 10px 5px 10px 5px; }
- .contentClean { color: green; }
- .contentNotClean { color: red; }
- .contentUnknown { color: blue; }
- #crSettingsDialog {
- width: 500px;
- height: 500px;
- position: fixed;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- background: white;
- border: 1px solid rgba(0,0,0,0.15);
- display: none;
- }
- #crSettingsHeader {
- height: 50px;
- width: 100%;
- background: #F4F1EA;
- text-align: center;
- box-shadow: 0 1px 2px rgba(0,0,0,0.15);
- }
- #crSettingsHeader h1 {
- line-height: 50px;
- color: #382110;
- }
- #crSettingsHeader h1, .crSettingsHeader {
- font-family: "Lato", "Helvetica Neue", "Helvetica", sans-serif;
- }
- .crSettingsHeader, #crSettingsTermButtons { padding-top: 20px; }
- #crSettingsTermButtons button { margin-right: 5px; }
- #crSettingsBody { height: 400px; overflow: auto; }
- #crSettingsFooter {
- height: 50px;
- width: 100%;
- box-shadow: 1px 0 2px rgba(0,0,0,0.15);
- }
- #crSettingsFooter button {
- float: right;
- margin: 10px 10px 0 0;
- }
- #crSettingsFooter button.saveButton {
- color: white;
- background-color: #409D69;
- }
- .crTermsContainer { display: inline-block; }
- #crSnippetHeader {
- float: left;
- padding-right: 10px;
- }
- `);
-
- (function(Cleanreads) {
- 'use strict';
-
- /** The group bookshelf ID to use as default clean check list */
- Cleanreads.CLEAN_READS_BOOKSHELF_ID = 5989;
-
- /** The positive search terms when determining verdict */
- Cleanreads.POSITIVE_SEARCH_TERMS = [
- { term: 'clean', exclude: { before: ['not', 'isn\'t'], after: ['ing'] }},
- { term: 'no sex', exclude: { before: [], after: [] }}
- ];
-
- /** The negative search terms when determining verdict */
- Cleanreads.NEGATIVE_SEARCH_TERMS = [
- { term: 'sex', exclude: { before: ['no'], after: ['ist'] }},
- { term: 'adult', exclude: { before: ['young', 'new'], after: ['hood', 'ing']}},
- { term: 'erotic', exclude: { before: ['not', 'isn\'t'], after: []}}
- ];
-
- Cleanreads.SNIPPET_HALF_LENGTH = 65;
- Cleanreads.ATTEMPTS = 10;
-
- /**
- * Load the settings from local storage if existant
- */
- Cleanreads.loadSettings = function() {
- try {
- Cleanreads.POSITIVE_SEARCH_TERMS = JSON.parse(localStorage.getItem("Cleanreads.POSITIVE_SEARCH_TERMS")) || Cleanreads.POSITIVE_SEARCH_TERMS;
- Cleanreads.NEGATIVE_SEARCH_TERMS = JSON.parse(localStorage.getItem("Cleanreads.NEGATIVE_SEARCH_TERMS")) || Cleanreads.NEGATIVE_SEARCH_TERMS;
- Cleanreads.SNIPPET_HALF_LENGTH = JSON.parse(localStorage.getItem("Cleanreads.SNIPPET_HALF_LENGTH")) || Cleanreads.SNIPPET_HALF_LENGTH;
- Cleanreads.ATTEMPTS = JSON.parse(localStorage.getItem("Cleanreads.ATTEMPTS")) || Cleanreads.ATTEMPTS;
- Cleanreads.CLEAN_READS_BOOKSHELF = JSON.parse(localStorage.getItem("Cleanreads.CLEAN_READS_BOOKSHELF")) || {
- books: [],
- timestamp: new Date(0),
- unloaded: true
- };
-
- // Get Clean Reads shelf clean books if not recently loaded (1 day)
- let now = new Date();
- if (now.setDate(now.getDate() - 1) > new Date(Cleanreads.CLEAN_READS_BOOKSHELF.timestamp)) {
- Cleanreads.getGroupBookshelfBooks(Cleanreads.CLEAN_READS_BOOKSHELF_ID, 5000)
- .then(data=> {
- Cleanreads.CLEAN_READS_BOOKSHELF = {
- books: data,
- timestamp: new Date()
- };
- localStorage.setItem("Cleanreads.CLEAN_READS_BOOKSHELF", JSON.stringify(Cleanreads.CLEAN_READS_BOOKSHELF));
- })
- .finally(Cleanreads.searchBookshelf);
- }
-
- let settingsBody = document.getElementById("crSettingsBody");
- if (settingsBody) {
- settingsBody.innerHTML = `
- <div class="userInfoBoxContent">
- <div id="crSettingsTermButtons">
- </div>
- <h1 class="crSettingsHeader">Positive Search Terms:</h1>
- <div id="crPositiveSearchTerms">
- </div>
- <h1 class="crSettingsHeader">Negative Search Terms:</h1>
- <div id="crNegativeSearchTerms">
- </div>
- <h1 class="crSettingsHeader">Other Settings:</h1>
- <h4 id="crSnippetHeader">Snippet length:</h4> <input id="crSnippetHalfLength" type="number" value="${Cleanreads.SNIPPET_HALF_LENGTH}" min="0" />
- <h4 id="crAttemptsHeader">Max Verdict Load Attempts (tries every second):</h4> <input id="crAttempts" type="number" value="${Cleanreads.ATTEMPTS}" min="1" />
- </div>
- `;
-
- // Add buttons
- let addPositiveButton = document.createElement("button");
- addPositiveButton.innerText = "Add Positive";
- addPositiveButton.className = "gr-button";
- addPositiveButton.onclick = Cleanreads.addSearchTerm.bind(null, true, null, null, null);
- document.getElementById("crSettingsTermButtons").appendChild(addPositiveButton);
- let addNegativeButton = document.createElement("button");
- addNegativeButton.innerText = "Add Negative";
- addNegativeButton.className = "gr-button";
- addNegativeButton.onclick = Cleanreads.addSearchTerm.bind(null, false, null, null, null);
- document.getElementById("crSettingsTermButtons").appendChild(addNegativeButton);
- let resetButton = document.createElement("button");
- resetButton.innerText = "Reset";
- resetButton.className = "gr-button";
- resetButton.onclick = function() {
- if (confirm("Are you sure you want to remove? You will have to refresh the page to see default values loaded.")) {
- localStorage.removeItem("Cleanreads.POSITIVE_SEARCH_TERMS");
- localStorage.removeItem("Cleanreads.NEGATIVE_SEARCH_TERMS");
- localStorage.removeItem("Cleanreads.SNIPPET_HALF_LENGTH");
- localStorage.removeItem("Cleanreads.ATTEMPTS");
- Cleanreads.loadSettings();
- }
- }
- document.getElementById("crSettingsTermButtons").appendChild(resetButton);
-
- // Add existing terms
- Cleanreads.POSITIVE_SEARCH_TERMS.forEach((search) => Cleanreads.addSearchTerm(true, search.term, search.exclude.before, search.exclude.after));
- Cleanreads.NEGATIVE_SEARCH_TERMS.forEach((search) => Cleanreads.addSearchTerm(false, search.term, search.exclude.before, search.exclude.after));
- }
- } catch (ex) {
- console.error("Cleanreads: Failed to load settings!", ex);
- }
- };
-
- /**
- * Save the positive and negative search terms to local storage
- */
- Cleanreads.saveSettings = function() {
- let positiveTerms = document.querySelectorAll("#crPositiveSearchTerms > .crTermsContainer");
- let negativeTerms = document.querySelectorAll("#crNegativeSearchTerms > .crTermsContainer");
-
- Cleanreads.POSITIVE_SEARCH_TERMS = [...positiveTerms].map((search) => {
- return {
- term: search.querySelector("[name=term]").value,
- exclude: {
- before: search.querySelector("[name=excludeBefore]").value.split(",").map(x => x.trim()),
- after: search.querySelector("[name=excludeAfter]").value.split(",").map(x => x.trim())
- }
- }
- }).filter(x => x.term);
-
- Cleanreads.NEGATIVE_SEARCH_TERMS = [...negativeTerms].map((search) => {
- return {
- term: search.querySelector("[name=term]").value,
- exclude: {
- before: search.querySelector("[name=excludeBefore]").value.split(",").map(x => x.trim()),
- after: search.querySelector("[name=excludeAfter]").value.split(",").map(x => x.trim())
- }
- }
- }).filter(x => x.term);
-
- Cleanreads.SNIPPET_HALF_LENGTH = parseInt(document.getElementById("crSnippetHalfLength").value) || Cleanreads.SNIPPET_HALF_LENGTH;
- Cleanreads.ATTEMPTS = parseInt(document.getElementById("crAttempts").value) || Cleanreads.ATTEMPTS;
-
- localStorage.setItem("Cleanreads.POSITIVE_SEARCH_TERMS", JSON.stringify(Cleanreads.POSITIVE_SEARCH_TERMS));
- localStorage.setItem("Cleanreads.NEGATIVE_SEARCH_TERMS", JSON.stringify(Cleanreads.NEGATIVE_SEARCH_TERMS));
- localStorage.setItem("Cleanreads.SNIPPET_HALF_LENGTH", JSON.stringify(Cleanreads.SNIPPET_HALF_LENGTH));
- localStorage.setItem("Cleanreads.ATTEMPTS", JSON.stringify(Cleanreads.ATTEMPTS));
- Cleanreads.loadSettings();
- }
-
- /**
- * Setup the settings modal for Cleanreads
- */
- Cleanreads.setupSettings = function() {
- // Add link to menu dropdown
- let links = Array.from(document.getElementsByClassName('menuLink')).filter(x => x.innerText == 'Account settings');
- if (links && links.length) {
- let li = document.createElement('li');
- li.className = 'menuLink';
- li.onclick = Cleanreads.showSettings;
- li.innerHTML = `<a href='#' class='siteHeader__subNavLink'>Cleanreads settings</a>`;
- links[0].parentNode.insertBefore(li, links[0].nextSibling);
- }
- // Add dialog
- document.body.innerHTML += `
- <div id="crSettingsDialog">
- <div id="crSettingsHeader"><h1>Cleanreads Settings</h1></div>
- <div id="crSettingsBody">
- </div>
- <div id="crSettingsFooter"></div>
- </div>
- `;
- // Add link to profile page
- let settingsLink = document.createElement('a');
- settingsLink.href = '#';
- settingsLink.innerText = 'Cleanreads settings';
- settingsLink.onclick = Cleanreads.showSettings;
- document.getElementsByClassName('userInfoBoxContent')[0].appendChild(settingsLink);
- // Add close button to dialog
- let closeButton = document.createElement('button');
- closeButton.innerText = 'Close';
- closeButton.className = 'gr-button';
- closeButton.onclick = Cleanreads.hideSettings;
- document.getElementById('crSettingsFooter').appendChild(closeButton);
- // Add save button to dialog
- let saveButton = document.createElement('button');
- saveButton.innerText = 'Save';
- saveButton.className = 'gr-button saveButton';
- saveButton.onclick = Cleanreads.saveSettings;
- document.getElementById('crSettingsFooter').appendChild(saveButton);
- Cleanreads.loadSettings();
- };
-
- /**
- * Add a search term to the settings UI
- */
- Cleanreads.addSearchTerm = function(positive, term, before, after) {
- document.getElementById(`cr${positive ? 'Positive' : 'Negative'}SearchTerms`).insertAdjacentHTML("beforeend",
- `<div class="crTermsContainer">
- <input name="excludeBefore" value="${before ? before.join(", ") : ''}" type="text" />
- <input name="term" value="${term || ''}" type="text" />
- <input name="excludeAfter" value="${after ? after.join(", ") : ''}" type="text" />
- </div>`);
- };
-
- /**
- * Setup the rating (verdict) container on a book page
- */
- Cleanreads.setupRating = function() {
- let match = window.location.pathname.match(/book\/show\/(\d+)/);
- if (match && match.length > 1) {
- Cleanreads.bookId = window.location.pathname.match(/show\/(\d*)/)[1];
- Cleanreads.loadSettings();
- Cleanreads.reviews = [];
- Cleanreads.shelves = [];
- Cleanreads.positives = 0;
- Cleanreads.negatives = 0;
-
- // Create container for rating
- let container = document.getElementById('descriptionContainer');
- let contentDescription = document.createElement('div');
- contentDescription.id = 'contentDescription';
- contentDescription.className = 'readable stacked u-bottomGrayBorder u-marginTopXSmall u-paddingBottomXSmall';
- contentDescription.innerHTML = `
- <h2 class="buyButtonContainer__title u-inlineBlock">Cleanreads Rating</h2>
- <h2 class="buyButtonContainer__title">
- Verdict: <span id="crVerdict">Loading...</span>
- (<span id="crPositives" class="contentClean">0</span>/<span id="crNegatives" class="contentNotClean">0</span>)
- </h2>
- <a id='expandCrDetails' href="#">(Details)</a>
- <div id="crDetails" style="display:none"></div>
- `;
- container.parentNode.insertBefore(contentDescription, container.nextSibling);
- Cleanreads.crDetails = document.getElementById('crDetails');
- document.getElementById('expandCrDetails').onclick = Cleanreads.expandDetails;
-
- Cleanreads.getTopBookShelves(Cleanreads.bookId).then(shelves => {
- Cleanreads.shelves = shelves;
- Cleanreads.startReviews();
- }).catch(err => Cleanreads.startReviews());
- }
- };
-
- /**
- * Start attempting to get the available reviews on the page and read their content
- */
- Cleanreads.startReviews = function() {
- Cleanreads.getReviews();
- // Reviews are delayed content so keep looking for a bit if nothing
- if (!Cleanreads.reviews.length && Cleanreads.ATTEMPTS--) {
- setTimeout(Cleanreads.startReviews, 1000);
- } else {
- Cleanreads.calculateContent();
- }
- };
-
- /**
- * Get reviews from page (only gets the first page of reviews, not easy to access others without API)
- */
- Cleanreads.getReviews = function() {
- let reviewElements = document.querySelectorAll('#reviews .reviewText');
- Cleanreads.reviews = Array.from(reviewElements).map(x => (x.querySelector('[style]') || x).innerText.trim());
- };
-
- /**
- * Get title as text with series appended
- */
- Cleanreads.getTitle = function() {
- return document.getElementById('bookTitle').innerText.trim() + document.getElementById('bookSeries').innerText.trim();
- };
-
- /**
- * Get book description text
- */
- Cleanreads.getDescription = function() {
- let description = document.getElementById('description');
- return (description.querySelector('[style]') || description).innerText.trim();
- };
-
- /**
- * Get group bookshelf titles
- * @param {string} shelfId - The bookshelf id
- * @param {number} maxCount - The maximum number of books in the bookshelf to return
- * @returns {Promise} - A promise that resolves to array of book ids or rejects with error
- */
- Cleanreads.getGroupBookshelfBooks = function(shelfId, maxCount) {
- return new Promise(function(resolve, reject) {
- jQuery.ajax(`${window.location.origin}/group/bookshelf/${shelfId}?utf8=✓&view=covers&per_page=${maxCount || 1000}`)
- .done(result => {
- resolve(jQuery(result).find(".rightContainer div > a").toArray().map(x => (x.href.match(/show\/(\d*)/)||[])[1]));
- })
- .fail(err => reject(err));
- });
- };
-
- /**
- * Get the top 100 shelf names for a given book
- * @param {string} bookId - The book id
- * @returns {Promise} - A promise that resolves to array of top 100 shelves for given book
- */
- Cleanreads.getTopBookShelves = function(bookId) {
- return new Promise(function(resolve, reject) {
- jQuery.ajax(`${window.location.origin}/book/shelves/${bookId}`)
- .done(result => {
- resolve(jQuery(result).find('.shelfStat').toArray().map(x => `${jQuery(x).find('.actionLinkLite').text().replace(/-/gi, ' ')} (${jQuery(x).find('.smallText').text().trim()})`));
- })
- .fail(err => reject(err));
- });
- };
-
- /**
- * Get list titles
- * TODO: currently only gets first page
- * @param {string} listId - The list id
- * @returns {Promise} - A promise that resolves to array of book ids or rejects with error
- */
- Cleanreads.getListBooks = function(listId) {
- return new Promise(function(resolve, reject) {
- jQuery.ajax(`${window.location.origin}/list/show/${listId}`)
- .done(result => {
- resolve(jQuery(result).find(".tableList tr td:nth-child(2) div:nth-child(1)").toArray().map(x => x.id))
- })
- .fail(err => {
- reject(err);
- });
- });
- };
-
- /**
- * Calculate the cleanliness
- */
- Cleanreads.calculateContent = function() {
- let count = 0, containing = [];
- // Insert containers for bases
- Cleanreads.crDetails.innerHTML +=
- `<h2 class="buyButtonContainer__title u-marginTopXSmall">Bookshelf Content Basis: </h2>
- <div id="bookshelfBasis">
- <i class="contentComment">
- Loading
- <a href="${window.location.origin}/group/bookshelf/${Cleanreads.CLEAN_READS_BOOKSHELF_ID}">Clean Reads bookshelf</a>
- </i>
- </div>`;
- Cleanreads.crDetails.innerHTML += `<h2 class="buyButtonContainer__title u-marginTopXSmall">Description Content Basis: </h2><div id="descriptionBasis"></div>`;
- Cleanreads.crDetails.innerHTML += `<h2 class="buyButtonContainer__title u-marginTopXSmall">Clean Basis: </h2><div id="cleanBasis"></div>`;
- Cleanreads.crDetails.innerHTML += `<h2 class="buyButtonContainer__title u-marginTopXSmall">Not Clean Basis: </h2><div id="notCleanBasis"></div>`;
-
- // Get containers
- let descriptionBasis = document.getElementById('descriptionBasis'),
- cleanBasis = document.getElementById('cleanBasis'),
- notCleanBasis = document.getElementById('notCleanBasis');
-
- // Search description
- let description = `Title: ${Cleanreads.getTitle()}\nDescription: ${Cleanreads.getDescription()}`;
- Cleanreads.searchContent(Cleanreads.POSITIVE_SEARCH_TERMS, [description], descriptionBasis, true, Cleanreads.insertComment);
- Cleanreads.searchContent(Cleanreads.NEGATIVE_SEARCH_TERMS, [description], descriptionBasis, false, Cleanreads.insertComment);
-
- // Search top shelves
- Cleanreads.searchContent(Cleanreads.POSITIVE_SEARCH_TERMS, Cleanreads.shelves, cleanBasis, true, Cleanreads.insertShelf);
- Cleanreads.searchContent(Cleanreads.NEGATIVE_SEARCH_TERMS, Cleanreads.shelves, notCleanBasis, false, Cleanreads.insertShelf);
-
- // Search reviews
- Cleanreads.searchContent(Cleanreads.POSITIVE_SEARCH_TERMS, Cleanreads.reviews, cleanBasis, true, Cleanreads.insertComment);
- Cleanreads.searchContent(Cleanreads.NEGATIVE_SEARCH_TERMS, Cleanreads.reviews, notCleanBasis, false, Cleanreads.insertComment);
-
- // Fill bases if nothing
- if (!descriptionBasis.innerHTML) {
- descriptionBasis.innerHTML = '<i class="contentComment">None</i>';
- }
- if (!cleanBasis.innerHTML) {
- cleanBasis.innerHTML = '<i class="contentComment">None</i>';
- }
- if (!notCleanBasis.innerHTML) {
- notCleanBasis.innerHTML = '<i class="contentComment">None</i>';
- }
-
- // Update Clean Reads verdict
- if (!Cleanreads.CLEAN_READS_BOOKSHELF.unloaded) {
- Cleanreads.updateVerdict();
- Cleanreads.searchBookshelf();
- }
- };
-
- /**
- * Function to search for terms in a given string
- * @param {term} term - Term object to match in content
- * @param {string} content - Content to search
- * @returns {Array} - RegExp result array
- */
- Cleanreads.matchTerm = function(term, content) {
- let regex = new RegExp(`(^|[^(${term.exclude.before.join`|`}|\\s*)])(\\W*)(${term.term})(\\W*)($|[^(${term.exclude.after.join`|`}|\\s*)])`);
- let contentMatch = content.toLowerCase().match(regex);
- return contentMatch;
- }
-
- /**
- * Search string array for given list of terms, add matches to given container, and increment positive/negative verdict
- * @param {term object array} terms - Terms to search for
- * @param {string array} contents - Contents to search
- * @param {element} container - Result container
- * @param {boolean} positive - Flag if positive or negative search term to determine result
- * @param {function} insertFunction - Function to append result to container
- */
- Cleanreads.searchContent = function(terms, contents, container, positive, insertFunction) {
- contents.forEach(content => {
- terms.forEach(term => {
- let contentMatch = Cleanreads.matchTerm(term, content);
- if (!!contentMatch) {
- positive ? Cleanreads.positives++ : Cleanreads.negatives++;
- let index = contentMatch.index + contentMatch[1].length + contentMatch[2].length;
- insertFunction(content, contentMatch[3], index, positive, container);
- }
- });
- })
- };
-
- /** Insert a matched comment into given container */
- Cleanreads.insertComment = function(content, term, index, positive, container) {
- container.innerHTML += `
- <div class="contentComment">
- ...${content.slice(index - Cleanreads.SNIPPET_HALF_LENGTH, index)}<b class="content${positive ? '' : 'Not'}Clean">${
- content.substr(index, term.length)
- }</b>${content.slice(index + term.length, index + Cleanreads.SNIPPET_HALF_LENGTH)}...
- </div>
- `;
- };
-
- /** Insert a matched shelf into given container */
- Cleanreads.insertShelf = function(content, term, index, positive, container) {
- container.innerHTML += `
- <div class="contentComment">
- Shelved as: ${content.slice(0, index)}<b class="content${positive ? '' : 'Not'}Clean">${
- content.substr(index, term.length)
- }</b>${content.slice(index + term.length)}
- </div>
- `;
- };
-
- /**
- * Search the loaded bookshelf book ids for current book and update verdict
- */
- Cleanreads.searchBookshelf = function() {
- let bookId = window.location.pathname.match(/show\/(\d*)/)[1];
- let bookshelfBasis = document.getElementById('bookshelfBasis');
- if (bookId && Cleanreads.CLEAN_READS_BOOKSHELF.books.indexOf(bookId) != -1) {
- bookshelfBasis.innerHTML =
- `<div class="contentClean">
- Found in
- <a href="${window.location.origin}/group/bookshelf/${Cleanreads.CLEAN_READS_BOOKSHELF_ID}">Clean Reads bookshelf</a>
- </div>`;
- Cleanreads.positives++;
- Cleanreads.updateVerdict(true);
- } else {
- bookshelfBasis.innerHTML =
- `<div class="contentNotClean">
- Not found in
- <a href="${window.location.origin}/group/bookshelf/${Cleanreads.CLEAN_READS_BOOKSHELF_ID}">Clean Reads bookshelf</a>
- </div>`;
- Cleanreads.updateVerdict();
- }
- };
-
- /**
- * Update the verdict shown in UI on the book
- * @param {boolean} overrideClean - If true, always set clean, but preserve positive/negative count
- */
- Cleanreads.updateVerdict = function(overrideClean) {
- let verdict = document.getElementById('crVerdict');
- if (overrideClean || (Cleanreads.positives && Cleanreads.positives > Cleanreads.negatives)) {
- verdict.innerText = `${Cleanreads.negatives ? 'Probably' : 'Most likely'} clean`;
- verdict.className += 'contentClean';
- } else if (Cleanreads.negatives && Cleanreads.negatives > Cleanreads.positives) {
- verdict.innerText = `${Cleanreads.positives ? 'Probably' : 'Most likely'} not clean`;
- verdict.className += 'contentNotClean';
- } else {
- verdict.innerText = Cleanreads.positives && Cleanreads.negatives ? 'Could be clean or not clean' : 'Unknown';
- verdict.className += 'contentUnknown';
- }
- document.getElementById('crPositives').innerText = Cleanreads.positives;
- document.getElementById('crNegatives').innerText = Cleanreads.negatives;
- };
-
- /**
- * Expand the details section of Cleanreads verdict
- */
- Cleanreads.expandDetails = function() {
- let collapsedText = '(Details)',
- expandedText = '(Hide)';
- if (this.innerText == collapsedText) {
- Cleanreads.crDetails.style.display = 'block';
- this.innerText = expandedText;
- } else if (this.innerText == expandedText) {
- Cleanreads.crDetails.style.display = 'none';
- this.innerText = collapsedText;
- }
- };
-
- /**
- * Show the settings modal for Cleanreads
- */
- Cleanreads.showSettings = function() {
- document.getElementById("crSettingsDialog").style.display = 'block';
- return false;
- };
-
- /**
- * Hide the settings modal for Cleanreads
- */
- Cleanreads.hideSettings = function() {
- document.getElementById("crSettingsDialog").style.display = 'none';
- return false;
- };
-
- // Loading. If on a book load the verdict, else if on a user page load settings
- if (window.location.href.match("/book/")) {
- Cleanreads.setupRating();
- } else if (window.location.href.match("/user/")) {
- Cleanreads.setupSettings()
- }
- })(window.Cleanreads = window.Cleanreads || {});