UNPKG

yoastseo

Version:

Yoast client-side content analysis

348 lines (323 loc) 10.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _lodash = require("lodash"); var _scoreToRating = _interopRequireDefault(require("../interpreters/scoreToRating.js")); var _presenter = _interopRequireDefault(require("../../config/presenter.js")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } /** * Represents the AssessorPresenter. */ class AssessorPresenter { /** * Constructs the AssessorPresenter. * * @param {Object} args A list of arguments to use in the presenter. * @param {object} args.targets The HTML elements to render the output to. * @param {string} args.targets.output The HTML element to render the individual ratings out to. * @param {string} args.targets.overall The HTML element to render the overall rating out to. * @param {string} args.keyword The keyword to use for checking, when calculating the overall rating. * @param {SEOAssessor} args.assessor The Assessor object to retrieve assessment results from. * * @constructor */ constructor(args) { this.keyword = args.keyword; this.assessor = args.assessor; this.output = args.targets.output; this.overall = args.targets.overall || "overallScore"; this.presenterConfig = (0, _presenter.default)(); this._disableMarkerButtons = false; this._activeMarker = false; } /** * Sets the keyword. * * @param {string} keyword The keyword to use. * @returns {void} */ setKeyword(keyword) { this.keyword = keyword; } /** * Checks whether a specific property exists in the presenter configuration. * * @param {string} property The property name to search for. * @returns {boolean} Whether or not the property exists. */ configHasProperty(property) { return this.presenterConfig.hasOwnProperty(property); } /** * Gets a fully formatted indicator object that can be used. * * @param {string} rating The rating to use. * @returns {Object} An object containing the class, the screen reader text, and the full text. */ getIndicator(rating) { return { className: this.getIndicatorColorClass(rating), screenReaderText: this.getIndicatorScreenReaderText(rating), fullText: this.getIndicatorFullText(rating), screenReaderReadabilityText: this.getIndicatorScreenReaderReadabilityText(rating) }; } /** * Gets the indicator color class from the presenter configuration, if it exists. * * @param {string} rating The rating to check against the config. * @returns {string} String containing the CSS class to be used. */ getIndicatorColorClass(rating) { if (!this.configHasProperty(rating)) { return ""; } return this.presenterConfig[rating].className; } /** * Gets the indicator screen reader text from the presenter configuration, if it exists. * * @param {string} rating The rating to check against the config. * @returns {string} Translated string containing the screen reader text to be used. */ getIndicatorScreenReaderText(rating) { if (!this.configHasProperty(rating)) { return ""; } return this.presenterConfig[rating].screenReaderText; } /** * Gets the indicator screen reader readability text from the presenter configuration, if it exists. * * @param {string} rating The rating to check against the config. * @returns {string} Translated string containing the screen reader readability text to be used. */ getIndicatorScreenReaderReadabilityText(rating) { if (!this.configHasProperty(rating)) { return ""; } return this.presenterConfig[rating].screenReaderReadabilityText; } /** * Gets the indicator full text from the presenter configuration, if it exists. * * @param {string} rating The rating to check against the config. * @returns {string} Translated string containing the full text to be used. */ getIndicatorFullText(rating) { if (!this.configHasProperty(rating)) { return ""; } return this.presenterConfig[rating].fullText; } /** * Adds a rating based on the numeric score. * * @param {Object} result Object based on the Assessment result. Requires a score property to work. * @returns {Object} The Assessment result object with the rating added. */ resultToRating(result) { if (!(0, _lodash.isObject)(result)) { return ""; } result.rating = (0, _scoreToRating.default)(result.score); return result; } /** * Takes the individual assessment results, sorts and rates them. * * @returns {Object} Object containing all the individual ratings. */ getIndividualRatings() { const ratings = {}; const validResults = this.sort(this.assessor.getValidResults()); const mappedResults = validResults.map(this.resultToRating); (0, _lodash.forEach)(mappedResults, function (item, key) { ratings[key] = this.addRating(item); }.bind(this)); return ratings; } /** * Excludes items from the results that are present in the `exclude` array. * * @param {Array} results Array containing the items to filter through. * @param {Array} exclude Array of results to exclude. * @returns {Array} Array containing items that remain after exclusion. */ excludeFromResults(results, exclude) { return (0, _lodash.difference)(results, exclude); } /** * Sorts results based on their score property and always places items considered to be non-sortable, at the top. * * @param {Array} results Array containing the results that need to be sorted. * @returns {Array} Array containing the sorted results. */ sort(results) { const nonSortables = this.getUndefinedScores(results); const sortables = this.excludeFromResults(results, nonSortables); sortables.sort(function (a, b) { return a.score - b.score; }); return nonSortables.concat(sortables); } /** * Returns a subset of results that have an undefined score or a score set to zero. * * @param {Array} results The results to filter through. * @returns {Array} A subset of results containing items with an undefined score or where the score is zero. */ getUndefinedScores(results) { return results.filter(function (result) { return (0, _lodash.isUndefined)(result.score) || result.score === 0; }); } /** * Creates a rating object based on the item that is being passed. * * @param {Object} item The item to check and create a rating object from. * @returns {Object} Object containing a parsed item, including a colored indicator. */ addRating(item) { const indicator = this.getIndicator(item.rating); indicator.text = item.text; indicator.identifier = item.getIdentifier(); if (item.hasMarker()) { indicator.marker = item.getMarker(); } return indicator; } /** * Calculates the overall rating score based on the overall score. * * @param {Number} overallScore The overall score to use in the calculation. * @returns {Object} The rating based on the score. */ getOverallRating(overallScore) { let rating = 0; if (this.keyword === "") { return this.resultToRating({ score: rating }); } if ((0, _lodash.isNumber)(overallScore)) { rating = overallScore / 10; } return this.resultToRating({ score: rating }); } /** * Marks with a given marker. This will set the active marker to the correct value. * * @param {string} identifier The identifier for the assessment/marker. * @param {Function} marker The marker function. * @returns {void} */ markAssessment(identifier, marker) { if (this._activeMarker === identifier) { this.removeAllMarks(); this._activeMarker = false; } else { marker(); this._activeMarker = identifier; } this.render(); } /** * Disables the currently active marker in the UI. * * @returns {void} */ disableMarker() { this._activeMarker = false; this.render(); } /** * Disables the marker buttons. * * @returns {void} */ disableMarkerButtons() { this._disableMarkerButtons = true; this.render(); } /** * Enables the marker buttons. * * @returns {void} */ enableMarkerButtons() { this._disableMarkerButtons = false; this.render(); } /** * Adds an event listener for the marker button * * @param {string} identifier The identifier for the assessment the marker belongs to. * @param {Function} marker The marker function that can mark the assessment in the text. * @returns {void} */ addMarkerEventHandler(identifier, marker) { const container = document.getElementById(this.output); const markButton = container.getElementsByClassName("js-assessment-results__mark-" + identifier)[0]; markButton.addEventListener("click", this.markAssessment.bind(this, identifier, marker)); } /** * Renders out both the individual and the overall ratings. * * @returns {void} */ render() { this.renderIndividualRatings(); this.renderOverallRating(); } /** * Adds event handlers to the mark buttons. * * @param {Object} scores The list of rendered scores. * * @returns {void} */ bindMarkButtons(scores) { // Make sure the button works for every score with a marker. (0, _lodash.forEach)(scores, function (score) { if (score.hasOwnProperty("marker")) { this.addMarkerEventHandler(score.identifier, score.marker); } }.bind(this)); } /** * Removes all marks currently on the text. * * @returns {void} */ removeAllMarks() { const marker = this.assessor.getSpecificMarker(); marker(this.assessor.getPaper(), []); } /** * Renders out the individual ratings. * Here, this method is set to noop. In `post-scraper.js` and `term-scraper.js` where this method is called, it is overridden with noop as well. * * @returns {void} */ renderIndividualRatings() {} /** * Renders out the overall rating. * * @returns {void} */ renderOverallRating() { const overallRating = this.getOverallRating(this.assessor.calculateOverallScore()); const overallRatingElement = document.getElementById(this.overall); if (!overallRatingElement) { return; } overallRatingElement.className = "overallScore " + this.getIndicatorColorClass(overallRating.rating); } } var _default = exports.default = AssessorPresenter; //# sourceMappingURL=AssessorPresenter.js.map