Files
edx-platform/xmodule/static/sass/include/video/display.scss
Kyle McCormick 0b455e0336 build: commit XModule SCSS entrypoints of generating them (#32290)
`xmodule_assets` generated a series of SCSS "entrypoint"
files, where each entrypoint file imported from the
SCSS "sources" in xmodule/css.

This process was more complicated up until very
recently (see PRs in issue linked below for more
context). Now that the process is simpler, though,
there is no reason to generate the SCSS entrypoints;
we can just commit them to the repository instead!
So, we go from this:

    # GENERATED: SCSS entrypoints files for CMS
    common/static/xmodule/descriptors:
       AboutBlockStudio.scss
       AnnotatableBlockStudio.scss
       ...
    # GENERATED: SCSS entrypoints files for LMS
    common/static/xmodule/modules:
       AboutBlockPreview.scss
       AnnotatableBlockPreview.scss
       ...
    # VERSION CONTROLLED: SCSS source files
    xmodule/css:
      annotatable/...
      capa/...
      ...

to this:

    # VERSION CONTROLLED: All XModule SCSS
    xmodule/static/sass:
      # Source files
      include:
        annotatable/...
        capa/...
        ...
      # CMS entrypoint files
      cms:
        AboutBlockStudio.scss
        AnnotatableBlockStudio.scss
        ...
      # LMS source files
      lms:
        AboutBlockPreview.scss
        AnnotatableBlockPreview.scss
        ...

Also, we are able to remove all SCSS-related logic from the
`xmodule_assets` script and from the `HTMLSnippet` class.
XModule JS assets still need processing, but we will address
those in a separate series of PRs.

Part of: https://github.com/openedx/edx-platform/issues/32292
2023-06-16 08:51:03 -04:00

1013 lines
20 KiB
SCSS

// This is for A Font Garde
// It loads the icon font only when it's available.
// ---
// It is scoped to the video player for now, but we
// will eventually want to move this to the main font
// sheet, globally, so it applies to all use cases.
// --------
// Defaults: what displays if the icon font doesn't load.
// --------
@import 'vendor/bi-app/bi-app-ltr';
@import 'bourbon/bourbon';
@import 'lms/theme/variables';
@import 'bootstrap/scss/variables';
@import 'bootstrap/scss/mixins/breakpoints';
@import 'lms/theme/variables-v1';
// the html target is necessary for xblocks and xmodules, but works across the board
$secondary-dark: rgb(142, 62, 99); // UXPL secondary dark
$secondary-base: rgb(203, 89, 141); // UXPL secondary base
$secondary-light: rgb(219, 139, 175); // UXPL secondary light
$cool-dark: rgb(79, 89, 93); // UXPL cool dark
& {
margin-bottom: ($baseline*1.5);
}
.is-hidden {
display: none;
}
.video {
@include clearfix();
background: rgb(245, 245, 245); // UXPL grayscale x-back
display: block;
margin: 0 -12px;
padding: 12px;
border-radius: 5px;
outline: none;
&:focus,
&:active,
&:hover {
border: 0;
}
&.is-initialized {
.video-wrapper {
.spinner {
display: none;
}
}
}
// CASE: video pre-roll state
&.is-pre-roll {
.slider {
visibility: hidden;
}
.video-player {
position: relative;
&::before {
display: block;
content: "";
width: 100%;
padding-top: 55%;
}
}
}
.tc-wrapper {
@include clearfix();
position: relative;
}
.focus_grabber {
position: relative;
display: inline;
width: 0;
height: 0;
}
.downloads-heading {
margin: 1em 0 0;
}
.wrapper-downloads {
@include media-breakpoint-up(md) {
display: flex;
}
.hd {
margin: 0;
}
.wrapper-download-video,
.wrapper-download-transcripts,
.wrapper-handouts,
.branding {
flex: 1;
margin-top: $baseline;
@include padding-right($baseline);
vertical-align: top;
}
.wrapper-download-video {
.video-sources {
margin: 0;
}
}
.wrapper-download-transcripts {
.list-download-transcripts {
margin: 0;
padding: 0;
list-style: none;
.transcript-option {
margin: 0;
a.btn , a.btn-link{
font-size: 16px !important;
font-weight: unset;
}
}
}
}
.branding {
@include padding-right(0);
.host-tag {
position: absolute;
left: -9999em;
display: inline-block;
vertical-align: middle;
color: $body-color;
}
.brand-logo {
display: inline-block;
max-width: 100%;
max-height: ($baseline*2);
padding: ($baseline/4) 0;
vertical-align: middle;
}
}
}
.video-wrapper {
@include float(left);
@include margin-right(flex-gutter(9));
width: flex-grid(6, 9);
background-color: black;
position: relative;
&:hover {
.btn-play {
color: theme-color("primary");
}
.btn-play::after {
background: theme-color("inverse");
}
}
.video-player-pre,
.video-player-post {
height: 50px;
background-color: rgb(17, 16, 16) // UXPL grayscale black;
}
.spinner {
@include transform(translate(-50%, -50%));
position: absolute;
z-index: 1;
background: rgba(0, 0, 0, 0.7);
top: 50%;
left: 50%;
padding: 30px;
border-radius: 25%;
&::after {
@include animation(rotateCW 3s infinite linear);
content: '';
display: block;
width: 30px;
height: 30px;
border: 7px solid white;
border-top-color: transparent;
border-radius: 100%;
position: relative;
}
}
.btn-play {
@include transform(translate(-50%, -50%));
position: absolute;
z-index: 1;
top: 46%;
left: 50%;
font-size: 4em;
cursor: pointer;
opacity: 0.1;
&::after {
background: $white;
position: absolute;
width: 50%;
height: 50%;
content: '';
left: 0;
top: 0;
bottom: 0;
right: 0;
margin: auto;
z-index: -1;
}
}
.closed-captions {
@include left(5%);
position: absolute;
width: 90%;
box-sizing: border-box;
top: 70%;
text-align: center;
}
.closed-captions.is-visible {
max-height: ($baseline * 3);
border-radius: ($baseline / 5);
padding: 8px ($baseline / 2) 8px ($baseline * 1.5);
background: rgba(0, 0, 0, 0.75);
color: $yellow;
&::before {
position: absolute;
display: inline-block;
top: 50%;
@include left($baseline);
margin-top: -0.6em;
font-family: 'FontAwesome';
content: "\f142";
color: $white;
opacity: 0.5;
}
&:hover,
&.is-dragging {
background: rgba(0, 0, 0, 1);
cursor: move;
&::before {
opacity: 1;
}
}
}
.video-player {
overflow: hidden;
min-height: 158px;
> div {
height: 100%;
&.hidden {
display: none;
}
}
.video-error,
.video-hls-error {
padding: ($baseline / 5);
background: black;
color: white !important; // the pattern library headings shim is more scoped
}
object,
iframe,
video {
@include left(0);
display: block;
border: none;
width: 100%;
}
h4 {
text-align: center;
color: white;
&.hidden {
display: none;
}
}
}
.video-controls {
@include clearfix();
position: relative;
border: 0;
background: rgb(40, 44, 46); // UXPL grayscale-cool x-dark
color: rgb(240, 243, 245); // UXPL grayscale-cool xx-light
&:hover,
&:focus {
ul,
div {
opacity: 1;
}
}
%video-control {
@extend %t-strong;
@extend %t-title7;
display: inline-block;
vertical-align: middle;
margin: 0;
border: 0;
border-radius: 0;
padding: ($baseline / 2) ($baseline / 1.5);
background: rgb(40, 44, 46); // UXPL grayscale-cool x-dark
box-shadow: none;
text-shadow: none;
color: rgb(207, 216, 220); // UXPL grayscale-cool light
&:hover,
&:focus {
background: darken(rgb(40, 44, 46), 7%); // UXPL secondary
}
&:active,
&.is-active,
&.active {
color: rgb(14, 166, 236); // UXPL primary accent
}
}
.control {
@extend %video-control;
.icon {
width: 1em;
&.icon-hd {
// except when it's text, like with HD
// otherwise it's shifted to the right because "HD" is wider than 1em
width: auto;
}
}
}
.slider {
@include clearfix();
@include transform-origin(bottom left);
@include transition(height 0.7s ease-in-out 0s);
box-sizing: border-box;
position: absolute;
bottom: 100%;
left: 0;
right: 0;
z-index: 1;
height: ($baseline / 4);
margin-left: 0;
border: 1px solid $cool-dark;
border-radius: 0;
background: $cool-dark;
.ui-widget-header {
background: $secondary-dark;
border: 1px solid $secondary-dark;
box-shadow: none;
top: -1px;
left: -1px;
}
.ui-corner-all.slider-range {
opacity: 0.3;
background-color: #1e91d3;
}
.ui-slider-handle {
@extend %ui-fake-link;
@include transform-origin(bottom left);
@include transition(all 0.7s ease-in-out 0s);
box-sizing: border-box;
top: -1px;
height: ($baseline / 4);
width: ($baseline / 4);
margin-left: -($baseline / 8); // center-center causes the control to be beyond the end of the sider
border: 1px solid $secondary-base;
border-radius: ($baseline / 5);
padding: 0;
background: $secondary-base;
box-shadow: none;
&:focus,
&:hover {
background-color: $secondary-light;
border-color: $secondary-light;
}
}
}
.vcr {
@include float(left);
list-style: none;
@include border-right(1px solid rgb(40, 44, 46)); // UXPL grayscale-cool x-dark
padding: 0;
@media (max-width: 1120px) {
@include margin-right(lh(0.5));
font-size: em(14);
}
.video_control {
&:focus {
position: relative;
}
&.skip {
white-space: nowrap;
}
}
.vidtime {
@extend %t-strong;
@extend %t-title7;
@include padding-left(lh(0.75));
display: inline-block;
color: rgb(207, 216, 220); // UXPL grayscale-cool light
-webkit-font-smoothing: antialiased;
@media (max-width: 1120px) {
@include padding-left(lh(0.5));
}
}
}
.secondary-controls {
@include float(right);
@include border-left(1px dotted rgb(79, 89, 93)); // UXPL grayscale-cool x-dark
.volume,
.add-fullscreen,
.grouped-controls,
.auto-advance,
.quality-control {
@include border-left(1px dotted rgb(79, 89, 93)); // UXPL grayscale-cool x-dark
}
.speed-button,
.volume > .control,
.add-fullscreen,
.auto-advance,
.quality-control,
.toggle-transcript {
&:focus {
position: relative;
}
}
.menu-container {
position: relative;
.menu {
@include transition(none);
@extend %ui-depth1;
position: absolute;
display: none;
bottom: ($baseline * 2);
@include right(0); // right-align menus since this whole collection is on the right
width: 120px;
margin: 0;
border: none;
padding: 0;
box-shadow: none;
background-color: rgb(40, 44, 46); // UXPL grayscale-cool x-dark
list-style: none;
li {
@extend %ui-fake-link;
color: rgb(231, 236, 238); // UXPL grayscale-cool x-light
.speed-option,
.control-lang {
@include text-align(left);
display: block;
width: 100%;
border: 0;
border-radius: 0;
padding: lh(0.5);
background: rgb(40, 44, 46); // UXPL grayscale-cool x-dark
box-shadow: none;
color: rgb(231, 236, 238); // UXPL grayscale-cool x-light
overflow: hidden;
text-shadow: none;
text-overflow: ellipsis;
white-space: nowrap;
&:hover,
&:focus {
background-color: rgb(79, 89, 93); // UXPL grayscale-cool dark
color: rgb(252, 252, 252); // UXPL grayscale white
}
}
&.is-active {
.speed-option,
.control-lang {
@include border-left($baseline/10 solid rgb(14, 166, 236));
font-weight: $font-bold;
color: rgb(14, 166, 236); // UXPL primary accent
}
}
}
}
&.is-opened {
.menu {
display: block;
}
}
}
.speeds,
.lang,
.grouped-controls {
display: inline-block;
}
.speeds {
&.is-opened {
.control {
.icon {
@include ltr {
@include transform(rotate(-90deg));
}
@include rtl {
@include transform(rotate(90deg));
}
}
}
}
.speed-button {
.label {
@include padding(0 ($baseline/3) 0 0);
font-family: $font-family-sans-serif;
color: rgb(231, 236, 238); // UXPL grayscale-cool x-light
@media (max-width: 1120px) {
position: absolute;
clip: rect(1px, 1px, 1px, 1px);
}
}
.value {
@include padding(0, lh(0.5), 0, 0);
color: rgb(231, 236, 238); // UXPL grayscale-cool x-light
font-weight: bold;
@media (max-width: 1120px) {
padding: 0 lh(0.5);
}
}
}
}
.lang {
.language-menu {
width: $baseline;
padding: ($baseline / 2) 0;
}
.control {
.icon {
@include rtl {
@include transform(rotate(-180deg));
}
}
}
&.is-opened {
.control {
.icon {
@include ltr {
@include transform(rotate(90deg));
}
@include rtl {
@include transform(rotate(90deg));
}
}
}
}
}
.volume {
display: inline-block;
position: relative;
&.is-opened {
.volume-slider-container {
display: block;
opacity: 1;
}
}
&:not(:first-child) > a {
@include border-left(none);
}
.volume-slider-container {
@include transition(none);
@extend %ui-depth1;
display: none;
position: absolute;
bottom: ($baseline * 2);
@include right(0);
width: 41px;
height: 120px;
background-color: rgb(40, 44, 46); // UXPL grayscale-cool x-dark
.volume-slider {
height: 100px;
width: ($baseline / 4);
margin: 14px auto;
box-sizing: border-box;
border: 1px solid $cool-dark;
background: $cool-dark;
.ui-slider-handle {
@extend %ui-fake-link;
@include transition(height $tmg-s2 ease-in-out 0s, width $tmg-s2 ease-in-out 0s);
@include left(-5px);
box-sizing: border-box;
height: 13px;
width: 13px;
border: 1px solid $secondary-base;
border-radius: ($baseline / 5);
padding: 0;
background: $secondary-base;
box-shadow: none;
&:hover,
&:focus {
background: $secondary-light;
border-color: $secondary-light;
}
}
.ui-slider-range {
background: $secondary-dark;
border: 1px solid $secondary-dark;
left: -1px;
bottom: -1px;
}
}
}
}
.quality-control {
font-weight: 700;
letter-spacing: -1px;
&.active {
color: rgb(14, 166, 236); // UXPL primary accent
}
&.is-hidden {
display: none !important;
}
}
.toggle-transcript {
&.is-active {
color: rgb(14, 166, 236); // UXPL primary accent
}
}
.lang {
& > .hide-subtitles {
@include transition(none);
}
}
}
}
&:hover {
.video-controls {
.slider {
height: ($baseline / 1.5);
.ui-slider-handle {
height: ($baseline / 1.5);
width: ($baseline / 1.5);
}
}
}
}
}
&.video-fullscreen {
.closed-captions {
width: 65%;
}
&.closed .closed-captions {
width: 90%;
}
}
.subtitles {
@include float(left);
overflow: auto;
max-height: 460px;
width: flex-grid(3, 9);
padding: 0;
font-size: 14px;
visibility: visible;
a {
color: #0074b5;
}
.subtitles-menu {
height: 100%;
margin: 0;
padding: 0 3px;
list-style: none;
li {
@extend %ui-fake-link;
margin-bottom: 8px;
border: 0;
padding: 0;
color: #0074b5; // AA compliant
line-height: lh();
span {
display: block;
}
&.current {
color: #333;
font-weight: 700;
}
&.focused {
outline: #000 dotted thin;
outline-offset: -1px;
}
&:hover,
&:focus {
text-decoration: underline;
}
&:empty {
margin-bottom: 0;
}
&.spacing:last-of-type {
position: relative;
.transcript-end {
position: absolute;
bottom: 0;
}
}
}
}
}
&.closed {
.video-wrapper {
width: flex-grid(9, 9);
background-color: inherit;
}
.video-wrapper .video-controls.html5 {
bottom: 0;
left: 0;
right: 0;
position: absolute;
z-index: 1;
}
.video-wrapper .video-player-pre,
.video-wrapper .video-player-post {
height: 0;
}
.video-wrapper .video-player {
h3 {
color: black;
}
}
.subtitles {
@extend .is-hidden;
}
.subtitles.html5 {
@extend %ui-depth0;
background-color: rgba(243, 243, 243, 0.8);
height: 100%;
position: absolute;
right: 0;
bottom: 0;
top: 0;
width: 275px;
padding: 0 $baseline;
display: none;
}
}
&.video-fullscreen {
@extend %ui-depth4;
background: rgba(#000, 0.95);
border: 0;
bottom: 0;
height: 100%;
left: 0;
margin: 0;
padding: 0;
position: fixed;
top: 0;
width: 100%;
vertical-align: middle;
border-radius: 0;
&.closed {
.tc-wrapper {
.video-wrapper {
width: 100%;
}
}
}
.video-wrapper .video-player-pre,
.video-wrapper .video-player-post {
height: 0;
}
.video-wrapper {
position: static;
}
.video-wrapper .video-player {
h3 {
color: white;
}
}
.tc-wrapper {
@include clearfix();
width: 100%;
height: 100%;
position: static;
.video-wrapper {
height: 100%;
width: 75%;
@include margin-right(0);
vertical-align: middle;
object,
iframe,
video {
position: absolute;
width: auto;
height: auto;
}
}
.video-controls {
@extend %ui-depth4;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
}
}
.subtitles {
height: 100%;
width: 25%;
padding: lh();
box-sizing: border-box;
@include transition(none);
background: $black;
visibility: visible;
li {
color: #aaa;
&.current {
color: $white;
}
}
}
}
&.is-touch {
.tc-wrapper {
.video-wrapper {
object,
iframe,
video {
width: 100%;
height: 100%;
}
}
}
}
.video-pre-roll {
@extend %ui-depth3;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-position: 50% 50%;
background-repeat: no-repeat;
background-size: 100%;
background-color: $black;
&.is-html5 {
background-size: 15%;
}
.btn-play.btn-pre-roll {
padding: $baseline;
border: none;
border-radius: $baseline;
background: $black-t2;
box-shadow: none;
&::after {
// the button class, ties to functionality, also uses an icon font
// we're overriding it here so we can use our image instead
display: none;
}
img {
height: ($baseline * 4);
width: ($baseline * 4);
}
&:hover,
&:focus {
background: $blue;
}
}
}
}