diff options
Diffstat (limited to 'app/javascript/core')
-rw-r--r-- | app/javascript/core/admin.js | 75 | ||||
-rw-r--r-- | app/javascript/core/common.js | 5 | ||||
-rw-r--r-- | app/javascript/core/embed.js | 23 | ||||
-rw-r--r-- | app/javascript/core/mailer.js | 1 | ||||
-rw-r--r-- | app/javascript/core/public.js | 51 | ||||
-rw-r--r-- | app/javascript/core/settings.js | 76 | ||||
-rw-r--r-- | app/javascript/core/theme.yml | 19 |
7 files changed, 250 insertions, 0 deletions
diff --git a/app/javascript/core/admin.js b/app/javascript/core/admin.js new file mode 100644 index 000000000..f2334c254 --- /dev/null +++ b/app/javascript/core/admin.js @@ -0,0 +1,75 @@ +// This file will be loaded on admin pages, regardless of theme. + +import { delegate } from '@rails/ujs'; +import ready from '../mastodon/ready'; + +const batchCheckboxClassName = '.batch-checkbox input[type="checkbox"]'; + +delegate(document, '#batch_checkbox_all', 'change', ({ target }) => { + [].forEach.call(document.querySelectorAll(batchCheckboxClassName), (content) => { + content.checked = target.checked; + }); +}); + +delegate(document, batchCheckboxClassName, 'change', () => { + const checkAllElement = document.querySelector('#batch_checkbox_all'); + + if (checkAllElement) { + checkAllElement.checked = [].every.call(document.querySelectorAll(batchCheckboxClassName), (content) => content.checked); + checkAllElement.indeterminate = !checkAllElement.checked && [].some.call(document.querySelectorAll(batchCheckboxClassName), (content) => content.checked); + } +}); + +delegate(document, '.media-spoiler-show-button', 'click', () => { + [].forEach.call(document.querySelectorAll('button.media-spoiler'), (element) => { + element.click(); + }); +}); + +delegate(document, '.media-spoiler-hide-button', 'click', () => { + [].forEach.call(document.querySelectorAll('.spoiler-button.spoiler-button--visible button'), (element) => { + element.click(); + }); +}); + +delegate(document, '.filter-subset--with-select select', 'change', ({ target }) => { + target.form.submit(); +}); + +const onDomainBlockSeverityChange = (target) => { + const rejectMediaDiv = document.querySelector('.input.with_label.domain_block_reject_media'); + const rejectReportsDiv = document.querySelector('.input.with_label.domain_block_reject_reports'); + + if (rejectMediaDiv) { + rejectMediaDiv.style.display = (target.value === 'suspend') ? 'none' : 'block'; + } + + if (rejectReportsDiv) { + rejectReportsDiv.style.display = (target.value === 'suspend') ? 'none' : 'block'; + } +}; + +delegate(document, '#domain_block_severity', 'change', ({ target }) => onDomainBlockSeverityChange(target)); + +const onEnableBootstrapTimelineAccountsChange = (target) => { + const bootstrapTimelineAccountsField = document.querySelector('#form_admin_settings_bootstrap_timeline_accounts'); + + if (bootstrapTimelineAccountsField) { + bootstrapTimelineAccountsField.disabled = !target.checked; + if (target.checked) { + bootstrapTimelineAccountsField.parentElement.classList.remove('disabled'); + } else { + bootstrapTimelineAccountsField.parentElement.classList.add('disabled'); + } + } +}; + +delegate(document, '#form_admin_settings_enable_bootstrap_timeline_accounts', 'change', ({ target }) => onEnableBootstrapTimelineAccountsChange(target)); + +ready(() => { + const domainBlockSeverityInput = document.getElementById('domain_block_severity'); + if (domainBlockSeverityInput) onDomainBlockSeverityChange(domainBlockSeverityInput); + + const enableBootstrapTimelineAccounts = document.getElementById('form_admin_settings_enable_bootstrap_timeline_accounts'); + if (enableBootstrapTimelineAccounts) onEnableBootstrapTimelineAccountsChange(enableBootstrapTimelineAccounts); +}); diff --git a/app/javascript/core/common.js b/app/javascript/core/common.js new file mode 100644 index 000000000..3b038ca40 --- /dev/null +++ b/app/javascript/core/common.js @@ -0,0 +1,5 @@ +// This file will be loaded on all pages, regardless of theme. + +import 'font-awesome/css/font-awesome.css'; + +require.context('../images/', true); diff --git a/app/javascript/core/embed.js b/app/javascript/core/embed.js new file mode 100644 index 000000000..6146e6592 --- /dev/null +++ b/app/javascript/core/embed.js @@ -0,0 +1,23 @@ +// This file will be loaded on embed pages, regardless of theme. + +window.addEventListener('message', e => { + const data = e.data || {}; + + if (!window.parent || data.type !== 'setHeight') { + return; + } + + function setEmbedHeight () { + window.parent.postMessage({ + type: 'setHeight', + id: data.id, + height: document.getElementsByTagName('html')[0].scrollHeight, + }, '*'); + }; + + if (['interactive', 'complete'].includes(document.readyState)) { + setEmbedHeight(); + } else { + document.addEventListener('DOMContentLoaded', setEmbedHeight); + } +}); diff --git a/app/javascript/core/mailer.js b/app/javascript/core/mailer.js new file mode 100644 index 000000000..baef7e7fb --- /dev/null +++ b/app/javascript/core/mailer.js @@ -0,0 +1 @@ +import 'styles/mailer.scss'; diff --git a/app/javascript/core/public.js b/app/javascript/core/public.js new file mode 100644 index 000000000..8c26f1404 --- /dev/null +++ b/app/javascript/core/public.js @@ -0,0 +1,51 @@ +// This file will be loaded on public pages, regardless of theme. + +import ready from '../mastodon/ready'; + +const { delegate } = require('@rails/ujs'); +const { length } = require('stringz'); + +delegate(document, '.webapp-btn', 'click', ({ target, button }) => { + if (button !== 0) { + return true; + } + window.location.href = target.href; + return false; +}); + +delegate(document, '.modal-button', 'click', e => { + e.preventDefault(); + + let href; + + if (e.target.nodeName !== 'A') { + href = e.target.parentNode.href; + } else { + href = e.target.href; + } + + window.open(href, 'mastodon-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes'); +}); + +const getProfileAvatarAnimationHandler = (swapTo) => { + //animate avatar gifs on the profile page when moused over + return ({ target }) => { + const swapSrc = target.getAttribute(swapTo); + //only change the img source if autoplay is off and the image src is actually different + if(target.getAttribute('data-autoplay') !== 'true' && target.src !== swapSrc) { + target.src = swapSrc; + } + }; +}; + +delegate(document, 'img#profile_page_avatar', 'mouseover', getProfileAvatarAnimationHandler('data-original')); + +delegate(document, 'img#profile_page_avatar', 'mouseout', getProfileAvatarAnimationHandler('data-static')); + +delegate(document, '#account_header', 'change', ({ target }) => { + const header = document.querySelector('.card .card__img img'); + const [file] = target.files || []; + const url = file ? URL.createObjectURL(file) : header.dataset.originalSrc; + + header.src = url; +}); diff --git a/app/javascript/core/settings.js b/app/javascript/core/settings.js new file mode 100644 index 000000000..9403e339b --- /dev/null +++ b/app/javascript/core/settings.js @@ -0,0 +1,76 @@ +// This file will be loaded on settings pages, regardless of theme. + +import escapeTextContentForBrowser from 'escape-html'; +const { delegate } = require('@rails/ujs'); +import emojify from '../mastodon/features/emoji/emoji'; + +delegate(document, '#account_display_name', 'input', ({ target }) => { + const name = document.querySelector('.card .display-name strong'); + if (name) { + if (target.value) { + name.innerHTML = emojify(escapeTextContentForBrowser(target.value)); + } else { + name.textContent = name.textContent = target.dataset.default; + } + } +}); + +delegate(document, '#account_avatar', 'change', ({ target }) => { + const avatar = document.querySelector('.card .avatar img'); + const [file] = target.files || []; + const url = file ? URL.createObjectURL(file) : avatar.dataset.originalSrc; + + avatar.src = url; +}); + +delegate(document, '#account_header', 'change', ({ target }) => { + const header = document.querySelector('.card .card__img img'); + const [file] = target.files || []; + const url = file ? URL.createObjectURL(file) : header.dataset.originalSrc; + + header.src = url; +}); + +delegate(document, '#account_locked', 'change', ({ target }) => { + const lock = document.querySelector('.card .display-name i'); + + if (lock) { + if (target.checked) { + delete lock.dataset.hidden; + } else { + lock.dataset.hidden = 'true'; + } + } +}); + +delegate(document, '.input-copy input', 'click', ({ target }) => { + target.focus(); + target.select(); + target.setSelectionRange(0, target.value.length); +}); + +delegate(document, '.input-copy button', 'click', ({ target }) => { + const input = target.parentNode.querySelector('.input-copy__wrapper input'); + + const oldReadOnly = input.readonly; + + input.readonly = false; + input.focus(); + input.select(); + input.setSelectionRange(0, input.value.length); + + try { + if (document.execCommand('copy')) { + input.blur(); + target.parentNode.classList.add('copied'); + + setTimeout(() => { + target.parentNode.classList.remove('copied'); + }, 700); + } + } catch (err) { + console.error(err); + } + + input.readonly = oldReadOnly; +}); diff --git a/app/javascript/core/theme.yml b/app/javascript/core/theme.yml new file mode 100644 index 000000000..dc641772c --- /dev/null +++ b/app/javascript/core/theme.yml @@ -0,0 +1,19 @@ +# These packs will be loaded on every appropriate page, regardless of +# theme. +pack: + about: + admin: admin.js + auth: settings.js + common: + filename: common.js + stylesheet: true + embed: embed.js + error: + home: + mailer: + filename: mailer.js + stylesheet: true + modal: public.js + public: public.js + settings: settings.js + share: |