Skip to content

Commit

Permalink
implement #296
Browse files Browse the repository at this point in the history
  • Loading branch information
shu8 committed Dec 27, 2018
1 parent 8828671 commit 13f8831
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
### Installed Version: 1.X.X Environment: Chrome/Tampermonkey
e### Installed Version: 1.X.X Environment: Chrome/Tampermonkey


### Current Behaviour
Expand Down
47 changes: 45 additions & 2 deletions sox.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
}
};

//var Stack = (typeof StackExchange === "undefined" ? window.eval('if (typeof StackExchange != "undefined") StackExchange') : StackExchange) | undefined;
let Chat;
let Stack;
if (location.href.indexOf('github.com') === -1) { //need this so it works on FF -- CSP blocks window.eval() it seems
Expand Down Expand Up @@ -256,6 +255,50 @@
const siteMatch = link.replace(/https?:\/\//, '').match(siteRegex);
return siteMatch ? siteMatch[1] : null;
},
createModal: function (params) {
const $dialog = $('<aside/>', {
'class': 's-modal js-modal-overlay js-modal-close js-stacks-managed-popup js-fades-with-aria-hidden sox-custom-dialog',
'role': 'dialog',
'aria-hidden': false,
});
if (params.css) $dialog.css(params.css);
const $dialogInnerContainer = $('<div/>', {
'class': 's-modal--dialog js-modal-dialog ',
'style': 'min-width: 568px;',// top: 227.736px; left: 312.653px;',
});
const $header = $('<h1/>', {
'class': 's-modal--header fs-headline1 fw-bold mr48 js-first-tabbable',
'text': params.header,
});
const $mainContent = $('<div/>', {
'class': 's-modal--body sox-custom-dialog-content',
});
if (params.html) $mainContent.html(params.html);
const $closeButton = $('<button/>', {
'class': 's-modal--close s-btn s-btn__muted js-modal-close js-last-tabbable',
'click': () => $('.sox-custom-dialog').remove(),
}).append($('<svg aria-hidden="true" class="svg-icon m0 iconClearSm" width="14" height="14" viewBox="0 0 14 14"><path d="M12 3.41L10.59 2 7 5.59 3.41 2 2 3.41 5.59 7 2 10.59 3.41 12 7 8.41 10.59 12 12 10.59 8.41 7z"></path></svg>'));

$dialogInnerContainer.append($header).append($mainContent).append($closeButton);
$dialog.append($dialogInnerContainer);

return $dialog;
},
addButtonToHelpMenu: function (params) {
const $li = $('<li/>');
const $a = $('<a/>', {
'href': 'javascript:void(0)',
'id': params.id,
'text': params.linkText,
});
const $span = $('<span/>', {
'class': 'item-summary',
'text': params.summary,
'click': params.click,
});
$li.append($a.append($span));
$('.topbar-dialog.help-dialog.js-help-dialog > .modal-content ul').append($li);
},
};

sox.site = {
Expand Down Expand Up @@ -335,7 +378,7 @@
let matchScheme = matchSplit[0];
let matchHost = matchSplit[2];
let matchPath = matchSplit.slice(-(matchSplit.length - 3)).join('/');

matchScheme = matchScheme.replace(/\*/g, '.*');
matchHost = matchHost.replace(/\./g, '\\.').replace(/\*\\\./g, '.*.?').replace(/\\\.\*/g, '.*').replace(/\*$/g, '.*');
matchPath = '^/' + matchPath.replace(/\//g, '\\/').replace(/\*/g, '.*');
Expand Down
18 changes: 17 additions & 1 deletion sox.css
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@
}

.fixedTopbar-linksList {
box-sizing: border-box;
-moz-box-sizing: border-box;
background: none repeat scroll 0 0 #fff;
}
Expand Down Expand Up @@ -350,7 +351,7 @@ li.fixedTopbar-siteLink {
}

.post-editor.sbs-on {
width: 1360px !important; //width: 1060px !important;
width: 1360px !important;
}

.sbs-on-left-side {
Expand Down Expand Up @@ -615,4 +616,19 @@ li.fixedTopbar-siteLink {
/* editComment -- for the checkboxes shown when editin */
.sox-editComment-reason {
display: inline-block !important;
}

/* customMagicLinks -- for the settings table in the dialog */
.sox-customMagicLinks-settings-table {
margin-bottom: 10px;
}

.sox-customMagicLinks-settings-table td,
.sox-customMagicLinks-settings-table th {
border: 1px solid #ddd;
padding: 8px;
}

.sox-customMagicLinks-settings-table th {
font-weight: bold;
}
8 changes: 8 additions & 0 deletions sox.features.info.json
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,14 @@
"meta": "",
"match": "",
"exclude": "*://chat.*.com/*,SE1.0"
}, {
"name": "customMagicLinks",
"desc": "Add custom magic links to comments and posts",
"extended_description": "Allows you to create your own magic links ('[text]' auto-converts to a link of your choice). Links can use the placeholders $BASEURL, $METABASEURL, $QUESTIONID, and $ANSWERID which are auto-replaced with the respective data. You can set the reasons by clicking the 'Magic Links' button added to the 'Help' dropdown at the top-right of the page. See https://stackapps.com/q/6650 for more details.",
"meta": "",
"match": "*://*/questions*",
"exclude": "",
"feature_packs": ["power_user"]
}]
}
}
154 changes: 144 additions & 10 deletions sox.features.js
Original file line number Diff line number Diff line change
Expand Up @@ -429,20 +429,22 @@
//reset textbox values to empty
$('#displayReason').val('');
$('#actualReason').val('');

}
});

