Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add first implementation of external modifications #10

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AutomaticSettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@
// import and expose module parts
export { default as Trigger } from "./internal/Trigger.js";
export * from "./internal/LoadAndSave.js";
export * from "./internal/ExternalModification.js";
export { setDefaultOptionProvider } from "./internal/OptionsModel.js";
41 changes: 41 additions & 0 deletions internal/DomModel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* Get data from the options as specified in the HTML/DOM.
*
* Thus, this is a model that uses the DOM as it's data source.
*
* @public
* @module AutomaticSettings
*/

/**
* Get the name of the option from an element.
*
* @package
* @param {string} option
* @returns {HTMLElement}
*/
export function getElementFromOptionId(option) {
return document.querySelector(`[name=${option}]`);
}

/**
* Get the option group from an HTMLElement.
*
* @package
* @param {HTMLElement} elOption
* @returns {string}
*/
export function getOptionGroup(elOption) {
return elOption.dataset.optiongroup || null;
}

/**
* Get all the HTML elements of an option group..
*
* @package
* @param {string} optionGroup
* @returns {string}
*/
export function getHtmlElementsOfOptionsGroup(optionGroup) {
return document.querySelectorAll(`[data-optiongroup=${optionGroup}]`);
}
39 changes: 39 additions & 0 deletions internal/ExternalModification.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Any APIs to allow external modiifications of the internal state of this module.
*
* @public
* @module AutomaticSettings
*/

import * as HtmlMod from "./HtmlModification.js";
import * as DomModel from "./DomModel.js";
import * as LoadAndSave from "./LoadAndSave.js";

/**
* Set an option from the outside.
*
* This sets the visible option and saves it, so the state is consistent.
* It also always triggers any registered triggers.
*
* @public
* @param {string} option option to change
* @param {Object} optionValue the value to set
* @param {Object} [optionGroup] the option group of the setting
* @returns {Promise}
*/
export async function setOption(option, optionValue, optionGroup) {
const elOption = DomModel.getElementFromOptionId(option);
optionGroup = optionGroup || DomModel.getOptionGroup(elOption);

if (optionGroup) {
await DomModel.getHtmlElementsOfOptionsGroup(optionGroup).map((elCurrentOption) => {
const currOption = HtmlMod.getOptionIdFromElement(elCurrentOption);
LoadAndSave.applyOption(currOption, optionGroup, elCurrentOption, { option: optionValue });
});
} else {
// apply HTML
await LoadAndSave.applyOption(option, optionGroup, elOption, { option: optionValue });
// now trigger saving of modified values
LoadAndSave.saveOption({target: elOption});
}
}
5 changes: 3 additions & 2 deletions internal/HtmlModification.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

// common modules
import * as OptionsModel from "./OptionsModel.js";
import * as DomModel from "./DomModel.js";

