diff --git a/core/shared/ghost.css b/core/shared/ghost.css new file mode 100644 index 0000000000..fb6a750771 --- /dev/null +++ b/core/shared/ghost.css @@ -0,0 +1,833 @@ +/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS and IE text size adjust after device orientation change, + * without disabling user zoom. + */ +html { + font-family: sans-serif; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} +/** + * Remove default margin. + */ +body { + margin: 0; +} +/* HTML5 display definitions + ========================================================================== */ +/** + * Correct `block` display not defined for any HTML5 element in IE 8/9. + * Correct `block` display not defined for `details` or `summary` in IE 10/11 + * and Firefox. + * Correct `block` display not defined for `main` in IE 11. + */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} +/** + * 1. Correct `inline-block` display not defined in IE 8/9. + * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. + */ +audio, +canvas, +progress, +video { + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ +} +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ +audio:not([controls]) { + display: none; + height: 0; +} +/** + * Address `[hidden]` styling not present in IE 8/9/10. + * Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22. + */ +[hidden], +template { + display: none; +} +/* Links + ========================================================================== */ +/** + * Remove the gray background color from active links in IE 10. + */ +a { + background-color: transparent; +} +/** + * Improve readability of focused elements when they are also in an + * active/hover state. + */ +a:active, +a:hover { + outline: 0; +} +/* Text-level semantics + ========================================================================== */ +/** + * Address styling not present in IE 8/9/10/11, Safari, and Chrome. + */ +abbr[title] { + border-bottom: 1px dotted; +} +/** + * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. + */ +b, +strong { + font-weight: bold; +} +/** + * Address styling not present in Safari and Chrome. + */ +dfn { + font-style: italic; +} +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari, and Chrome. + */ +h1 { + font-size: 2em; + margin: 0.67em 0; +} +/** + * Address styling not present in IE 8/9. + */ +mark { + background: #ff0; + color: #000; +} +/** + * Address inconsistent and variable font size in all browsers. + */ +small { + font-size: 80%; +} +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} +/* Embedded content + ========================================================================== */ +/** + * Remove border when inside `a` element in IE 8/9/10. + */ +img { + border: 0; +} +/** + * Correct overflow not hidden in IE 9/10/11. + */ +svg:not(:root) { + overflow: hidden; +} +/* Grouping content + ========================================================================== */ +/** + * Address margin not present in IE 8/9 and Safari. + */ +figure { + margin: 1em 40px; +} +/** + * Address differences between Firefox and other browsers. + */ +hr { + box-sizing: content-box; + height: 0; +} +/** + * Contain overflow in all browsers. + */ +pre { + overflow: auto; +} +/** + * Address odd `em`-unit font size rendering in all browsers. + */ +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} +/* Forms + ========================================================================== */ +/** + * Known limitation: by default, Chrome and Safari on OS X allow very limited + * styling of `select`, unless a `border` property is set. + */ +/** + * 1. Correct color not being inherited. + * Known issue: affects color of disabled elements. + * 2. Correct font properties not being inherited. + * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. + */ +button, +input, +optgroup, +select, +textarea { + color: inherit; /* 1 */ + font: inherit; /* 2 */ + margin: 0; /* 3 */ +} +/** + * Address `overflow` set to `hidden` in IE 8/9/10/11. + */ +button { + overflow: visible; +} +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. + * Correct `select` style inheritance in Firefox. + */ +button, +select { + text-transform: none; +} +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + */ +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ +} +/** + * Re-set default cursor for disabled elements. + */ +button[disabled], +html input[disabled] { + cursor: default; +} +/** + * Remove inner padding and border in Firefox 4+. + */ +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ +input { + line-height: normal; +} +/** + * It's recommended that you don't attempt to style these elements. + * Firefox's implementation doesn't respect box-sizing, padding, or width. + * + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. + */ +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} +/** + * Fix the cursor style for Chrome's increment/decrement buttons. For certain + * `font-size` values of the `input`, it causes the cursor style of the + * decrement button to change from `default` to `text`. + */ +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} +/** + * 1. Address `appearance` set to `searchfield` in Safari and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari and Chrome. + */ +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + box-sizing: content-box; /* 2 */ +} +/** + * Remove inner padding and search cancel button in Safari and Chrome on OS X. + * Safari (but not Chrome) clips the cancel button when the search input has + * padding (and `textfield` appearance). + */ +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +/** + * Define consistent border, margin, and padding. + */ +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} +/** + * 1. Correct `color` not being inherited in IE 8/9/10/11. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ +} +/** + * Remove default vertical scrollbar in IE 8/9/10/11. + */ +textarea { + overflow: auto; +} +/** + * Don't inherit the `font-weight` (applied by a rule above). + * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. + */ +optgroup { + font-weight: bold; +} +/* Tables + ========================================================================== */ +/** + * Remove most spacing between table cells. + */ +table { + border-collapse: collapse; + border-spacing: 0; +} +td, +th { + padding: 0; +} +/* Patterns: Groups of Styles +/* ---------------------------------------------------------- */ +/* Global styles +/* ---------------------------------------------------------- */ +/* Variables +/* ---------------------------------------------------------- */ +:root { + /* Colours */ + /* Style values */ +} +/* Colour classes +/* ---------------------------------------------------------- */ +.darkgrey { + color: #343f44; +} +.midgrey { + color: #738a94; +} +.lightgrey { + color: #e5eff5; +} +.blue { + color: #3eb0ef; +} +.red { + color: #f05230; +} +.orange { + color: #fecd35; +} +.green { + color: #a4d037; +} +/* Colour classes (hover) +/* ---------------------------------------------------------- */ +.darkgrey-hover:hover { + color: #343f44; +} +.midgrey-hover:hover { + color: #738a94; +} +.lightgrey-hover:hover { + color: #e5eff5; +} +.blue-hover:hover { + color: #3eb0ef; +} +.red-hover:hover { + color: #f05230; +} +.orange-hover:hover { + color: #fecd35; +} +.green-hover:hover { + color: #a4d037; +} + +/* Layout +/* ---------------------------------------------------------- */ +*, +*:before, +*:after { + box-sizing: border-box; +} +html { + overflow: hidden; + width: 100%; + /* Prevent elastic scrolling on the whole page */ + height: 100%; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; + font-size: 62.5%; + line-height: 1.65; + letter-spacing: 0.2px; + + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +body { + overflow: auto; + overflow-x: hidden; + width: 100%; + /* Prevent elastic scrolling on the whole page */ + height: 100%; + color: #343f44; + font-size: 1.4rem; +} + +.gh-view { + -ms-flex-positive: 1; + flex-grow: 1; + display: -ms-flexbox; + display: flex; + -ms-flex-direction: column; + flex-direction: column; +} + +/* Text +/* ---------------------------------------------------------- */ +h1 { + margin: 0 0 0.3em 0; + color: #343f44; + line-height: 1.15em; + text-rendering: optimizeLegibility; + text-indent: -1px; + font-size: 2.9rem; +} + +h2 { + margin: 0 0 0.3em 0; + color: #343f44; + line-height: 1.15em; + text-rendering: optimizeLegibility; + text-indent: -1px; + font-size: 2.9rem; +} + +@media (max-width: 500px) { + h1 { + font-size: 2.4rem; + } +} +/* Inputs +/* ---------------------------------------------------------- */ +.gh-input { + display: block; + padding: 10px 12px; + width: 100%; + height: 40px; + border: rgb(214, 227, 235) 1px solid; + border-radius: 4px; + color: rgb(75, 91, 98); + font-size: 1.6rem; + line-height: 1em; + font-weight: 300; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + transition: border-color 0.15s linear; + + -webkit-appearance: none; +} + +.gh-input:focus { + outline: 0; + border-color: rgb(180, 203, 218); +} + +/* Buttons +/* ---------------------------------------------------------- */ +/* Base button style */ +/* Should only be applied to tags */ +.gh-btn { + display: inline-block; + outline: none; + border: 1px solid rgb(214, 227, 235); + color: rgb(130, 154, 168); + text-shadow: 0 1px 0 #fff; + text-decoration: none !important; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + fill: rgb(130, 154, 168); + border-radius: 5px; + transition: all 0.2s ease; + + -webkit-font-smoothing: subpixel-antialiased; +} +/* ALL buttons must have a span for content */ +.gh-btn span { + display: block; + padding: 0 12px; + height: 33px; + font-size: 1.3rem; + line-height: 33px; + font-weight: 400; + text-align: center; + letter-spacing: 0.2px; + border-radius: 4px; +} +.gh-btn:hover { + border-color: rgb(180, 203, 218); +} + +/* Button highlights +/* ---------------------------------------------------------- */ +.gh-btn-hover-blue:hover { + border-color: #3eb0ef; + color: #3eb0ef; +} + +/* Blue button +/* ---------------------------------------------------------- */ +/* The background of the button creates 1px gradient border */ +.gh-btn-blue { + padding: 1px; + border: 0; + color: #fff; + text-shadow: 0 -1px 0 rgba(0,0,0,0.1); + fill: #fff; + background: linear-gradient( + rgb(61, 161, 214), + rgb(34, 136, 191) + ); + box-shadow: 0 1px 0 rgba(0,0,0,0.12); + transition: none !important; +} +/* The background of the span is the main visual element */ +.gh-btn-blue span { + background: linear-gradient( + rgb(74, 182, 240), + rgb(47, 165, 228) 60%, + rgb(47, 165, 228) 90%, + rgb(56, 169, 229) + ); + box-shadow: 0 1px 0 rgba(255,255,255,0.1) inset; +} +/* When clicked or focused with keyboard */ +.gh-btn-blue:active, +.gh-btn-blue:focus { + background: rgb(30, 120, 169); +} +.gh-btn-blue:active span, +.gh-btn-blue:focus span { + background: rgb(41, 160, 224); + box-shadow: none; +} +/* Special Buttons +/* ---------------------------------------------------------- */ +.gh-btn-block { + display: block; + width: 100%; +} + +/* Layouts: Groups of Components +/* ---------------------------------------------------------- */ +/* Global Layout +/* ---------------------------------------------------------- */ + +/* Main viewport, contains main content, and alerts */ +.gh-app { + display: -ms-flexbox; + display: flex; + -ms-flex-direction: column; + flex-direction: column; + overflow: hidden; + height: 100%; +} +/* Content viewport, contains everything else */ +.gh-viewport { + -ms-flex-positive: 1; + flex-grow: 1; + display: -ms-flexbox; + display: flex; + overflow: hidden; + max-height: 100%; +} +.gh-main { + position: relative; + -ms-flex-positive: 1; + flex-grow: 1; + display: -ms-flexbox; + display: flex; + background: #fff; + overflow-y: auto; +} + +/* Full screen workflow +/* ---------------------------------------------------------- */ +.gh-flow { + -ms-flex-positive: 1; + flex-grow: 1; + display: -ms-flexbox; + display: flex; + -ms-flex-direction: column; + flex-direction: column; + overflow-y: auto; + min-height: 100%; +} +.gh-flow-head { + -ms-flex-negative: 0; + flex-shrink: 0; + display: -ms-flexbox; + display: flex; + -ms-flex-pack: justify; + justify-content: space-between; + padding-top: 4vh; + padding-bottom: 20px; +} +.gh-flow-content-wrap { + -ms-flex-positive: 1; + flex-grow: 1; + -ms-flex-negative: 0; + flex-shrink: 0; + display: -ms-flexbox; + display: flex; + -ms-flex-pack: center; + justify-content: center; + -ms-flex-align: center; + align-items: center; + margin: 0 5%; + padding-bottom: 8vh; +} +.gh-flow-back { + position: absolute; + top: 0; + left: 0; + display: -ms-flexbox; + display: flex; + -ms-flex-align: center; + align-items: center; + margin: 0 0 0 3%; + padding: 2px 9px 2px 5px; + border: transparent 1px solid; + border-radius: 4px; + color: #7d878a; + font-weight: 100; + transition: all 0.3s ease; +} +.gh-flow-back i { + margin-right: 4px; + font-size: 12px; + line-height: 8px; +} +.gh-flow-back:hover { + border: #dae1e3 1px solid; +} +.gh-flow-nav { + position: relative; + -ms-flex: 1; + flex: 1; +} +.gh-flow-content { + display: -ms-flexbox; + display: flex; + -ms-flex-direction: column; + flex-direction: column; + max-width: 700px; + width: 100%; + color: #738a94; + text-align: center; + font-size: 1.9rem; + line-height: 1.5em; + font-weight: 100; +} +@media (max-width: 500px) { + .gh-flow-content { + font-size: 4vw; + } +} +.gh-flow-content header { + margin: 0 auto; + max-width: 520px; +} +.gh-flow-content h1 { + font-size: 4.2rem; + font-weight: 100; +} +@media (max-width: 600px) { + .gh-flow-content h1 { + font-size: 7vw; + } +} +.gh-flow-content .gh-btn { + display: block; + margin: 20px auto 0; + max-width: 400px; +} +.gh-flow-content .form-group { + margin-bottom: 2.5rem; +} +.gh-flow-content input { + padding: 10px; + border: #dae1e3 1px solid; + font-size: 1.6rem; + line-height: 1.4em; + font-weight: 100; +} + +/* Sign in +/* ---------------------------------------------------------- */ +.gh-signin { + position: relative; + margin: 30px auto; + padding: 40px; + max-width: 400px; + width: 100%; + border: #dae1e3 1px solid; + background: #f8fbfd; + border-radius: 5px; + text-align: left; +} +.gh-signin .form-group { + margin-bottom: 1.5rem; +} +.gh-signin .gh-btn { + margin: 0; +} + +/* Error /ghost/404/ +/* ---------------------------------------------------------- */ + +.error-content { + flex-grow: 1; + display: flex; + justify-content: center; + align-items: center; + user-select: text; +} + +.error-details { + display: flex; + align-items: center; + margin-bottom: 4rem; +} + +.error-ghost { + margin: 15px; + height: 115px; +} + +@media (max-width: 630px) { + .error-ghost { + display: none; + } +} + +.error-code { + margin: 0; + color: #979797; + font-size: 7.8rem; + line-height: 0.9em; +} + + +.error-description { + margin: 0; + padding: 0; + border: none; + color: #979797; + font-size: 1.9rem; + font-weight: 300; +} + +.error-message { + display: flex; + flex-direction: column; + margin: 15px; +} + +.error-message a { + margin-top: 5px; + font-size: 1.4rem; + line-height: 1; +} + +.error-link { + background-color: transparent; + color: #5ba4e5; + transition: background .3s,color .3s; + text-decoration: none; +} + +/* Stack trace +/* ---------------------------------------------------------- */ + +.error-stack { + margin: 1rem auto; + padding: 2rem; + max-width: 800px; + background-color: rgba(255, 255, 255, 0.3); +} + +.error-stack-list { + margin: 0; + padding: 0; + list-style-type: none; +} + +.error-stack-list li { + display: block; +} + +.error-stack-list li:before { + content: "\21AA"; + display: inline-block; + margin-right: 0.5rem; + color: #bbb; + font-size: 1.2rem; +} + +.error-stack-function { + font-weight: bold; +} diff --git a/core/test/unit/metadata/asset_url_spec.js b/core/test/unit/metadata/asset_url_spec.js index c360ffd3aa..fe89fce52a 100644 --- a/core/test/unit/metadata/asset_url_spec.js +++ b/core/test/unit/metadata/asset_url_spec.js @@ -28,6 +28,11 @@ describe('getAssetUrl', function () { testUrl.should.equal('/favicon.ico'); }); + it('should not add ghost or asset to url if ghost.css for default templates', function () { + var testUrl = getAssetUrl('shared/ghost.css'); + testUrl.should.equal('/shared/ghost.css?v=' + config.get('assetHash')); + }); + it('should not add ghost or asset to url has shared in it', function () { var testUrl = getAssetUrl('shared/myfile.js'); testUrl.should.equal('/shared/myfile.js?v=' + config.get('assetHash')); diff --git a/core/test/unit/server_helpers/asset_spec.js b/core/test/unit/server_helpers/asset_spec.js index a9d7b96317..be0677c3b5 100644 --- a/core/test/unit/server_helpers/asset_spec.js +++ b/core/test/unit/server_helpers/asset_spec.js @@ -35,6 +35,18 @@ describe('{{asset}} helper', function () { String(rendered).should.equal('/favicon.ico'); }); + it('handles ghost.css for default templates correctly', function () { + // with ghost set + rendered = helpers.asset('shared/ghost.css', {hash: {ghost: 'true'}}); + should.exist(rendered); + String(rendered).should.equal('/shared/ghost.css?v=abc'); + + // without ghost set + rendered = helpers.asset('shared/ghost.css'); + should.exist(rendered); + String(rendered).should.equal('/shared/ghost.css?v=abc'); + }); + it('handles custom favicon correctly', function () { localSettingsCache.icon = '/content/images/favicon.png'; @@ -107,6 +119,18 @@ describe('{{asset}} helper', function () { String(rendered).should.equal('/blog/favicon.ico'); }); + it('handles ghost.css for default templates correctly', function () { + // with ghost set + rendered = helpers.asset('shared/ghost.css', {hash: {ghost: 'true'}}); + should.exist(rendered); + String(rendered).should.equal('/blog/shared/ghost.css?v=abc'); + + // without ghost set + rendered = helpers.asset('shared/ghost.css'); + should.exist(rendered); + String(rendered).should.equal('/blog/shared/ghost.css?v=abc'); + }); + it('handles custom favicon correctly', function () { localSettingsCache.icon = '/content/images/favicon.png';