diff options
author | Lukas Reschke <lukas@statuscode.ch> | 2017-03-20 19:49:53 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-20 19:49:53 +0100 |
commit | 21cf1b22e9efa17aa4b9fcd4575c891c309c30df (patch) | |
tree | ee0dff452a18a887baaed583d081cf03c2608d57 | |
parent | 03a92eaf74ea3898f67a12e3c19216683abb44d8 (diff) | |
parent | a0f7d4b6888466600698a31a50a551f915c69045 (diff) | |
download | nextcloud-server-21cf1b22e9efa17aa4b9fcd4575c891c309c30df.tar.gz nextcloud-server-21cf1b22e9efa17aa4b9fcd4575c891c309c30df.zip |
Merge pull request #3530 from nextcloud/scss-variables
Implement scss variables
-rwxr-xr-x | autotest-js.sh | 7 | ||||
-rw-r--r-- | core/css/apps.scss | 79 | ||||
-rw-r--r-- | core/css/header.scss | 31 | ||||
-rw-r--r-- | core/css/icons.scss | 8 | ||||
-rw-r--r-- | core/css/inputs.scss | 126 | ||||
-rw-r--r-- | core/css/multiselect.scss | 22 | ||||
-rw-r--r-- | core/css/share.scss | 10 | ||||
-rw-r--r-- | core/css/styles.scss | 161 | ||||
-rw-r--r-- | core/css/tooltip.scss | 12 | ||||
-rw-r--r-- | core/css/variables.scss | 22 | ||||
-rw-r--r-- | lib/private/Template/SCSSCacher.php | 31 | ||||
-rw-r--r-- | lib/private/TemplateLayout.php | 2 | ||||
-rw-r--r-- | tests/data/scss/styles-error.scss | 1 | ||||
-rw-r--r-- | tests/data/scss/styles-success.scss | 1 | ||||
-rw-r--r-- | tests/lib/Template/SCSSCacherTest.php | 278 |
15 files changed, 528 insertions, 263 deletions
diff --git a/autotest-js.sh b/autotest-js.sh index bd7310c4e43..5f03132ee42 100755 --- a/autotest-js.sh +++ b/autotest-js.sh @@ -24,7 +24,12 @@ mkdir -p "$PREFIX" && $NPM install --link --prefix "$PREFIX" || exit 3 # create scss test mkdir -p tests/css -./build/bin/node-sass --output tests/css core/css +for SCSSFILE in core/css/*.scss +do + FILE=$(basename $SCSSFILE) + FILENAME="${FILE%.*}" + printf "@import 'variables.scss'; @import '${FILE}';" | ./build/bin/node-sass --include-path core/css/ > tests/css/${FILE}.css +done KARMA="$PREFIX/node_modules/karma/bin/karma" diff --git a/core/css/apps.scss b/core/css/apps.scss index 91805fe16b2..e9ed9f470cd 100644 --- a/core/css/apps.scss +++ b/core/css/apps.scss @@ -55,13 +55,13 @@ em { height: 100%; float: left; box-sizing: border-box; - background-color: #fff; + background-color: $color-main-background; padding-bottom: 44px; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; - border-right: 1px solid #eee; + border-right: 1px solid nc-darken($color-main-background, 8%); display: flex; flex-direction: column; > ul { @@ -78,7 +78,7 @@ em { &, > a { opacity: 1; - box-shadow: inset 2px 0 #0082c9; + box-shadow: inset 2px 0 $color-primary; } } } @@ -115,7 +115,7 @@ em { box-sizing: border-box; white-space: nowrap; text-overflow: ellipsis; - color: #000; + color: $color-main-text; opacity: .57; } li > a:first-child img { @@ -166,9 +166,9 @@ em { -ms-transform: rotate(0); transform: rotate(0); } - background-image: linear-gradient(top, rgb(238, 238, 238) 0%, rgb(245, 245, 245) 100%); - background-image: -webkit-linear-gradient(top, rgb(238, 238, 238) 0%, rgb(245, 245, 245) 100%); - background-image: -ms-linear-gradient(top, rgb(238, 238, 238) 0%, rgb(245, 245, 245) 100%); + background-image: linear-gradient(top, nc-darken($color-main-background, 8%) 0%, nc-darken($color-main-background, 3%) 100%); + background-image: -webkit-linear-gradient(top, nc-darken($color-main-background, 8%) 0%, nc-darken($color-main-background, 3%) 100%); + background-image: -ms-linear-gradient(top, nc-darken($color-main-background, 8%) 0%, nc-darken($color-main-background, 3%) 100%); } } > { @@ -190,7 +190,7 @@ em { > ul .collapsible.open { &:hover, &:focus { - box-shadow: inset 0 0 3px #ddd; + box-shadow: inset 0 0 3px $color-box-shadow; } ul { display: block; @@ -248,10 +248,10 @@ em { padding-bottom: 40px; } .error { - color: #dd1144; + color: $color-error; } .app-navigation-separator { - border-bottom: 1px solid #ddd; + border-bottom: 1px solid nc-lighten($color-main-text, 86%); } /** @@ -324,7 +324,7 @@ em { margin-right: 0; height: 38px; float: left; - border: 1px solid rgba(190, 190, 190, 0.9); + border: 1px solid rgba(nc-lighten($color-main-text, 73%), 0.9); } button, input[type='submit'] { @@ -377,8 +377,8 @@ em { width: 27%; min-width: 300px; display: block; - background: #fff; - border-left: 1px solid #eee; + background: $color-main-background; + border-left: 1px solid nc-darken($color-main-background, 8%); -webkit-transition: margin-right 300ms; transition: margin-right 300ms; overflow-x: hidden; @@ -408,11 +408,11 @@ em { #app-settings-content { display: none; padding: 10px; - background-color: #fff; + background-color: $color-main-background; /* restrict height of settings and make scrollable */ max-height: 300px; overflow-y: auto; - border-right: 1px solid #eee; + border-right: 1px solid nc-darken($color-main-background, 8%); width: 250px; box-sizing: border-box; @@ -423,12 +423,12 @@ em { .info-text { padding: 5px 0 7px 22px; - color: #999; + color: rgba($color-main-text, .4); } } #app-settings-header { - border-right: 1px solid #eee; + border-right: 1px solid nc-darken($color-main-background, 8%); width: 250px; box-sizing: border-box; } @@ -439,7 +439,7 @@ em { width: 100%; padding: 0; margin: 0; - background-color: #fff; + background-color: $color-main-background; background-image: url('../img/actions/settings.svg?v=1'); background-position: 14px center; background-repeat: no-repeat; @@ -451,11 +451,11 @@ em { font-weight: normal; &:hover, &:focus { - background-color: #fff; + background-color: $color-main-background; } &.opened { &:hover, &:focus { - background-color: #fff; + background-color: $color-main-background; } } } @@ -464,7 +464,7 @@ em { .section { display: block; padding: 30px; - color: #555; + color: nc-lighten($color-main-text, 33%); margin-bottom: 24px; &.hidden { display: none !important; @@ -499,10 +499,10 @@ em { /* DROPDOWN ----------------------------------------------------------------- */ .dropdown { - background: #eee; + background: nc-darken($color-main-background, 8%); border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; - box-shadow: 0 1px 1px #777; + box-shadow: 0 1px 1px $color-box-shadow; display: block; margin-right: 0; position: absolute; @@ -520,25 +520,25 @@ em { float: left; padding: 5px; cursor: pointer; - color: #888; + color: nc-lighten($color-main-text, 33%); margin-bottom: 1px; a { - color: #888; + color: nc-lighten($color-main-text, 33%); margin-bottom: 1px; } &.selected { font-weight: 600; - border-bottom: 1px solid #333; + border-bottom: 1px solid nc-lighten($color-main-text, 20%); } &:hover { - border-bottom: 1px solid #333; + border-bottom: 1px solid nc-lighten($color-main-text, 20%); } &.selected, &:hover { margin-bottom: 0px; - color: #000; + color: $color-main-text; a { margin-bottom: 0px; - color: #000; + color: $color-main-text; } } } @@ -557,7 +557,7 @@ em { .popovermenu, .popovermenu:after, #app-navigation .app-navigation-entry-menu, #app-navigation .app-navigation-entry-menu:after { - border: 1px solid #eee; + border: 1px solid nc-darken($color-main-background, 8%); } } @@ -565,18 +565,18 @@ em { .app-navigation-entry-menu, .popovermenu { position: absolute; - background-color: #fff; - color: #333; + background-color: $color-main-background; + color: nc-lighten($color-main-text, 20%); border-radius: 3px; z-index: 110; margin: 5px; margin-top: -5px; right: 0; - -webkit-filter: drop-shadow(0 0 5px rgba(150, 150, 150, 0.75)); - -moz-filter: drop-shadow(0 0 5px rgba(150, 150, 150, 0.75)); - -ms-filter: drop-shadow(0 0 5px rgba(150, 150, 150, 0.75)); - -o-filter: drop-shadow(0 0 5px rgba(150, 150, 150, 0.75)); - filter: drop-shadow(0 0 5px rgba(150, 150, 150, 0.75)); + -webkit-filter: drop-shadow(0 0 5px $color-box-shadow); + -moz-filter: drop-shadow(0 0 5px $color-box-shadow); + -ms-filter: drop-shadow(0 0 5px $color-box-shadow); + -o-filter: drop-shadow(0 0 5px $color-box-shadow); + filter: drop-shadow(0 0 5px $color-box-shadow); display: none; &:after { @@ -591,8 +591,7 @@ em { width: 0; position: absolute; pointer-events: none; - border-color: rgba(238, 238, 238, 0); - border-bottom-color: #fff; + border-bottom-color: $color-main-background; border-width: 10px; } /* Center the popover */ @@ -644,7 +643,7 @@ em { margin: 0; font-weight: inherit; box-shadow: none; - color: #333 !important; /* Overwrite app-navigation li */ + color: nc-lighten($color-main-text, 20%) !important; /* Overwrite app-navigation li */ /* prevent .action class to break the design */ &.action { padding: inherit !important; diff --git a/core/css/header.scss b/core/css/header.scss index fd2da104c38..0687a6fed13 100644 --- a/core/css/header.scss +++ b/core/css/header.scss @@ -25,8 +25,7 @@ &.menu:after, .menu:after { border: 10px solid transparent; - border-color: transparent; - border-bottom-color: #fff; + border-bottom-color: $color-main-background; bottom: 100%; content: ' '; height: 0; @@ -47,7 +46,7 @@ &:focus { left: 76px; top: -9px; - color: #fff; + color: $color-primary-text; width: auto; height: auto; } @@ -64,7 +63,7 @@ right: 0; z-index: 2000; height: 45px; - background-color: #0082c9; + background-color: $color-primary; box-sizing: border-box; justify-content: space-between; } @@ -90,7 +89,7 @@ #header { .logo { - background-image: url('../img/logo-icon.svg?v=1'); + background-image: url('#{$image-logo}'); background-repeat: no-repeat; background-size: 175px; background-position: center; @@ -101,7 +100,7 @@ .logo-icon { /* display logo so appname can be shown next to it */ display: inline-block; - background-image: url('../img/logo-icon.svg?v=1'); + background-image: url($image-logo); background-repeat: no-repeat; background-position: center center; width: 62px; @@ -176,7 +175,7 @@ .header-appname { display: inline-block; position: relative; - color: #fff; + color: $color-primary-text; font-size: 16px; font-weight: 300; margin: 0; @@ -203,8 +202,8 @@ nav { max-height: 85%; margin-top: 0; padding-bottom: 10px; - background-color: rgba(255, 255, 255, .97); - box-shadow: 0 1px 10px rgba(150, 150, 150, .75); + background-color: $color-main-background; + box-shadow: 0 1px 10px $color-box-shadow; border-radius: 3px; border-top-left-radius: 0; border-top-right-radius: 0; @@ -275,7 +274,7 @@ nav { padding-left: 0; width: 80px; text-align: center; - color: #000; + color: $color-main-text; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @@ -358,7 +357,7 @@ nav { #settings { display: inline-block; - color: #ddd; + color: rgba($color-primary-text, 0.7); cursor: pointer; .icon-loading-small-dark { display: inline-block; @@ -386,7 +385,7 @@ nav { &:hover, &:focus, &:active { - color: #fff; + color: $color-primary-text; img { -ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=100)'; opacity: 1; @@ -418,8 +417,8 @@ nav { top: 45px; z-index: 2000; display: none; - background: rgb(255, 255, 255); - box-shadow: 0 1px 10px rgba(150, 150, 150, .75); + background: $color-main-background; + box-shadow: 0 1px 10px $color-box-shadow; border-radius: 3px; border-top-left-radius: 0; border-top-right-radius: 0; @@ -431,10 +430,10 @@ nav { a { display: block; height: 40px; - color: #000; + color: $color-main-text; + opacity: .5; padding: 10px 12px 0; -ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=50)'; - opacity: .5; box-sizing: border-box; img { margin-bottom: -3px; diff --git a/core/css/icons.scss b/core/css/icons.scss index f4ae0ce8d5f..42224a9cfc4 100644 --- a/core/css/icons.scss +++ b/core/css/icons.scss @@ -42,15 +42,15 @@ -webkit-transform-origin: center; -ms-transform-origin: center; transform-origin: center; - border: 2px solid rgba(150, 150, 150, 0.5); - border-top-color: rgb(100, 100, 100); + border: 2px solid rgba($color-loading, 0.5); + border-top-color: $color-loading; } } .icon-loading-dark:after, .icon-loading-small-dark:after { - border: 2px solid rgba(187, 187, 187, 0.5); - border-top-color: #bbb; + border: 2px solid rgba($color-loading-dark, 0.5); + border-top-color: $color-loading-dark; } .icon-loading-small:after, diff --git a/core/css/inputs.scss b/core/css/inputs.scss index faddcc50214..37405172d3a 100644 --- a/core/css/inputs.scss +++ b/core/css/inputs.scss @@ -39,9 +39,9 @@ textarea, margin: 3px 3px 3px 0; padding: 7px 6px; font-size: 13px; - background-color: #fff; - color: #333; - border: 1px solid #ddd; + background-color: $color-main-background; + color: nc-lighten($color-main-text, 33%); + border: 1px solid nc-lighten($color-main-text, 86%); outline: none; border-radius: 3px; &:not(:disabled):not(.primary) { @@ -50,38 +50,38 @@ textarea, &:focus, &.active { /* active class used for multiselect */ - border-color: #0082c9; + border-color: $color-primary; outline: none; } &:active { outline: none; - background-color: #fff; + background-color: $color-main-background; } } &:disabled { - background-color: #eee; - color: #999; + background-color: nc-darken($color-main-background, 8%); + color: rgba($color-main-text, 0.4); cursor: default; opacity: 0.5; } /* Primary action button, use sparingly */ &.primary { - border: 1px solid #0082c9; - background-color: #00a2e9; - color: #fff; + border: 1px solid $color-primary; + background-color: rgba($color-primary, .7); + color: $color-primary-text; cursor: pointer; &:not(:disabled) { &:hover, &:focus { - background-color: #0092d9; + background-color: rgba($color-primary, .85); } &:active { - background-color: #00a2e9; + background-color: rgba($color-primary, .7); } } &:disabled { - background-color: #00a2e9; - color: #bbb; + background-color: rgba($color-primary, .7); + color: nc-lighten($color-main-text, 73%); } } } @@ -128,7 +128,7 @@ input[type='reset'] { min-height: 34px; cursor: pointer; box-sizing: border-box; - background-color: #fafafa; + background-color: nc-darken($color-main-background, 3%); } /* Buttons */ @@ -155,7 +155,7 @@ button, .button { } textarea { - color: #555; + color: nc-lighten($color-main-text, 33%); cursor: text; font-family: inherit; height: auto; @@ -163,8 +163,8 @@ textarea { &:active, &:hover, &:focus { - border-color: #ddd !important; - background-color: #fff !important; + border-color: nc-lighten($color-main-text, 86%) !important; + background-color: $color-main-background !important; } } } @@ -186,7 +186,7 @@ button img, cursor: pointer; } #quota { - color: #555; + color: nc-lighten($color-main-text, 33%); } select, .button.multiselect { @@ -221,27 +221,26 @@ input { border-radius: 50%; margin: 3px; margin-top: 1px; - border: 1px solid #888; + border: 1px solid nc-lighten($color-main-text, 53%); } &:not(:disabled):not(:checked) + label:hover:before, &:focus + label:before { - border-color: #0082c9; + border-color: $color-primary; } &:checked + label:before, &.checkbox:indeterminate + label:before { /* ^ :indeterminate have a strange behavior on radio, so we respecified the checkbox class again to be safe */ - box-shadow: inset 0px 0px 0px 2px #fff; - background-color: #0082c9; - border-color: #0082c9 + box-shadow: inset 0px 0px 0px 2px $color-main-background; + background-color: $color-primary; + border-color: $color-primary } &:disabled + label:before { - background-color: #ccc !important; /* override other status */ + border: 1px solid nc-lighten($color-main-text, 53%); + background-color: nc-lighten($color-main-text, 73%) !important; /* override other status */ } &:checked:disabled + label:before { - box-shadow: inset 0px 0px 0px 2px #fff; - border-color: #aaa; - background-color: #bbb; + background-color: nc-lighten($color-main-text, 73%); } } &.checkbox { @@ -258,49 +257,46 @@ input { &:indeterminate + label:before { background-image: url('../img/actions/checkbox-mixed.svg'); } - &:indeterminate:disabled + label:before { - border-color: #888; - } } &.radio--white, &.checkbox--white { + label:before { - border-color: #ddd; + border-color: nc-lighten($color-main-text, 86%); } &:not(:disabled):not(:checked) + label:hover:before, &:focus + label:before { - border-color: #fff; + border-color: $color-main-background; } &:checked + label:before { - box-shadow: inset 0px 0px 0px 2px #000; - background-color: #eee; - border-color: #eee + box-shadow: inset 0px 0px 0px 2px $color-main-text; + background-color: nc-darken($color-main-background, 8%); + border-color: nc-darken($color-main-background, 8%) } &:disabled + label:before { - background-color: #666 !important; /* override other status */ - border-color: #999 !important; /* override other status */ + background-color: nc-lighten($color-main-text, 33%) !important; /* override other status */ + border-color: rgba($color-main-text, 0.4) !important; /* override other status */ } &:checked:disabled + label:before { - box-shadow: inset 0px 0px 0px 2px #000; - border-color: #666; - background-color: #222; + box-shadow: inset 0px 0px 0px 2px $color-main-text; + border-color: nc-lighten($color-main-text, 33%); + background-color: nc-lighten($color-main-text, 33%); } } &.checkbox--white { &:checked + label:before, &:indeterminate + label:before { background-color: transparent !important; /* Override default checked */ - border-color: #fff !important; /* Override default checked */ + border-color: $color-main-background !important; /* Override default checked */ background-image: url('../img/actions/checkbox-mark-white.svg'); } &:indeterminate + label:before { background-image: url('../img/actions/checkbox-mixed-white.svg'); } &:checked:disabled + label:after { - border-color: #aaa; + border-color: nc-lighten($color-main-text, 73%); } &:indeterminate:disabled + label:after { - background-color: #aaa; + background-color: nc-lighten($color-main-text, 73%); } } } @@ -310,7 +306,7 @@ input { .select2-drop { margin-top: -2px; &.select2-drop-active { - border-color: #ddd; + border-color: nc-lighten($color-main-text, 86%); } .avatar { display: inline-block; @@ -343,17 +339,17 @@ input { position: relative; display: list-item; padding: 12px; - background-color: #fff; + background-color: $color-main-background; cursor: pointer; - color: #222; + color: nc-lighten($color-main-text, 33%); } .select2-result { &.select2-selected { - background-color: #f8f8f8; + background-color: nc-darken($color-main-background, 3%); } &.select2-highlighted { - background-color: #f8f8f8; - color: #000; + background-color: nc-darken($color-main-background, 3%); + color: $color-main-text; } } } @@ -371,11 +367,11 @@ input { box-shadow: none; white-space: nowrap; text-overflow: ellipsis; - background: #fff; - color: #555; + background: $color-main-background; + color: nc-lighten($color-main-text, 33%); box-sizing: content-box; border-radius: 3px; - border: 1px solid #ddd; + border: 1px solid nc-lighten($color-main-text, 86%); margin: 0; padding: 2px 0; min-height: auto; @@ -387,9 +383,9 @@ input { &:active, & { background-image: none; - background-color: #fff; - color: #333; - border: 1px solid #ddd; + background-color: $color-main-background; + color: nc-lighten($color-main-text, 33%); + border: 1px solid nc-lighten($color-main-text, 86%); } .select2-search-choice-close { display: none; @@ -413,11 +409,11 @@ input { box-shadow: none; white-space: nowrap; text-overflow: ellipsis; - background: #fff; - color: #555; + background: $color-main-background; + color: nc-lighten($color-main-text, 33%); box-sizing: content-box; border-radius: 3px; - border: 1px solid #ddd; + border: 1px solid nc-lighten($color-main-text, 86%); margin: 0; padding: 2px 0; padding-left: 6px; @@ -426,15 +422,15 @@ input { line-height: 20px; padding-left: 5px; background-image: none; - background-color: #f8f8f8; - border-color: #f8f8f8; + background-color: nc-darken($color-main-background, 3%); + border-color: nc-darken($color-main-background, 3%); .select2-search-choice-close { display: none; } &.select2-search-choice-focus, &:hover { - background-color: #f0f0f0; - border-color: #f0f0f0; + background-color: nc-darken($color-main-background, 8%); + border-color: nc-darken($color-main-background, 8%); } } .select2-arrow { @@ -470,7 +466,7 @@ input { } .ui-widget-content { - background: #fff; + background: $color-main-background; border-top: none; } @@ -482,7 +478,7 @@ input { .ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: none; - background: #f8f8f8; + background: nc-darken($color-main-background, 3%); } /* Animation */ diff --git a/core/css/multiselect.scss b/core/css/multiselect.scss index 4b5d9cb6cf3..cf13563e772 100644 --- a/core/css/multiselect.scss +++ b/core/css/multiselect.scss @@ -17,27 +17,27 @@ */ ul.multiselectoptions { - background-color: #fff; - border: 1px solid #ddd; + background-color: $color-main-background; + border: 1px solid $color-primary; border-top: none; - box-shadow: 0 1px 1px #ddd; + box-shadow: 0 1px 10px $color-box-shadow; padding-top: 8px; position: absolute; max-height: 20em; overflow-y: auto; z-index: 49; &.down { - border-bottom-left-radius: 8px; - border-bottom-right-radius: 8px; + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; width: 100%; /* do not cut off group names */ - -webkit-box-shadow: 0px 0px 20px rgba(29, 45, 68, 0.4); - -moz-box-shadow: 0px 0px 20px rgba(29, 45, 68, 0.4); - box-shadow: 0px 0px 20px rgba(29, 45, 68, 0.4); + -webkit-box-shadow: 0 1px 10px $color-box-shadow; + -moz-box-shadow: 0 1px 10px $color-box-shadow; + box-shadow: 0 1px 10px $color-box-shadow; } &.up { - border-top-left-radius: 8px; - border-top-right-radius: 8px; + border-top-left-radius: 3px; + border-top-right-radius: 3px; } > li { overflow: hidden; @@ -96,7 +96,7 @@ select.multiselect { /* To make a select look like a multiselect until it's initialized */ div.multiselect { &.active { - background-color: #fff; + background-color: $color-main-background; position: relative; z-index: 50; } diff --git a/core/css/share.scss b/core/css/share.scss index 6d98dc74945..0e6eb3ccf8b 100644 --- a/core/css/share.scss +++ b/core/css/share.scss @@ -56,9 +56,9 @@ margin-right: 0; } .error { - color: #e9322d; - border-color: #e9322d; - box-shadow: 0 0 6px #f8b9b7; + color: $color-error; + border-color: $color-error; + box-shadow: 0 0 6px rgba($color-error, 0.35); } .mailView .icon-mail { opacity: 0.5; @@ -144,7 +144,7 @@ a { } #link { - border-top: 1px solid #ddd; + border-top: 1px solid nc-lighten($color-main-text, 86%); padding-top: 8px; #showPassword img { padding-left: 5px; @@ -182,5 +182,5 @@ a { .notCreatable { padding-left: 12px; padding-top: 12px; - color: #999; + color: rgba($color-main-text, .4); } diff --git a/core/css/styles.scss b/core/css/styles.scss index aa97c91a55d..2bec3c8d3b1 100644 --- a/core/css/styles.scss +++ b/core/css/styles.scss @@ -54,7 +54,7 @@ table, td, th { a { border: 0; - color: #000; + color: $color-main-text; text-decoration: none; cursor: pointer; * { @@ -78,18 +78,18 @@ ul { } body { - background-color: #ffffff; + background-color: $color-main-background; font-weight: 400; font-size: .8em; line-height: 1.6em; font-family: 'Open Sans', Frutiger, Calibri, 'Myriad Pro', Myriad, sans-serif; - color: #000; + color: $color-main-text; height: auto; } #body-login { text-align: center; - background-color: #0082c9; + background-color: $color-primary; background-image: url('../img/background.jpg?v=1'); background-position: 50% 50%; background-repeat: no-repeat; @@ -105,14 +105,14 @@ body { width: 258px !important; display: inline-block; margin-bottom: 0 !important; - background-color: rgba(0, 0, 0, 0.3) !important; + background-color: rgba($color-main-text, 0.3) !important; border: none !important; } .two-factor-link { display: inline-block; padding: 12px; - color: rgba(255, 255, 255, 0.75); + color: rgba($color-main-background, 0.75); } .float-spinner { @@ -133,8 +133,8 @@ body { width: 100%; z-index: 9000; text-align: center; - background-color: rgba(0, 0, 0, 0.5); - color: #fff; + background-color: rgba($color-main-text, 0.5); + color: $color-primary-text; line-height: 125%; font-size: 24px; div { @@ -145,10 +145,10 @@ body { margin: 0px auto; } a { - color: #fff; - border-bottom: 2px dotted #fff; + color: $color-primary-text; + border-bottom: 2px dotted $color-main-background; &:hover, &:focus { - color: #ddd; + color: nc-lighten($color-main-text, 86%); } } } @@ -164,7 +164,7 @@ body { } ::-webkit-scrollbar-thumb { - background: #ddd; + background: nc-lighten($color-main-text, 86%); border-radius: 3px; } @@ -178,7 +178,7 @@ body { padding: 3px; padding-left: 25px; background: transparent url('../img/actions/search-white.svg?v=1') no-repeat 6px center; - color: #fff; + color: $color-primary-text; border: 0; border-radius: 3px; margin-top: 3px; @@ -189,11 +189,11 @@ body { -ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=70)'; opacity: .7; &:focus, &:active, &:valid { - color: #fff; + color: $color-primary-text; width: 155px; cursor: text; - background-color: #0082c9 !important; - border: 1px solid rgba(255, 255, 255, 0.5) !important; + background-color: $color-primary !important; + border: 1px solid rgba($color-primary-text, 0.5) !important; } & ~ .icon-close-white { display: inline; @@ -228,7 +228,7 @@ body { width: 100%; padding: 0; margin: 0; - background-color: rgba(255, 255, 255, 0.95); + background-color: rgba($color-main-background, 0.95); z-index: 50; -webkit-user-select: none; -moz-user-select: none; @@ -298,7 +298,7 @@ body { } #emptycontent, .emptycontent { - color: #888; + color: nc-darken($color-main-background, 8%); text-align: center; margin-top: 30vh; width: 100%; @@ -336,16 +336,16 @@ body { /* fix sticky footer */ p.info, form fieldset legend, #datadirContent label { text-align: center; - color: #fff; + color: $color-primary-text; } form { fieldset .warning-info, input[type='checkbox'] + label { text-align: center; - color: #fff; + color: $color-primary-text; } .warning input[type='checkbox'] { &:hover + label, &:focus + label, + label { - color: #fff !important; + color: $color-primary-text !important; } } } @@ -354,8 +354,8 @@ body { margin: 0 0 20px; } a { - color: #fff; - border-bottom: 1px solid #aaa; + color: $color-primary-text; + border-bottom: 1px solid nc-lighten($color-main-text, 73%); } } .infogroup { @@ -442,10 +442,6 @@ body { top: -23px; width: 250px; } - .tipsy-inner { - font-weight: bold; - color: #ccc; - } input { &[type='text'], &[type='password'], &[type='email'] { border: none; @@ -456,8 +452,6 @@ body { /* strengthify wrapper */ -/* tipsy for the strengthify wrapper looks better with following font settings */ - /* General new input field look */ /* Nicely grouping input field sets */ @@ -483,7 +477,7 @@ body { border-top: 0 !important; border-bottom: 0 !important; border-radius: 0 !important; - box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1) inset !important; + box-shadow: 0 1px 0 rgba($color-main-text, 0.1) inset !important; } #body-login .groupbottom input, .groupbottom input { @@ -491,7 +485,7 @@ body { border-top: 0 !important; border-top-right-radius: 0 !important; border-top-left-radius: 0 !important; - box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1) inset !important; + box-shadow: 0 1px 0 rgba($color-main-text, 0.1) inset !important; } #body-login .groupbottom input[type=submit] { @@ -517,16 +511,16 @@ label.infield { user-select: none; } .errors { - background: #fed7d7; - border: 1px solid #f00; + background: rgba($color-error, .35); + border: 1px solid $color-error; list-style-indent: inside; margin: 0 0 2em; padding: 1em; } } .success { - background: #d7fed7; - border: 1px solid #0f0; + background: rgba($color-success, .35); + border: 1px solid $color-success; width: 35%; margin: 30px auto; padding: 1em; @@ -537,7 +531,7 @@ label.infield { box-sizing: border-box; } p.info a, #showAdvanced { - color: #fff; + color: $color-primary-text; } #remember_login { &:hover + label, &:focus + label { @@ -626,25 +620,25 @@ label.infield { position: static; margin: 0 -3px 5px; font-size: 12px; - background: #f8f8f8; - color: #888; + background: nc-darken($color-main-background, 3%); + color: nc-lighten($color-main-text, 53%); cursor: pointer; - border: 1px solid #ddd; + border: 1px solid nc-lighten($color-main-text, 86%); span { cursor: pointer; padding: 10px 20px; } &.ui-state-hover, &.ui-state-active { - color: #000; - background-color: #e8e8e8; + color: $color-main-text; + background-color: nc-darken($color-main-background, 8%); } } } .warning, .update, .error { display: block; padding: 10px; - background-color: rgba(0, 0, 0, 0.3); - color: #fff; + background-color: rgba($color-main-text, 0.3); + color: $color-primary-text; text-align: left; border-radius: 3px; cursor: default; @@ -672,23 +666,23 @@ label.infield { #body-user .warning, #body-settings .warning { margin-top: 8px; padding: 5px; - background: #fdd; + background: rgba($color-error, .15); border-radius: 3px; } .warning { legend, a { - color: #fff !important; + color: $color-primary-text !important; font-weight: 600 !important; } } .error { a { - color: #fff !important; + color: $color-primary-text !important; font-weight: 600 !important; &.button { - color: #555 !important; + color: nc-lighten($color-main-text, 33%) !important; display: inline-block; text-align: center; } @@ -708,7 +702,7 @@ label.infield { } .warning-input { - border-color: #ce3702 !important; + border-color: $color-error !important; } /* Fixes for log in page, TODO should be removed some time */ @@ -782,7 +776,7 @@ label.infield { #forgot-password { padding: 11px; float: right; - color: #fff; + color: $color-primary-text; } .wrapper { min-height: 100%; @@ -822,7 +816,7 @@ td.avatar { margin: 0 auto; max-width: 60%; z-index: 8000; - background-color: #fff; + background-color: $color-main-background; border: 0; padding: 1px 8px; display: none; @@ -905,7 +899,7 @@ tr { tbody tr { &:hover, &:focus, &:active { - background-color: #f8f8f8; + background-color: nc-darken($color-main-background, 3%); } } @@ -920,7 +914,7 @@ code { padding: 0 !important; div { padding: 0; - background-color: rgb(220, 220, 220); + background-color: nc-darken($color-main-background, 10%); font-weight: normal; white-space: nowrap; border-bottom-left-radius: 3px; @@ -935,7 +929,7 @@ code { } #quota div.quota-warning { - background-color: #fc4; + background-color: $color-warning; } .pager { @@ -953,35 +947,6 @@ code { text-overflow: ellipsis; } -.separator { - display: inline; - border-left: 1px solid #d3d3d3; - border-right: 1px solid #fff; - height: 10px; - width: 0px; - margin: 4px; -} - -a.bookmarklet { - background-color: #ddd; - border: 1px solid #ccc; - padding: 5px; - padding-top: 0px; - padding-bottom: 2px; - text-decoration: none; - margin-top: 5px; -} - -.exception { - color: #000; - textarea { - width: 95%; - height: 200px; - background: #ffe; - border: 0; - } -} - .ui-icon-circle-triangle-e { background-image: url('../img/actions/play-next.svg?v=1'); } @@ -991,8 +956,8 @@ a.bookmarklet { } .ui-datepicker-prev, .ui-datepicker-next { - border: 1px solid #ddd; - background: #fff; + border: nc-lighten($color-main-text, 86%); + background: $color-main-background; } /* ---- DIALOGS ---- */ @@ -1030,7 +995,7 @@ a.bookmarklet { width: 100%; } .emptycontent { - color: #888; + color: nc-lighten($color-main-text, 53%); text-align: center; margin-top: 80px; width: 100%; @@ -1048,7 +1013,7 @@ a.bookmarklet { .filelist { td { padding: 14px; - border-bottom: 1px solid #eee; + border-bottom: 1px solid nc-darken($color-main-background, 8%); } tr:last-child td { border-bottom: none; @@ -1096,12 +1061,6 @@ span.ui-icon { padding-right: 5px !important; } -.tipsy-inner { - max-width: 400px !important; - overflow: hidden; - text-overflow: ellipsis; -} - /* ---- TAGS ---- */ #tagsdialog { @@ -1111,7 +1070,7 @@ span.ui-icon { } .scrollarea { overflow: auto; - border: 1px solid #ddd; + border: 1px solid nc-lighten($color-main-text, 86%); width: 100%; height: 240px; } @@ -1123,7 +1082,7 @@ span.ui-icon { } } .taglist li { - background: #f8f8f8; + background: nc-darken($color-main-background, 3%); padding: .3em .8em; white-space: nowrap; overflow: hidden; @@ -1131,7 +1090,7 @@ span.ui-icon { -webkit-transition: background-color 500ms; transition: background-color 500ms; &:hover, &:active { - background: #eee; + background: nc-darken($color-main-background, 8%); } } .addinput { @@ -1143,10 +1102,10 @@ span.ui-icon { /* ---- APP SETTINGS - LEGACY, DO NOT USE THE POPUP! ---- */ .popup { - background-color: #fff; + background-color: $color-main-background; border-radius: 3px; - box-shadow: 0 0 10px #aaa; - color: #333; + box-shadow: 0 0 10px $color-box-shadow; + color: nc-lighten($color-main-text, 20%); padding: 10px; position: fixed !important; z-index: 100; @@ -1215,7 +1174,7 @@ div.crumb { position: relative; top: 12px; padding: 14px 24px 14px 17px; - color: #555; + color: nc-lighten($color-main-text, 33%); } &.last a { padding-right: 0; @@ -1263,12 +1222,12 @@ div.crumb { position: relative; text-align: center; .info { - color: #777; + color: nc-lighten($color-main-text, 33%); text-align: center; margin: 0 auto; padding: 20px 0; a { - color: #777; + color: nc-lighten($color-main-text, 33%); font-weight: 600; padding: 13px; margin: -13px; diff --git a/core/css/tooltip.scss b/core/css/tooltip.scss index 263dad0b0c9..66234cad9f2 100644 --- a/core/css/tooltip.scss +++ b/core/css/tooltip.scss @@ -54,7 +54,7 @@ left: 0; margin-top: -5px; border-width: 5px 5px 5px 0; - border-right-color: #000000; + border-right-color: $color-main-text; } } &.left { @@ -65,7 +65,7 @@ right: 0; margin-top: -5px; border-width: 5px 0 5px 5px; - border-left-color: #000000; + border-left-color: $color-main-text; } } @@ -75,7 +75,7 @@ &.top-right .tooltip-arrow { bottom: 0; border-width: 5px 5px 0; - border-top-color: #000000; + border-top-color: $color-main-text; } &.top .tooltip-arrow { left: 50%; @@ -96,7 +96,7 @@ &.bottom-right .tooltip-arrow { top: 0; border-width: 0 5px 5px; - border-bottom-color: #000000; + border-bottom-color: $color-main-text; } &.bottom .tooltip-arrow { left: 50%; @@ -115,9 +115,9 @@ .tooltip-inner { max-width: 350px; padding: 3px 8px; - color: #ffffff; + color: $color-main-background; text-align: center; - background-color: #000000; + background-color: $color-main-text; border-radius: 4px; } diff --git a/core/css/variables.scss b/core/css/variables.scss new file mode 100644 index 00000000000..47c8e1a27f8 --- /dev/null +++ b/core/css/variables.scss @@ -0,0 +1,22 @@ +$color-main-text: #000000; +$color-main-background: #ffffff; +$color-primary: #0082c9; +$color-primary-text: #ffffff; +$color-error: #e9322d; +$color-warning: #ffcc44; +$color-success: #46ba61; + +@function nc-darken($color, $value) { + @return darken($color, $value); +} + +@function nc-lighten($color, $value) { + @return lighten($color, $value); +} + +$image-logo: '../img/logo-icon.svg?v=1'; +$image-login-background: '../img/background.jpg?v=1'; + +$color-loading: #969696; +$color-loading-dark: #bbbbbb; +$color-box-shadow: rgba(nc-lighten($color-main-text, 20%), 0.75);
\ No newline at end of file diff --git a/lib/private/Template/SCSSCacher.php b/lib/private/Template/SCSSCacher.php index b55cd0b93b0..4f5c66f2409 100644 --- a/lib/private/Template/SCSSCacher.php +++ b/lib/private/Template/SCSSCacher.php @@ -28,7 +28,9 @@ use Leafo\ScssPhp\Formatter\Expanded; use OC\SystemConfig; use OCP\Files\IAppData; use OCP\Files\NotFoundException; +use OCP\Files\NotPermittedException; use OCP\Files\SimpleFS\ISimpleFolder; +use OCP\IConfig; use OCP\ILogger; use OCP\IURLGenerator; @@ -43,8 +45,8 @@ class SCSSCacher { /** @var IURLGenerator */ protected $urlGenerator; - /** @var SystemConfig */ - protected $systemConfig; + /** @var IConfig */ + protected $config; /** @var string */ protected $serverRoot; @@ -59,12 +61,12 @@ class SCSSCacher { public function __construct(ILogger $logger, IAppData $appData, IURLGenerator $urlGenerator, - SystemConfig $systemConfig, + IConfig $config, $serverRoot) { $this->logger = $logger; $this->appData = $appData; $this->urlGenerator = $urlGenerator; - $this->systemConfig = $systemConfig; + $this->config = $config; $this->serverRoot = $serverRoot; } @@ -94,9 +96,8 @@ class SCSSCacher { if($this->isCached($fileNameCSS, $fileNameSCSS, $folder, $path)) { return true; - } else { - return $this->cache($path, $fileNameCSS, $fileNameSCSS, $folder, $webDir); } + return $this->cache($path, $fileNameCSS, $fileNameSCSS, $folder, $webDir); } /** @@ -108,7 +109,7 @@ class SCSSCacher { * @return boolean */ private function isCached($fileNameCSS, $fileNameSCSS, ISimpleFolder $folder, $path) { - try{ + try { $cachedFile = $folder->getFile($fileNameCSS); if ($cachedFile->getSize() > 0) { $depFile = $folder->getFile($fileNameCSS . '.deps'); @@ -124,7 +125,6 @@ class SCSSCacher { } catch(NotFoundException $e) { return false; } - return false; } /** @@ -138,8 +138,11 @@ class SCSSCacher { */ private function cache($path, $fileNameCSS, $fileNameSCSS, ISimpleFolder $folder, $webDir) { $scss = new Compiler(); - $scss->setImportPaths($path); - if($this->systemConfig->getValue('debug')) { + $scss->setImportPaths([ + $path, + \OC::$SERVERROOT . '/core/css/', + ]); + if($this->config->getSystemValue('debug')) { // Debug mode $scss->setFormatter(Expanded::class); $scss->setLineNumberStyle(Compiler::LINE_COMMENTS); @@ -163,7 +166,9 @@ class SCSSCacher { // Compile try { - $compiledScss = $scss->compile('@import "'.$fileNameSCSS.'";'); + $compiledScss = $scss->compile( + '@import "variables.scss";' . + '@import "'.$fileNameSCSS.'";'); } catch(ParserException $e) { $this->logger->error($e, ['app' => 'core']); return false; @@ -174,7 +179,7 @@ class SCSSCacher { $depFile->putContent(json_encode($scss->getParsedFiles())); $this->logger->debug($webDir.'/'.$fileNameSCSS.' compiled and successfully cached', ['app' => 'core']); return true; - } catch(NotFoundException $e) { + } catch(NotPermittedException $e) { return false; } } @@ -188,7 +193,7 @@ class SCSSCacher { private function rebaseUrls($css, $webDir) { $re = '/url\([\'"]([\.\w?=\/-]*)[\'"]\)/x'; // OC\Route\Router:75 - if(($this->systemConfig->getValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true')) { + if(($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true')) { $subst = 'url(\'../../'.$webDir.'/$1\')'; } else { $subst = 'url(\'../../../'.$webDir.'/$1\')'; diff --git a/lib/private/TemplateLayout.php b/lib/private/TemplateLayout.php index 6d2c3b2674f..a9bfaf9a7c7 100644 --- a/lib/private/TemplateLayout.php +++ b/lib/private/TemplateLayout.php @@ -218,7 +218,7 @@ class TemplateLayout extends \OC_Template { \OC::$server->getLogger(), \OC::$server->getAppDataDir('css'), \OC::$server->getURLGenerator(), - \OC::$server->getSystemConfig(), + \OC::$server->getConfig(), \OC::$SERVERROOT ); } else { diff --git a/tests/data/scss/styles-error.scss b/tests/data/scss/styles-error.scss new file mode 100644 index 00000000000..bd6c6d4ffb5 --- /dev/null +++ b/tests/data/scss/styles-error.scss @@ -0,0 +1 @@ +body { error } diff --git a/tests/data/scss/styles-success.scss b/tests/data/scss/styles-success.scss new file mode 100644 index 00000000000..bf4efa71a6a --- /dev/null +++ b/tests/data/scss/styles-success.scss @@ -0,0 +1 @@ +body { background-color: $color-primary; }
\ No newline at end of file diff --git a/tests/lib/Template/SCSSCacherTest.php b/tests/lib/Template/SCSSCacherTest.php new file mode 100644 index 00000000000..d49f0cdc6a1 --- /dev/null +++ b/tests/lib/Template/SCSSCacherTest.php @@ -0,0 +1,278 @@ +<?php +/** + * @copyright Copyright (c) 2017 Julius Härtl <jus@bitgrid.net> + * + * @author Julius Härtl <jus@bitgrid.net> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace Test\Template; + +use OC\Template\SCSSCacher; +use OCP\Files\IAppData; +use OCP\Files\NotFoundException; +use OCP\Files\SimpleFS\ISimpleFile; +use OCP\Files\SimpleFS\ISimpleFolder; +use OCP\IConfig; +use OCP\ILogger; +use OCP\IURLGenerator; + +class SCSSCacherTest extends \Test\TestCase { + /** @var ILogger|\PHPUnit_Framework_MockObject_MockObject */ + protected $logger; + /** @var IAppData|\PHPUnit_Framework_MockObject_MockObject */ + protected $appData; + /** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */ + protected $urlGenerator; + /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ + protected $config; + /** @var \OC_Defaults|\PHPUnit_Framework_MockObject_MockObject */ + protected $defaults; + /** @var SCSSCacher */ + protected $scssCacher; + + protected function setUp() { + parent::setUp(); + $this->logger = $this->createMock(ILogger::class); + $this->appData = $this->createMock(IAppData::class); + $this->urlGenerator = $this->createMock(IURLGenerator::class); + $this->config = $this->createMock(IConfig::class); + $this->scssCacher = new SCSSCacher( + $this->logger, + $this->appData, + $this->urlGenerator, + $this->config, + \OC::$SERVERROOT + ); + } + + public function testProcessUncachedFileNoAppDataFolder() { + $folder = $this->createMock(ISimpleFolder::class); + $this->appData->expects($this->once())->method('getFolder')->with('core')->willThrowException(new NotFoundException()); + $this->appData->expects($this->once())->method('newFolder')->with('core')->willReturn($folder); + $file = $this->createMock(ISimpleFile::class); + $file->expects($this->any())->method('getSize')->willReturn(1); + $fileDeps = $this->createMock(ISimpleFile::class); + $folder->expects($this->at(0))->method('getFile')->with('styles.css')->willReturn($file); + $folder->expects($this->at(1))->method('getFile')->with('styles.css.deps')->willThrowException(new NotFoundException()); + $folder->expects($this->at(2))->method('getFile')->with('styles.css')->willReturn($file); + $folder->expects($this->at(3))->method('getFile')->with('styles.css.deps')->willThrowException(new NotFoundException()); + $folder->expects($this->at(4))->method('newFile')->with('styles.css.deps')->willReturn($fileDeps); + $actual = $this->scssCacher->process(\OC::$SERVERROOT, '/core/css/styles.scss', 'core'); + $this->assertTrue($actual); + } + + public function testProcessUncachedFile() { + $folder = $this->createMock(ISimpleFolder::class); + $this->appData->expects($this->once())->method('getFolder')->with('core')->willReturn($folder); + $file = $this->createMock(ISimpleFile::class); + $file->expects($this->any())->method('getSize')->willReturn(1); + $fileDeps = $this->createMock(ISimpleFile::class); + $folder->expects($this->at(0))->method('getFile')->with('styles.css')->willReturn($file); + $folder->expects($this->at(1))->method('getFile')->with('styles.css.deps')->willThrowException(new NotFoundException()); + $folder->expects($this->at(2))->method('getFile')->with('styles.css')->willReturn($file); + $folder->expects($this->at(3))->method('getFile')->with('styles.css.deps')->willThrowException(new NotFoundException()); + $folder->expects($this->at(4))->method('newFile')->with('styles.css.deps')->willReturn($fileDeps); + $actual = $this->scssCacher->process(\OC::$SERVERROOT, '/core/css/styles.scss', 'core'); + $this->assertTrue($actual); + } + + public function testProcessCacheFile() { + $folder = $this->createMock(ISimpleFolder::class); + $this->appData->expects($this->once())->method('getFolder')->with('core')->willReturn($folder); + $file = $this->createMock(ISimpleFile::class); + $file->expects($this->any())->method('getSize')->willReturn(1); + $fileDeps = $this->createMock(ISimpleFile::class); + $fileDeps->expects($this->any())->method('getSize')->willReturn(1); + $fileDeps->expects($this->once())->method('getContent')->willReturn('{}'); + $folder->expects($this->at(0))->method('getFile')->with('styles.css')->willReturn($file); + $folder->expects($this->at(1))->method('getFile')->with('styles.css.deps')->willReturn($fileDeps); + $actual = $this->scssCacher->process(\OC::$SERVERROOT, '/core/css/styles.scss', 'core'); + $this->assertTrue($actual); + } + + public function testProcessCachedFile() { + $folder = $this->createMock(ISimpleFolder::class); + $this->appData->expects($this->once())->method('getFolder')->with('core')->willReturn($folder); + $file = $this->createMock(ISimpleFile::class); + $file->expects($this->once())->method('getSize')->willReturn(1); + $fileDeps = $this->createMock(ISimpleFile::class); + $fileDeps->expects($this->any())->method('getSize')->willReturn(1); + $fileDeps->expects($this->once())->method('getContent')->willReturn('{}'); + $folder->expects($this->at(0))->method('getFile')->with('styles.css')->willReturn($file); + $folder->expects($this->at(1))->method('getFile')->with('styles.css.deps')->willReturn($fileDeps); + $actual = $this->scssCacher->process(\OC::$SERVERROOT, '/core/css/styles.scss', 'core'); + $this->assertTrue($actual); + } + + public function testIsCachedNoFile() { + $fileNameCSS = "styles.css"; + $fileNameSCSS = "styles.scss"; + $folder = $this->createMock(ISimpleFolder::class); + $path = \OC::$SERVERROOT . '/core/css/'; + + $folder->expects($this->at(0))->method('getFile')->with($fileNameCSS)->willThrowException(new NotFoundException()); + $actual = self::invokePrivate($this->scssCacher, 'isCached', [$fileNameCSS, $fileNameSCSS, $folder, $path]); + $this->assertFalse($actual); + } + + public function testIsCachedNoDepsFile() { + $fileNameCSS = "styles.css"; + $fileNameSCSS = "styles.scss"; + $folder = $this->createMock(ISimpleFolder::class); + $file = $this->createMock(ISimpleFile::class); + $path = \OC::$SERVERROOT . '/core/css/'; + + $file->expects($this->once())->method('getSize')->willReturn(1); + $folder->expects($this->at(0))->method('getFile')->with($fileNameCSS)->willReturn($file); + $folder->expects($this->at(1))->method('getFile')->with($fileNameCSS . '.deps')->willThrowException(new NotFoundException()); + + $actual = self::invokePrivate($this->scssCacher, 'isCached', [$fileNameCSS, $fileNameSCSS, $folder, $path]); + $this->assertFalse($actual); + } + public function testCacheNoFile() { + $fileNameCSS = "styles.css"; + $fileNameSCSS = "styles.scss"; + $folder = $this->createMock(ISimpleFolder::class); + $file = $this->createMock(ISimpleFile::class); + $depsFile = $this->createMock(ISimpleFile::class); + + $webDir = "core/css"; + $path = \OC::$SERVERROOT . '/core/css/'; + + $folder->expects($this->at(0))->method('getFile')->with($fileNameCSS)->willThrowException(new NotFoundException()); + $folder->expects($this->at(1))->method('newFile')->with($fileNameCSS)->willReturn($file); + $folder->expects($this->at(2))->method('getFile')->with($fileNameCSS . '.deps')->willThrowException(new NotFoundException()); + $folder->expects($this->at(3))->method('newFile')->with($fileNameCSS . '.deps')->willReturn($depsFile); + + $file->expects($this->once())->method('putContent'); + $depsFile->expects($this->once())->method('putContent'); + + $actual = self::invokePrivate($this->scssCacher, 'cache', [$path, $fileNameCSS, $fileNameSCSS, $folder, $webDir]); + $this->assertTrue($actual); + } + + public function testCache() { + $fileNameCSS = "styles.css"; + $fileNameSCSS = "styles.scss"; + $folder = $this->createMock(ISimpleFolder::class); + $file = $this->createMock(ISimpleFile::class); + $depsFile = $this->createMock(ISimpleFile::class); + + $webDir = "core/css"; + $path = \OC::$SERVERROOT; + + $folder->expects($this->at(0))->method('getFile')->with($fileNameCSS)->willReturn($file); + $folder->expects($this->at(1))->method('getFile')->with($fileNameCSS . '.deps')->willReturn($depsFile); + + $file->expects($this->once())->method('putContent'); + $depsFile->expects($this->once())->method('putContent'); + + $actual = self::invokePrivate($this->scssCacher, 'cache', [$path, $fileNameCSS, $fileNameSCSS, $folder, $webDir]); + $this->assertTrue($actual); + } + + public function testCacheSuccess() { + $fileNameCSS = "styles-success.css"; + $fileNameSCSS = "../../tests/data/scss/styles-success.scss"; + $folder = $this->createMock(ISimpleFolder::class); + $file = $this->createMock(ISimpleFile::class); + $depsFile = $this->createMock(ISimpleFile::class); + + $webDir = "tests/data/scss"; + $path = \OC::$SERVERROOT . $webDir; + + $folder->expects($this->at(0))->method('getFile')->with($fileNameCSS)->willReturn($file); + $folder->expects($this->at(1))->method('getFile')->with($fileNameCSS . '.deps')->willReturn($depsFile); + + $file->expects($this->at(0))->method('putContent')->with($this->callback( + function ($content){ + return 'body{background-color:#0082c9}' === $content; + })); + $depsFile->expects($this->at(0))->method('putContent')->with($this->callback( + function ($content) { + $deps = json_decode($content, true); + return array_key_exists(\OC::$SERVERROOT . '/core/css/variables.scss', $deps) + && array_key_exists(\OC::$SERVERROOT . '/tests/data/scss/styles-success.scss', $deps); + })); + + $actual = self::invokePrivate($this->scssCacher, 'cache', [$path, $fileNameCSS, $fileNameSCSS, $folder, $webDir]); + $this->assertTrue($actual); + } + + public function testCacheFailure() { + $fileNameCSS = "styles-error.css"; + $fileNameSCSS = "../../tests/data/scss/styles-error.scss"; + $folder = $this->createMock(ISimpleFolder::class); + $file = $this->createMock(ISimpleFile::class); + $depsFile = $this->createMock(ISimpleFile::class); + + $webDir = "/tests/data/scss"; + $path = \OC::$SERVERROOT . $webDir; + + $folder->expects($this->at(0))->method('getFile')->with($fileNameCSS)->willReturn($file); + $folder->expects($this->at(1))->method('getFile')->with($fileNameCSS . '.deps')->willReturn($depsFile); + + $actual = self::invokePrivate($this->scssCacher, 'cache', [$path, $fileNameCSS, $fileNameSCSS, $folder, $webDir]); + $this->assertFalse($actual); + } + + public function testRebaseUrls() { + $webDir = 'apps/files/css'; + $css = '#id { background-image: url(\'../img/image.jpg\'); }'; + $actual = self::invokePrivate($this->scssCacher, 'rebaseUrls', [$css, $webDir]); + $expected = '#id { background-image: url(\'../../../apps/files/css/../img/image.jpg\'); }'; + $this->assertEquals($expected, $actual); + } + + public function testRebaseUrlsIgnoreFrontendController() { + $this->config->expects($this->once())->method('getSystemValue')->with('htaccess.IgnoreFrontController', false)->willReturn(true); + $webDir = 'apps/files/css'; + $css = '#id { background-image: url(\'../img/image.jpg\'); }'; + $actual = self::invokePrivate($this->scssCacher, 'rebaseUrls', [$css, $webDir]); + $expected = '#id { background-image: url(\'../../apps/files/css/../img/image.jpg\'); }'; + $this->assertEquals($expected, $actual); + } + + public function dataGetCachedSCSS() { + return [ + ['core', 'core/css/styles.scss', '/css/core/styles.css'], + ['files', 'apps/files/css/styles.scss', '/css/files/styles.css'] + ]; + } + + /** + * @param $appName + * @param $fileName + * @param $result + * @dataProvider dataGetCachedSCSS + */ + public function testGetCachedSCSS($appName, $fileName, $result) { + $this->urlGenerator->expects($this->once()) + ->method('linkToRoute') + ->with('core.Css.getCss', [ + 'fileName' => 'styles.css', + 'appName' => $appName + ]) + ->willReturn(\OC::$WEBROOT . $result); + $actual = $this->scssCacher->getCachedSCSS($appName, $fileName); + $this->assertEquals(substr($result, 1), $actual); + } + + +}
\ No newline at end of file |