2023-09-09 00:07:04 +08:00
|
|
|
#main-outlet > .regular {
|
|
|
|
background: var(--d-content-background);
|
|
|
|
}
|
|
|
|
|
2019-05-04 02:26:37 +08:00
|
|
|
.button-count.has-pending {
|
|
|
|
span {
|
2020-08-04 10:57:10 +08:00
|
|
|
background-color: var(--danger);
|
|
|
|
color: var(--secondary);
|
2019-05-04 02:26:37 +08:00
|
|
|
border-radius: 10px;
|
|
|
|
padding: 0.25em 0.5em;
|
|
|
|
display: inline-block;
|
|
|
|
font-size: 0.8em;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-02 06:27:32 +08:00
|
|
|
.placeholder-avatar {
|
|
|
|
display: inline-block;
|
|
|
|
width: 45px;
|
|
|
|
height: 45px;
|
|
|
|
border-radius: 50%;
|
2019-04-27 00:29:48 +08:00
|
|
|
position: relative;
|
|
|
|
overflow: hidden;
|
|
|
|
&:before {
|
2023-09-15 05:31:43 +08:00
|
|
|
@media (prefers-reduced-motion: no-preference) {
|
|
|
|
animation: placeHolderShimmer 4s linear infinite forwards;
|
|
|
|
}
|
2019-04-27 00:29:48 +08:00
|
|
|
position: absolute;
|
|
|
|
left: 0;
|
|
|
|
content: "";
|
|
|
|
background: linear-gradient(
|
|
|
|
to right,
|
2020-08-04 10:57:10 +08:00
|
|
|
var(--primary-very-low) 10%,
|
|
|
|
var(--primary-low) 28%,
|
|
|
|
var(--primary-very-low) 43%
|
2019-04-27 00:29:48 +08:00
|
|
|
);
|
|
|
|
height: 45px;
|
|
|
|
width: 700px;
|
|
|
|
}
|
2015-12-02 06:27:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
.placeholder-text {
|
2022-10-26 02:45:37 +08:00
|
|
|
margin-left: var(--topic-body-width-padding);
|
2015-12-02 06:27:32 +08:00
|
|
|
display: inline-block;
|
2022-10-26 02:45:37 +08:00
|
|
|
width: calc(100% - var(--topic-body-width-padding));
|
2015-12-02 06:27:32 +08:00
|
|
|
height: 1.5em;
|
|
|
|
margin-bottom: 0.6em;
|
|
|
|
}
|
|
|
|
|
2022-09-23 10:21:00 +08:00
|
|
|
.post-stream .placeholder .row {
|
|
|
|
display: flex;
|
|
|
|
}
|
|
|
|
|
2014-05-12 09:28:24 +08:00
|
|
|
.names {
|
2018-09-06 05:48:31 +08:00
|
|
|
flex: 1 1 auto;
|
|
|
|
overflow: hidden;
|
2018-06-08 17:49:31 +08:00
|
|
|
span.first {
|
2019-02-23 10:28:58 +08:00
|
|
|
display: flex;
|
|
|
|
align-items: baseline;
|
2018-06-08 17:49:31 +08:00
|
|
|
font-weight: bold;
|
|
|
|
}
|
|
|
|
|
2024-04-09 17:10:12 +08:00
|
|
|
> span {
|
2022-10-12 21:31:59 +08:00
|
|
|
font-size: var(--font-0);
|
2024-04-09 17:10:12 +08:00
|
|
|
margin-right: 0.33em;
|
2018-06-08 17:49:31 +08:00
|
|
|
display: inline-block;
|
2019-11-07 03:00:29 +08:00
|
|
|
@include ellipsis;
|
2018-11-27 05:49:57 +08:00
|
|
|
vertical-align: middle;
|
2018-06-08 17:49:31 +08:00
|
|
|
a {
|
2020-08-04 10:57:10 +08:00
|
|
|
color: var(--primary-high-or-secondary-low);
|
2023-12-09 00:06:21 +08:00
|
|
|
outline-offset: -1px;
|
2018-06-08 17:49:31 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
.fa {
|
2022-10-12 21:31:59 +08:00
|
|
|
font-size: var(--font-down-1);
|
2020-08-04 10:57:10 +08:00
|
|
|
color: var(--primary-med-or-secondary-med);
|
2018-11-08 02:05:43 +08:00
|
|
|
}
|
2018-11-27 05:49:57 +08:00
|
|
|
.svg-icon-title {
|
|
|
|
margin-left: 3px;
|
|
|
|
margin-right: 0px;
|
|
|
|
}
|
2018-06-08 17:49:31 +08:00
|
|
|
.new_user a,
|
|
|
|
.user-title,
|
|
|
|
.user-title a {
|
2020-08-04 10:57:10 +08:00
|
|
|
color: var(--primary-med-or-secondary-med);
|
2018-06-08 17:49:31 +08:00
|
|
|
}
|
2014-05-12 09:28:24 +08:00
|
|
|
}
|
2014-06-05 14:59:18 +08:00
|
|
|
|
2014-07-01 06:53:22 +08:00
|
|
|
// global styles for the cooked HTML content in posts (and preview)
|
2018-06-08 17:49:31 +08:00
|
|
|
.cooked,
|
|
|
|
.d-editor-preview {
|
2014-06-24 15:40:12 +08:00
|
|
|
word-wrap: break-word;
|
2024-05-22 01:13:38 +08:00
|
|
|
line-height: 1.5;
|
2020-11-09 13:03:36 +08:00
|
|
|
|
|
|
|
> *:first-child {
|
|
|
|
margin-top: 0;
|
|
|
|
}
|
|
|
|
|
2018-06-08 17:49:31 +08:00
|
|
|
h1,
|
|
|
|
h2,
|
|
|
|
h3,
|
|
|
|
h4,
|
|
|
|
h5,
|
|
|
|
h6 {
|
2024-05-22 01:13:38 +08:00
|
|
|
margin: 2rem 0 0.67rem;
|
2022-10-12 22:05:42 +08:00
|
|
|
line-height: var(--line-height-medium);
|
2021-05-04 01:56:58 +08:00
|
|
|
a.anchor {
|
2021-10-27 01:43:20 +08:00
|
|
|
opacity: 0;
|
|
|
|
transition: opacity 0.25s;
|
2021-05-04 01:56:58 +08:00
|
|
|
&:before {
|
|
|
|
content: svg-uri(
|
|
|
|
'<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 512 512" fill="#{$primary-medium}"><path d="M326.612 185.391c59.747 59.809 58.927 155.698.36 214.59-.11.12-.24.25-.36.37l-67.2 67.2c-59.27 59.27-155.699 59.262-214.96 0-59.27-59.26-59.27-155.7 0-214.96l37.106-37.106c9.84-9.84 26.786-3.3 27.294 10.606.648 17.722 3.826 35.527 9.69 52.721 1.986 5.822.567 12.262-3.783 16.612l-13.087 13.087c-28.026 28.026-28.905 73.66-1.155 101.96 28.024 28.579 74.086 28.749 102.325.51l67.2-67.19c28.191-28.191 28.073-73.757 0-101.83-3.701-3.694-7.429-6.564-10.341-8.569a16.037 16.037 0 0 1-6.947-12.606c-.396-10.567 3.348-21.456 11.698-29.806l21.054-21.055c5.521-5.521 14.182-6.199 20.584-1.731a152.482 152.482 0 0 1 20.522 17.197zM467.547 44.449c-59.261-59.262-155.69-59.27-214.96 0l-67.2 67.2c-.12.12-.25.25-.36.37-58.566 58.892-59.387 154.781.36 214.59a152.454 152.454 0 0 0 20.521 17.196c6.402 4.468 15.064 3.789 20.584-1.731l21.054-21.055c8.35-8.35 12.094-19.239 11.698-29.806a16.037 16.037 0 0 0-6.947-12.606c-2.912-2.005-6.64-4.875-10.341-8.569-28.073-28.073-28.191-73.639 0-101.83l67.2-67.19c28.239-28.239 74.3-28.069 102.325.51 27.75 28.3 26.872 73.934-1.155 101.96l-13.087 13.087c-4.35 4.35-5.769 10.79-3.783 16.612 5.864 17.194 9.042 34.999 9.69 52.721.509 13.906 17.454 20.446 27.294 10.606l37.106-37.106c59.271-59.259 59.271-155.699.001-214.959z"></path></svg>'
|
|
|
|
);
|
|
|
|
line-height: 1.4;
|
|
|
|
margin-left: -20px;
|
|
|
|
padding-right: 4px;
|
|
|
|
position: absolute;
|
2023-04-14 10:02:57 +08:00
|
|
|
z-index: 2;
|
2021-05-04 01:56:58 +08:00
|
|
|
}
|
|
|
|
}
|
2021-10-27 01:43:20 +08:00
|
|
|
|
|
|
|
// show when hovering where icon should be
|
|
|
|
// show when hovering header
|
|
|
|
.discourse-no-touch & a.anchor:hover,
|
|
|
|
.discourse-no-touch &:hover a.anchor {
|
|
|
|
opacity: 1;
|
2021-03-23 16:45:06 +08:00
|
|
|
}
|
2018-01-13 06:27:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
h1 {
|
2021-07-14 09:15:58 +08:00
|
|
|
font-size: var(--font-up-3-rem);
|
2018-01-13 06:27:38 +08:00
|
|
|
}
|
2018-01-22 11:22:30 +08:00
|
|
|
|
2018-01-13 06:27:38 +08:00
|
|
|
h2 {
|
2021-07-14 09:15:58 +08:00
|
|
|
font-size: var(--font-up-2-rem);
|
2018-01-13 06:27:38 +08:00
|
|
|
}
|
2018-01-22 11:22:30 +08:00
|
|
|
|
2018-01-13 06:27:38 +08:00
|
|
|
h3 {
|
2021-07-14 09:15:58 +08:00
|
|
|
font-size: var(--font-up-1-rem);
|
2018-01-13 06:27:38 +08:00
|
|
|
}
|
2018-01-22 11:22:30 +08:00
|
|
|
|
2018-01-13 06:27:38 +08:00
|
|
|
h4 {
|
2021-07-14 09:15:58 +08:00
|
|
|
font-size: var(--font-0-rem);
|
2018-01-13 06:27:38 +08:00
|
|
|
}
|
2018-01-22 11:22:30 +08:00
|
|
|
|
2018-01-13 06:27:38 +08:00
|
|
|
h5 {
|
2021-07-14 09:15:58 +08:00
|
|
|
font-size: var(--font-down-1-rem);
|
2018-01-13 06:27:38 +08:00
|
|
|
}
|
2018-01-22 11:22:30 +08:00
|
|
|
|
2018-01-13 06:27:38 +08:00
|
|
|
h6 {
|
2021-07-14 09:15:58 +08:00
|
|
|
font-size: var(--font-down-2-rem);
|
2017-12-16 00:29:15 +08:00
|
|
|
}
|
2018-01-22 11:22:30 +08:00
|
|
|
|
2018-06-08 17:49:31 +08:00
|
|
|
a {
|
|
|
|
word-wrap: break-word;
|
|
|
|
}
|
2020-05-13 10:51:28 +08:00
|
|
|
|
2021-02-16 00:17:30 +08:00
|
|
|
mark {
|
2020-05-13 10:51:28 +08:00
|
|
|
text-decoration: none;
|
|
|
|
}
|
2020-05-13 11:12:46 +08:00
|
|
|
|
2018-06-08 17:49:31 +08:00
|
|
|
ins {
|
2020-08-04 10:57:10 +08:00
|
|
|
background-color: var(--success-low);
|
2022-02-01 06:42:14 +08:00
|
|
|
text-decoration: underline;
|
2018-06-08 17:49:31 +08:00
|
|
|
}
|
|
|
|
del {
|
2020-08-04 10:57:10 +08:00
|
|
|
background-color: var(--danger-low);
|
2022-02-01 06:42:14 +08:00
|
|
|
text-decoration: line-through;
|
2018-06-08 17:49:31 +08:00
|
|
|
}
|
2021-02-16 00:17:30 +08:00
|
|
|
mark {
|
|
|
|
background-color: var(--highlight);
|
|
|
|
}
|
2018-01-23 23:34:37 +08:00
|
|
|
// Prevents users from breaking posts with tag nesting
|
2018-06-08 17:49:31 +08:00
|
|
|
big {
|
|
|
|
font-size: 1.5rem;
|
|
|
|
}
|
|
|
|
small {
|
|
|
|
font-size: 0.75rem;
|
|
|
|
}
|
|
|
|
small small {
|
|
|
|
font-size: 0.75em;
|
|
|
|
}
|
|
|
|
big big {
|
|
|
|
font-size: 1em;
|
|
|
|
}
|
|
|
|
sub sub sub {
|
|
|
|
bottom: 0;
|
|
|
|
}
|
|
|
|
sup sup sup {
|
|
|
|
top: 0;
|
|
|
|
}
|
2014-06-30 17:06:13 +08:00
|
|
|
}
|
|
|
|
|
2018-06-08 17:49:31 +08:00
|
|
|
.cooked,
|
|
|
|
.d-editor-preview {
|
2015-01-27 00:00:18 +08:00
|
|
|
video {
|
|
|
|
max-width: 100%;
|
|
|
|
}
|
2015-05-01 05:05:04 +08:00
|
|
|
sup sup {
|
|
|
|
top: 0;
|
|
|
|
}
|
2021-06-18 21:15:03 +08:00
|
|
|
|
|
|
|
img:not(.thumbnail):not(.ytp-thumbnail-image):not(.emoji) {
|
|
|
|
max-width: 100%;
|
2022-02-04 22:40:54 +08:00
|
|
|
height: auto;
|
2022-11-01 01:55:24 +08:00
|
|
|
display: inline-block; // Ensure dimensions are maintained even after load error
|
2022-04-05 20:43:17 +08:00
|
|
|
|
|
|
|
@supports not (aspect-ratio: 1) {
|
|
|
|
// (see javascripts/discourse/app/initializers/image-aspect-ratio.js)
|
|
|
|
height: var(--calculated-height);
|
|
|
|
}
|
2021-06-18 21:15:03 +08:00
|
|
|
}
|
2023-10-17 21:55:02 +08:00
|
|
|
|
|
|
|
svg {
|
|
|
|
max-height: 2000px;
|
|
|
|
}
|
2015-01-27 00:00:18 +08:00
|
|
|
}
|
2017-12-08 01:40:39 +08:00
|
|
|
|
|
|
|
// add staff color
|
|
|
|
.moderator {
|
2017-12-21 10:24:59 +08:00
|
|
|
.regular > .cooked {
|
2023-01-27 22:50:36 +08:00
|
|
|
background-color: var(--highlight-bg);
|
2017-12-08 01:40:39 +08:00
|
|
|
}
|
2017-12-21 10:24:59 +08:00
|
|
|
.clearfix > .topic-meta-data > .names {
|
2017-12-08 05:10:54 +08:00
|
|
|
span.user-title {
|
2020-08-04 10:57:10 +08:00
|
|
|
color: var(--primary-high-or-secondary-low);
|
2018-08-13 13:29:46 +08:00
|
|
|
a {
|
2023-02-21 17:15:49 +08:00
|
|
|
background-color: var(--highlight-bg);
|
2018-08-13 13:29:46 +08:00
|
|
|
padding-left: 4px;
|
|
|
|
padding-right: 4px;
|
|
|
|
}
|
2017-12-08 01:40:39 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-21 01:06:20 +08:00
|
|
|
.topic-meta-data {
|
|
|
|
display: flex;
|
|
|
|
align-items: flex-start;
|
|
|
|
|
|
|
|
.names {
|
|
|
|
margin-right: auto;
|
|
|
|
}
|
|
|
|
|
|
|
|
.post-infos {
|
|
|
|
display: flex;
|
2018-09-20 06:53:48 +08:00
|
|
|
flex: 0 0 auto;
|
2018-12-01 10:31:36 +08:00
|
|
|
align-items: center;
|
2018-06-21 01:06:20 +08:00
|
|
|
}
|
2022-09-03 01:48:36 +08:00
|
|
|
|
2022-10-13 00:07:07 +08:00
|
|
|
.user-status-message {
|
|
|
|
display: flex;
|
|
|
|
img.emoji {
|
|
|
|
width: 1em;
|
|
|
|
height: 1em;
|
|
|
|
}
|
2022-09-03 01:48:36 +08:00
|
|
|
}
|
2018-06-21 01:06:20 +08:00
|
|
|
}
|
|
|
|
|
2022-01-04 22:44:54 +08:00
|
|
|
nav.post-controls {
|
|
|
|
padding: 0;
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
justify-content: space-between;
|
|
|
|
color: var(--primary-low-mid);
|
|
|
|
|
|
|
|
.actions {
|
|
|
|
display: inline-flex;
|
|
|
|
text-align: right;
|
|
|
|
margin-left: auto;
|
|
|
|
|
|
|
|
// Some buttons can be doubled up, like likes or flags
|
|
|
|
.double-button {
|
|
|
|
display: inline-flex;
|
|
|
|
flex: 0 1 auto;
|
|
|
|
align-items: center;
|
|
|
|
white-space: nowrap;
|
|
|
|
button {
|
|
|
|
// It looks really confusing when one half a double button has an inner shadow on click.
|
|
|
|
&:active {
|
|
|
|
box-shadow: none;
|
|
|
|
}
|
|
|
|
&.my-likes,
|
|
|
|
&.read-indicator,
|
|
|
|
&.regular-likes {
|
|
|
|
// Like count on posts
|
|
|
|
.d-icon {
|
|
|
|
color: var(--primary-low-mid);
|
|
|
|
padding-left: 0.45em;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
&.has-like {
|
|
|
|
// Like button after I've liked
|
|
|
|
.d-icon {
|
|
|
|
color: var(--love);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
&[disabled] {
|
|
|
|
// Disabled like button
|
|
|
|
cursor: not-allowed;
|
|
|
|
}
|
|
|
|
&.button-count {
|
|
|
|
// Like count button
|
|
|
|
height: 100%; // sometimes the font might be shorter than the icon
|
|
|
|
&:not(.my-likes) {
|
|
|
|
padding-right: 0;
|
|
|
|
}
|
|
|
|
+ .toggle-like {
|
|
|
|
// Like button when like count is present
|
|
|
|
padding-left: 0.45em;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
a,
|
|
|
|
button {
|
|
|
|
color: var(--primary-low-mid-or-secondary-high);
|
|
|
|
.d-icon {
|
|
|
|
opacity: 1;
|
|
|
|
}
|
2024-05-21 23:58:15 +08:00
|
|
|
display: inline-flex;
|
2022-01-04 22:44:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
button {
|
|
|
|
flex: 0 1 auto;
|
|
|
|
font-size: var(--font-up-1);
|
|
|
|
padding: 8px 10px;
|
|
|
|
vertical-align: top;
|
|
|
|
background: transparent;
|
|
|
|
border: none;
|
2023-06-16 22:25:58 +08:00
|
|
|
.d-icon {
|
|
|
|
// this avoids an issue where hovering off the icon
|
|
|
|
// removes the .d-hover class from the button prematurely
|
|
|
|
pointer-events: none;
|
|
|
|
}
|
2022-07-12 02:20:40 +08:00
|
|
|
&.d-hover,
|
2022-01-04 22:44:54 +08:00
|
|
|
&:focus,
|
|
|
|
&:active {
|
|
|
|
outline: none;
|
|
|
|
background: var(--primary-low);
|
|
|
|
color: var(--primary);
|
|
|
|
}
|
|
|
|
&.hidden {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
&.admin {
|
|
|
|
position: relative;
|
|
|
|
}
|
|
|
|
&.delete.d-hover,
|
2023-06-16 22:25:58 +08:00
|
|
|
&.delete:active,
|
2022-01-04 22:44:54 +08:00
|
|
|
&.delete:focus {
|
|
|
|
background: var(--danger);
|
|
|
|
color: var(--secondary);
|
|
|
|
.d-icon {
|
|
|
|
color: var(--secondary);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
&.bookmarked .d-icon {
|
|
|
|
color: var(--tertiary);
|
|
|
|
}
|
|
|
|
&.create {
|
|
|
|
margin-right: 0;
|
|
|
|
color: var(--primary-high-or-secondary-low);
|
|
|
|
.d-icon {
|
|
|
|
color: var(--primary-high-or-secondary-low);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.show-replies {
|
|
|
|
font-size: var(--font-up-1);
|
|
|
|
font-size: inherit;
|
|
|
|
padding: 10px;
|
|
|
|
color: var(--primary-medium);
|
|
|
|
&:hover,
|
|
|
|
&:focus {
|
|
|
|
outline: none;
|
|
|
|
color: var(--primary);
|
|
|
|
background: var(--primary-low);
|
|
|
|
}
|
|
|
|
.d-icon {
|
|
|
|
font-size: var(--font-down-1);
|
|
|
|
}
|
|
|
|
.d-button-label + .d-icon {
|
|
|
|
margin-left: 0.45em;
|
|
|
|
margin-right: 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-21 22:41:04 +08:00
|
|
|
.deleted {
|
|
|
|
.regular > .cooked {
|
|
|
|
background-color: var(--danger-low-mid);
|
|
|
|
}
|
|
|
|
.topic-meta-data:not(.embedded-reply) {
|
|
|
|
color: var(--danger);
|
|
|
|
|
|
|
|
.post-info a,
|
|
|
|
a {
|
|
|
|
color: currentColor;
|
|
|
|
}
|
|
|
|
|
|
|
|
.d-icon {
|
|
|
|
color: currentColor;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
nav.post-controls {
|
|
|
|
color: var(--danger);
|
|
|
|
|
|
|
|
.show-replies,
|
|
|
|
button.reply.create {
|
|
|
|
color: var(--danger);
|
|
|
|
.d-icon {
|
|
|
|
color: var(--danger);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.widget-button {
|
|
|
|
&:hover {
|
|
|
|
color: currentColor;
|
|
|
|
background: var(--danger-low);
|
|
|
|
.d-icon {
|
|
|
|
color: currentColor;
|
|
|
|
}
|
|
|
|
}
|
2022-03-29 23:58:50 +08:00
|
|
|
&[disabled]:hover {
|
|
|
|
background-color: transparent;
|
|
|
|
cursor: not-allowed;
|
|
|
|
}
|
2021-07-21 22:41:04 +08:00
|
|
|
&.fade-out {
|
|
|
|
opacity: 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.d-icon {
|
|
|
|
color: var(--danger);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.post-action {
|
|
|
|
color: var(--danger);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-09 02:21:16 +08:00
|
|
|
@keyframes heartBump {
|
|
|
|
0% {
|
|
|
|
transform: scale(1);
|
|
|
|
}
|
|
|
|
50% {
|
|
|
|
transform: scale(1.5);
|
|
|
|
}
|
|
|
|
100% {
|
|
|
|
transform: scale(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.has-like .d-icon.heart-animation {
|
2023-09-15 05:31:43 +08:00
|
|
|
@media (prefers-reduced-motion: no-preference) {
|
|
|
|
animation: heartBump 0.4s;
|
|
|
|
}
|
2021-11-09 02:21:16 +08:00
|
|
|
}
|
|
|
|
|
2021-12-16 02:13:06 +08:00
|
|
|
@keyframes slideout {
|
|
|
|
from {
|
|
|
|
max-height: 60px;
|
|
|
|
}
|
|
|
|
|
|
|
|
to {
|
|
|
|
max-height: 9999px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-01 06:53:22 +08:00
|
|
|
// we use aside to hold expandable quotes (versus, say, static blockquotes)
|
|
|
|
aside.quote {
|
|
|
|
margin-top: 1em;
|
|
|
|
margin-bottom: 1em;
|
2014-09-14 14:02:46 +08:00
|
|
|
|
|
|
|
.title {
|
2015-08-20 01:27:17 +08:00
|
|
|
@include post-aside;
|
|
|
|
|
2020-08-04 10:57:10 +08:00
|
|
|
color: var(--primary-high-or-secondary-low);
|
2024-05-22 01:13:38 +08:00
|
|
|
padding: 0.8em 0.8em 0 0.8em;
|
2015-05-22 17:11:18 +08:00
|
|
|
// blockquote is underneath this and has top margin
|
2018-06-08 17:49:31 +08:00
|
|
|
.avatar {
|
2024-05-22 01:13:38 +08:00
|
|
|
margin-right: 0.5em;
|
2018-06-08 17:49:31 +08:00
|
|
|
}
|
|
|
|
img {
|
2024-05-22 01:13:38 +08:00
|
|
|
margin-top: -0.26em;
|
2018-06-08 17:49:31 +08:00
|
|
|
}
|
2014-12-24 15:23:47 +08:00
|
|
|
@include unselectable;
|
2014-09-14 14:02:46 +08:00
|
|
|
}
|
|
|
|
|
2014-07-01 15:19:56 +08:00
|
|
|
// blockquote is docked within aside for content
|
|
|
|
blockquote {
|
|
|
|
margin-top: 0;
|
2021-12-16 02:13:06 +08:00
|
|
|
.expanded-quote {
|
|
|
|
overflow: hidden;
|
2023-09-15 05:31:43 +08:00
|
|
|
@media (prefers-reduced-motion: no-preference) {
|
|
|
|
animation: slideout 1s ease-in-out;
|
|
|
|
}
|
2021-12-16 02:13:06 +08:00
|
|
|
&.icon-only {
|
|
|
|
text-align: center;
|
|
|
|
font-size: var(--font-up-4);
|
|
|
|
padding-top: 0.5em;
|
|
|
|
padding-bottom: 0.5em;
|
|
|
|
color: var(--primary-medium);
|
|
|
|
}
|
|
|
|
}
|
2014-07-01 15:19:56 +08:00
|
|
|
}
|
2014-07-01 06:53:22 +08:00
|
|
|
}
|
|
|
|
|
2018-06-08 17:49:31 +08:00
|
|
|
.quote-controls,
|
|
|
|
.quote-controls .d-icon {
|
2020-08-04 10:57:10 +08:00
|
|
|
color: var(--primary-low-mid-or-secondary-high);
|
2014-09-14 14:02:46 +08:00
|
|
|
}
|
|
|
|
|
2021-02-15 19:31:35 +08:00
|
|
|
.quote-controls {
|
|
|
|
.quote-toggle {
|
|
|
|
padding: 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-30 17:06:13 +08:00
|
|
|
.cooked .highlight {
|
2020-08-04 10:57:10 +08:00
|
|
|
background-color: var(--tertiary-low);
|
2024-05-22 01:13:38 +08:00
|
|
|
padding: 0.15em;
|
|
|
|
margin: -0.15em;
|
2014-06-25 08:39:55 +08:00
|
|
|
}
|
|
|
|
|
2019-03-06 17:20:45 +08:00
|
|
|
.post-ignored {
|
|
|
|
font-style: italic;
|
|
|
|
}
|
|
|
|
|
2014-06-25 08:39:55 +08:00
|
|
|
.post-action {
|
2020-08-04 10:57:10 +08:00
|
|
|
color: var(--primary-medium);
|
2018-06-08 17:49:31 +08:00
|
|
|
.undo-action,
|
|
|
|
.act-action {
|
2014-06-25 08:39:55 +08:00
|
|
|
margin-left: 5px;
|
|
|
|
}
|
|
|
|
}
|
2014-07-22 14:52:26 +08:00
|
|
|
|
2024-03-25 20:35:52 +08:00
|
|
|
.small-user-list {
|
|
|
|
.small-user-list-content {
|
|
|
|
display: flex;
|
2024-03-29 01:40:23 +08:00
|
|
|
flex-wrap: wrap;
|
2024-03-25 20:35:52 +08:00
|
|
|
align-items: flex-start;
|
|
|
|
justify-content: flex-end;
|
|
|
|
}
|
|
|
|
|
|
|
|
.unknown {
|
|
|
|
display: inline-block;
|
|
|
|
background-color: var(--primary-low);
|
|
|
|
width: 25px;
|
|
|
|
height: 25px;
|
|
|
|
border-radius: 50%;
|
|
|
|
vertical-align: middle;
|
|
|
|
margin-right: 0.25em;
|
|
|
|
}
|
2020-06-19 22:44:21 +08:00
|
|
|
}
|
|
|
|
|
2014-07-22 14:52:26 +08:00
|
|
|
.post-hidden {
|
2019-12-19 00:34:33 +08:00
|
|
|
.topic-avatar,
|
|
|
|
.cooked,
|
|
|
|
.topic-meta-data,
|
|
|
|
.post-actions {
|
|
|
|
opacity: 0.5;
|
|
|
|
}
|
2014-09-04 11:16:19 +08:00
|
|
|
}
|
|
|
|
|
2016-07-12 15:03:42 +08:00
|
|
|
.topic-post.staged {
|
|
|
|
opacity: 0.4;
|
|
|
|
}
|
|
|
|
|
2014-09-04 11:16:19 +08:00
|
|
|
.quote-controls {
|
|
|
|
float: right;
|
2017-10-07 03:27:02 +08:00
|
|
|
display: flex;
|
2018-12-12 10:17:31 +08:00
|
|
|
align-items: center;
|
|
|
|
a {
|
|
|
|
margin-left: 0.3em;
|
2014-09-04 11:16:19 +08:00
|
|
|
}
|
|
|
|
}
|
2014-09-08 04:55:31 +08:00
|
|
|
|
|
|
|
.quote-button {
|
2021-09-15 23:10:30 +08:00
|
|
|
flex-direction: column;
|
2014-09-08 04:55:31 +08:00
|
|
|
|
2020-07-18 02:44:31 +08:00
|
|
|
&.visible {
|
2021-09-15 23:10:30 +08:00
|
|
|
display: flex;
|
|
|
|
}
|
|
|
|
|
|
|
|
.buttons {
|
|
|
|
display: flex;
|
2024-07-17 03:17:44 +08:00
|
|
|
flex-wrap: wrap;
|
|
|
|
@media screen and (max-width: 420px) {
|
|
|
|
flex-direction: column;
|
|
|
|
align-items: flex-start;
|
|
|
|
|
|
|
|
.btn,
|
|
|
|
.ai-post-helper {
|
|
|
|
width: 100%;
|
|
|
|
justify-content: flex-start;
|
|
|
|
}
|
|
|
|
}
|
2021-09-15 23:10:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
.extra {
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
width: 100%;
|
|
|
|
}
|
|
|
|
|
|
|
|
.fast-edit-container {
|
|
|
|
display: flex;
|
2021-09-22 15:34:29 +08:00
|
|
|
padding: 0.5em;
|
|
|
|
padding-top: 0;
|
2021-09-15 23:10:30 +08:00
|
|
|
flex-direction: column;
|
|
|
|
align-items: flex-start;
|
|
|
|
|
|
|
|
#fast-edit-input {
|
|
|
|
margin: 0;
|
|
|
|
width: 300px;
|
|
|
|
height: 90px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.save-fast-edit {
|
2021-09-22 15:34:29 +08:00
|
|
|
margin-top: 0.5em;
|
2021-09-15 23:10:30 +08:00
|
|
|
}
|
2014-09-08 04:55:31 +08:00
|
|
|
}
|
|
|
|
|
2020-07-18 02:44:31 +08:00
|
|
|
.insert-quote + .quote-sharing {
|
2020-07-29 21:09:37 +08:00
|
|
|
border-left: 1px solid rgba(255, 255, 255, 0.3);
|
2020-07-18 02:44:31 +08:00
|
|
|
}
|
|
|
|
|
2023-01-18 01:28:33 +08:00
|
|
|
.btn-flat {
|
DEV: FloatKit (#23650)
This PR introduces three new concepts to Discourse codebase through an addon called "FloatKit":
- menu
- tooltip
- toast
## Tooltips
### Component
Simple cases can be express with an API similar to DButton:
```hbs
<DTooltip
@Label={{i18n "foo.bar"}}
@ICON="check"
@content="Something"
/>
```
More complex cases can use blocks:
```hbs
<DTooltip>
<:trigger>
{{d-icon "check"}}
<span>{{i18n "foo.bar"}}</span>
</:trigger>
<:content>
Something
</:content>
</DTooltip>
```
### Service
You can manually show a tooltip using the `tooltip` service:
```javascript
const tooltipInstance = await this.tooltip.show(
document.querySelector(".my-span"),
options
)
// and later manual close or destroy it
tooltipInstance.close();
tooltipInstance.destroy();
// you can also just close any open tooltip through the service
this.tooltip.close();
```
The service also allows you to register event listeners on a trigger, it removes the need for you to manage open/close of a tooltip started through the service:
```javascript
const tooltipInstance = this.tooltip.register(
document.querySelector(".my-span"),
options
)
// when done you can destroy the instance to remove the listeners
tooltipInstance.destroy();
```
Note that the service also allows you to use a custom component as content which will receive `@data` and `@close` as args:
```javascript
const tooltipInstance = await this.tooltip.show(
document.querySelector(".my-span"),
{
component: MyComponent,
data: { foo: 1 }
}
)
```
## Menus
Menus are very similar to tooltips and provide the same kind of APIs:
### Component
```hbs
<DMenu @ICON="plus" @Label={{i18n "foo.bar"}}>
<ul>
<li>Foo</li>
<li>Bat</li>
<li>Baz</li>
</ul>
</DMenu>
```
They also support blocks:
```hbs
<DMenu>
<:trigger>
{{d-icon "plus"}}
<span>{{i18n "foo.bar"}}</span>
</:trigger>
<:content>
<ul>
<li>Foo</li>
<li>Bat</li>
<li>Baz</li>
</ul>
</:content>
</DMenu>
```
### Service
You can manually show a menu using the `menu` service:
```javascript
const menuInstance = await this.menu.show(
document.querySelector(".my-span"),
options
)
// and later manual close or destroy it
menuInstance.close();
menuInstance.destroy();
// you can also just close any open tooltip through the service
this.menu.close();
```
The service also allows you to register event listeners on a trigger, it removes the need for you to manage open/close of a tooltip started through the service:
```javascript
const menuInstance = this.menu.register(
document.querySelector(".my-span"),
options
)
// when done you can destroy the instance to remove the listeners
menuInstance.destroy();
```
Note that the service also allows you to use a custom component as content which will receive `@data` and `@close` as args:
```javascript
const menuInstance = await this.menu.show(
document.querySelector(".my-span"),
{
component: MyComponent,
data: { foo: 1 }
}
)
```
## Toasts
Interacting with toasts is made only through the `toasts` service.
A default component is provided (DDefaultToast) and can be used through dedicated service methods:
- this.toasts.success({ ... });
- this.toasts.warning({ ... });
- this.toasts.info({ ... });
- this.toasts.error({ ... });
- this.toasts.default({ ... });
```javascript
this.toasts.success({
data: {
title: "Foo",
message: "Bar",
actions: [
{
label: "Ok",
class: "btn-primary",
action: (componentArgs) => {
// eslint-disable-next-line no-alert
alert("Closing toast:" + componentArgs.data.title);
componentArgs.close();
},
}
]
},
});
```
You can also provide your own component:
```javascript
this.toasts.show(MyComponent, {
autoClose: false,
class: "foo",
data: { baz: 1 },
})
```
Co-authored-by: Martin Brennan <mjrbrennan@gmail.com>
Co-authored-by: Isaac Janzen <50783505+janzenisaac@users.noreply.github.com>
Co-authored-by: David Taylor <david@taylorhq.com>
Co-authored-by: Jarek Radosz <jradosz@gmail.com>
2023-09-26 19:39:52 +08:00
|
|
|
&:hover {
|
|
|
|
.d-icon {
|
|
|
|
color: var(--tertiary);
|
2023-01-18 01:28:33 +08:00
|
|
|
}
|
|
|
|
}
|
2023-11-29 08:43:52 +08:00
|
|
|
|
|
|
|
.d-button-label {
|
|
|
|
white-space: nowrap;
|
|
|
|
}
|
2023-01-18 01:28:33 +08:00
|
|
|
}
|
|
|
|
|
2020-07-18 02:44:31 +08:00
|
|
|
.quote-sharing {
|
|
|
|
vertical-align: middle;
|
|
|
|
display: inline-flex;
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
.btn {
|
|
|
|
display: inline-flex;
|
|
|
|
align-items: center;
|
|
|
|
}
|
|
|
|
|
|
|
|
.quote-share-label {
|
|
|
|
opacity: 1;
|
2023-01-18 01:28:33 +08:00
|
|
|
transition: opacity 0.3s ease-in-out;
|
2020-07-18 02:44:31 +08:00
|
|
|
}
|
|
|
|
|
2023-01-18 01:28:33 +08:00
|
|
|
&:hover {
|
|
|
|
.quote-share-label {
|
|
|
|
background: transparent;
|
|
|
|
opacity: 0;
|
|
|
|
max-width: 0;
|
|
|
|
padding: 0;
|
|
|
|
overflow: hidden;
|
|
|
|
}
|
|
|
|
.quote-share-label + .quote-share-buttons {
|
|
|
|
max-width: 10em;
|
|
|
|
opacity: 1;
|
|
|
|
transition: opacity 0.3s ease-in-out;
|
|
|
|
}
|
2023-04-04 01:27:32 +08:00
|
|
|
// this pseudo element creates a transition buffer zone
|
2023-01-18 01:28:33 +08:00
|
|
|
// without it, the width change on hover can cause transition jitter
|
|
|
|
// the width is roughly wide enough to cover long translations of "share"
|
|
|
|
&:after {
|
|
|
|
content: "";
|
|
|
|
position: absolute;
|
|
|
|
display: block;
|
|
|
|
background: transparent;
|
|
|
|
height: 100%;
|
|
|
|
padding: 0.5em 4em;
|
|
|
|
z-index: -1; // below the buttons
|
|
|
|
}
|
2020-07-18 02:44:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
.quote-share-label + .quote-share-buttons {
|
|
|
|
opacity: 0;
|
|
|
|
overflow: hidden;
|
|
|
|
max-width: 0;
|
|
|
|
display: inline-flex;
|
2023-01-18 01:28:33 +08:00
|
|
|
transition: opacity 0.3s ease-in-out;
|
2020-07-18 02:44:31 +08:00
|
|
|
}
|
2014-09-08 04:55:31 +08:00
|
|
|
}
|
2014-09-10 21:25:31 +08:00
|
|
|
}
|
|
|
|
|
2021-12-09 08:38:39 +08:00
|
|
|
.post-avatar,
|
2018-06-08 17:49:31 +08:00
|
|
|
.topic-avatar,
|
|
|
|
.user-card-avatar {
|
2016-08-18 23:18:18 +08:00
|
|
|
position: relative;
|
|
|
|
}
|
|
|
|
|
2018-06-08 17:49:31 +08:00
|
|
|
.topic-avatar,
|
|
|
|
.avatar-flair-preview,
|
|
|
|
.user-card-avatar,
|
2018-12-17 17:44:34 +08:00
|
|
|
.user-profile-avatar,
|
2020-03-31 09:40:11 +08:00
|
|
|
.user-image,
|
|
|
|
.latest-topic-list-item {
|
2017-01-19 00:37:43 +08:00
|
|
|
.avatar-flair {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
justify-content: center;
|
|
|
|
background-repeat: no-repeat;
|
|
|
|
background-position: center;
|
|
|
|
position: absolute;
|
|
|
|
bottom: 0;
|
|
|
|
right: -6px;
|
|
|
|
}
|
2016-09-16 04:15:08 +08:00
|
|
|
}
|
2018-06-08 17:49:31 +08:00
|
|
|
.topic-avatar .avatar-flair,
|
|
|
|
.avatar-flair-preview .avatar-flair,
|
2018-12-17 17:44:34 +08:00
|
|
|
.collapsed-info .user-profile-avatar .avatar-flair,
|
2020-03-31 09:40:11 +08:00
|
|
|
.user-image .avatar-flair,
|
|
|
|
.latest-topic-list-item .avatar-flair {
|
2016-09-16 04:15:08 +08:00
|
|
|
background-size: 20px 20px;
|
|
|
|
width: 20px;
|
|
|
|
height: 20px;
|
2016-08-17 00:34:04 +08:00
|
|
|
&.rounded {
|
|
|
|
background-size: 18px 18px;
|
|
|
|
border-radius: 12px;
|
|
|
|
width: 24px;
|
|
|
|
height: 24px;
|
2016-08-18 23:18:18 +08:00
|
|
|
bottom: -2px;
|
2016-08-17 00:34:04 +08:00
|
|
|
right: -8px;
|
|
|
|
}
|
|
|
|
}
|
2018-06-08 17:49:31 +08:00
|
|
|
.user-card-avatar .avatar-flair,
|
|
|
|
.user-profile-avatar .avatar-flair {
|
2016-09-16 04:15:08 +08:00
|
|
|
background-size: 40px 40px;
|
|
|
|
width: 40px;
|
|
|
|
height: 40px;
|
|
|
|
&.rounded {
|
|
|
|
background-size: 30px 30px;
|
|
|
|
border-radius: 24px;
|
|
|
|
width: 40px;
|
|
|
|
height: 40px;
|
|
|
|
bottom: -2px;
|
|
|
|
right: -4px;
|
|
|
|
}
|
2016-09-20 02:04:51 +08:00
|
|
|
.fa {
|
2022-10-12 21:31:59 +08:00
|
|
|
font-size: var(--font-up-4);
|
2016-09-20 02:04:51 +08:00
|
|
|
}
|
2016-09-16 04:15:08 +08:00
|
|
|
}
|
2018-01-13 06:27:38 +08:00
|
|
|
|
2015-08-19 06:51:50 +08:00
|
|
|
.topic-body {
|
2016-02-22 17:17:50 +08:00
|
|
|
// this is necessary for ANYTHING that extends past the right edge of
|
|
|
|
// the post body, such as an image in a deeply nested list, image in
|
|
|
|
// a deeply nested blockquote, and so on.. you get the idea.
|
2018-10-05 22:51:27 +08:00
|
|
|
.cooked {
|
|
|
|
overflow: hidden;
|
2021-06-08 16:58:18 +08:00
|
|
|
|
|
|
|
.button-wrapper {
|
|
|
|
display: none;
|
|
|
|
}
|
2018-10-05 22:51:27 +08:00
|
|
|
}
|
2020-03-24 17:12:52 +08:00
|
|
|
.group-request {
|
2020-08-04 10:57:10 +08:00
|
|
|
border-top: 1px solid var(--primary-low);
|
2020-03-24 17:12:52 +08:00
|
|
|
padding-top: 0.5em;
|
|
|
|
}
|
2023-12-12 00:02:48 +08:00
|
|
|
}
|
2023-12-09 00:06:21 +08:00
|
|
|
|
2023-12-12 00:02:48 +08:00
|
|
|
@media (prefers-reduced-motion: no-preference) {
|
2024-01-03 05:53:40 +08:00
|
|
|
.topic-body.highlighted,
|
2023-12-12 00:02:48 +08:00
|
|
|
.small-action-desc.highlighted {
|
|
|
|
animation: background-fade-highlight 2.5s ease-out;
|
|
|
|
}
|
|
|
|
// Disable animation so deleted status is visible immediately
|
2024-01-03 05:53:40 +08:00
|
|
|
.deleted .topic-body.highlighted {
|
2023-12-12 00:02:48 +08:00
|
|
|
animation: none;
|
2015-08-19 06:51:50 +08:00
|
|
|
}
|
2023-12-09 00:06:21 +08:00
|
|
|
}
|
|
|
|
|
2023-12-12 00:02:48 +08:00
|
|
|
.small-action-desc,
|
|
|
|
.topic-body {
|
|
|
|
&:focus-visible {
|
2023-12-09 00:06:21 +08:00
|
|
|
outline: none;
|
|
|
|
}
|
2015-08-19 06:51:50 +08:00
|
|
|
}
|
2014-09-10 21:25:31 +08:00
|
|
|
|
|
|
|
.post-info {
|
2018-06-25 22:50:16 +08:00
|
|
|
flex: 0 0 auto;
|
|
|
|
margin-right: 0.5em;
|
2018-06-21 03:39:36 +08:00
|
|
|
|
2018-06-25 22:50:16 +08:00
|
|
|
&.post-date {
|
|
|
|
margin-right: 0;
|
|
|
|
}
|
2018-06-08 17:49:31 +08:00
|
|
|
&.via-email,
|
|
|
|
&.whisper,
|
|
|
|
&.post-locked {
|
2017-07-28 03:03:41 +08:00
|
|
|
.d-icon {
|
2022-10-12 21:31:59 +08:00
|
|
|
font-size: var(--font-0);
|
2014-09-10 21:25:31 +08:00
|
|
|
}
|
|
|
|
}
|
2017-01-16 15:54:51 +08:00
|
|
|
|
2017-09-12 21:37:47 +08:00
|
|
|
.wiki,
|
|
|
|
.last-wiki-edit {
|
2020-08-04 10:57:10 +08:00
|
|
|
color: var(--wiki);
|
2014-09-10 21:25:31 +08:00
|
|
|
}
|
2017-01-16 15:54:51 +08:00
|
|
|
|
2014-09-10 21:25:31 +08:00
|
|
|
&.via-email {
|
2020-08-04 10:57:10 +08:00
|
|
|
color: var(--primary-low-mid-or-secondary-high);
|
2014-09-10 21:25:31 +08:00
|
|
|
}
|
2014-10-18 01:28:23 +08:00
|
|
|
&.raw-email {
|
|
|
|
cursor: pointer;
|
|
|
|
}
|
2021-01-23 00:09:39 +08:00
|
|
|
&.edits {
|
|
|
|
.widget-button {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
.d-button-label {
|
|
|
|
order: 0;
|
|
|
|
padding-right: 0.25em;
|
2021-01-23 09:31:01 +08:00
|
|
|
color: var(--primary-med-or-secondary-med);
|
2021-01-23 00:09:39 +08:00
|
|
|
}
|
|
|
|
.d-icon {
|
|
|
|
order: 1;
|
2021-01-28 09:38:15 +08:00
|
|
|
color: var(--primary-med-or-secondary-med);
|
2021-01-23 09:31:01 +08:00
|
|
|
}
|
|
|
|
.discourse-no-touch & {
|
|
|
|
&:hover {
|
|
|
|
.d-button-label {
|
|
|
|
color: var(--primary-high);
|
|
|
|
}
|
|
|
|
.d-icon {
|
|
|
|
color: var(--primary-high);
|
|
|
|
}
|
|
|
|
}
|
2021-01-23 00:09:39 +08:00
|
|
|
}
|
2021-04-21 09:03:47 +08:00
|
|
|
&:focus {
|
|
|
|
@include default-focus;
|
|
|
|
background: transparent;
|
|
|
|
}
|
2021-01-23 00:09:39 +08:00
|
|
|
}
|
|
|
|
}
|
2014-09-10 21:25:31 +08:00
|
|
|
}
|
2014-09-13 13:58:15 +08:00
|
|
|
|
|
|
|
pre {
|
2023-10-17 21:55:02 +08:00
|
|
|
max-height: 2000px;
|
2014-09-13 13:58:15 +08:00
|
|
|
code {
|
2015-06-26 11:30:32 +08:00
|
|
|
word-wrap: normal;
|
2014-09-13 13:58:15 +08:00
|
|
|
display: block;
|
2019-01-10 01:36:51 +08:00
|
|
|
padding: 0.5em;
|
2020-08-04 10:57:10 +08:00
|
|
|
color: var(--primary);
|
|
|
|
background: var(--blend-primary-secondary-5);
|
2014-09-13 13:58:15 +08:00
|
|
|
max-height: 500px;
|
|
|
|
}
|
2021-11-22 08:43:03 +08:00
|
|
|
|
|
|
|
.bidi-warning,
|
|
|
|
.bidi-warning span {
|
|
|
|
font-style: normal;
|
|
|
|
background-color: var(--highlight);
|
|
|
|
color: var(--danger);
|
|
|
|
cursor: help;
|
|
|
|
}
|
2014-09-13 13:58:15 +08:00
|
|
|
}
|
|
|
|
|
2022-03-01 06:37:24 +08:00
|
|
|
.codeblock-buttons {
|
2020-04-21 21:02:13 +08:00
|
|
|
display: block;
|
|
|
|
position: relative;
|
|
|
|
overflow: visible;
|
|
|
|
|
2022-03-01 06:37:24 +08:00
|
|
|
.codeblock-button-wrapper {
|
2020-04-21 21:02:13 +08:00
|
|
|
position: absolute;
|
2022-03-01 06:37:24 +08:00
|
|
|
display: flex;
|
|
|
|
}
|
|
|
|
|
|
|
|
.copy-cmd,
|
|
|
|
.fullscreen-cmd {
|
|
|
|
@include unselectable;
|
|
|
|
top: 0;
|
2020-04-21 21:02:13 +08:00
|
|
|
min-height: 0;
|
2022-10-12 21:31:59 +08:00
|
|
|
font-size: var(--font-down-2);
|
2020-04-21 21:02:13 +08:00
|
|
|
min-height: 0;
|
2022-10-12 21:31:59 +08:00
|
|
|
font-size: var(--font-down-2);
|
2021-03-17 10:22:35 +08:00
|
|
|
opacity: 0.7;
|
2023-03-01 00:54:24 +08:00
|
|
|
cursor: pointer;
|
2020-04-21 21:02:13 +08:00
|
|
|
|
2022-03-01 06:37:24 +08:00
|
|
|
&.action-complete {
|
2023-03-01 00:54:24 +08:00
|
|
|
cursor: auto;
|
2020-04-21 21:02:13 +08:00
|
|
|
.d-icon {
|
2020-08-04 10:57:10 +08:00
|
|
|
color: var(--tertiary);
|
2020-04-21 21:02:13 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.d-icon {
|
|
|
|
pointer-events: none;
|
|
|
|
margin-right: 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-08 17:49:31 +08:00
|
|
|
kbd {
|
2020-06-01 21:00:56 +08:00
|
|
|
align-items: center;
|
2020-08-04 10:57:10 +08:00
|
|
|
border: 1px solid var(--primary-low-mid);
|
|
|
|
background: var(--primary-very-low);
|
2020-06-01 21:00:56 +08:00
|
|
|
border-bottom-width: 2px;
|
|
|
|
border-radius: 3px;
|
|
|
|
box-sizing: border-box;
|
|
|
|
display: inline-flex;
|
2022-12-13 02:53:48 +08:00
|
|
|
gap: 0 0.5em; // space between text and images/emoji
|
2022-10-12 21:31:59 +08:00
|
|
|
font-size: var(--font-down-1);
|
2020-06-01 21:00:56 +08:00
|
|
|
justify-content: center;
|
2022-10-12 22:05:42 +08:00
|
|
|
line-height: var(--line-height-large);
|
2020-06-01 21:00:56 +08:00
|
|
|
margin: 0 0.15em;
|
|
|
|
min-width: 24px;
|
|
|
|
padding: 0.15em 0.6em;
|
2014-09-13 13:58:15 +08:00
|
|
|
|
2015-03-03 00:00:05 +08:00
|
|
|
// don't allow more than 3 nested elements to prevent FF from crashing
|
|
|
|
// cf. http://what.thedailywtf.com/t/nested-elements/7927
|
|
|
|
// 3 levels are needed to prevent highlighted words being hidden
|
|
|
|
// cf. https://meta.discourse.org/t/word-disappears-when-searched-and-in-details-summary-kbd-b/25741
|
2018-06-08 17:49:31 +08:00
|
|
|
* * * {
|
|
|
|
display: none;
|
|
|
|
}
|
2014-09-23 00:55:13 +08:00
|
|
|
}
|
2015-01-12 18:24:06 +08:00
|
|
|
|
|
|
|
// we assume blockquotes have their own margins, so all blockquotes
|
|
|
|
// will remove margins from first (top) and last (bottom) child elements
|
|
|
|
blockquote > *:first-child {
|
|
|
|
margin-top: 0 !important;
|
|
|
|
}
|
|
|
|
blockquote > *:last-child {
|
|
|
|
margin-bottom: 0 !important;
|
|
|
|
}
|
2015-06-29 15:47:07 +08:00
|
|
|
|
|
|
|
.gap {
|
2022-10-26 02:45:37 +08:00
|
|
|
padding: 0.25em 0 0.5em
|
|
|
|
calc(var(--topic-avatar-width) + var(--topic-body-width-padding));
|
2020-08-04 10:57:10 +08:00
|
|
|
color: var(--primary-med-or-secondary-high);
|
2015-06-29 15:47:07 +08:00
|
|
|
cursor: pointer;
|
2017-05-06 08:06:13 +08:00
|
|
|
text-transform: uppercase;
|
|
|
|
font-weight: bold;
|
2022-10-12 21:31:59 +08:00
|
|
|
font-size: var(--font-down-1);
|
2015-06-29 15:47:07 +08:00
|
|
|
}
|
2015-07-04 02:57:07 +08:00
|
|
|
|
2019-08-27 20:09:00 +08:00
|
|
|
.who-liked,
|
|
|
|
.who-read {
|
2015-07-10 12:48:44 +08:00
|
|
|
transition: height 0.5s;
|
2015-07-04 02:57:07 +08:00
|
|
|
a {
|
|
|
|
margin: 0 0.25em 0.5em 0;
|
|
|
|
display: inline-block;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-04 04:29:20 +08:00
|
|
|
.reviewable .post-body,
|
2018-06-08 17:49:31 +08:00
|
|
|
.cooked table,
|
|
|
|
.d-editor-preview table {
|
2015-07-20 14:56:32 +08:00
|
|
|
thead {
|
|
|
|
th {
|
|
|
|
text-align: left;
|
|
|
|
padding-bottom: 2px;
|
2019-02-27 10:40:17 +08:00
|
|
|
font-weight: bold;
|
2020-08-04 10:57:10 +08:00
|
|
|
color: var(--primary);
|
2015-07-20 14:56:32 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-27 10:40:17 +08:00
|
|
|
td {
|
|
|
|
padding: 3px 3px 3px 0.5em;
|
2015-07-20 14:56:32 +08:00
|
|
|
}
|
|
|
|
}
|
2015-07-08 13:10:53 +08:00
|
|
|
|
2015-07-28 01:05:31 +08:00
|
|
|
.small-action {
|
2018-02-09 06:04:29 +08:00
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
2022-10-26 02:45:37 +08:00
|
|
|
|
2023-12-09 00:06:21 +08:00
|
|
|
&:focus-visible {
|
|
|
|
outline: none;
|
|
|
|
}
|
|
|
|
|
2022-12-05 22:54:29 +08:00
|
|
|
&.deleted {
|
2024-05-31 04:09:45 +08:00
|
|
|
.topic-avatar,
|
|
|
|
.small-action-desc {
|
|
|
|
background-color: var(--danger-low-mid);
|
|
|
|
}
|
2022-12-05 22:54:29 +08:00
|
|
|
}
|
|
|
|
|
2022-10-26 02:45:37 +08:00
|
|
|
.topic-avatar,
|
|
|
|
.small-action-desc {
|
|
|
|
border-top: 1px solid var(--primary-low);
|
|
|
|
}
|
|
|
|
|
2015-07-28 01:05:31 +08:00
|
|
|
.topic-avatar {
|
2022-12-05 22:54:29 +08:00
|
|
|
display: flex;
|
|
|
|
align-self: stretch;
|
2019-01-22 06:57:47 +08:00
|
|
|
flex: 0 0 auto;
|
2022-12-05 22:54:29 +08:00
|
|
|
margin: 0;
|
|
|
|
padding-top: 1em;
|
2022-10-26 02:45:37 +08:00
|
|
|
width: var(--topic-avatar-width);
|
2022-12-05 22:54:29 +08:00
|
|
|
justify-content: center;
|
2024-05-31 04:09:45 +08:00
|
|
|
height: auto;
|
2018-11-27 05:49:57 +08:00
|
|
|
.d-icon {
|
2022-12-05 22:54:29 +08:00
|
|
|
font-size: var(--font-up-3);
|
2022-10-26 02:45:37 +08:00
|
|
|
width: var(--topic-avatar-width);
|
2020-08-04 10:57:10 +08:00
|
|
|
color: var(--primary-low-mid);
|
2015-07-28 01:05:31 +08:00
|
|
|
}
|
|
|
|
}
|
2017-11-15 21:20:16 +08:00
|
|
|
|
2015-07-28 01:05:31 +08:00
|
|
|
.small-action-desc {
|
2022-10-26 02:45:37 +08:00
|
|
|
box-sizing: border-box;
|
2018-04-20 23:42:06 +08:00
|
|
|
display: flex;
|
2018-02-09 06:04:29 +08:00
|
|
|
flex-wrap: wrap;
|
2022-12-05 22:54:29 +08:00
|
|
|
color: var(--primary-700);
|
2022-10-26 02:45:37 +08:00
|
|
|
padding: 1em 0 1em var(--topic-body-width-padding);
|
|
|
|
width: calc(
|
|
|
|
var(--topic-body-width) + (var(--topic-body-width-padding) * 2)
|
|
|
|
);
|
2019-06-06 00:47:49 +08:00
|
|
|
min-width: 0; // Allows flex container to shrink
|
2015-07-30 09:19:30 +08:00
|
|
|
|
2023-08-29 21:24:16 +08:00
|
|
|
.avatar {
|
|
|
|
margin-right: 0.5em;
|
|
|
|
float: left;
|
|
|
|
}
|
|
|
|
|
2022-12-05 22:54:29 +08:00
|
|
|
p {
|
2015-07-28 01:05:31 +08:00
|
|
|
margin: 0;
|
2023-04-18 01:21:13 +08:00
|
|
|
padding: 0.15em 0.5em 0 0;
|
2015-07-28 01:05:31 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-05 22:54:29 +08:00
|
|
|
.small-action-contents {
|
|
|
|
flex: 1 1 auto;
|
|
|
|
}
|
|
|
|
|
|
|
|
.small-action-buttons {
|
|
|
|
margin-left: auto;
|
|
|
|
}
|
|
|
|
|
|
|
|
.small-action-custom-message {
|
|
|
|
flex: 1 1 100%;
|
|
|
|
font-weight: normal;
|
|
|
|
margin-top: 0.5em;
|
|
|
|
word-break: break-word;
|
|
|
|
min-width: 0; // Allows content like oneboxes to shrink
|
|
|
|
color: var(--primary);
|
|
|
|
p {
|
|
|
|
margin-bottom: 0;
|
2018-02-09 06:04:29 +08:00
|
|
|
}
|
2015-07-28 01:05:31 +08:00
|
|
|
}
|
2021-07-07 12:40:40 +08:00
|
|
|
|
2022-12-05 22:54:29 +08:00
|
|
|
button {
|
|
|
|
background: transparent;
|
|
|
|
font-size: var(--font-down-1);
|
|
|
|
.d-icon {
|
|
|
|
color: var(--primary-500);
|
|
|
|
}
|
2021-07-07 12:40:40 +08:00
|
|
|
|
2022-12-05 22:54:29 +08:00
|
|
|
.discourse-no-touch & {
|
|
|
|
&:hover,
|
|
|
|
&:focus {
|
|
|
|
background: var(--primary-200);
|
|
|
|
.d-icon {
|
|
|
|
color: var(--primary);
|
|
|
|
}
|
|
|
|
}
|
2021-07-07 12:40:40 +08:00
|
|
|
}
|
2022-12-05 22:54:29 +08:00
|
|
|
}
|
2021-07-07 12:40:40 +08:00
|
|
|
|
2022-12-05 22:54:29 +08:00
|
|
|
&.topic-post-visited {
|
2021-07-07 12:40:40 +08:00
|
|
|
.topic-post-visited-line {
|
|
|
|
text-align: center;
|
|
|
|
border-bottom: 1px solid var(--danger-medium);
|
2022-12-05 22:54:29 +08:00
|
|
|
z-index: z("base") + 2; // ensures last visit border is on top of post borders
|
|
|
|
line-height: 0;
|
|
|
|
margin: 0;
|
|
|
|
margin-bottom: -1px;
|
|
|
|
color: var(--danger-medium);
|
|
|
|
font-size: var(--font-down-1);
|
2022-10-27 22:59:58 +08:00
|
|
|
width: calc(
|
|
|
|
var(--topic-body-width) + var(--topic-avatar-width) +
|
|
|
|
(var(--topic-body-width-padding) * 2)
|
|
|
|
);
|
2021-07-07 12:40:40 +08:00
|
|
|
.topic-post-visited-message {
|
|
|
|
background-color: var(--secondary);
|
2022-12-05 22:54:29 +08:00
|
|
|
padding: 0 0.5em;
|
2021-07-07 12:40:40 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-07-28 01:05:31 +08:00
|
|
|
}
|
2015-09-13 02:44:20 +08:00
|
|
|
|
|
|
|
.whisper {
|
2016-02-17 01:47:54 +08:00
|
|
|
.post-info.whisper {
|
|
|
|
margin-left: 0.5em;
|
|
|
|
}
|
2015-09-13 02:44:20 +08:00
|
|
|
.topic-body {
|
|
|
|
.cooked {
|
|
|
|
font-style: italic;
|
2020-08-04 10:57:10 +08:00
|
|
|
color: var(--primary-medium);
|
2015-09-13 02:44:20 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-04-18 10:26:43 +08:00
|
|
|
|
2022-11-24 06:35:57 +08:00
|
|
|
a.mention,
|
|
|
|
a.mention-group {
|
2022-11-23 07:17:03 +08:00
|
|
|
// linked
|
FEATURE: Generic hashtag autocomplete lookup and markdown cooking (#18937)
This commit fleshes out and adds functionality for the new `#hashtag` search and
lookup system, still hidden behind the `enable_experimental_hashtag_autocomplete`
feature flag.
**Serverside**
We have two plugin API registration methods that are used to define data sources
(`register_hashtag_data_source`) and hashtag result type priorities depending on
the context (`register_hashtag_type_in_context`). Reading the comments in plugin.rb
should make it clear what these are doing. Reading the `HashtagAutocompleteService`
in full will likely help a lot as well.
Each data source is responsible for providing its own **lookup** and **search**
method that returns hashtag results based on the arguments provided. For example,
the category hashtag data source has to take into account parent categories and
how they relate, and each data source has to define their own icon to use for the
hashtag, and so on.
The `Site` serializer has two new attributes that source data from `HashtagAutocompleteService`.
There is `hashtag_icons` that is just a simple array of all the different icons that
can be used for allowlisting in our markdown pipeline, and there is `hashtag_context_configurations`
that is used to store the type priority orders for each registered context.
When sending emails, we cannot render the SVG icons for hashtags, so
we need to change the HTML hashtags to the normal `#hashtag` text.
**Markdown**
The `hashtag-autocomplete.js` file is where I have added the new `hashtag-autocomplete`
markdown rule, and like all of our rules this is used to cook the raw text on both the clientside
and on the serverside using MiniRacer. Only on the server side do we actually reach out to
the database with the `hashtagLookup` function, on the clientside we just render a plainer
version of the hashtag HTML. Only in the composer preview do we do further lookups based
on this.
This rule is the first one (that I can find) that uses the `currentUser` based on a passed
in `user_id` for guardian checks in markdown rendering code. This is the `last_editor_id`
for both the post and chat message. In some cases we need to cook without a user present,
so the `Discourse.system_user` is used in this case.
**Chat Channels**
This also contains the changes required for chat so that chat channels can be used
as a data source for hashtag searches and lookups. This data source will only be
used when `enable_experimental_hashtag_autocomplete` is `true`, so we don't have
to worry about channel results suddenly turning up.
------
**Known Rough Edges**
- Onebox excerpts will not render the icon svg/use tags, I plan to address that in a follow up PR
- Selecting a hashtag + pressing the Quote button will result in weird behaviour, I plan to address that in a follow up PR
- Mixed hashtag contexts for hashtags without a type suffix will not work correctly, e.g. #ux which is both a category and a channel slug will resolve to a category when used inside a post or within a [chat] transcript in that post. Users can get around this manually by adding the correct suffix, for example ::channel. We may get to this at some point in future
- Icons will not show for the hashtags in emails since SVG support is so terrible in email (this is not likely to be resolved, but still noting for posterity)
- Additional refinements and review fixes wil
2022-11-21 06:37:06 +08:00
|
|
|
@include mention;
|
2024-09-17 21:36:15 +08:00
|
|
|
|
|
|
|
.user-status-message {
|
|
|
|
user-select: none;
|
|
|
|
}
|
2020-02-15 02:02:56 +08:00
|
|
|
}
|
|
|
|
|
2022-12-22 18:15:52 +08:00
|
|
|
.mention .emoji {
|
|
|
|
margin-left: 0.3em;
|
|
|
|
width: 15px;
|
|
|
|
height: 15px;
|
|
|
|
}
|
|
|
|
|
2020-02-19 03:38:13 +08:00
|
|
|
span.mention {
|
2022-11-24 06:35:57 +08:00
|
|
|
// unlinked, invalid mention
|
2022-11-23 07:17:03 +08:00
|
|
|
color: var(--primary-high);
|
2020-02-19 03:38:13 +08:00
|
|
|
}
|
|
|
|
|
2018-11-12 10:04:30 +08:00
|
|
|
.suggested-topics {
|
2017-06-13 03:46:01 +08:00
|
|
|
.topics {
|
|
|
|
padding-bottom: 15px;
|
|
|
|
}
|
|
|
|
}
|
2017-09-01 22:26:13 +08:00
|
|
|
|
2017-11-15 18:30:47 +08:00
|
|
|
.large-image-placeholder {
|
|
|
|
> a {
|
|
|
|
&.link {
|
|
|
|
margin-right: 10px;
|
|
|
|
}
|
|
|
|
|
2018-06-08 17:49:31 +08:00
|
|
|
> * {
|
|
|
|
overflow: hidden;
|
2018-11-27 05:49:57 +08:00
|
|
|
vertical-align: middle;
|
2018-06-08 17:49:31 +08:00
|
|
|
}
|
2017-11-15 18:30:47 +08:00
|
|
|
|
2018-11-27 05:49:57 +08:00
|
|
|
> .d-icon {
|
2020-08-04 10:57:10 +08:00
|
|
|
color: var(--primary-med-or-secondary-med);
|
2017-11-15 18:30:47 +08:00
|
|
|
margin-right: 6px;
|
2022-10-12 21:31:59 +08:00
|
|
|
font-size: var(--font-0);
|
2022-10-12 22:05:42 +08:00
|
|
|
line-height: var(--line-height-large);
|
2017-11-15 18:30:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
> span.url {
|
|
|
|
display: inline-block;
|
|
|
|
max-width: 300px;
|
|
|
|
margin-right: 6px;
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
white-space: nowrap;
|
|
|
|
}
|
|
|
|
|
|
|
|
> span.help {
|
|
|
|
display: inline-block;
|
2020-08-04 10:57:10 +08:00
|
|
|
color: var(--primary-med-or-secondary-med);
|
2022-10-12 21:31:59 +08:00
|
|
|
font-size: var(--font-down-1);
|
2017-11-15 18:30:47 +08:00
|
|
|
font-style: italic;
|
2022-10-12 22:05:42 +08:00
|
|
|
line-height: var(--line-height-large);
|
2017-11-15 21:20:16 +08:00
|
|
|
margin-bottom: 1px;
|
|
|
|
}
|
|
|
|
|
|
|
|
> span.badge-notification {
|
|
|
|
vertical-align: unset;
|
2017-11-15 18:30:47 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
FEATURE: Allow hotlinked media to be blocked (#16940)
This commit introduces a new site setting: `block_hotlinked_media`. When enabled, all attempts to hotlink media (images, videos, and audio) will fail, and be replaced with a linked placeholder. Exceptions to the rule can be added via `block_hotlinked_media_exceptions`.
`download_remote_image_to_local` can be used alongside this feature. In that case, hotlinked images will be blocked immediately when the post is created, but will then be replaced with the downloaded version a few seconds later.
This implementation is purely server-side, and does not impact the composer preview.
Technically, there are two stages to this feature:
1. `PrettyText.sanitize_hotlinked_media` is called during `PrettyText.cook`, and whenever new images are introduced by Onebox. It will iterate over all src/srcset attributes in the post HTML and check if they're allowed. If not, the attributes will be removed and replaced with a `data-blocked-hotlinked-src(set)` attribute
2. In the `CookedPostProcessor`, we iterate over all `data-blocked-hotlinked-src(set)` attributes and check whether we have a downloaded version of the media. If yes, we update the src to use the downloaded version. If not, the entire media element is replaced with a placeholder. The placeholder is labelled 'external media', and is a link to the offsite media.
2022-06-07 22:23:04 +08:00
|
|
|
.broken-image,
|
|
|
|
.blocked-hotlinked-placeholder {
|
|
|
|
&:not(a) {
|
|
|
|
color: var(--primary-low-mid-or-secondary-high);
|
|
|
|
}
|
|
|
|
|
2020-04-22 02:00:47 +08:00
|
|
|
display: inline-flex;
|
FEATURE: Allow hotlinked media to be blocked (#16940)
This commit introduces a new site setting: `block_hotlinked_media`. When enabled, all attempts to hotlink media (images, videos, and audio) will fail, and be replaced with a linked placeholder. Exceptions to the rule can be added via `block_hotlinked_media_exceptions`.
`download_remote_image_to_local` can be used alongside this feature. In that case, hotlinked images will be blocked immediately when the post is created, but will then be replaced with the downloaded version a few seconds later.
This implementation is purely server-side, and does not impact the composer preview.
Technically, there are two stages to this feature:
1. `PrettyText.sanitize_hotlinked_media` is called during `PrettyText.cook`, and whenever new images are introduced by Onebox. It will iterate over all src/srcset attributes in the post HTML and check if they're allowed. If not, the attributes will be removed and replaced with a `data-blocked-hotlinked-src(set)` attribute
2. In the `CookedPostProcessor`, we iterate over all `data-blocked-hotlinked-src(set)` attributes and check whether we have a downloaded version of the media. If yes, we update the src to use the downloaded version. If not, the entire media element is replaced with a placeholder. The placeholder is labelled 'external media', and is a link to the offsite media.
2022-06-07 22:23:04 +08:00
|
|
|
flex-direction: column;
|
2020-08-04 10:57:10 +08:00
|
|
|
border: 1px solid var(--primary-low);
|
FEATURE: Allow hotlinked media to be blocked (#16940)
This commit introduces a new site setting: `block_hotlinked_media`. When enabled, all attempts to hotlink media (images, videos, and audio) will fail, and be replaced with a linked placeholder. Exceptions to the rule can be added via `block_hotlinked_media_exceptions`.
`download_remote_image_to_local` can be used alongside this feature. In that case, hotlinked images will be blocked immediately when the post is created, but will then be replaced with the downloaded version a few seconds later.
This implementation is purely server-side, and does not impact the composer preview.
Technically, there are two stages to this feature:
1. `PrettyText.sanitize_hotlinked_media` is called during `PrettyText.cook`, and whenever new images are introduced by Onebox. It will iterate over all src/srcset attributes in the post HTML and check if they're allowed. If not, the attributes will be removed and replaced with a `data-blocked-hotlinked-src(set)` attribute
2. In the `CookedPostProcessor`, we iterate over all `data-blocked-hotlinked-src(set)` attributes and check whether we have a downloaded version of the media. If yes, we update the src to use the downloaded version. If not, the entire media element is replaced with a placeholder. The placeholder is labelled 'external media', and is a link to the offsite media.
2022-06-07 22:23:04 +08:00
|
|
|
align-items: center;
|
|
|
|
justify-content: center;
|
2020-01-27 09:39:05 +08:00
|
|
|
|
|
|
|
.d-icon {
|
|
|
|
margin: 16px;
|
FEATURE: Allow hotlinked media to be blocked (#16940)
This commit introduces a new site setting: `block_hotlinked_media`. When enabled, all attempts to hotlink media (images, videos, and audio) will fail, and be replaced with a linked placeholder. Exceptions to the rule can be added via `block_hotlinked_media_exceptions`.
`download_remote_image_to_local` can be used alongside this feature. In that case, hotlinked images will be blocked immediately when the post is created, but will then be replaced with the downloaded version a few seconds later.
This implementation is purely server-side, and does not impact the composer preview.
Technically, there are two stages to this feature:
1. `PrettyText.sanitize_hotlinked_media` is called during `PrettyText.cook`, and whenever new images are introduced by Onebox. It will iterate over all src/srcset attributes in the post HTML and check if they're allowed. If not, the attributes will be removed and replaced with a `data-blocked-hotlinked-src(set)` attribute
2. In the `CookedPostProcessor`, we iterate over all `data-blocked-hotlinked-src(set)` attributes and check whether we have a downloaded version of the media. If yes, we update the src to use the downloaded version. If not, the entire media element is replaced with a placeholder. The placeholder is labelled 'external media', and is a link to the offsite media.
2022-06-07 22:23:04 +08:00
|
|
|
font-size: var(--font-up-5);
|
|
|
|
}
|
|
|
|
|
|
|
|
.notice {
|
|
|
|
margin: 0 0.5em 0.5em 0.5em;
|
2020-01-27 09:39:05 +08:00
|
|
|
}
|
2017-09-01 22:26:13 +08:00
|
|
|
}
|
2017-12-08 01:40:39 +08:00
|
|
|
|
|
|
|
/* below standard tablet portrait ----------- */
|
|
|
|
|
2018-06-21 01:06:20 +08:00
|
|
|
.reply-to-tab {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
margin-right: 2em;
|
2022-10-18 02:09:49 +08:00
|
|
|
max-width: 400px;
|
|
|
|
overflow: hidden;
|
2018-06-21 01:06:20 +08:00
|
|
|
|
|
|
|
img {
|
|
|
|
margin: 0 0.25em;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-21 04:37:43 +08:00
|
|
|
// Select posts
|
|
|
|
|
|
|
|
.topic-post {
|
|
|
|
&.selected {
|
|
|
|
article.boxed {
|
|
|
|
.select-posts {
|
|
|
|
button.select-post {
|
2020-08-04 10:57:10 +08:00
|
|
|
background-color: var(--tertiary);
|
|
|
|
color: var(--secondary);
|
|
|
|
border-color: var(--tertiary);
|
2018-07-21 04:37:43 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
.topic-body {
|
|
|
|
.contents:after {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
article.boxed {
|
|
|
|
position: relative;
|
|
|
|
.select-posts {
|
|
|
|
position: absolute;
|
2023-11-08 22:08:33 +08:00
|
|
|
right: 7em;
|
2018-07-23 09:40:50 +08:00
|
|
|
z-index: z("dropdown");
|
2018-07-21 04:37:43 +08:00
|
|
|
top: 0.5em;
|
|
|
|
height: 100px;
|
|
|
|
button {
|
|
|
|
margin-left: 8px;
|
2020-08-04 10:57:10 +08:00
|
|
|
background-color: var(--primary-low);
|
|
|
|
color: var(--primary);
|
2023-06-14 04:38:31 +08:00
|
|
|
box-shadow: var(--shadow-dropdown);
|
2018-07-21 04:37:43 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-08 17:49:31 +08:00
|
|
|
@media all and (max-width: 767px) {
|
2017-12-08 01:40:39 +08:00
|
|
|
.reply-to-tab {
|
2018-06-08 17:49:31 +08:00
|
|
|
span {
|
|
|
|
display: none;
|
|
|
|
}
|
2017-12-08 01:40:39 +08:00
|
|
|
}
|
|
|
|
.user-title {
|
|
|
|
float: left;
|
|
|
|
clear: left;
|
|
|
|
}
|
|
|
|
}
|
2018-04-26 09:59:47 +08:00
|
|
|
|
|
|
|
.signup-cta {
|
2021-04-21 01:00:39 +08:00
|
|
|
box-sizing: border-box;
|
2022-10-26 02:45:37 +08:00
|
|
|
max-width: calc(var(--topic-body-width) + 4.5em);
|
|
|
|
padding: 3em 5em 2em
|
2023-07-29 00:55:04 +08:00
|
|
|
calc(var(--topic-avatar-width) + var(--topic-body-width-padding));
|
2021-04-21 01:00:39 +08:00
|
|
|
@include breakpoint(mobile-extra-large) {
|
|
|
|
padding: 1.5em 1.5em 0.25em;
|
|
|
|
}
|
|
|
|
h3 {
|
|
|
|
margin-bottom: 0.5em;
|
|
|
|
}
|
2018-04-26 09:59:47 +08:00
|
|
|
a {
|
|
|
|
text-decoration: underline;
|
|
|
|
}
|
|
|
|
.buttons {
|
2021-04-21 01:00:39 +08:00
|
|
|
display: flex;
|
|
|
|
flex-wrap: wrap;
|
|
|
|
align-items: center;
|
|
|
|
margin: 1.5em 0 1em;
|
|
|
|
> * {
|
|
|
|
margin-bottom: 0.5em;
|
|
|
|
}
|
|
|
|
.btn {
|
|
|
|
margin-right: 0.5em;
|
|
|
|
white-space: nowrap;
|
2023-12-11 19:26:00 +08:00
|
|
|
|
|
|
|
.d-icon {
|
|
|
|
color: inherit;
|
|
|
|
}
|
|
|
|
|
2021-04-21 01:00:39 +08:00
|
|
|
&.btn-remind {
|
|
|
|
background: var(--primary-very-low);
|
|
|
|
margin-right: auto;
|
|
|
|
@include hover {
|
|
|
|
background: var(--primary-medium);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@include breakpoint(mobile-extra-large) {
|
|
|
|
&.btn-primary {
|
|
|
|
margin-right: 100%;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-04-26 09:59:47 +08:00
|
|
|
}
|
|
|
|
}
|
2019-03-08 16:48:35 +08:00
|
|
|
|
|
|
|
.post-notice {
|
2023-03-07 00:24:49 +08:00
|
|
|
box-sizing: border-box;
|
2019-07-09 19:42:02 +08:00
|
|
|
align-items: center;
|
2020-08-04 10:57:10 +08:00
|
|
|
background-color: var(--tertiary-low);
|
|
|
|
border-top: 1px solid var(--primary-low);
|
2019-07-09 19:42:02 +08:00
|
|
|
display: flex;
|
2022-07-06 03:49:47 +08:00
|
|
|
width: 100%;
|
2019-11-25 20:32:19 +08:00
|
|
|
max-width: calc(
|
2022-10-26 02:45:37 +08:00
|
|
|
var(--topic-body-width) + (var(--topic-body-width-padding) * 2) +
|
|
|
|
var(--topic-avatar-width)
|
2019-11-25 20:32:19 +08:00
|
|
|
);
|
2022-10-26 02:45:37 +08:00
|
|
|
padding: var(--topic-body-width-padding);
|
|
|
|
padding-left: 0;
|
2019-03-19 00:20:49 +08:00
|
|
|
&.old {
|
|
|
|
background-color: unset;
|
2020-08-04 10:57:10 +08:00
|
|
|
color: var(--primary-medium);
|
2019-03-19 21:43:56 +08:00
|
|
|
|
|
|
|
.d-icon {
|
2020-08-04 10:57:10 +08:00
|
|
|
color: var(--primary-medium);
|
2019-03-19 21:43:56 +08:00
|
|
|
}
|
2019-03-19 00:20:49 +08:00
|
|
|
}
|
2019-03-08 16:48:35 +08:00
|
|
|
|
|
|
|
p {
|
|
|
|
margin: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
.d-icon {
|
2019-03-09 05:02:51 +08:00
|
|
|
font-size: 2em;
|
2022-10-26 02:45:37 +08:00
|
|
|
width: var(--topic-avatar-width);
|
2020-08-04 10:57:10 +08:00
|
|
|
color: var(--primary-high);
|
2022-10-26 02:45:37 +08:00
|
|
|
margin-right: var(--topic-body-width-padding);
|
2019-03-08 16:48:35 +08:00
|
|
|
}
|
|
|
|
}
|
2019-07-29 23:54:23 +08:00
|
|
|
|
2023-12-16 06:15:38 +08:00
|
|
|
html.anon #topic-footer-buttons {
|
|
|
|
display: flex;
|
|
|
|
justify-content: end;
|
|
|
|
}
|
|
|
|
|
2019-07-29 23:54:23 +08:00
|
|
|
#topic-footer-buttons {
|
2021-04-23 04:11:47 +08:00
|
|
|
margin: var(--below-topic-margin) 0;
|
|
|
|
padding: 0;
|
2020-05-23 12:56:13 +08:00
|
|
|
|
|
|
|
.topic-footer-main-buttons {
|
|
|
|
display: flex;
|
|
|
|
flex-wrap: wrap;
|
2021-01-28 10:40:45 +08:00
|
|
|
align-items: stretch; // aligns items by making them the same height
|
2021-11-12 17:21:34 +08:00
|
|
|
button,
|
|
|
|
details {
|
2021-01-28 05:17:08 +08:00
|
|
|
margin-right: 0.54em;
|
2020-05-23 12:56:13 +08:00
|
|
|
}
|
2021-03-18 10:42:52 +08:00
|
|
|
> * {
|
|
|
|
margin-bottom: 0.5em; // all immediate children should have a bottom margin in case of wrapping
|
|
|
|
}
|
2020-05-23 12:56:13 +08:00
|
|
|
.topic-admin-menu-button-container {
|
|
|
|
display: inline-flex;
|
2021-10-29 21:23:15 +08:00
|
|
|
.topic-admin-menu-button {
|
2021-01-28 10:40:45 +08:00
|
|
|
display: flex; // to make this button match siblings behavior, all of its parents need to be flex
|
|
|
|
}
|
2020-05-23 12:56:13 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.pinned-button:not(.is-hidden) + .topic-notifications-button {
|
|
|
|
margin-top: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
.pinned-button,
|
|
|
|
.topic-notifications-button {
|
2021-03-18 10:42:52 +08:00
|
|
|
margin: 0.5em 0 1em;
|
2020-05-23 12:56:13 +08:00
|
|
|
|
|
|
|
.reason {
|
2020-08-04 10:57:10 +08:00
|
|
|
color: var(--primary-high);
|
2020-05-23 12:56:13 +08:00
|
|
|
display: inline-flex;
|
|
|
|
margin: 0;
|
|
|
|
align-items: center;
|
|
|
|
|
2021-03-18 10:42:52 +08:00
|
|
|
.dropdown-select-box {
|
|
|
|
.select-kit-selected-name {
|
|
|
|
width: 100%;
|
|
|
|
overflow: hidden;
|
|
|
|
}
|
|
|
|
.name {
|
|
|
|
@include ellipsis;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-23 12:56:13 +08:00
|
|
|
.text {
|
|
|
|
margin-left: 0.5em;
|
2022-10-12 22:05:42 +08:00
|
|
|
line-height: var(--line-height-medium);
|
2020-05-23 12:56:13 +08:00
|
|
|
}
|
|
|
|
}
|
2019-07-29 23:54:23 +08:00
|
|
|
}
|
|
|
|
}
|
2020-05-29 14:05:21 +08:00
|
|
|
|
2023-06-14 01:07:32 +08:00
|
|
|
iframe {
|
|
|
|
max-width: 100%;
|
|
|
|
max-height: #{"min(1000px, 200vh)"};
|
|
|
|
}
|
|
|
|
|
2020-05-29 14:05:21 +08:00
|
|
|
.post-admin-menu {
|
|
|
|
display: inline-flex;
|
|
|
|
flex-direction: column;
|
|
|
|
box-sizing: border-box;
|
|
|
|
width: auto;
|
|
|
|
max-width: 320px;
|
|
|
|
position: absolute;
|
|
|
|
text-align: left;
|
|
|
|
bottom: -2px;
|
|
|
|
right: 15px;
|
|
|
|
}
|
2020-12-11 01:02:07 +08:00
|
|
|
|
|
|
|
.posts-filtered-notice {
|
|
|
|
position: -webkit-sticky;
|
|
|
|
position: sticky;
|
|
|
|
background-color: var(--tertiary-low);
|
|
|
|
bottom: 0;
|
|
|
|
padding: 1em;
|
|
|
|
margin-top: 0.5em;
|
|
|
|
text-align: center;
|
|
|
|
z-index: 2;
|
|
|
|
display: flex;
|
|
|
|
justify-content: center;
|
|
|
|
align-items: center;
|
|
|
|
max-width: calc(
|
2022-10-26 02:45:37 +08:00
|
|
|
var(--topic-body-width) + (var(--topic-body-width-padding) * 2) +
|
|
|
|
var(--topic-avatar-width)
|
2020-12-11 01:02:07 +08:00
|
|
|
);
|
|
|
|
|
|
|
|
.filtered-avatar {
|
|
|
|
margin: 0 0.5em;
|
|
|
|
+ .names {
|
|
|
|
flex: inherit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.filtered-replies-show-all {
|
|
|
|
margin-left: 1em;
|
|
|
|
}
|
|
|
|
|
|
|
|
.filtered-user-row {
|
|
|
|
@include ellipsis;
|
|
|
|
}
|
|
|
|
}
|
2021-04-22 23:28:35 +08:00
|
|
|
|
2021-04-28 22:48:00 +08:00
|
|
|
.pausable-animated-image {
|
2021-04-22 23:28:35 +08:00
|
|
|
position: relative;
|
2021-04-28 22:48:00 +08:00
|
|
|
display: inline-block;
|
|
|
|
|
|
|
|
> canvas,
|
|
|
|
> .animated-image-overlay {
|
2021-04-22 23:28:35 +08:00
|
|
|
position: absolute;
|
2021-04-28 22:48:00 +08:00
|
|
|
bottom: 0;
|
|
|
|
right: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
> canvas {
|
|
|
|
background-color: var(--primary-very-low);
|
|
|
|
}
|
|
|
|
|
|
|
|
> .animated-image-overlay {
|
|
|
|
pointer-events: none;
|
|
|
|
text-align: right;
|
|
|
|
display: flex;
|
|
|
|
justify-content: flex-end;
|
|
|
|
align-items: flex-end;
|
|
|
|
> .d-icon {
|
|
|
|
cursor: pointer;
|
|
|
|
padding: 0.5em;
|
|
|
|
margin: 0.5em;
|
|
|
|
background-color: rgba(var(--always-black-rgb), 0.25);
|
|
|
|
color: var(--secondary-or-primary);
|
|
|
|
cursor: pointer;
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
img.animated {
|
|
|
|
cursor: pointer;
|
|
|
|
}
|
|
|
|
|
|
|
|
html.no-touch
|
|
|
|
&:not(.paused-animated-image)
|
|
|
|
.animated:hover
|
|
|
|
+ .animated-image-overlay
|
|
|
|
.d-icon-pause {
|
|
|
|
display: initial;
|
2021-04-22 23:28:35 +08:00
|
|
|
}
|
|
|
|
|
2021-04-28 22:48:00 +08:00
|
|
|
&.paused-animated-image
|
|
|
|
.animated.manually-paused
|
|
|
|
+ .animated-image-overlay
|
|
|
|
.d-icon-play {
|
|
|
|
display: initial;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.paused-animated-image {
|
2021-04-22 23:28:35 +08:00
|
|
|
img.animated {
|
|
|
|
// need to keep the image hidden but clickable
|
|
|
|
// so the user can resume animation
|
|
|
|
opacity: 0;
|
|
|
|
}
|
|
|
|
}
|
2021-10-26 03:06:28 +08:00
|
|
|
|
|
|
|
.open-popup-link {
|
2023-12-01 02:54:29 +08:00
|
|
|
display: inline;
|
|
|
|
margin-inline: 0.25em;
|
2021-10-26 03:06:28 +08:00
|
|
|
position: sticky;
|
2023-03-25 02:55:49 +08:00
|
|
|
left: 1rem;
|
2021-10-26 03:06:28 +08:00
|
|
|
opacity: 0%;
|
|
|
|
white-space: nowrap;
|
2023-12-01 02:54:29 +08:00
|
|
|
transition: 0.25s ease-in-out opacity;
|
2021-10-26 03:06:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
.fullscreen-table-wrapper {
|
|
|
|
transition: all 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
|
|
|
|
display: block;
|
2023-03-25 02:55:49 +08:00
|
|
|
position: relative;
|
2021-10-26 03:06:28 +08:00
|
|
|
}
|
2023-12-18 18:18:54 +08:00
|
|
|
|
|
|
|
.fullscreen-code-modal {
|
|
|
|
pre code {
|
|
|
|
max-width: none;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.fullscreen-table-modal {
|
|
|
|
.d-modal__container {
|
|
|
|
width: auto;
|
|
|
|
}
|
|
|
|
.d-modal__body {
|
|
|
|
padding-top: 0;
|
|
|
|
thead {
|
|
|
|
position: sticky;
|
|
|
|
top: 0;
|
|
|
|
z-index: 1;
|
|
|
|
background-color: var(--secondary);
|
|
|
|
}
|
2024-03-06 05:36:00 +08:00
|
|
|
|
|
|
|
td {
|
|
|
|
padding: 5px 6px 5px 3px;
|
|
|
|
}
|
2023-12-18 18:18:54 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
html.discourse-no-touch .fullscreen-table-wrapper:hover {
|
|
|
|
border-radius: 5px;
|
|
|
|
box-shadow: 0 2px 5px 0 rgba(var(--always-black-rgb), 0.1),
|
|
|
|
0 2px 10px 0 rgba(var(--always-black-rgb), 0.1);
|
|
|
|
.open-popup-link {
|
|
|
|
opacity: 100%;
|
|
|
|
}
|
|
|
|
}
|
2024-02-07 00:50:49 +08:00
|
|
|
|
|
|
|
.read-state {
|
|
|
|
position: absolute;
|
|
|
|
// We use absolute positioning here because we want it to display in the padding
|
|
|
|
align-self: center;
|
|
|
|
color: var(--tertiary-medium);
|
|
|
|
right: 0;
|
|
|
|
font-size: 0.571em;
|
|
|
|
&.read {
|
|
|
|
visibility: hidden;
|
|
|
|
opacity: 0;
|
|
|
|
transition: visibility 1s, opacity ease-out 1s;
|
|
|
|
}
|
|
|
|
}
|