diff options
| -rw-r--r-- | ext/bg/js/settings/main.js | 20 | ||||
| -rw-r--r-- | ext/bg/js/settings/profiles.js | 422 | 
2 files changed, 233 insertions, 209 deletions
| diff --git a/ext/bg/js/settings/main.js b/ext/bg/js/settings/main.js index 0cb1734e..64611ad5 100644 --- a/ext/bg/js/settings/main.js +++ b/ext/bg/js/settings/main.js @@ -16,6 +16,7 @@   */  /* global + * ProfileController   * SettingsBackup   * SettingsController   * ankiInitialize @@ -25,15 +26,28 @@   * appearanceInitialize   * audioSettingsInitialize   * dictSettingsInitialize - * getOptionsContext   * onAnkiOptionsChanged   * onDictionaryOptionsChanged - * profileOptionsSetup   * storageInfoInitialize   * utilBackend   * utilBackgroundIsolate   */ +let profileIndex = 0; + +function getOptionsContext() { +    return {index: getProfileIndex()}; +} + +function getProfileIndex() { +    return profileIndex; +} + +function setProfileIndex(value) { +    profileIndex = value; +} + +  function getOptionsMutable(optionsContext) {      return utilBackend().getOptions(          utilBackgroundIsolate(optionsContext) @@ -302,7 +316,7 @@ async function onReady() {      formSetupEventListeners();      appearanceInitialize();      await audioSettingsInitialize(); -    await profileOptionsSetup(); +    await (new ProfileController()).prepare();      await dictSettingsInitialize();      ankiInitialize();      ankiTemplatesInitialize(); diff --git a/ext/bg/js/settings/profiles.js b/ext/bg/js/settings/profiles.js index 59f7fbb1..e2c558e9 100644 --- a/ext/bg/js/settings/profiles.js +++ b/ext/bg/js/settings/profiles.js @@ -20,281 +20,291 @@   * api   * conditionsClearCaches   * getOptionsFullMutable + * getProfileIndex   * onOptionsUpdated   * profileConditionsDescriptor   * profileConditionsDescriptorPromise + * setProfileIndex   * settingsSaveOptions   * utilBackgroundIsolate   */ -let currentProfileIndex = 0; -let profileConditionsContainer = null; - -function getOptionsContext() { -    return { -        index: currentProfileIndex -    }; -} +class ProfileController { +    constructor() { +        this._conditionsContainer = null; +    } +    async prepare() { +        const optionsFull = await getOptionsFullMutable(); +        setProfileIndex(optionsFull.profileCurrent); -async function profileOptionsSetup() { -    const optionsFull = await getOptionsFullMutable(); -    currentProfileIndex = optionsFull.profileCurrent; +        this._setupEventListeners(); +        await this._updateTarget(optionsFull); +    } -    profileOptionsSetupEventListeners(); -    await profileOptionsUpdateTarget(optionsFull); -} +    // Private + +    _setupEventListeners() { +        $('#profile-target').change(this._onTargetProfileChanged.bind(this)); +        $('#profile-name').change(this._onNameChanged.bind(this)); +        $('#profile-add').click(this._onAdd.bind(this)); +        $('#profile-remove').click(this._onRemove.bind(this)); +        $('#profile-remove-confirm').click(this._onRemoveConfirm.bind(this)); +        $('#profile-copy').click(this._onCopy.bind(this)); +        $('#profile-copy-confirm').click(this._onCopyConfirm.bind(this)); +        $('#profile-move-up').click(() => this._onMove(-1)); +        $('#profile-move-down').click(() => this._onMove(1)); +        $('.profile-form').find('input, select, textarea').not('.profile-form-manual').change(this._onInputChanged.bind(this)); +    } -function profileOptionsSetupEventListeners() { -    $('#profile-target').change(onTargetProfileChanged); -    $('#profile-name').change(onProfileNameChanged); -    $('#profile-add').click(onProfileAdd); -    $('#profile-remove').click(onProfileRemove); -    $('#profile-remove-confirm').click(onProfileRemoveConfirm); -    $('#profile-copy').click(onProfileCopy); -    $('#profile-copy-confirm').click(onProfileCopyConfirm); -    $('#profile-move-up').click(() => onProfileMove(-1)); -    $('#profile-move-down').click(() => onProfileMove(1)); -    $('.profile-form').find('input, select, textarea').not('.profile-form-manual').change(onProfileOptionsChanged); -} +    _tryGetIntegerValue(selector, min, max) { +        const value = parseInt($(selector).val(), 10); +        return ( +            typeof value === 'number' && +            Number.isFinite(value) && +            Math.floor(value) === value && +            value >= min && +            value < max +        ) ? value : null; +    } -function tryGetIntegerValue(selector, min, max) { -    const value = parseInt($(selector).val(), 10); -    return ( -        typeof value === 'number' && -        Number.isFinite(value) && -        Math.floor(value) === value && -        value >= min && -        value < max -    ) ? value : null; -} +    async _formRead(optionsFull) { +        const currentProfileIndex = getProfileIndex(); +        const profile = optionsFull.profiles[currentProfileIndex]; -async function profileFormRead(optionsFull) { -    const profile = optionsFull.profiles[currentProfileIndex]; +        // Current profile +        const index = this._tryGetIntegerValue('#profile-active', 0, optionsFull.profiles.length); +        if (index !== null) { +            optionsFull.profileCurrent = index; +        } -    // Current profile -    const index = tryGetIntegerValue('#profile-active', 0, optionsFull.profiles.length); -    if (index !== null) { -        optionsFull.profileCurrent = index; +        // Profile name +        profile.name = $('#profile-name').val();      } -    // Profile name -    profile.name = $('#profile-name').val(); -} +    async _formWrite(optionsFull) { +        const currentProfileIndex = getProfileIndex(); +        const profile = optionsFull.profiles[currentProfileIndex]; -async function profileFormWrite(optionsFull) { -    const profile = optionsFull.profiles[currentProfileIndex]; +        this._populateSelect($('#profile-active'), optionsFull.profiles, optionsFull.profileCurrent, null); +        this._populateSelect($('#profile-target'), optionsFull.profiles, currentProfileIndex, null); +        $('#profile-remove').prop('disabled', optionsFull.profiles.length <= 1); +        $('#profile-copy').prop('disabled', optionsFull.profiles.length <= 1); +        $('#profile-move-up').prop('disabled', currentProfileIndex <= 0); +        $('#profile-move-down').prop('disabled', currentProfileIndex >= optionsFull.profiles.length - 1); -    profileOptionsPopulateSelect($('#profile-active'), optionsFull.profiles, optionsFull.profileCurrent, null); -    profileOptionsPopulateSelect($('#profile-target'), optionsFull.profiles, currentProfileIndex, null); -    $('#profile-remove').prop('disabled', optionsFull.profiles.length <= 1); -    $('#profile-copy').prop('disabled', optionsFull.profiles.length <= 1); -    $('#profile-move-up').prop('disabled', currentProfileIndex <= 0); -    $('#profile-move-down').prop('disabled', currentProfileIndex >= optionsFull.profiles.length - 1); +        $('#profile-name').val(profile.name); -    $('#profile-name').val(profile.name); +        if (this._conditionsContainer !== null) { +            this._conditionsContainer.cleanup(); +        } -    if (profileConditionsContainer !== null) { -        profileConditionsContainer.cleanup(); +        await profileConditionsDescriptorPromise; +        this._conditionsContainer = new ConditionsUI.Container( +            profileConditionsDescriptor, +            'popupLevel', +            profile.conditionGroups, +            $('#profile-condition-groups'), +            $('#profile-add-condition-group') +        ); +        this._conditionsContainer.save = () => { +            settingsSaveOptions(); +            conditionsClearCaches(profileConditionsDescriptor); +        }; +        this._conditionsContainer.isolate = utilBackgroundIsolate;      } -    await profileConditionsDescriptorPromise; -    profileConditionsContainer = new ConditionsUI.Container( -        profileConditionsDescriptor, -        'popupLevel', -        profile.conditionGroups, -        $('#profile-condition-groups'), -        $('#profile-add-condition-group') -    ); -    profileConditionsContainer.save = () => { -        settingsSaveOptions(); -        conditionsClearCaches(profileConditionsDescriptor); -    }; -    profileConditionsContainer.isolate = utilBackgroundIsolate; -} - -function profileOptionsPopulateSelect(select, profiles, currentValue, ignoreIndices) { -    select.empty(); +    _populateSelect(select, profiles, currentValue, ignoreIndices) { +        select.empty(); -    for (let i = 0; i < profiles.length; ++i) { -        if (ignoreIndices !== null && ignoreIndices.indexOf(i) >= 0) { -            continue; +        for (let i = 0; i < profiles.length; ++i) { +            if (ignoreIndices !== null && ignoreIndices.indexOf(i) >= 0) { +                continue; +            } +            const profile = profiles[i]; +            select.append($(`<option value="${i}">${profile.name}</option>`));          } -        const profile = profiles[i]; -        select.append($(`<option value="${i}">${profile.name}</option>`)); -    } -    select.val(`${currentValue}`); -} +        select.val(`${currentValue}`); +    } -async function profileOptionsUpdateTarget(optionsFull) { -    await profileFormWrite(optionsFull); -    await onOptionsUpdated({source: null}); -} +    async _updateTarget(optionsFull) { +        await this._formWrite(optionsFull); +        await onOptionsUpdated({source: null}); +    } -function profileOptionsCreateCopyName(name, profiles, maxUniqueAttempts) { -    let space, index, prefix, suffix; -    const match = /^([\w\W]*\(Copy)((\s+)(\d+))?(\)\s*)$/.exec(name); -    if (match === null) { -        prefix = `${name} (Copy`; -        space = ''; -        index = ''; -        suffix = ')'; -    } else { -        prefix = match[1]; -        suffix = match[5]; -        if (typeof match[2] === 'string') { -            space = match[3]; -            index = parseInt(match[4], 10) + 1; +    _createCopyName(name, profiles, maxUniqueAttempts) { +        let space, index, prefix, suffix; +        const match = /^([\w\W]*\(Copy)((\s+)(\d+))?(\)\s*)$/.exec(name); +        if (match === null) { +            prefix = `${name} (Copy`; +            space = ''; +            index = ''; +            suffix = ')';          } else { -            space = ' '; -            index = 2; +            prefix = match[1]; +            suffix = match[5]; +            if (typeof match[2] === 'string') { +                space = match[3]; +                index = parseInt(match[4], 10) + 1; +            } else { +                space = ' '; +                index = 2; +            }          } -    } -    let i = 0; -    while (true) { -        const newName = `${prefix}${space}${index}${suffix}`; -        if (i++ >= maxUniqueAttempts || profiles.findIndex((profile) => profile.name === newName) < 0) { -            return newName; -        } -        if (typeof index !== 'number') { -            index = 2; -            space = ' '; -        } else { -            ++index; +        let i = 0; +        while (true) { +            const newName = `${prefix}${space}${index}${suffix}`; +            if (i++ >= maxUniqueAttempts || profiles.findIndex((profile) => profile.name === newName) < 0) { +                return newName; +            } +            if (typeof index !== 'number') { +                index = 2; +                space = ' '; +            } else { +                ++index; +            }          }      } -} -async function onProfileOptionsChanged(e) { -    if (!e.originalEvent && !e.isTrigger) { -        return; +    async _onInputChanged(e) { +        if (!e.originalEvent && !e.isTrigger) { +            return; +        } + +        const optionsFull = await getOptionsFullMutable(); +        await this._formRead(optionsFull); +        await settingsSaveOptions();      } -    const optionsFull = await getOptionsFullMutable(); -    await profileFormRead(optionsFull); -    await settingsSaveOptions(); -} +    async _onTargetProfileChanged() { +        const optionsFull = await getOptionsFullMutable(); +        const currentProfileIndex = getProfileIndex(); +        const index = this._tryGetIntegerValue('#profile-target', 0, optionsFull.profiles.length); +        if (index === null || currentProfileIndex === index) { +            return; +        } -async function onTargetProfileChanged() { -    const optionsFull = await getOptionsFullMutable(); -    const index = tryGetIntegerValue('#profile-target', 0, optionsFull.profiles.length); -    if (index === null || currentProfileIndex === index) { -        return; +        setProfileIndex(index); + +        await this._updateTarget(optionsFull); + +        yomichan.trigger('modifyingProfileChange');      } -    currentProfileIndex = index; +    async _onAdd() { +        const optionsFull = await getOptionsFullMutable(); +        const currentProfileIndex = getProfileIndex(); +        const profile = utilBackgroundIsolate(optionsFull.profiles[currentProfileIndex]); +        profile.name = this._createCopyName(profile.name, optionsFull.profiles, 100); +        optionsFull.profiles.push(profile); -    await profileOptionsUpdateTarget(optionsFull); +        setProfileIndex(optionsFull.profiles.length - 1); -    yomichan.trigger('modifyingProfileChange'); -} +        await this._updateTarget(optionsFull); +        await settingsSaveOptions(); -async function onProfileAdd() { -    const optionsFull = await getOptionsFullMutable(); -    const profile = utilBackgroundIsolate(optionsFull.profiles[currentProfileIndex]); -    profile.name = profileOptionsCreateCopyName(profile.name, optionsFull.profiles, 100); -    optionsFull.profiles.push(profile); +        yomichan.trigger('modifyingProfileChange'); +    } -    currentProfileIndex = optionsFull.profiles.length - 1; +    async _onRemove(e) { +        if (e.shiftKey) { +            return await this._onRemoveConfirm(); +        } -    await profileOptionsUpdateTarget(optionsFull); -    await settingsSaveOptions(); +        const optionsFull = await api.optionsGetFull(); +        if (optionsFull.profiles.length <= 1) { +            return; +        } -    yomichan.trigger('modifyingProfileChange'); -} +        const currentProfileIndex = getProfileIndex(); +        const profile = optionsFull.profiles[currentProfileIndex]; -async function onProfileRemove(e) { -    if (e.shiftKey) { -        return await onProfileRemoveConfirm(); +        $('#profile-remove-modal-profile-name').text(profile.name); +        $('#profile-remove-modal').modal('show');      } -    const optionsFull = await api.optionsGetFull(); -    if (optionsFull.profiles.length <= 1) { -        return; -    } +    async _onRemoveConfirm() { +        $('#profile-remove-modal').modal('hide'); -    const profile = optionsFull.profiles[currentProfileIndex]; +        const optionsFull = await getOptionsFullMutable(); +        if (optionsFull.profiles.length <= 1) { +            return; +        } -    $('#profile-remove-modal-profile-name').text(profile.name); -    $('#profile-remove-modal').modal('show'); -} +        const currentProfileIndex = getProfileIndex(); +        optionsFull.profiles.splice(currentProfileIndex, 1); -async function onProfileRemoveConfirm() { -    $('#profile-remove-modal').modal('hide'); +        if (currentProfileIndex >= optionsFull.profiles.length) { +            setProfileIndex(optionsFull.profiles.length - 1); +        } -    const optionsFull = await getOptionsFullMutable(); -    if (optionsFull.profiles.length <= 1) { -        return; -    } +        if (optionsFull.profileCurrent >= optionsFull.profiles.length) { +            optionsFull.profileCurrent = optionsFull.profiles.length - 1; +        } -    optionsFull.profiles.splice(currentProfileIndex, 1); +        await this._updateTarget(optionsFull); +        await settingsSaveOptions(); -    if (currentProfileIndex >= optionsFull.profiles.length) { -        --currentProfileIndex; +        yomichan.trigger('modifyingProfileChange');      } -    if (optionsFull.profileCurrent >= optionsFull.profiles.length) { -        optionsFull.profileCurrent = optionsFull.profiles.length - 1; +    _onNameChanged() { +        const currentProfileIndex = getProfileIndex(); +        $('#profile-active, #profile-target').find(`[value="${currentProfileIndex}"]`).text(this.value);      } -    await profileOptionsUpdateTarget(optionsFull); -    await settingsSaveOptions(); +    async _onMove(offset) { +        const optionsFull = await getOptionsFullMutable(); +        const currentProfileIndex = getProfileIndex(); +        const index = currentProfileIndex + offset; +        if (index < 0 || index >= optionsFull.profiles.length) { +            return; +        } -    yomichan.trigger('modifyingProfileChange'); -} +        const profile = optionsFull.profiles[currentProfileIndex]; +        optionsFull.profiles.splice(currentProfileIndex, 1); +        optionsFull.profiles.splice(index, 0, profile); -function onProfileNameChanged() { -    $('#profile-active, #profile-target').find(`[value="${currentProfileIndex}"]`).text(this.value); -} +        if (optionsFull.profileCurrent === currentProfileIndex) { +            optionsFull.profileCurrent = index; +        } -async function onProfileMove(offset) { -    const optionsFull = await getOptionsFullMutable(); -    const index = currentProfileIndex + offset; -    if (index < 0 || index >= optionsFull.profiles.length) { -        return; -    } +        setProfileIndex(index); -    const profile = optionsFull.profiles[currentProfileIndex]; -    optionsFull.profiles.splice(currentProfileIndex, 1); -    optionsFull.profiles.splice(index, 0, profile); +        await this._updateTarget(optionsFull); +        await settingsSaveOptions(); -    if (optionsFull.profileCurrent === currentProfileIndex) { -        optionsFull.profileCurrent = index; +        yomichan.trigger('modifyingProfileChange');      } -    currentProfileIndex = index; - -    await profileOptionsUpdateTarget(optionsFull); -    await settingsSaveOptions(); - -    yomichan.trigger('modifyingProfileChange'); -} +    async _onCopy() { +        const optionsFull = await api.optionsGetFull(); +        if (optionsFull.profiles.length <= 1) { +            return; +        } -async function onProfileCopy() { -    const optionsFull = await api.optionsGetFull(); -    if (optionsFull.profiles.length <= 1) { -        return; +        const currentProfileIndex = getProfileIndex(); +        this._populateSelect($('#profile-copy-source'), optionsFull.profiles, currentProfileIndex === 0 ? 1 : 0, [currentProfileIndex]); +        $('#profile-copy-modal').modal('show');      } -    profileOptionsPopulateSelect($('#profile-copy-source'), optionsFull.profiles, currentProfileIndex === 0 ? 1 : 0, [currentProfileIndex]); -    $('#profile-copy-modal').modal('show'); -} - -async function onProfileCopyConfirm() { -    $('#profile-copy-modal').modal('hide'); +    async _onCopyConfirm() { +        $('#profile-copy-modal').modal('hide'); -    const optionsFull = await getOptionsFullMutable(); -    const index = tryGetIntegerValue('#profile-copy-source', 0, optionsFull.profiles.length); -    if (index === null || index === currentProfileIndex) { -        return; -    } +        const optionsFull = await getOptionsFullMutable(); +        const index = this._tryGetIntegerValue('#profile-copy-source', 0, optionsFull.profiles.length); +        const currentProfileIndex = getProfileIndex(); +        if (index === null || index === currentProfileIndex) { +            return; +        } -    const profileOptions = utilBackgroundIsolate(optionsFull.profiles[index].options); -    optionsFull.profiles[currentProfileIndex].options = profileOptions; +        const profileOptions = utilBackgroundIsolate(optionsFull.profiles[index].options); +        optionsFull.profiles[currentProfileIndex].options = profileOptions; -    await profileOptionsUpdateTarget(optionsFull); -    await settingsSaveOptions(); +        await this._updateTarget(optionsFull); +        await settingsSaveOptions(); +    }  } |