setTimeout(() => {
addCheckboxes();
//Add the button to update and view the values in the help menu:
$('.topbar-dialog.help-dialog.js-help-dialog > .modal-content ul').append('<li><a href=\'javascript:void(0)\' id=\'editReasonsLink\'>Edit Reasons \
<span class=\'item-summary\'>Edit your personal edit reasons for SE sites</span></a></li>');
$('.topbar-dialog.help-dialog.js-help-dialog > .modal-content ul #editReasonsLink').on('click', () => {
addCheckboxes();

//Add the button to update and view the values in the help menu:
sox.helpers.addButtonToHelpMenu({
'id': 'editReasonsLink',
'linkText': 'Edit Reasons',
'summary': 'Edit your personal edit reasons for SE sites',
'click': function () {
displayDeleteValues();
$('#dialogEditReasons').show(500); //Show the dialog to view and update values
});
}, 500);
},
});

$(document).on('sox-edit-window', addCheckboxes);

$('.post-menu > .edit-post').click(() => {
Expand Down Expand Up @@ -690,7 +692,7 @@

function updateTS() {
const utcTimestamp = $(this).attr('title');
const matches = utcTimestamp.match(/^([\d]{4})-([\d]{2})-([\d]{2}) ([\d]{2}):([\d]{2}):([\d]{2}) ?(?:Z|UTC|GMT(?:[+\-]00:?00))$/);
const matches = utcTimestamp.match(/^([\d]{4})-([\d]{2})-([\d]{2}) ([\d]{2}):([\d]{2}):([\d]{2}) ?(?:Z|UTC|GMT(?:[+-]00:?00))$/);
const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

if (!matches) return;
Expand Down Expand Up @@ -2478,5 +2480,137 @@
$('.top-bar .related-links').find('a').eq(0).replaceWith('<a href="/help/on-topic">on-topic</a>');
},

customMagicLinks: function () {
// Description: Adds custom magic links to the post and comment editors

var magicLinks = JSON.parse(GM_getValue('SOX-customMagicLinks', '[]'));
// magicLinks = [ { text: 'edit/q', replacement: 'Edit Question', link: '$BASEURL$/posts/$QUESTIONID$/edit' }];

function updateGMValue(magicLinks) {
GM_setValue('SOX-customMagicLinks', JSON.stringify(magicLinks));
}

function generateSettingsTableHtml(magicLinks) {
const $magicLinksTable = $(`
<table class='sox-customMagicLinks-settings-table'>
<tr>
<th>Text</th>
<th>Replacement</th>
<th>Link</th>
</tr>
</table>`);
for (let i = 0; i < magicLinks.length; i++) {
const currentLink = magicLinks[i];
const $saveButton = $('<button/>', {
'text': 'save',
'click': function () {
const $parentTr = $(this).parent().parent();
const index = $parentTr.attr('data-magic-link-index');
magicLinks[index].text = $parentTr.find('.magic-link-text').text();
magicLinks[index].replacement = $parentTr.find('.magic-link-replacement').text();
magicLinks[index].link = $parentTr.find('.magic-link-link').text();
window.alert('Your changes were saved!');
updateGMValue(magicLinks);
},
});
const $deleteButton = $('<button/>', {
'text': 'delete',
'click': function () {
magicLinks.splice($(this).parent().attr('data-magic-link-index'), 1);
$(this).parent().parent().remove();
updateGMValue(magicLinks);
},
});
const $linkDetails = $(
`<tr class='sox-magic-link-details' data-magic-link-index=${i}>
<td contenteditable class='magic-link-text'>${currentLink.text}</td>
<td contenteditable class='magic-link-replacement'>${currentLink.replacement}</td>
<td contenteditable class='magic-link-link'>${currentLink.link}</td>
</tr>`);
$linkDetails.append($('<td/>').append($saveButton)).append($('<td/>').append($deleteButton));
$magicLinksTable.append($linkDetails);
}
return $magicLinksTable;
}

function replacePlaceholders(text, $textarea) {
const baseUrl = $(location).attr('protocol') + '//' + $(location).attr('hostname');
const localMetaBase = $(location).attr('protocol') + '//meta.' + $(location).attr('hostname');
const questionId = $('.question').data('questionid');
const answerId = $textarea.closest('.answer').data('answerid');

return text
.replace(/\$BASEURL\$/ig, baseUrl)
.replace(/\$METABASEURL\$/ig, localMetaBase)
.replace(/\$QUESTIONID\$/ig, questionId)
.replace(/\$ANSWERID\$/ig, answerId);
}

function magicLink($el) {
const $textarea = $el.is('textarea') ? $el : $el.parents('form').find('textarea').eq(0);
var newVal = $textarea.val();
for (let i = 0; i < magicLinks.length; i++) {
const currentMagicLink = magicLinks[i];
const replacementText = currentMagicLink.replacement;
const url = replacePlaceholders(currentMagicLink.link, $textarea);
const regex = new RegExp('\\[' + currentMagicLink.text + '\\]', 'g');
newVal = newVal.replace(regex, '[' + replacementText + '](' + url + ')');
}
$textarea.val(newVal);
}

$(document).on('keydown', '.comment-form textarea', function (e) {
if (e.keyCode == 13) magicLink($(this));
});
$(document).on('click', '.comment-form input[type="submit"], .form-submit #submit-button, form.inline-post button[id*="submit-button-"]', function (e) {
magicLink($(this));
});

function createSettingsDialog(magicLinks) {
const $settingsDialog = sox.helpers.createModal({
'header': 'SOX: Magic Link Settings',
'css': {
'min- width': '50%',
},
'html': '<i>the table cells below are editable; be sure to save any changes!</i><br><br><div class="table-container"></div>',
});
const $settingsDialogContent = $settingsDialog.find('.sox-custom-dialog-content');

const $newMagicLinkButton = $('<button/>', {
'text': 'new link',
'click': function () {
const text = window.prompt('Enter the magic link text (e.g. edit/q)');
const replacement = window.prompt('Enter the text you would like the link to show as (e.g. Edit Question)');
const link = window.prompt('Enter the replacement link, using the placeholders as required');

if (text && replacement && link) {
magicLinks.push({
text,
replacement,
link,
});
updateGMValue(magicLinks);
$settingsDialogContent.find('.table-container table').remove();
$settingsDialogContent.find('.table-container').append(generateSettingsTableHtml(magicLinks));
} else {
window.alert('Please enter details for all three fields');
}
},
});
$settingsDialogContent.find('.table-container').append(generateSettingsTableHtml(magicLinks));
$settingsDialogContent.append($newMagicLinkButton);

$('body').append($settingsDialog);
}

sox.helpers.addButtonToHelpMenu({
'id': 'magicLinksSettingsLink',
'linkText': 'Magic Links',
'summary': 'Edit your custom magic links for SE sites',
'click': function () {
createSettingsDialog(magicLinks);
},
});
},
};
})(window.sox = window.sox || {}, jQuery);
2 changes: 1 addition & 1 deletion sox.user.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// @namespace https://github.com/soscripted/sox
// @homepage https://github.com/soscripted/sox
// @homepageURL https://github.com/soscripted/sox
// @version 2.3.20 DEV
// @version 2.3.21 DEV
// @description Extra optional features for Stack Overflow and Stack Exchange sites
// @contributor ᴉʞuǝ (https://stackoverflow.com/users/1454538/, https://github.com/mezmi)
// @contributor ᔕᖺᘎᕊ (https://stackexchange.com/users/4337810/, https://github.com/shu8)
Expand Down

0 comments on commit 13f8831

Please sign in to comment.