Skip to content

Commit

Permalink
settingsConsole: Replace window.confirm and window.alert with utils A…
Browse files Browse the repository at this point in the history
…lert/Notification

Usage of those methods in cross-origin embedded frames are deprecated in Chrome.
  • Loading branch information
larsjohnsen committed Dec 6, 2021
1 parent f5001bc commit a4ffe1e
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 37 deletions.
22 changes: 22 additions & 0 deletions lib/css/res.scss
Expand Up @@ -558,6 +558,10 @@ span.multi-count {
position: relative;
}

.builderNote {
margin-left: 10px;
}

.builderBlock {
flex-wrap: wrap;
white-space: pre-wrap;
Expand Down Expand Up @@ -935,3 +939,21 @@ body.res-dashboard {
tr:hover .deleteIcon { color: #369; }
}
}

.res-button-undo {
position: absolute;
bottom: 20px;
right: 20px;
border-radius: 5px;
background-color: #3a3a3af2;
box-shadow: 0 0 6px 2px #3a3a3a;
border: none;
padding: 7px;
color: white;
font-size: 14px;
cursor: pointer;
}

.pushRight {
margin-left: auto;
}
20 changes: 8 additions & 12 deletions lib/options/settingsConsole.js
Expand Up @@ -739,13 +739,10 @@ function drawConfigOptions(mod) {
thisDeleteButton.textContent = '\uF056';
thisDeleteButton.title = 'remove this row';

thisDeleteButton.addEventListener('click', (e: Event) => {
if (!confirm('Are you sure you want to delete this row?')) {
e.preventDefault();
return;
}

$(thisTR).trigger('change').remove();
thisDeleteButton.addEventListener('click', () => {
const tbody = downcast(thisTR.closest('tbody'), HTMLTableSectionElement);
$(thisTR).trigger('change').detach();
CreateElement.undo('Restore deleted row').then(() => { $(thisTR).appendTo(tbody).trigger('change'); });
});
thisTD.appendChild(thisDeleteButton);
thisTR.appendChild(thisTD);
Expand Down Expand Up @@ -908,16 +905,17 @@ function handleEscapeKey(event: KeyboardEvent) {
}
}

const abandonChangesConfirmation = 'Abandon your changes to RES settings?';

function handleBeforeUnload() {
if (Options.stage.isDirty()) {
return abandonChangesConfirmation;
}
}

function close({ promptIfStagedOptions = true }: {| promptIfStagedOptions?: boolean |} = {}) {
async function close({ promptIfStagedOptions = true }: {| promptIfStagedOptions?: boolean |} = {}) {
if (promptIfStagedOptions && Options.stage.isDirty()) {
const abandonChanges = confirm(abandonChangesConfirmation);
if (!abandonChanges) return;
await Alert.open(abandonChangesConfirmation, { cancelable: true });
}

SettingsNavigation.close();
Expand All @@ -939,8 +937,6 @@ function getOptions(mod) {
}));
}

const abandonChangesConfirmation = 'Abandon your changes to RES settings?';

function notifyOptionsSaved() {
const statusEle = RESConsoleContainer.querySelector('#moduleOptionsSaveStatus');
if (statusEle) {
Expand Down
50 changes: 25 additions & 25 deletions lib/utils/caseBuilder.js
Expand Up @@ -3,7 +3,8 @@
import $ from 'jquery';
import { Sortable } from '../vendor';
import { i18n } from '../environment';
import { downcast, string } from './';
import { undo } from './createElement';
import { Alert, downcast, string } from './';

export function drawOptionBuilder(options: *, mod: *, optionName: *) {
const option = options[optionName];
Expand Down Expand Up @@ -32,30 +33,28 @@ export function drawOptionBuilder(options: *, mod: *, optionName: *) {
}

function drawBuilderItem(data: *, customOptionsFields: * = [], cases: *) {
const $item = $('<div class="builderItem">');

const $editButton = $('<div>')
.addClass('res-icon-button res-icon builderControls builderTrailingControls')
.html('&#xF061;')
.attr('title', 'copy and share, or update your settings with a new version')
.on('click', function() {
const $item = $(this).closest('.builderItem');
.on('click', async () => {
const data = readBuilderItem($item, customOptionsFields, cases);
const json = prompt(
'Copy this and share it, or paste a new version and update your settings',
JSON.stringify(data),
);
if (json !== null) {
const newData = JSON.parse(json);
$item.trigger('change').replaceWith(drawBuilderItem(newData, customOptionsFields, cases));
}
const element = string.html`<div>Copy this and share it, or update your settings with a new version: <br><br><textarea rows="5" cols="50"></textarea></div>`;
const textarea = downcast(element.querySelector('textarea'), HTMLTextAreaElement);
textarea.value = JSON.stringify(data);
const newData = await Alert.open(element, { cancelable: true })
.then(() => JSON.parse(textarea.value));
$item.replaceWith(drawBuilderItem(newData, customOptionsFields, cases)).trigger('change');
});

const $deleteButton = drawDeleteButton()
.addClass('builderTrailingControls')
.on('click', function() {
if (confirm('Are you sure you want remove this filter?')) {
$(this).trigger('change');
$(this).closest('.builderItem').trigger('change').remove();
}
.on('click', () => {
const parent = $item.parent();
$item.trigger('change').detach();
undo('Restore deleted item').then(() => { parent.append($item).trigger('change'); });
});

const customOptions = string.html`<ul class="builderCustomOptions"></ul>`;
Expand All @@ -71,13 +70,13 @@ function drawBuilderItem(data: *, customOptionsFields: * = [], cases: *) {
$('<input type="hidden" name="version">').val(data.ver),
$('<input type="hidden" name="id">').val(data.id),
customOptions,
$('<textarea name="builderNote" style="margin-left: 10px" rows="1" cols="40" placeholder="Write a description/note for this">').val(data.note),
$('<div>').css({ 'margin-left': 'auto' }).append($editButton, $deleteButton),
$('<textarea name="builderNote" rows="1" cols="40" placeholder="Write a description/note for this">').val(data.note),
$('<div class="pushRight">').append($editButton, $deleteButton),
);

const $body = drawBuilderBlock(data.body, cases, false);

return $('<div class="builderItem">').append($header, $body);
return $item.append($header, $body);
}

function drawHandle() {
Expand Down Expand Up @@ -107,16 +106,17 @@ export function drawBuilderBlock(data: *, cases: *, addBaseControls: boolean = t

if (!addBaseControls) return $block;

const $wrap = $('<div class="builderWrap">');

const $deleteButton = drawDeleteButton()
.addClass('builderTrailingControls')
.on('click', function() {
if (confirm('Are you sure you want to delete this condition?')) {
$(this).trigger('change');
$(this).closest('.builderWrap').parent('li').remove();
}
.on('click', () => {
const parent = $wrap.parent();
$wrap.trigger('change').detach();
undo('Restore deleted block').then(() => { parent.append($wrap).trigger('change'); });
});

return $('<div class="builderWrap">')
return $wrap
.append(
drawHandle(),
$block,
Expand Down
22 changes: 22 additions & 0 deletions lib/utils/createElement.js
Expand Up @@ -3,6 +3,7 @@
import { once } from 'lodash-es';
import { i18n } from '../environment';
import type { Iteratee } from './array';
import { waitForEvent } from './dom';
import { downcast } from './flow';
import { addFloater } from './floater';
import { isCurrentSubreddit, currentSubreddit } from './location';
Expand Down Expand Up @@ -100,6 +101,27 @@ export function tabMenuItem({ text, aftercontent, className, title, checked, onC
return a;
}

export function undo(buttonText: string, timeout: number = 5000) {
const restoreButton = string.html`<button class="res-button-undo">${buttonText}</button>`;
let hideTimer, fadeTimer;
const scheduleFade = () => {
hideTimer = setTimeout(() => {
restoreButton.classList.add('transitionToTransparent');
restoreButton.style.transitionDuration = '2s';
fadeTimer = setTimeout(() => { restoreButton.remove(); }, 2000);
}, timeout);
};
restoreButton.addEventListener('mouseenter', () => {
clearTimeout(hideTimer);
clearTimeout(fadeTimer);
restoreButton.classList.remove('transitionToTransparent');
});
restoreButton.addEventListener('mouseleave', scheduleFade);
scheduleFade();
document.body.append(restoreButton);
return waitForEvent(restoreButton, 'click').then(() => { restoreButton.remove(); });
}

export function fancyToggleButton(text: string, title: string, getState: () => boolean, callback: boolean => any) {
const element = document.createElement('span');
element.className = 'res-fancy-toggle-button';
Expand Down

0 comments on commit a4ffe1e

Please sign in to comment.