/**
* Applies option to element.
Expand All @@ -16,7 +17,7 @@ import * as OptionsModel from "./OptionsModel.js";
*
* @protected
* @function
* @param {string} option string ob object ID
* @param {string} option string ob object ID // TODO. UNUSED OPTION
* @param {Object} optionValue the value to set
* @param {HTMLElement} elOption where to apply feature
* @returns {void}
Expand Down Expand Up @@ -153,7 +154,7 @@ export function getIdAndOptionsFromElement(elOption, useDatagroup = true) {
optionValue = OptionsModel.getOptionGroup(optionGroup);

// update data in group with new values from settings HTML page
document.querySelectorAll(`[data-optiongroup=${optionGroup}]`).forEach((elCurrentOption) => {
DomModel.getHtmlElementsOfOptionsGroup(optionGroup).forEach((elCurrentOption) => {
const [currentOption, currentOptionValue] = getIdAndOptionFromElement(elCurrentOption);
optionValue[currentOption] = currentOptionValue;
});
Expand Down
37 changes: 11 additions & 26 deletions internal/LoadAndSave.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ import debounce from "../../lodash/debounce.js";
import * as CommonMessages from "../../MessageHandler/CommonMessages.js";

// import internal modules
import * as DomModel from "./DomModel.js";
import * as Trigger from "./Trigger.js";
import * as HtmlMod from "./HtmlModification.js";
import * as OptionsModel from "./OptionsModel.js";

const DEFAULT_DEBOUNCE_TIME = 250; // 250 ms
const DEFAULT_DEBOUNCE_TIME = 250; // ms

// vars
let managedInfoIsShown = false;
Expand All @@ -28,12 +29,12 @@ let lastOptionsBeforeReset;
/**
* Saves the specific settings that triggered this.
*
* @private
* @package
* @function
* @param {Object} event
* @returns {void}
*/
async function saveOption(event) {
export async function saveOption(event) {
/** @var {HTMLElement} */
let elOption = event.target;

Expand Down Expand Up @@ -94,31 +95,18 @@ function showManagedInfo() {
managedInfoIsShown = true;
}

/**
* Get the name of the option from an element..
*
* @private
* @function
* @param {string} option
* @returns {HTMLElement}
*/
function getElementFromOptionId(option) {
return document.querySelector(`[name=${option}]`);
}

/**
* Applies an option to the HTML element. This is the final step, before it goes
* into the {@link HtmlMod} module.
*
* @private
* @function
* @package
* @param {string} option string ob object ID
* @param {string|null} optionGroup optiom group, if it is used
* @param {HTMLElement} elOption where to apply feature
* @param {Object|undefined} optionValues object values
* @returns {Promise}
*/
async function applyOption(option, optionGroup, elOption, optionValues) {
export async function applyOption(option, optionGroup, elOption, optionValues) {
let optionValue = OptionsModel.getOptionValueFromRequestResults(option, optionGroup, optionValues);

const overwriteResult = await Trigger.runOverrideLoad(option, optionValue, elOption, optionValues);
Expand Down Expand Up @@ -152,7 +140,7 @@ async function applyOption(option, optionGroup, elOption, optionValues) {
* be autodetected otherwise
* @returns {Promise}
*/
function setManagedOption(option, optionGroup, elOption = getElementFromOptionId(option)) {
function setManagedOption(option, optionGroup, elOption = DomModel.getElementFromOptionId(option)) {
if (optionGroup === undefined && elOption.hasAttribute("data-optiongroup")) {
optionGroup = elOption.getAttribute("data-optiongroup");
}
Expand Down Expand Up @@ -194,7 +182,7 @@ function setManagedOption(option, optionGroup, elOption = getElementFromOptionId
* be autodetected otherwise
* @returns {Promise}
*/
function setSyncedOption(option, optionGroup, elOption = getElementFromOptionId(option)) {
function setSyncedOption(option, optionGroup, elOption = DomModel.getElementFromOptionId(option)) {
if (optionGroup === undefined && elOption.hasAttribute("data-optiongroup")) {
optionGroup = elOption.getAttribute("data-optiongroup");
}
Expand Down Expand Up @@ -227,15 +215,12 @@ function setSyncedOption(option, optionGroup, elOption = getElementFromOptionId(
export function loadOption(elOption, option) {
option = option ? option : HtmlMod.getOptionIdFromElement(elOption);

let optionGroup = null;
if ("optiongroup" in elOption.dataset) {
optionGroup = elOption.dataset.optiongroup;
}
const optionGroup = DomModel.getOptionGroup(elOption);

// try to get option ID from input element if needed
if (!option && elOption.dataset.type === "radiogroup") {
option = elOption.querySelector("input[type=radio]").getAttribute("name");
}
} // TODO: refactor this if to include in getOptionIdFromElement

return setManagedOption(option, optionGroup, elOption).catch((error) => {
/* only log warning as that is expected when no manifest file is found */
Expand All @@ -256,7 +241,7 @@ export function loadOption(elOption, option) {
* be autodetected otherwise
* @returns {Promise}
*/
export function loadOptionByName(option, elOption = getElementFromOptionId(option)) {
export function loadOptionByName(option, elOption = DomModel.getElementFromOptionId(option)) {
return loadOption(elOption, option);
}

Expand Down