Compare commits

...

156 Commits
2.0.3 ... 2.9.8

Author SHA1 Message Date
23bd9cc1d5 2.9.8 2019-04-04 14:58:47 +01:00
8e5c1b22dd Updated .travis.yml file
- ran slimer fix travis to get latest settings
2019-04-03 19:38:58 +01:00
c4fb156508 Added SECURITY.md file
- Consistent with other public repos
- Points at our docs on how to report security issues
2019-04-03 19:38:16 +01:00
91ffa335de Update Renovate Configuration
Updates the base configuration to include:
- node support policy
- lockfile maintenance
- optimistic automerging
2019-04-02 17:54:50 +01:00
0d8f4471d9 2.9.7 2019-04-02 10:02:13 +01:00
4464d5809b Fixed deprecated {{lang}} helper usage
no issue

- {{lang}} helper was deprecated in favor of {{@site.lang}} with 73e008270d
2019-04-02 12:39:00 +08:00
37c0f22b09 2.9.6 2019-03-19 16:41:50 +05:30
7706045616 Update dependency @tryghost/release-utils to v0.3.1 2019-03-19 14:38:30 +05:30
51b93e389c Update dependency autoprefixer to v9.5.0 (#553) 2019-03-18 14:29:41 +00:00
b1ce464ea3 Added .yarnrc
no issue

- Casper uses `%s` tag naming
- Let's keep this, otherwise release order is broken
- Ghost & Ghost-Admin use this notation too
- It will tell `yarn version` to use `%s` instead of `v%s`
2019-03-15 14:38:26 +01:00
8729dafcf5 Extended yarn ship: more automation
no issue

- added gulp task to extend casper release automation
- will draft the release for you
- will get the user facing commits from changelog
- runs after `yarn ship` (postship)
- full automation with env variables is possible
2019-03-15 14:38:26 +01:00
406ef78109 Gulpfile ES6
no issue

- ES6
2019-03-15 14:38:26 +01:00
2bf64cbffc v2.9.5 2019-03-12 18:38:14 +00:00
a212518827 🐛 Fixed incorrect/missing colours for various elements
closes https://github.com/TryGhost/Casper/issues/548
- the recent postcss upgrade resulted in real CSS variables being output with a fallback mechanism, unfortunately this broke a number of colors throughout the theme
- disabled the fallback mechanism to revert back to the previous behaviour
2019-03-12 18:14:48 +00:00
2da714ef2e Upgrading Casper to 2.9.4 2019-03-12 20:23:45 +08:00
66def0d7c0 Update Renovate Configuration
- schedule renovate for early monday mornings
2019-03-10 17:50:24 +00:00
6640701aeb Regenerate yarn.lock
- results in clean lodash versions
- needed due to lodash security vuln
2019-03-10 17:44:44 +00:00
7fec21f7d9 Update dependency gscan to v2.3.0 2019-03-10 17:39:42 +00:00
018423738e 🛠 Always build before test, test before ship
- Make sure we update our build files before running tests
- This also ensures they get updated before shipping
2019-03-10 17:30:20 +00:00
371ad586d3 Updated all built assets
- many dependencies have changed, need to rebuild
2019-03-10 17:30:20 +00:00
06c8020c16 Re-written gulpfile for gulp 4
- use the new, simpler format
- sourcemap and watch support is built in, so these plugins can be removed
- remove js filter - not sure what that did :/
- simplified task structure
2019-03-10 17:30:20 +00:00
3a40332515 Update gulp 2019-03-10 17:30:20 +00:00
56c9795306 Update css processors 2019-03-10 16:09:25 +00:00
dd19a0a65b Update css processors 2019-03-10 16:07:35 +00:00
3b3a091069 Update gulp 2019-03-10 15:27:03 +00:00
ff189b7c08 Update dependency gscan to v2.2.1 2019-03-10 15:21:18 +00:00
5bbaa68863 Update Renovate Configuration
- make PR names make more sense
2019-03-10 15:19:51 +00:00
10672c642e 🐛 Fixed author cover images not displaying
closes https://github.com/TryGhost/Casper/issues/542
- user model has `cover_image` property rather than `feature_image`
2019-03-08 08:47:58 +00:00
3e7a85a82e Update renovate.json
- group CSS dependencies together
2019-03-04 19:53:35 +00:00
8fa0aa1b64 Pin dependencies 2019-03-04 19:48:25 +00:00
18018d9edf Update renovate.json 2019-03-04 19:45:12 +00:00
e0faae69ed Add renovate.json 2019-03-04 19:45:12 +00:00
bf89e8e5ab v2.9.3 2019-02-21 11:56:29 +01:00
c8c63d170c Fix bug with embeds overflowing content width 2019-02-18 12:54:29 +07:00
40ae0e97f9 Upgrading Casper to 2.9.2 2019-02-12 16:17:57 +05:30
6541544026 Added "yarn ship" command
no issue

- @TODO: add the ability to draft a release when running `yarn ship`
2019-02-11 19:30:21 +01:00
d92b90db96 Updated .travis.yml to use Node v10
no issue

- see 99c3338ca9 (diff-354f30a63fb0907d4ad57269548329e3)
- see https://docs.ghost.org/faq/node-versions/
2019-02-11 16:42:11 +01:00
9ababa2886 Upgrading Casper to 2.9.1 2019-01-22 11:04:56 +00:00
047c7c0c9c Added missing closing brackets in partials/header.hbs styles (#521) 2019-01-22 11:04:03 +00:00
273e987240 Updated gulp to handle errors for every stream (#500)
no-issue

Previously we only added an error handler to the first stream in each
pipeline, this meant that if another stream errors you would get
unhelpful error handlers.
2019-01-22 11:00:10 +00:00
0171b3e05b Use a larger logo size (#520) 2019-01-15 22:51:08 +07:00
72a9416197 Upgrading Casper to 2.9.0 2019-01-15 14:01:40 +01:00
f57f9ebc99 Update no-image classes
Closes https://github.com/TryGhost/Casper/pull/513
2019-01-15 15:06:19 +07:00
b2322157d5 Migrated from @blog -> @site
no issue

- This rename is due to new {{@site}} alias introduced in Ghost (dd1cf5ffc7) as {{@blog}} variable is deprecated now, and will be removed in v3
2019-01-08 17:37:14 +00:00
3b8f3f1eac Bumped default Ghost API version to v2
no issue

- This change is due to Content API becoming stable https://github.com/TryGhost/Ghost/releases/tag/2.10.0
2019-01-08 14:30:22 +00:00
7d080d564f Upgrading Casper to 2.8.1 2019-01-08 11:48:06 +00:00
3388283f02 2019 2019-01-01 14:18:28 +00:00
475c015fa2 Upgrading Casper to 2.8.0 2018-12-17 14:13:04 +00:00
79ebbd50a3 Responsive images (#505) 2018-12-17 12:25:57 +00:00
a22dda9694 Upgrading Casper to 2.7.1
no issue
2018-12-11 12:03:03 +01:00
3c2347c7f9 🎨 Optimised infinite scroll (#503)
no issue
- removed jQuery usage
- use the `<link rel="next">` tag provided by Ghost to determine the next page to fetch
2018-12-05 12:38:11 +00:00
f695d69aeb Upgrading Casper to 2.7.0 2018-10-16 15:45:26 +01:00
d53b25bf5d Remove double slash in link
no issue
2018-10-12 12:56:54 +07:00
bef56a2294 Minified js (#485)
no issue

- Added a `js` task to run on the gulp build process and minifies our js files
- Changed the required scripts in `default.hbs` to use the minified js files in `/built/`
- Moved existing `js` tasks from `zip` task
2018-10-12 12:41:06 +07:00
5ad6e1ed1f Add titles to icon links 2018-10-12 12:01:05 +07:00
36971db512 Upgrading Casper to 2.6.4 2018-10-09 16:06:07 +02:00
bfcab7172f Minified javascript in zip(#476)
no issue

* Added js minification step to gulp zip script
2018-10-08 16:34:07 +05:30
fce92d6cf1 Link to required dependencies
Refs https://github.com/TryGhost/Casper/pull/468
2018-10-08 11:45:06 +07:00
d48178fde9 Remove css rule that stops syntax highlighting (#484)
* Remove suspect css rule

Removed the ".post-full-content pre code * { color: inherit }" rule which prevents highlight.js from working.

* Changed to just exclude span

Less disruptive to just remove span from color inheritance.

* Remove extra newline
2018-10-08 06:40:06 +02:00
6f4fe840b3 [Fix] Inline <code> tag word-break inside a <p> tag (#483) 2018-10-08 06:38:28 +02:00
8a9efb5ef1 Upgrading Casper to 2.6.3 2018-09-25 11:32:08 +07:00
04854967a8 Adjusting spaces for galleries and wide images in a sequence (#480) 2018-09-24 14:35:47 +02:00
fa18115aa6 Upgrading Casper to 2.6.2 2018-09-11 13:42:34 +02:00
ae192a9fff 🐛 Fixed word-wrap for extra long anchor links text (#478)
refs #466

Anchor links didn't break, when the text was too long. Using `word-break: break-all` specifically on a-tags in post-content fixes this without screwing up other tags and their breaks.
2018-09-07 14:45:18 +02:00
78993720fd Upgrading Casper to 2.6.1 2018-08-31 11:26:01 +01:00
676e17bd13 Restructure spacings for generic figure element 2018-08-31 11:24:50 +01:00
67e595741c Upgrading Casper to 2.6.0 2018-08-30 17:45:43 +01:00
7a88c88ea2 Added Koenig gallery card support (#475)
no issue

- Update CSS and JS for new gallery card
- Updates CSS to support new gallery card
- Adds JS to support grid layout for gallery view
- Fix gallery breakout size
- Refining styles for gallery card
2018-08-30 17:44:55 +01:00
a0e42e0599 Rebuild CSS 2018-08-30 14:56:38 +01:00
dc3bb316c7 Fixed incorrect image aspect ratio when images have width/height attrs
no issue
- when large images have width/height attributes but the image is constrained to it's container or `max-width` style the aspect ratio would be broken because browsers use the `height` attribute value even though the width is smaller
2018-08-30 14:49:40 +01:00
7380ed0291 Upgrading Casper to 2.5.1 2018-08-22 14:31:02 +02:00
ecaf3d921f 🐛 Fixed image positioning on pages
closes https://github.com/TryGhost/Casper/issues/473
- added missing `<div class="post-content">` wrapper around `{{content}}`
2018-08-21 17:47:42 +01:00
89ea6c5872 Upgrading Casper to 2.5.0 2018-08-16 13:59:03 +02:00
9d803067a4 🛠 Added .travis.yml and gscan tests (#470)
- Add gscan dependency & travis.yml file, so that we can run gscan as a test for this repo
- This check tells us whether or not the theme is valid & compatible with Ghost according to gscan
- We recommend that all themes do this!
2018-08-14 22:10:01 +01:00
0ea375643b Added required "ghost-theme" keyword
- We're going to start showing this as a warning in gscan
- The purpose is to give us a way to detect if a package is a valid Ghost theme
2018-08-13 14:29:56 +01:00
f31957bd0d Replaced {{author}} by {{primary_author}} in byline-single.hbs
refs https://github.com/TryGhost/gscan/issues/99

- single author usages will be deprecated in Ghost 2.0
- make Casper 100% compatible with Ghost 2.0
2018-08-12 15:02:03 +02:00
36841d4624 Set minimum Ghost version to 2.0 2018-08-11 20:22:43 +01:00
d41fcbbc8a Remove .kg-card-markdown styles
no issue
- `.kg-card-markdown` no longer exists in Ghost 2.x
2018-08-11 19:09:58 +01:00
5d318225f5 Upgrading Casper to 2.4.2 2018-08-08 17:08:21 +02:00
9b56779ca6 Use id attribute to query reading progress element (#467)
no issue
- using an `id` selector doesn't break if other `progress` elements are present on a page
2018-08-03 09:21:05 +01:00
1bf2cdb52a Upgrading Casper to 2.4.1 2018-07-31 11:31:35 +01:00
f67caaba5c 🐛 Fixed content overflow on mobile
closes https://github.com/TryGhost/Casper/issues/464
- setting max-width of `kg-markdown-card` wrapper that is still used by non-Koenig posts
2018-07-30 12:21:17 +01:00
25d1e368d6 Upgrading Casper to 2.4.0 2018-07-24 15:13:30 +02:00
5c6cce1519 Ghost 1.25 Koenig updates (#463)
refs https://github.com/TryGhost/Ghost/pull/9741
- Ghost 1.25 has updated the HTML output of Koenig beta posts
  - the `<div class="kg-post">` wrapper around post content has been removed
  - for image cards the `.kg-image-wide` and `.kg-image-full` classes have been changed to `.kg-width-wide` and `.kg-width-full` and applied to the `<figure>` element rather than the `<img>` element
- this will be the default for *all* posts after upgrading to Ghost 2.0

Example output of the `{{content}}` helper for Koenig beta...

Before 1.25.0 (Ghost 1.23.0-1.24.9):
```html
<div class="kg-post">
    <figure class="kg-image-card">
        <img class="kg-image kg-image-wide" src="...">
        <figcaption>example wide image</figcaption>
    </figure>
</div>
```

After 1.25.0:
```html
<figure class="kg-image-card kg-width-wide">
    <img class="kg-image" src="...">
    <figcaption>example wide image</figcaption>
</figure>
```

For reference, in Ghost 1.x a non Koenig post with nothing but an image in the markdown (`![](...)`) would generate output like this:

```html
<div class="kg-card-markdown">
    <img src="...">
</div>
```
2018-07-23 12:20:46 +01:00
019842155a Upgrading Casper to 2.3.3 2018-06-14 17:00:26 +01:00
1860a8305b Koenig embed card (#460) 2018-06-13 18:34:59 +01:00
6417b4cf2a Fix rendering bug for non-square user images 2018-06-06 19:29:22 -07:00
1c61bc5f16 Upgrading Casper to 2.3.2 2018-05-29 16:10:07 +01:00
7a7f04c716 Update built files 2018-05-29 16:09:40 +01:00
fd56128f9b Upgrading Casper to 2.3.1 2018-05-29 15:40:50 +01:00
cd3b470c18 Fix for missing default avatar and firefox footer misalignment (#458) 2018-05-29 10:38:27 +02:00
f3b44a7411 Upgrading Casper to 2.3.0 2018-05-22 20:17:56 +01:00
b83917060f Applying styles for Koenig content (#455)
refs https://github.com/TryGhost/Ghost/issues/9311
- move `.kg-card-markdown` styles and add deprecation notice
- add support for new `.kg-post` wrapper
- add support for `.kg-image` and `.kg-image-wide/full` image variants
- add support for image captions
2018-05-22 19:09:58 +01:00
4aaedf69d2 Running CSSComb 2018-05-21 17:36:08 +02:00
03ac0d91b8 Upgrading Casper to 2.2.1 2018-04-24 10:53:15 +08:00
b55d5e2b32 Remove unnecessary role attributes from main element
Source: https://validator.w3.org/nu/#textarea
2018-04-17 22:19:05 +02:00
4fe2eac739 Additional comments 2018-04-12 10:05:53 +02:00
6e3399366d Small refactor of multi-authors 2018-04-12 10:05:40 +02:00
98e9c12018 Split out different byline templates into separate files 2018-04-11 11:05:25 +02:00
986a954f33 Upgrading Casper to 2.2.0
no issue
2018-04-10 23:27:53 +02:00
636882bce4 Fix mobile display bug on smaller screens 2018-04-10 20:34:35 +02:00
79e113226c Multiple authors in Casper (#448) 2018-04-10 20:19:29 +02:00
8e865b797b Maybe fix it properly this time instead of completely failing 2018-04-10 15:29:09 +02:00
a655b59e69 Fix link target size 2018-04-10 15:27:01 +02:00
b078dcb86e Updated hover animations 2018-04-10 15:21:25 +02:00
d5002f2c51 🐛 Fixed infinitescroll when a paged url is loaded directly (#447)
closes #445
- added an fn to sanitize the pathname, that might include a pagination url
- fixed an issue, where the request would still be made if the current page is bigger than max pages
- added comments
2018-04-10 10:04:43 +01:00
41bcbb7157 💨 Infinite scroll perf improvements
no issue
- swap jQuery HTML parsing and insertion for pure DOM
- remove fade animation
- increase buffer by 100px so next page request happens sooner
2018-04-09 11:03:48 +01:00
452776939c Added yarn.lock and updated README for new yarn scripts
no issue
2018-04-09 16:19:05 +08:00
57c31ddacb Add HTML lang head tag (#429)
Refs #286
2018-04-06 20:49:42 +02:00
21088b1d38 Slack -> Forum
- replacing references to slack with forum
2018-04-02 16:35:21 +01:00
16f283e675 Upgrading Casper to 2.1.10 2018-03-16 15:53:45 +07:00
942054ba0d Revert "Upgrading Casper to 2.2.0"
This reverts commit 782aba3991.
2018-03-16 15:52:56 +07:00
782aba3991 Upgrading Casper to 2.2.0 2018-03-16 09:50:09 +07:00
9df85fbbe5 CSS built and comb
no issue
2018-02-27 11:48:17 +07:00
1e10549ee2 🐛Fixed render issue with code blocks in lists (#436)
Closes #415

* Add max-width to ul & ol tags
2018-02-27 11:43:39 +07:00
a6eb6848de Removed obsolete gulp-nodemon (#435)
Closes #420

* Remove gulp-nodemon from dev dependencies
* Remove required dependency from gulpfile
2018-02-27 11:18:32 +07:00
6788302f62 🐛Removed unnecessary slash from Feedly URL (#437)
closes #434.
2018-02-27 11:11:29 +07:00
67e55abfed Upgrading Casper to 2.1.9 2018-01-23 16:19:58 +00:00
bfaae0f7ba 🐛 Fixed Feedly URL and protocol (#418)
no issue

* Changed Feedly URL to HTTPS protocol
* Updated Feedly URL pattern
2018-01-23 10:30:03 +07:00
edfafffd32 Upgrading Casper to 2.1.8 2018-01-03 13:47:12 +00:00
7798bf115f 2018 2018-01-02 21:48:53 +00:00
9395846fdf Upgrading Casper to 2.1.7 2017-11-21 21:26:49 +08:00
99fad4cbc4 Fix colors in code blocks
Closes #407
The font color should be inherited to avoid "invisible" text.

* fix conflicts with upstream branch
2017-11-21 17:50:54 +08:00
990f712209 💅 CSS comb and built
no issue
2017-11-20 13:42:32 +08:00
4ff4b4c7f8 Removed double semicolons (#400)
no issue
2017-11-20 13:38:20 +08:00
de05d90fe9 Upgrading Casper to 2.1.6 2017-10-26 19:03:21 +07:00
978e54403c 🐛 Do not exclude assets/css from built zips
no issue

https://github.com/TryGhost/Casper/pull/403 added optimisations for reducing size of zip files but unfortunately it also stripped out `assets/css` which means that it's no longer possible to download the theme from the admin panel and use it for development.

- remove `assets/css` from the ignored files in the `zip` task
2017-10-24 12:08:26 +01:00
73bd9c630e Upgrading Casper to 2.1.5 2017-10-24 16:10:48 +07:00
9597a28320 🎨 Optimized gulp zip file generation (#403)
no issue

- Optimised the `gulp zip` task, so the zip file doesn't include the `assets/css` (`built` folder is used for CSS) and the `dist` folder (is used to output the zip file)
2017-10-23 16:52:52 +07:00
461639886e Upgrading Casper to 2.1.4 2017-10-03 18:20:14 +07:00
7592ad182b 🔒 Added rel="noopener" to all target="_blank" links (#398)
closes #394
- closes potential phishing avenues by preventing external sites from changing the blogs url in the background after opening
- see https://mathiasbynens.github.io/rel-noopener/ for more info
2017-10-03 16:42:08 +07:00
97a522a037 Fix permissions on certain files 2017-10-02 13:29:23 +01:00
25f12d760b Fix typo in default.hbs (#393) 2017-09-29 08:23:39 -04:00
4f78d99112 Upgrading Casper to 2.1.3 2017-09-26 14:38:05 +01:00
f5b7b45f2e Remove /dist/casper.zip
no issue

With https://github.com/TryGhost/Casper/pull/384 the directory `/dist` was created and includes a `casper.zip` file. The PR, that got merged after that (https://github.com/TryGhost/Casper/pull/374) actually implemented the creation of this, but also added the directory to `.gitignore` so it wouldn't be pushed to the repo.
2017-09-19 12:01:17 +07:00
d34ff1d32b Add a Gulp task to create the zip (#374) 2017-09-18 09:37:00 -07:00
73a1ab52da Add the same .editorconfig as from the Ghost repository (#384) 2017-09-18 09:35:53 -07:00
5ec77dfb31 Upgrading Casper to 2.1.2 2017-09-12 18:34:23 +07:00
269d2b5787 Fix border radius bug on featured posts 2017-09-07 09:34:44 -07:00
d1d0bca2d8 Upgrading Casper to 2.1.1 2017-09-07 14:33:38 +02:00
d92dda3523 Wrapped primary-tag get helper with if (#383)
closes #382

- If there is no primary tag, the filter will be invalid syntax
- This wraps the if helper and gets rid of errors in the logs
2017-09-07 14:31:42 +02:00
ca325285bf Upgrading Casper to 2.1.0 2017-08-29 13:35:37 +01:00
aee9f69bb0 Refactor headings, quotes and margins, mobile improvements
A few people commented how pull-quote styling is odd for blockquotes. I agree. This reverts casper to use more traditional blockquote styling, but maintains the special pullquote styling now over on the H5 element. So if you want nice/wide/centered blue text, use an H5.

- Closes https://github.com/TryGhost/Casper/issues/364
- Closes https://github.com/TryGhost/Casper/issues/368
2017-08-25 16:31:10 -04:00
a7d5c885bd Upgrading Casper to 2.0.6 2017-08-22 12:38:02 +01:00
9bc5c92628 Fix z-index bug with header author profile image
no issue
- add z-index to `.site-header-content .author-profile-image` so it isn't covered by the header overlay
2017-08-22 12:05:09 +01:00
0f3651c23f 🎨 Do not stretch author profile image (#365)
- add `object-fit: cover` to `.author-profile-image` to prevent non-square images being stretched/squashed
2017-08-22 11:56:38 +01:00
d739bb52a4 Fixed z-index bug with header social links on author page (#370)
no issue
- add z-index to `.author-bio` and `.author-meta` so they aren't covered by the header image overlay
2017-08-22 11:49:49 +01:00
8d17e9a452 Upgrading Casper to 2.0.5 2017-08-17 17:47:36 +01:00
e4e6bb9c5a Fixed z-index bug with header title/description
closes #363
- add z-index to `.site-title` and `.site-description` so they aren't covered by the header overlay
2017-08-17 12:35:37 +01:00
d2375a3917 Sticky footer
Closes https://github.com/TryGhost/Casper/issues/354, Closes https://github.com/TryGhost/Casper/issues/362
2017-08-16 11:57:39 +01:00
577b92811c Add progress bar styling for Firefox (#360)
I alter this color to reddish for my own site, so it stood out much more easily than the Casper blue not matching the Firefox default. Autoprefixer isn't handling this one. Also, I tried adding this rule, comma separated, to the immediately above webkit rule... but it doesn't actually work when I do that, for some reason. Sorry for the redundancy!

https://developer.mozilla.org/en-US/docs/Web/CSS/::-moz-progress-bar
2017-08-16 11:43:58 +01:00
2f385ba5f1 Upgrading Casper to 2.0.4 2017-08-15 18:01:02 +01:00
b024b544e4 Fixed janky webkit border-radius bug
Closes https://github.com/TryGhost/Casper/issues/352
2017-08-14 11:22:27 +01:00
9caeb2a2e7 Fixed wide blockquote bug when used first in post
Closes https://github.com/TryGhost/Casper/issues/355
2017-08-14 11:11:12 +01:00
12d139aa7d Fixed z-index bug on index post-feed
Closes https://github.com/TryGhost/Casper/issues/349, closes https://github.com/TryGhost/Casper/pull/350
2017-08-14 11:03:28 +01:00
690e1bad1f Added issue template 2017-08-12 13:17:42 -04:00
42 changed files with 5739 additions and 385 deletions

17
.editorconfig Normal file
View File

@ -0,0 +1,17 @@
# http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 4
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.hbs]
insert_final_newline = false
[*.md]
trim_trailing_whitespace = false

19
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,19 @@
Do you need help or have a question? Please come chat in our forum: https://forum.ghost.org 👫.
If you're filing a bug 🐛, please include the following information:
### Screenshot
![]()
### Steps to Reproduce
1. This is the first step
2. This may be the post content used to cause an issue...
### Technical details
* Casper Version:
* Ghost Version:
* Browser Version:
* OS Version:

9
.gitignore vendored
View File

@ -13,9 +13,16 @@ results
npm-debug.log npm-debug.log
node_modules node_modules
package-lock.json
.idea/* .idea/*
*.iml *.iml
projectFilesBackup projectFilesBackup
.DS_Store .DS_Store
dist/
config.json
changelog.md
changelog.md.bk

15
.travis.yml Normal file
View File

@ -0,0 +1,15 @@
dist: xenial
language: node_js
sudo: false
node_js:
- 10
cache:
directories:
- node_modules
branches:
except:
- "/^renovate\\/.+$/"

2
.yarnrc Normal file
View File

@ -0,0 +1,2 @@
version-tag-prefix ""
version-git-message "%s"

View File

@ -1,4 +1,4 @@
Copyright (c) 2013-2017 Ghost Foundation Copyright (c) 2013-2019 Ghost Foundation
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation

View File

@ -32,14 +32,20 @@ One really neat trick is that you can also create custom one-off templates just
# Development # Development
Casper styles are compiled using Gulp/PostCSS to polyfill future CSS spec. You'll need Node and Gulp installed globally. After that, from the theme's root directory: Casper styles are compiled using Gulp/PostCSS to polyfill future CSS spec. You'll need [Node](https://nodejs.org/), [Yarn](https://yarnpkg.com/) and [Gulp](https://gulpjs.com) installed globally. After that, from the theme's root directory:
`$ npm install` ```bash
$ yarn install
`$ gulp` $ yarn dev
```
Now you can edit `/assets/css/` files, which will be compiled to `/assets/built/` automatically. Now you can edit `/assets/css/` files, which will be compiled to `/assets/built/` automatically.
The `zip` Gulp task packages the theme files into `dist/<theme-name>.zip`, which you can then upload to your site.
```bash
$ yarn zip
```
# PostCSS Features Used # PostCSS Features Used
@ -57,4 +63,4 @@ You can add your own SVG icons in the same manner.
# Copyright & License # Copyright & License
Copyright (c) 2013-2017 Ghost Foundation - Released under the [MIT license](LICENSE). Copyright (c) 2013-2019 Ghost Foundation - Released under the [MIT license](LICENSE).

9
SECURITY.md Normal file
View File

@ -0,0 +1,9 @@
# Reporting Security Vulnerabilities
Potential security vulnerabilities can be reported directly us at `security@ghost.org`. The Ghost Security Team communicates privately and works in a secured, isolated repository for tracking, testing, and resolving security-related issues.
The full, up-to-date details of our security policy and procedure can always be found in our documentation:
https://docs.ghost.org/security/
Please refer to this before emailing us. Thanks for helping make Ghost safe for everyone 🙏.

View File

@ -1,2 +1,2 @@
a,abbr,acronym,address,applet,article,aside,audio,big,blockquote,body,canvas,caption,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,ul,var,video{margin:0;padding:0;border:0;font:inherit;font-size:100%;vertical-align:baseline}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:"";content:none}img{max-width:100%}html{box-sizing:border-box;font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}*,:after,:before{box-sizing:inherit}a{background-color:transparent}a:active,a:hover{outline:0}b,strong{font-weight:700}dfn,em,i{font-style:italic}h1{margin:.67em 0;font-size:2em}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}mark{background-color:#fdffb6}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;color:inherit;font:inherit}button{overflow:visible;border:none}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input:focus{outline:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}legend{padding:0;border:0}textarea{overflow:auto}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}html{overflow-y:scroll;font-size:62.5%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body,html{overflow-x:hidden}body{color:#3c484e;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif;font-size:1.5rem;line-height:1.6em;font-weight:400;font-style:normal;letter-spacing:0;text-rendering:optimizeLegibility;background:#fff;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-moz-font-feature-settings:"liga" on}::-moz-selection{text-shadow:none;background:#cbeafb}::selection{text-shadow:none;background:#cbeafb}hr{position:relative;display:block;width:100%;margin:2.5em 0 3.5em;padding:0;height:1px;border:0;border-top:1px solid #e3e9ed}audio,canvas,iframe,img,svg,video{vertical-align:middle}fieldset{margin:0;padding:0;border:0}textarea{resize:vertical}blockquote,dl,ol,p,ul{margin:0 0 1.5em}ol,ul{padding-left:1em;padding-right:1.5em}ol ol,ol ul,ul ol,ul ul{margin:.5em 0 1em}ul{list-style:disc}ol{list-style:decimal}li{margin:.5em 0;padding-left:.5em;line-height:1.6em}dt{float:left;margin:0 20px 0 0;width:120px;color:#15171a;font-weight:500;text-align:right}dd{margin:0 0 5px;text-align:left}blockquote{margin:1.5em 0;padding:0 1.6em;border-left:.5em solid #e5eff5}blockquote p{margin:.8em 0;font-size:1.2em;font-weight:300}blockquote small{display:inline-block;margin:.8em 0 .8em 1.5em;font-size:.9em;opacity:.8}blockquote small:before{content:"\2014 \00A0"}blockquote cite{font-weight:700}blockquote cite a{font-weight:400}a{color:#26a8ed;text-decoration:none}a:hover{text-decoration:underline}h1,h2,h3,h4,h5,h6{margin-top:0;line-height:1.15;font-weight:700;text-rendering:optimizeLegibility}h1{margin:0 0 .5em;font-size:5rem;font-weight:700}@media (max-width:500px){h1{font-size:2.2rem}}h2{margin:1.5em 0 .5em;font-size:2rem}@media (max-width:500px){h2{font-size:1.8rem}}h3{margin:1.5em 0 .5em;font-size:1.8rem;font-weight:500}@media (max-width:500px){h3{font-size:1.7rem}}h4{margin:1.5em 0 .5em;font-size:1.6rem;font-weight:500}h5,h6{margin:1.5em 0 .5em;font-size:1.4rem;font-weight:500} a,abbr,acronym,address,applet,article,aside,audio,big,blockquote,body,canvas,caption,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,ul,var,video{margin:0;padding:0;border:0;font:inherit;font-size:100%;vertical-align:baseline}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:"";content:none}img{max-width:100%}html{-webkit-box-sizing:border-box;box-sizing:border-box;font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}*,:after,:before{-webkit-box-sizing:inherit;box-sizing:inherit}a{background-color:transparent}a:active,a:hover{outline:0}b,strong{font-weight:700}dfn,em,i{font-style:italic}h1{margin:.67em 0;font-size:2em}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}mark{background-color:#fdffb6}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;color:inherit;font:inherit}button{overflow:visible;border:none}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input:focus{outline:none}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}legend{padding:0;border:0}textarea{overflow:auto}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}html{overflow-y:scroll;font-size:62.5%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body,html{overflow-x:hidden}body{color:#3c484e;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif;font-size:1.5rem;line-height:1.6em;font-weight:400;font-style:normal;letter-spacing:0;text-rendering:optimizeLegibility;background:#fff;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-moz-font-feature-settings:"liga" on}::selection{text-shadow:none;background:#cbeafb}hr{position:relative;display:block;width:100%;margin:2.5em 0 3.5em;padding:0;height:1px;border:0;border-top:1px solid #e3e9ed}audio,canvas,iframe,img,svg,video{vertical-align:middle}fieldset{margin:0;padding:0;border:0}textarea{resize:vertical}blockquote,dl,ol,p,ul{margin:0 0 1.5em}ol,ul{padding-left:1.3em;padding-right:1.5em}ol ol,ol ul,ul ol,ul ul{margin:.5em 0 1em}ul{list-style:disc}ol{list-style:decimal}ol,ul{max-width:100%}li{margin:.5em 0;padding-left:.3em;line-height:1.6em}dt{float:left;margin:0 20px 0 0;width:120px;color:#15171a;font-weight:500;text-align:right}dd{margin:0 0 5px;text-align:left}blockquote{margin:1.5em 0;padding:0 1.6em;border-left:.5em solid #e5eff5}blockquote p{margin:.8em 0;font-size:1.2em;font-weight:300}blockquote small{display:inline-block;margin:.8em 0 .8em 1.5em;font-size:.9em;opacity:.8}blockquote small:before{content:"\2014 \00A0"}blockquote cite{font-weight:700}blockquote cite a{font-weight:400}a{color:#26a8ed;text-decoration:none}a:hover{text-decoration:underline}h1,h2,h3,h4,h5,h6{margin-top:0;line-height:1.15;font-weight:700;text-rendering:optimizeLegibility}h1{margin:0 0 .5em;font-size:5rem;font-weight:700}@media (max-width:500px){h1{font-size:2.2rem}}h2{margin:1.5em 0 .5em;font-size:2rem}@media (max-width:500px){h2{font-size:1.8rem}}h3{margin:1.5em 0 .5em;font-size:1.8rem;font-weight:500}@media (max-width:500px){h3{font-size:1.7rem}}h4{margin:1.5em 0 .5em;font-size:1.6rem;font-weight:500}h5,h6{margin:1.5em 0 .5em;font-size:1.4rem;font-weight:500}
/*# sourceMappingURL=global.css.map */ /*# sourceMappingURL=global.css.map */

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,2 @@
!function(n,t){var r=t.querySelector("link[rel=next]");if(r){var i=t.querySelector(".post-feed");if(i){var o=300,s=!1,l=!1,c=n.scrollY,u=n.innerHeight,d=t.documentElement.scrollHeight;n.addEventListener("scroll",a,{passive:!0}),n.addEventListener("resize",m),f()}}function v(){if(404===this.status)return n.removeEventListener("scroll",a),void n.removeEventListener("resize",m);this.response.querySelectorAll(".post-card").forEach(function(e){i.appendChild(e)});var e=this.response.querySelector("link[rel=next]");e?r.href=e.href:(n.removeEventListener("scroll",a),n.removeEventListener("resize",m)),d=t.documentElement.scrollHeight,l=s=!1}function e(){if(!l)if(c+u<=d-o)s=!1;else{l=!0;var e=new n.XMLHttpRequest;e.responseType="document",e.addEventListener("load",v),e.open("GET",r.href),e.send(null)}}function f(){s||n.requestAnimationFrame(e),s=!0}function a(){c=n.scrollY,f()}function m(){u=n.innerHeight,d=t.documentElement.scrollHeight,f()}}(window,document);
//# sourceMappingURL=infinitescroll.js.map

View File

@ -0,0 +1 @@
{"version":3,"sources":["infinitescroll.js"],"names":["window","document","nextElement","querySelector","feedElement","buffer","ticking","loading","lastScrollY","scrollY","lastWindowHeight","innerHeight","lastDocumentHeight","documentElement","scrollHeight","addEventListener","onScroll","passive","onResize","requestTick","onPageLoad","this","status","removeEventListener","response","querySelectorAll","forEach","item","appendChild","resNextElement","href","onUpdate","xhr","XMLHttpRequest","responseType","open","send","requestAnimationFrame"],"mappings":"CAIA,SAAUA,EAAQC,GAEd,IAAIC,EAAcD,EAASE,cAAc,kBACzC,GAAKD,EAAL,CAGA,IAAIE,EAAcH,EAASE,cAAc,cACzC,GAAKC,EAAL,CAEA,IAAIC,EAAS,IAETC,GAAU,EACVC,GAAU,EAEVC,EAAcR,EAAOS,QACrBC,EAAmBV,EAAOW,YAC1BC,EAAqBX,EAASY,gBAAgBC,aAmElDd,EAAOe,iBAAiB,SAAUC,EAAU,CAAEC,SAAS,IACvDjB,EAAOe,iBAAiB,SAAUG,GAElCC,KApEA,SAASC,IACL,GAAoB,MAAhBC,KAAKC,OAGL,OAFAtB,EAAOuB,oBAAoB,SAAUP,QACrChB,EAAOuB,oBAAoB,SAAUL,GAKtBG,KAAKG,SAASC,iBAAiB,cACrCC,QAAQ,SAAUC,GAC3BvB,EAAYwB,YAAYD,KAI5B,IAAIE,EAAiBR,KAAKG,SAASrB,cAAc,kBAC7C0B,EACA3B,EAAY4B,KAAOD,EAAeC,MAElC9B,EAAOuB,oBAAoB,SAAUP,GACrChB,EAAOuB,oBAAoB,SAAUL,IAIzCN,EAAqBX,EAASY,gBAAgBC,aAE9CP,EADAD,GAAU,EAId,SAASyB,IAEL,IAAIxB,EAGJ,GAAIC,EAAcE,GAAoBE,EAAqBP,EACvDC,GAAU,MADd,CAKAC,GAAU,EAEV,IAAIyB,EAAM,IAAIhC,EAAOiC,eACrBD,EAAIE,aAAe,WAEnBF,EAAIjB,iBAAiB,OAAQK,GAE7BY,EAAIG,KAAK,MAAOjC,EAAY4B,MAC5BE,EAAII,KAAK,OAGb,SAASjB,IACLb,GAAWN,EAAOqC,sBAAsBN,GACxCzB,GAAU,EAGd,SAASU,IACLR,EAAcR,EAAOS,QACrBU,IAGJ,SAASD,IACLR,EAAmBV,EAAOW,YAC1BC,EAAqBX,EAASY,gBAAgBC,aAC9CK,KAhFR,CAuFGnB,OAAQC","file":"infinitescroll.js","sourcesContent":["/**\n * Infinite Scroll\n */\n\n(function(window, document) {\n // next link element\n var nextElement = document.querySelector('link[rel=next]');\n if (!nextElement) return;\n\n // post feed element\n var feedElement = document.querySelector('.post-feed');\n if (!feedElement) return;\n\n var buffer = 300;\n\n var ticking = false;\n var loading = false;\n\n var lastScrollY = window.scrollY;\n var lastWindowHeight = window.innerHeight;\n var lastDocumentHeight = document.documentElement.scrollHeight;\n\n function onPageLoad() {\n if (this.status === 404) {\n window.removeEventListener('scroll', onScroll);\n window.removeEventListener('resize', onResize);\n return;\n }\n\n // append contents\n var postElements = this.response.querySelectorAll('.post-card');\n postElements.forEach(function (item) {\n feedElement.appendChild(item);\n });\n\n // set next link\n var resNextElement = this.response.querySelector('link[rel=next]');\n if (resNextElement) {\n nextElement.href = resNextElement.href;\n } else {\n window.removeEventListener('scroll', onScroll);\n window.removeEventListener('resize', onResize);\n }\n\n // sync status\n lastDocumentHeight = document.documentElement.scrollHeight;\n ticking = false;\n loading = false;\n }\n\n function onUpdate() {\n // return if already loading\n if (loading) return;\n\n // return if not scroll to the bottom\n if (lastScrollY + lastWindowHeight <= lastDocumentHeight - buffer) {\n ticking = false;\n return;\n }\n\n loading = true;\n\n var xhr = new window.XMLHttpRequest();\n xhr.responseType = 'document';\n\n xhr.addEventListener('load', onPageLoad);\n\n xhr.open('GET', nextElement.href);\n xhr.send(null);\n }\n\n function requestTick() {\n ticking || window.requestAnimationFrame(onUpdate);\n ticking = true;\n }\n\n function onScroll() {\n lastScrollY = window.scrollY;\n requestTick();\n }\n\n function onResize() {\n lastWindowHeight = window.innerHeight;\n lastDocumentHeight = document.documentElement.scrollHeight;\n requestTick();\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n window.addEventListener('resize', onResize);\n\n requestTick();\n})(window, document);\n"]}

View File

@ -0,0 +1,2 @@
!function(d){"use strict";d.fn.fitVids=function(t){var i={customSelector:null,ignore:null};if(!document.getElementById("fit-vids-style")){var e=document.head||document.getElementsByTagName("head")[0],r=document.createElement("div");r.innerHTML='<p>x</p><style id="fit-vids-style">.fluid-width-video-container{flex-grow: 1;width:100%;}.fluid-width-video-wrapper{width:100%;position:relative;padding:0;}.fluid-width-video-wrapper iframe,.fluid-width-video-wrapper object,.fluid-width-video-wrapper embed {position:absolute;top:0;left:0;width:100%;height:100%;}</style>',e.appendChild(r.childNodes[1])}return t&&d.extend(i,t),this.each(function(){var t=['iframe[src*="player.vimeo.com"]','iframe[src*="youtube.com"]','iframe[src*="youtube-nocookie.com"]','iframe[src*="kickstarter.com"][src*="video.html"]',"object","embed"];i.customSelector&&t.push(i.customSelector);var r=".fitvidsignore";i.ignore&&(r=r+", "+i.ignore);var e=d(this).find(t.join(","));(e=(e=e.not("object object")).not(r)).each(function(){var t=d(this);if(!(0<t.parents(r).length||"embed"===this.tagName.toLowerCase()&&t.parent("object").length||t.parent(".fluid-width-video-wrapper").length)){t.css("height")||t.css("width")||!isNaN(t.attr("height"))&&!isNaN(t.attr("width"))||(t.attr("height",9),t.attr("width",16));var e=("object"===this.tagName.toLowerCase()||t.attr("height")&&!isNaN(parseInt(t.attr("height"),10))?parseInt(t.attr("height"),10):t.height())/(isNaN(parseInt(t.attr("width"),10))?t.width():parseInt(t.attr("width"),10));if(!t.attr("name")){var i="fitvid"+d.fn.fitVids._count;t.attr("name",i),d.fn.fitVids._count++}t.wrap('<div class="fluid-width-video-container"><div class="fluid-width-video-wrapper"></div></div>').parent(".fluid-width-video-wrapper").css("padding-top",100*e+"%"),t.removeAttr("height").removeAttr("width")}})})},d.fn.fitVids._count=0}(window.jQuery||window.Zepto);
//# sourceMappingURL=jquery.fitvids.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -267,7 +267,6 @@ th {
padding: 0; padding: 0;
} }
/* ========================================================================== /* ==========================================================================
Base styles: opinionated defaults Base styles: opinionated defaults
========================================================================== */ ========================================================================== */
@ -341,7 +340,7 @@ blockquote {
ol, ol,
ul { ul {
padding-left: 1em; padding-left: 1.3em;
padding-right: 1.5em; padding-right: 1.5em;
} }
@ -360,9 +359,14 @@ ol {
list-style: decimal; list-style: decimal;
} }
ul,
ol {
max-width: 100%;
}
li { li {
margin: 0.5em 0; margin: 0.5em 0;
padding-left: 0.5em; padding-left: 0.3em;
line-height: 1.6em; line-height: 1.6em;
} }
@ -383,7 +387,7 @@ dd {
blockquote { blockquote {
margin: 1.5em 0; margin: 1.5em 0;
padding: 0 1.6em 0 1.6em; padding: 0 1.6em 0 1.6em;
border-left: var(--whitegrey) 0.5em solid;; border-left: var(--whitegrey) 0.5em solid;
} }
blockquote p { blockquote p {

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,78 @@
// Code snippet inspired by https://github.com/douglasrodrigues5/ghost-blog-infinite-scroll /**
$(function ($) { * Infinite Scroll
var currentPage = 1; */
var pathname = window.location.pathname;
var $document = $(document); (function(window, document) {
var $result = $('.post-feed'); // next link element
var buffer = 100; var nextElement = document.querySelector('link[rel=next]');
if (!nextElement) return;
// post feed element
var feedElement = document.querySelector('.post-feed');
if (!feedElement) return;
var buffer = 300;
var ticking = false; var ticking = false;
var isLoading = false; var loading = false;
var lastScrollY = window.scrollY; var lastScrollY = window.scrollY;
var lastWindowHeight = window.innerHeight; var lastWindowHeight = window.innerHeight;
var lastDocumentHeight = $document.height(); var lastDocumentHeight = document.documentElement.scrollHeight;
// remove hash params from pathname function onPageLoad() {
pathname = pathname.replace(/#(.*)$/g, '').replace('/\//g', '/'); if (this.status === 404) {
window.removeEventListener('scroll', onScroll);
window.removeEventListener('resize', onResize);
return;
}
// append contents
var postElements = this.response.querySelectorAll('.post-card');
postElements.forEach(function (item) {
feedElement.appendChild(item);
});
// set next link
var resNextElement = this.response.querySelector('link[rel=next]');
if (resNextElement) {
nextElement.href = resNextElement.href;
} else {
window.removeEventListener('scroll', onScroll);
window.removeEventListener('resize', onResize);
}
// sync status
lastDocumentHeight = document.documentElement.scrollHeight;
ticking = false;
loading = false;
}
function onUpdate() {
// return if already loading
if (loading) return;
// return if not scroll to the bottom
if (lastScrollY + lastWindowHeight <= lastDocumentHeight - buffer) {
ticking = false;
return;
}
loading = true;
var xhr = new window.XMLHttpRequest();
xhr.responseType = 'document';
xhr.addEventListener('load', onPageLoad);
xhr.open('GET', nextElement.href);
xhr.send(null);
}
function requestTick() {
ticking || window.requestAnimationFrame(onUpdate);
ticking = true;
}
function onScroll() { function onScroll() {
lastScrollY = window.scrollY; lastScrollY = window.scrollY;
@ -23,61 +81,12 @@ $(function ($) {
function onResize() { function onResize() {
lastWindowHeight = window.innerHeight; lastWindowHeight = window.innerHeight;
lastDocumentHeight = $document.height(); lastDocumentHeight = document.documentElement.scrollHeight;
requestTick(); requestTick();
} }
function requestTick() { window.addEventListener('scroll', onScroll, { passive: true });
if (!ticking) {
requestAnimationFrame(infiniteScroll)
}
ticking = true;
}
function infiniteScroll () {
// return if already loading
if (isLoading) {
return;
}
// return if not scroll to the bottom
if (lastScrollY + lastWindowHeight <= lastDocumentHeight - buffer) {
ticking = false;
return;
}
// return if currentPage is the last page already
if (currentPage === maxPages) {
return;
}
isLoading = true;
// next page
currentPage++;
// Load more
var nextPage = pathname + 'page/' + currentPage + '/';
$.get(nextPage, function (content) {
$result.append($(content).find('.post').hide().fadeIn(100));
}).fail(function (xhr) {
// 404 indicates we've run out of pages
if (xhr.status === 404) {
window.removeEventListener('scroll', onScroll, {passive: true});
window.removeEventListener('resize', onResize);
}
}).always(function () {
lastDocumentHeight = $document.height();
isLoading = false;
ticking = false;
});
}
window.addEventListener('scroll', onScroll, {passive: true});
window.addEventListener('resize', onResize); window.addEventListener('resize', onResize);
infiniteScroll(); requestTick();
}); })(window, document);

0
assets/screenshot-desktop.jpg Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 106 KiB

0
assets/screenshot-mobile.jpg Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 102 KiB

View File

@ -3,7 +3,9 @@
{{#author}} {{#author}}
{{!-- Everything inside the #author tags pulls data from the author --}} {{!-- Everything inside the #author tags pulls data from the author --}}
<header class="site-header outer {{#if cover_image}}" style="background-image: url({{cover_image}}){{else}}no-cover{{/if}}">
{{> header background=cover_image}} {{!--Special header.hbs partial to generate the <header> tag--}}
<div class="inner"> <div class="inner">
{{> "site-nav"}} {{> "site-nav"}}
<div class="site-header-content"> <div class="site-header-content">
@ -22,15 +24,15 @@
{{plural ../pagination.total empty='No posts' singular='% post' plural='% posts'}} <span class="bull">&bull;</span> {{plural ../pagination.total empty='No posts' singular='% post' plural='% posts'}} <span class="bull">&bull;</span>
</div> </div>
{{#if website}} {{#if website}}
<a class="social-link social-link-wb" href="{{website}}" target="_blank">{{> "icons/website"}}</a> <a class="social-link social-link-wb" href="{{website}}" target="_blank" rel="noopener">{{> "icons/website"}}</a>
{{/if}} {{/if}}
{{#if twitter}} {{#if twitter}}
<a class="social-link social-link-tw" href="{{twitter_url}}" target="_blank">{{> "icons/twitter"}}</a> <a class="social-link social-link-tw" href="{{twitter_url}}" target="_blank" rel="noopener">{{> "icons/twitter"}}</a>
{{/if}} {{/if}}
{{#if facebook}} {{#if facebook}}
<a class="social-link social-link-fb" href="{{facebook_url}}" target="_blank">{{> "icons/facebook"}}</a> <a class="social-link social-link-fb" href="{{facebook_url}}" target="_blank" rel="noopener">{{> "icons/facebook"}}</a>
{{/if}} {{/if}}
<a class="social-link social-link-rss" href="http://cloud.feedly.com/#subscription/feed/{{url absolute="true"}}/rss/" target="_blank">{{> "icons/rss"}}</a> <a class="social-link social-link-rss" href="https://feedly.com/i/subscription/feed/{{url absolute="true"}}rss/" target="_blank" rel="noopener">{{> "icons/rss"}}</a>
</div> </div>
</div> </div>
</div> </div>
@ -38,7 +40,7 @@
{{/author}} {{/author}}
{{!-- The main content area --}} {{!-- The main content area --}}
<main id="site-main" class="site-main outer" role="main"> <main id="site-main" class="site-main outer">
<div class="inner"> <div class="inner">
<div class="post-feed"> <div class="post-feed">

6
config.example.json Normal file
View File

@ -0,0 +1,6 @@
{
"github": {
"username": "<username>",
"token": "<gh-personal-access-token>"
}
}

View File

@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html lang="{{@site.lang}}">
<head> <head>
{{!-- Document Settings --}} {{!-- Document Settings --}}
@ -14,7 +14,7 @@
{{!-- Styles'n'Scripts --}} {{!-- Styles'n'Scripts --}}
<link rel="stylesheet" type="text/css" href="{{asset "built/screen.css"}}" /> <link rel="stylesheet" type="text/css" href="{{asset "built/screen.css"}}" />
{{!-- This tag outputes SEO meta+structured data and other important settings --}} {{!-- This tag outputs SEO meta+structured data and other important settings --}}
{{ghost_head}} {{ghost_head}}
</head> </head>
@ -28,12 +28,12 @@
{{!-- The footer at the very bottom of the screen --}} {{!-- The footer at the very bottom of the screen --}}
<footer class="site-footer outer"> <footer class="site-footer outer">
<div class="site-footer-content inner"> <div class="site-footer-content inner">
<section class="copyright"><a href="{{@blog.url}}">{{@blog.title}}</a> &copy; {{date format="YYYY"}}</section> <section class="copyright"><a href="{{@site.url}}">{{@site.title}}</a> &copy; {{date format="YYYY"}}</section>
<nav class="site-footer-nav"> <nav class="site-footer-nav">
<a href="{{@blog.url}}">Latest Posts</a> <a href="{{@site.url}}">Latest Posts</a>
{{#if @blog.facebook}}<a href="{{facebook_url @blog.facebook}}" target="_blank">Facebook</a>{{/if}} {{#if @site.facebook}}<a href="{{facebook_url @site.facebook}}" target="_blank" rel="noopener">Facebook</a>{{/if}}
{{#if @blog.twitter}}<a href="{{twitter_url @blog.twitter}}" target="_blank">Twitter</a>{{/if}} {{#if @site.twitter}}<a href="{{twitter_url @site.twitter}}" target="_blank" rel="noopener">Twitter</a>{{/if}}
<a href="https://ghost.org" target="_blank">Ghost</a> <a href="https://ghost.org" target="_blank" rel="noopener">Ghost</a>
</nav> </nav>
</div> </div>
</footer> </footer>
@ -45,29 +45,38 @@
<div id="subscribe" class="subscribe-overlay"> <div id="subscribe" class="subscribe-overlay">
<a class="subscribe-overlay-close" href="#"></a> <a class="subscribe-overlay-close" href="#"></a>
<div class="subscribe-overlay-content"> <div class="subscribe-overlay-content">
{{#if @blog.logo}} {{#if @site.logo}}
<img class="subscribe-overlay-logo" src="{{@blog.logo}}" alt="{{@blog.title}}" /> <img class="subscribe-overlay-logo" src="{{@site.logo}}" alt="{{@site.title}}" />
{{/if}} {{/if}}
<h1 class="subscribe-overlay-title">Subscribe to {{@blog.title}}</h1> <h1 class="subscribe-overlay-title">Subscribe to {{@site.title}}</h1>
<p class="subscribe-overlay-description">Stay up to date! Get all the latest &amp; greatest posts delivered straight to your inbox</p> <p class="subscribe-overlay-description">Stay up to date! Get all the latest &amp; greatest posts delivered straight to your inbox</p>
{{subscribe_form placeholder="youremail@example.com"}} {{subscribe_form placeholder="youremail@example.com"}}
</div> </div>
</div> </div>
{{/if}} {{/if}}
<script>
var images = document.querySelectorAll('.kg-gallery-image img');
images.forEach(function (image) {
var container = image.closest('.kg-gallery-image');
var width = image.attributes.width.value;
var height = image.attributes.height.value;
var ratio = width / height;
container.style.flex = ratio + ' 1 0%';
})
</script>
{{!-- jQuery + Fitvids, which makes all video embeds responsive --}} {{!-- jQuery + Fitvids, which makes all video embeds responsive --}}
<script <script
src="https://code.jquery.com/jquery-3.2.1.min.js" src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"> crossorigin="anonymous">
</script> </script>
<script type="text/javascript" src="{{asset "js/jquery.fitvids.js"}}"></script> <script type="text/javascript" src="{{asset "built/jquery.fitvids.js"}}"></script>
{{#if pagination.pages}} {{#if pagination.pages}}
<script> <script src="{{asset "built/infinitescroll.js"}}"></script>
var maxPages = parseInt('{{pagination.pages}}');
</script>
<script src="{{asset "js/infinitescroll.js"}}"></script>
{{/if}} {{/if}}
{{!-- The #block helper will pull in data from the #contentFor other template files. In this case, there's some JavaScript which we only want to use in post.hbs, but it needs to be included down here, after jQuery has already loaded. --}} {{!-- The #block helper will pull in data from the #contentFor other template files. In this case, there's some JavaScript which we only want to use in post.hbs, but it needs to be included down here, after jQuery has already loaded. --}}

View File

@ -16,25 +16,25 @@ It's a good idea to keep this template as minimal as possible in terms of both f
<body class="error-template"> <body class="error-template">
<div class="site-wrapper"> <div class="site-wrapper">
<header class="site-header outer {{#if feature_image}}" style="background-image: url({{feature_image}}){{else}}no-cover{{/if}}"> <header class="site-header outer {{#if feature_image}}" style="background-image: url({{feature_image}}){{else}}no-image{{/if}}">
<div class="inner"> <div class="inner">
<nav class="site-nav-center"> <nav class="site-nav-center">
{{#if @blog.logo}} {{#if @site.logo}}
<a class="site-nav-logo" href="{{@blog.url}}"><img src="{{@blog.logo}}" alt="{{@blog.title}}" /></a> <a class="site-nav-logo" href="{{@site.url}}"><img src="{{img_url @site.logo size="xs"}}" alt="{{@site.title}}" /></a>
{{else}} {{else}}
<a class="site-nav-logo" href="{{@blog.url}}">{{@blog.title}}</a> <a class="site-nav-logo" href="{{@site.url}}">{{@site.title}}</a>
{{/if}} {{/if}}
</nav> </nav>
</div> </div>
</header> </header>
<main id="site-main" class="site-main outer" role="main"> <main id="site-main" class="site-main outer">
<div class="inner"> <div class="inner">
<section class="error-message"> <section class="error-message">
<h1 class="error-code">{{code}}</h1> <h1 class="error-code">{{code}}</h1>
<p class="error-description">{{message}}</p> <p class="error-description">{{message}}</p>
<a class="error-link" href="{{@blog.url}}">Go to the front page →</a> <a class="error-link" href="{{@site.url}}">Go to the front page →</a>
</section> </section>
</div> </div>
</main> </main>

View File

@ -17,25 +17,25 @@ You'll notice that we *don't* use any JavsScript, or ghost_head / ghost_foot in
<body class="error-template"> <body class="error-template">
<div class="site-wrapper"> <div class="site-wrapper">
<header class="site-header outer {{#if feature_image}}" style="background-image: url({{feature_image}}){{else}}no-cover{{/if}}"> <header class="site-header outer {{#if feature_image}}" style="background-image: url({{feature_image}}){{else}}no-image{{/if}}">
<div class="inner"> <div class="inner">
<nav class="site-nav-center"> <nav class="site-nav-center">
{{#if @blog.logo}} {{#if @site.logo}}
<a class="site-nav-logo" href="{{@blog.url}}"><img src="{{@blog.logo}}" alt="{{@blog.title}}" /></a> <a class="site-nav-logo" href="{{@site.url}}"><img src="{{img_url @site.logo size="xs"}}" alt="{{@site.title}}" /></a>
{{else}} {{else}}
<a class="site-nav-logo" href="{{@blog.url}}">{{@blog.title}}</a> <a class="site-nav-logo" href="{{@site.url}}">{{@site.title}}</a>
{{/if}} {{/if}}
</nav> </nav>
</div> </div>
</header> </header>
<main id="site-main" class="site-main outer" role="main"> <main id="site-main" class="site-main outer">
<div class="inner"> <div class="inner">
<section class="error-message"> <section class="error-message">
<h1 class="error-code">{{code}}</h1> <h1 class="error-code">{{code}}</h1>
<p class="error-description">{{message}}</p> <p class="error-description">{{message}}</p>
<a class="error-link" href="{{@blog.url}}">Go to the front page →</a> <a class="error-link" href="{{@site.url}}">Go to the front page →</a>
</section> </section>
{{#if errorDetails}} {{#if errorDetails}}

View File

@ -1,54 +1,199 @@
var gulp = require('gulp'); const {series, watch, src, dest} = require('gulp');
const pump = require('pump');
// gulp plugins and utils // gulp plugins and utils
var gutil = require('gulp-util'); const livereload = require('gulp-livereload');
var livereload = require('gulp-livereload'); const postcss = require('gulp-postcss');
var nodemon = require('gulp-nodemon'); const zip = require('gulp-zip');
var postcss = require('gulp-postcss'); const uglify = require('gulp-uglify');
var sourcemaps = require('gulp-sourcemaps'); const beeper = require('beeper');
// postcss plugins // postcss plugins
var autoprefixer = require('autoprefixer'); const autoprefixer = require('autoprefixer');
var colorFunction = require('postcss-color-function'); const colorFunction = require('postcss-color-function');
var cssnano = require('cssnano'); const cssnano = require('cssnano');
var customProperties = require('postcss-custom-properties'); const customProperties = require('postcss-custom-properties');
var easyimport = require('postcss-easy-import'); const easyimport = require('postcss-easy-import');
var swallowError = function swallowError(error) { function serve(done) {
gutil.log(error.toString()); livereload.listen();
gutil.beep(); done();
this.emit('end'); }
const handleError = (done) => {
return function (err) {
if (err) {
beeper();
}
return done(err);
};
}; };
var nodemonServerInit = function () { function css(done) {
livereload.listen(1234); const processors = [
};
gulp.task('build', ['css'], function (/* cb */) {
return nodemonServerInit();
});
gulp.task('css', function () {
var processors = [
easyimport, easyimport,
customProperties, customProperties({preserve: false}),
colorFunction(), colorFunction(),
autoprefixer({browsers: ['last 2 versions']}), autoprefixer({browsers: ['last 2 versions']}),
cssnano() cssnano()
]; ];
gulp.src('assets/css/*.css')
.on('error', swallowError)
.pipe(sourcemaps.init())
.pipe(postcss(processors))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('assets/built/'))
.pipe(livereload());
});
gulp.task('watch', function () { pump([
gulp.watch('assets/css/**', ['css']); src('assets/css/*.css', {sourcemaps: true}),
}); postcss(processors),
dest('assets/built/', {sourcemaps: '.'}),
livereload()
], handleError(done));
}
gulp.task('default', ['build'], function () { function js(done) {
gulp.start('watch'); pump([
}); src('assets/js/*.js', {sourcemaps: true}),
uglify(),
dest('assets/built/', {sourcemaps: '.'}),
livereload()
], handleError(done));
}
function zipper(done) {
const targetDir = 'dist/';
const themeName = require('./package.json').name;
const filename = themeName + '.zip';
pump([
src([
'**',
'!node_modules', '!node_modules/**',
'!dist', '!dist/**'
]),
zip(filename),
dest(targetDir)
], handleError(done));
}
const watcher = () => watch('assets/css/**', css);
const build = series(css, js);
const dev = series(build, serve, watcher);
exports.build = build;
exports.zip = series(build, zipper);
exports.default = dev;
// release imports
const path = require('path');
const releaseUtils = require('@tryghost/release-utils');
let config;
try {
config = require('./config');
} catch (err) {
config = null;
}
const REPO = 'TryGhost/Casper';
const USER_AGENT = 'Casper';
const CHANGELOG_PATH = path.join(process.cwd(), '.', 'changelog.md');
const changelog = ({previousVersion}) => {
const changelog = new releaseUtils.Changelog({
changelogPath: CHANGELOG_PATH,
folder: path.join(process.cwd(), '.')
});
changelog
.write({
githubRepoPath: `https://github.com/${REPO}`,
lastVersion: previousVersion
})
.sort()
.clean();
};
const previousRelease = () => {
return releaseUtils
.releases
.get({
userAgent: USER_AGENT,
uri: `https://api.github.com/repos/${REPO}/releases`
})
.then((response) => {
if (!response || !response.length) {
console.log('No releases found. Skipping');
return;
}
console.log(`Previous version ${response[0].name}`);
return response[0].name;
});
};
/**
*
* `yarn ship` will trigger `postship` task.
*
* [optional] For full automation
*
* `GHOST=2.10.1,2.10.0 yarn ship`
* First value: Ships with Ghost
* Second value: Compatible with Ghost/GScan
*
* You can manually run in case the task has thrown an error.
*
* `npm_package_version=0.5.0 gulp release`
*/
const release = () => {
// @NOTE: https://yarnpkg.com/lang/en/docs/cli/version/
const newVersion = process.env.npm_package_version;
let shipsWithGhost = '{version}';
let compatibleWithGhost = '2.10.0';
const ghostEnvValues = process.env.GHOST || null;
if (ghostEnvValues) {
shipsWithGhost = ghostEnvValues.split(',')[0];
compatibleWithGhost = ghostEnvValues.split(',')[1];
if (!compatibleWithGhost) {
compatibleWithGhost = '2.10.0';
}
}
if (!newVersion || newVersion === '') {
console.log('Invalid version.');
return;
}
console.log(`\nDraft release for ${newVersion}.`);
if (!config || !config.github || !config.github.username || !config.github.token) {
console.log('Please copy config.example.json and configure Github token.');
return;
}
return previousRelease()
.then((previousVersion)=> {
changelog({previousVersion});
return releaseUtils
.releases
.create({
draft: true,
preRelease: false,
tagName: newVersion,
releaseName: newVersion,
userAgent: USER_AGENT,
uri: `https://api.github.com/repos/${REPO}/releases`,
github: {
username: config.github.username,
token: config.github.token
},
content: [`**Ships with Ghost ${shipsWithGhost} Compatible with Ghost >= ${compatibleWithGhost}**\n\n`],
changelogPath: CHANGELOG_PATH
})
.then((response)=> {
console.log(`\nRelease draft generated: ${response.releaseUrl}\n`);
});
});
};
exports.release = release;

View File

@ -2,25 +2,24 @@
{{!-- The tag above means: insert everything in this file {{!-- The tag above means: insert everything in this file
into the {body} of the default.hbs template --}} into the {body} of the default.hbs template --}}
{{!-- The big featured header, it uses blog cover image as a BG if available --}} {{> header background=@site.cover_image}} {{!--Special header.hbs partial to generate the <header> tag--}}
<header class="site-header outer {{#if @blog.cover_image}}" style="background-image: url({{@blog.cover_image}}){{else}}no-cover{{/if}}">
<div class="inner"> <div class="inner">
<div class="site-header-content"> <div class="site-header-content">
<h1 class="site-title"> <h1 class="site-title">
{{#if @blog.logo}} {{#if @site.logo}}
<img class="site-logo" src="{{@blog.logo}}" alt="{{@blog.title}}" /> <img class="site-logo" src="{{img_url @site.logo size="l"}}" alt="{{@site.title}}" />
{{else}} {{else}}
{{@blog.title}} {{@site.title}}
{{/if}} {{/if}}
</h1> </h1>
<h2 class="site-description">{{@blog.description}}</h2> <h2 class="site-description">{{@site.description}}</h2>
</div> </div>
{{> "site-nav"}} {{> "site-nav"}}
</div> </div>
</header> </header>
{{!-- The main content area --}} {{!-- The main content area --}}
<main id="site-main" class="site-main outer" role="main"> <main id="site-main" class="site-main outer">
<div class="inner"> <div class="inner">
<div class="post-feed"> <div class="post-feed">

View File

@ -2,15 +2,25 @@
"name": "casper", "name": "casper",
"description": "The default personal blogging theme for Ghost. Beautiful, minimal and responsive.", "description": "The default personal blogging theme for Ghost. Beautiful, minimal and responsive.",
"demo": "https://demo.ghost.io", "demo": "https://demo.ghost.io",
"version": "2.0.3", "version": "2.9.8",
"engines": { "engines": {
"ghost": ">=1.2.0" "ghost": ">=2.0.0",
"ghost-api": "v2"
}, },
"license": "MIT", "license": "MIT",
"screenshots": { "screenshots": {
"desktop": "assets/screenshot-desktop.jpg", "desktop": "assets/screenshot-desktop.jpg",
"mobile": "assets/screenshot-mobile.jpg" "mobile": "assets/screenshot-mobile.jpg"
}, },
"scripts": {
"dev": "gulp",
"zip": "gulp zip",
"test": "gscan .",
"pretest": "gulp build",
"preship": "yarn test",
"ship": "STATUS=$(git status --porcelain); echo $STATUS; if [ -z \"$STATUS\" ]; then yarn version && git push --follow-tags; else echo \"Uncomitted changes found.\" && exit 1; fi",
"postship": "git fetch && gulp release"
},
"author": { "author": {
"name": "Ghost Foundation", "name": "Ghost Foundation",
"email": "hello@ghost.org", "email": "hello@ghost.org",
@ -25,7 +35,8 @@
}, },
"keywords": [ "keywords": [
"ghost", "ghost",
"theme" "theme",
"ghost-theme"
], ],
"repository": { "repository": {
"type": "git", "type": "git",
@ -34,20 +45,42 @@
"bugs": "https://github.com/TryGhost/Casper/issues", "bugs": "https://github.com/TryGhost/Casper/issues",
"contributors": "https://github.com/TryGhost/Casper/graphs/contributors", "contributors": "https://github.com/TryGhost/Casper/graphs/contributors",
"devDependencies": { "devDependencies": {
"autoprefixer": "6.3.6", "@tryghost/release-utils": "0.3.1",
"cssnano": "3.7.1", "autoprefixer": "9.5.0",
"gulp": "3.9.1", "beeper": "1.1.1",
"gulp-livereload": "3.8.1", "cssnano": "4.1.10",
"gulp-nodemon": "2.1.0", "gscan": "2.3.0",
"gulp-postcss": "6.1.1", "gulp": "4.0.0",
"gulp-sourcemaps": "1.6.0", "gulp-livereload": "4.0.1",
"gulp-util": "3.0.7", "gulp-postcss": "8.0.0",
"gulp-watch": "4.3.8", "gulp-uglify": "3.0.2",
"postcss-color-function": "2.0.1", "gulp-zip": "4.2.0",
"postcss-custom-properties": "5.0.1", "postcss-color-function": "4.0.1",
"postcss-easy-import": "1.0.1" "postcss-custom-properties": "8.0.9",
"postcss-easy-import": "3.0.0",
"pump": "3.0.0"
}, },
"config": { "config": {
"posts_per_page": 25 "posts_per_page": 25,
"image_sizes": {
"xxs": {
"width": 30
},
"xs": {
"width": 100
},
"s": {
"width": 300
},
"m": {
"width": 600
},
"l": {
"width": 1000
},
"xl": {
"width": 2000
}
}
} }
} }

View File

@ -12,7 +12,7 @@ into the {body} of the default.hbs template --}}
{{!-- Everything inside the #post tags pulls data from the post --}} {{!-- Everything inside the #post tags pulls data from the post --}}
{{#post}} {{#post}}
<main id="site-main" class="site-main outer" role="main"> <main id="site-main" class="site-main outer">
<div class="inner"> <div class="inner">
<article class="post-full {{post_class}} {{#unless feature_image}}no-image{{/unless}}"> <article class="post-full {{post_class}} {{#unless feature_image}}no-image{{/unless}}">
@ -22,12 +22,27 @@ into the {body} of the default.hbs template --}}
</header> </header>
{{#if feature_image}} {{#if feature_image}}
<figure class="post-full-image" style="background-image: url({{feature_image}})"> <figure class="post-full-image">
{{!-- This is a responsive image, it loads different sizes depending on device
https://medium.freecodecamp.org/a-guide-to-responsive-images-with-ready-to-use-templates-c400bd65c433 --}}
<img
srcset="{{img_url feature_image size="s"}} 300w,
{{img_url feature_image size="m"}} 600w,
{{img_url feature_image size="l"}} 1000w,
{{img_url feature_image size="xl"}} 2000w"
sizes="(max-width: 800px) 400px,
(max-width: 1170px) 700px,
1400px"
src="{{img_url feature_image size="xl"}}"
alt="{{title}}"
/>
</figure> </figure>
{{/if}} {{/if}}
<section class="post-full-content"> <section class="post-full-content">
{{content}} <div class="post-content">
{{content}}
</div>
</section> </section>
</article> </article>

View File

@ -0,0 +1,74 @@
<section class="post-full-authors">
<div class="post-full-authors-content">
<p>This post was a collaboration between</p>
<p>{{authors}}</p>
</div>
<ul class="author-list">
{{#foreach authors}}
<li class="author-list-item">
<div class="author-card">
<div class="basic-info">
{{#if profile_image}}
<img class="author-profile-image" src="{{img_url profile_image size="xs"}}" alt="{{name}}" />
{{else}}
<div class="author-profile-image">{{> "icons/avatar"}}</div>
{{/if}}
<h2>{{name}}</h2>
</div>
<div class="bio">
{{#if bio}}
<p>{{bio}}</p>
<p><a href="{{url}}">More posts</a> by {{name}}.</p>
{{else}}
<p>Read <a href="{{url}}">more posts</a> by this author.</p>
{{/if}}
</div>
</div>
{{#if profile_image}}
<a href="{{url}}" class="moving-avatar">
<img class="author-profile-image" src="{{img_url profile_image size="xs"}}" alt="{{name}}" />
</a>
{{else}}
<a href="{{url}}" class="moving-avatar author-profile-image">{{> "icons/avatar"}}</a>
{{/if}}
</li>
{{/foreach}}
</ul>
</section>
{{#contentFor "scripts"}}
<script>
// Adds delay to author card dropups to disappear. This gives enough
// time for the user to interact with the author card while they move
// the mouse from the avatar to the card. Also makes space for the
// interacted avatar.
$(document).ready(function () {
var hoverTimeout;
$('.author-list-item').hover(function(){
var $this = $(this);
clearTimeout(hoverTimeout);
$('.author-card').removeClass('hovered');
$(this).children('.author-card').addClass('hovered');
}, function() {
var $this = $(this);
hoverTimeout = setTimeout(function() {
$this.children('.author-card').removeClass('hovered');
}, 800);
});
});
</script>
{{/contentFor}}

View File

@ -0,0 +1,23 @@
{{!-- Everything inside the #author tags pulls data from the author --}}
{{#primary_author}}
<section class="author-card">
{{#if profile_image}}
<img class="author-profile-image" src="{{img_url profile_image size="xs"}}" alt="{{name}}" />
{{else}}
<span class="avatar-wrapper">{{> "icons/avatar"}}</span>
{{/if}}
<section class="author-card-content">
<h4 class="author-card-name"><a href="{{url}}">{{name}}</a></h4>
{{#if bio}}
<p>{{bio}}</p>
{{else}}
<p>Read <a href="{{url}}">more posts</a> by this author.</p>
{{/if}}
</section>
</section>
<div class="post-full-footer-right">
<a class="author-card-button" href="{{url}}">Read More</a>
</div>
{{/primary_author}}

View File

@ -1,10 +1,10 @@
<div class="floating-header"> <div class="floating-header">
<div class="floating-header-logo"> <div class="floating-header-logo">
<a href="{{@blog.url}}"> <a href="{{@site.url}}">
{{#if @blog.icon}} {{#if @site.icon}}
<img src="{{@blog.icon}}" alt="{{@blog.title}} icon" /> <img src="{{img_url @site.icon size="xxs"}}" alt="{{@site.title}} icon" />
{{/if}} {{/if}}
<span>{{@blog.title}}</span> <span>{{@site.title}}</span>
</a> </a>
</div> </div>
<span class="floating-header-divider">&mdash;</span> <span class="floating-header-divider">&mdash;</span>
@ -20,7 +20,7 @@
{{> "icons/facebook"}} {{> "icons/facebook"}}
</a> </a>
</div> </div>
<progress class="progress" value="0"> <progress id="reading-progress" class="progress" value="0">
<div class="progress-container"> <div class="progress-container">
<span class="progress-bar"></span> <span class="progress-bar"></span>
</div> </div>

53
partials/header.hbs Normal file
View File

@ -0,0 +1,53 @@
{{!--
Wow what the hell is going on in here even?
Ok so, several templates use this big header with a giant BG image. Nice idea, but big images
have a heavy impact on performance, so it's a good idea to make them responsive. Because we
can only get the image dynamically using Handlebars, and we can only set the image to properly
be a background image using CSS, we end up with a handful of inline styles.
If the template in question has a background image, then we render responsive image styles
for it, and apply those styles to the <header> tag. Else, we just output a <header> tag
with a `no-image` class so we can style it accordingly.
--}}
{{#if background}}
<style type="text/css">
.responsive-header-img {
background-image: url({{img_url background size='xl'}});
}
@media(max-width: 1000px) {
.responsive-header-img {
background-image: url({{img_url background size='l'}});
background-image: -webkit-image-set(
url({{img_url background size='l'}}) 1x,
url({{img_url background size='xl'}}) 2x
);
background-image: image-set(
url({{img_url background size='l'}}) 1x,
url({{img_url background size='xl'}}) 2x
);
}
}
@media(max-width: 600px) {
.responsive-header-img {
background-image: url({{img_url background size='m'}});
background-image: -webkit-image-set(
url({{img_url background size='m'}}) 1x,
url({{img_url background size='l'}}) 2x
);
background-image: image-set(
url({{img_url background size='m'}}) 1x,
url({{img_url background size='l'}}) 2x
);
}
}
</style>
<header class="site-header outer responsive-header-img">
{{else}}
<header class="site-header outer no-image">
{{/if}}

View File

@ -0,0 +1 @@
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path d="M3.513 18.998C4.749 15.504 8.082 13 12 13s7.251 2.504 8.487 5.998C18.47 21.442 15.417 23 12 23s-6.47-1.558-8.487-4.002zM12 12c2.21 0 4-2.79 4-5s-1.79-4-4-4-4 1.79-4 4 1.79 5 4 5z" fill="#FFF"/></g></svg>

After

Width:  |  Height:  |  Size: 308 B

0
partials/icons/facebook.hbs Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 155 B

After

Width:  |  Height:  |  Size: 155 B

View File

@ -1,26 +1,63 @@
<article class="post-card {{post_class}}{{#unless feature_image}} no-image{{/unless}}"> <article class="post-card {{post_class}} {{#unless feature_image}}no-image{{else}}{{#is "home"}}{{#has index="nth:6"}}post-card-large{{/has}}{{/is}}{{/unless}}">
{{#if feature_image}} {{#if feature_image}}
<a class="post-card-image-link" href="{{url}}"> <a class="post-card-image-link" href="{{url}}">
<div class="post-card-image" style="background-image: url({{feature_image}})"></div> {{!-- This is a responsive image, it loads different sizes depending on device
</a> https://medium.freecodecamp.org/a-guide-to-responsive-images-with-ready-to-use-templates-c400bd65c433 --}}
<img class="post-card-image"
srcset="{{img_url feature_image size="s"}} 300w,
{{img_url feature_image size="m"}} 600w,
{{img_url feature_image size="l"}} 1000w,
{{img_url feature_image size="xl"}} 2000w"
sizes="(max-width: 1000px) 400px, 700px"
src="{{img_url feature_image size="m"}}"
alt="{{title}}"
/>
</a>
{{/if}} {{/if}}
<div class="post-card-content"> <div class="post-card-content">
<a class="post-card-content-link" href="{{url}}"> <a class="post-card-content-link" href="{{url}}">
<header class="post-card-header"> <header class="post-card-header">
{{#if primary_tag}} {{#if primary_tag}}
<span class="post-card-tags">{{primary_tag.name}}</span> <span class="post-card-tags">{{primary_tag.name}}</span>
{{/if}} {{/if}}
<h2 class="post-card-title">{{title}}</h2> <h2 class="post-card-title">{{title}}</h2>
</header> </header>
<section class="post-card-excerpt"> <section class="post-card-excerpt">
<p>{{excerpt words="33"}}</p> <p>{{excerpt words="33"}}</p>
</section> </section>
</a> </a>
<footer class="post-card-meta"> <footer class="post-card-meta">
{{#if author.profile_image}}
<img class="author-profile-image" src="{{author.profile_image}}" alt="{{author.name}}" /> <ul class="author-list">
{{/if}} {{#foreach authors}}
<span class="post-card-author">{{author}}</span> <li class="author-list-item">
<div class="author-name-tooltip">
{{name}}
</div>
{{#if profile_image}}
<a href="{{url}}" class="static-avatar">
<img class="author-profile-image" src="{{img_url profile_image size="xs"}}" alt="{{name}}" />
</a>
{{else}}
<a href="{{url}}" class="static-avatar author-profile-image">{{> "icons/avatar"}}</a>
{{/if}}
</li>
{{/foreach}}
</ul>
<span class="reading-time">{{reading_time}}</span>
</footer> </footer>
</div>
</div>{{!--/.post-card-content--}}
</article> </article>

View File

@ -1,29 +1,29 @@
<nav class="site-nav"> <nav class="site-nav">
<div class="site-nav-left"> <div class="site-nav-left">
{{^is "home"}} {{^is "home"}}
{{#if @blog.logo}} {{#if @site.logo}}
<a class="site-nav-logo" href="{{@blog.url}}"><img src="{{@blog.logo}}" alt="{{@blog.title}}" /></a> <a class="site-nav-logo" href="{{@site.url}}"><img src="{{@site.logo}}" alt="{{@site.title}}" /></a>
{{else}} {{else}}
<a class="site-nav-logo" href="{{@blog.url}}">{{@blog.title}}</a> <a class="site-nav-logo" href="{{@site.url}}">{{@site.title}}</a>
{{/if}} {{/if}}
{{/is}} {{/is}}
{{#if @blog.navigation}} {{#if @site.navigation}}
{{navigation}} {{navigation}}
{{/if}} {{/if}}
</div> </div>
<div class="site-nav-right"> <div class="site-nav-right">
<div class="social-links"> <div class="social-links">
{{#if @blog.facebook}} {{#if @site.facebook}}
<a class="social-link social-link-fb" href="{{facebook_url @blog.facebook}}" target="_blank">{{> "icons/facebook"}}</a> <a class="social-link social-link-fb" href="{{facebook_url @site.facebook}}" title="Facebook" target="_blank" rel="noopener">{{> "icons/facebook"}}</a>
{{/if}} {{/if}}
{{#if @blog.twitter}} {{#if @site.twitter}}
<a class="social-link social-link-tw" href="{{twitter_url @blog.twitter}}" target="_blank">{{> "icons/twitter"}}</a> <a class="social-link social-link-tw" href="{{twitter_url @site.twitter}}" title="Twitter" target="_blank" rel="noopener">{{> "icons/twitter"}}</a>
{{/if}} {{/if}}
</div> </div>
{{#if @labs.subscribers}} {{#if @labs.subscribers}}
<a class="subscribe-button" href="#subscribe">Subscribe</a> <a class="subscribe-button" href="#subscribe">Subscribe</a>
{{else}} {{else}}
<a class="rss-button" href="http://cloud.feedly.com/#subscription/feed/{{@blog.url}}/rss/" target="_blank">{{> "icons/rss"}}</a> <a class="rss-button" href="https://feedly.com/i/subscription/feed/{{@site.url}}/rss/" title="RSS" target="_blank" rel="noopener">{{> "icons/rss"}}</a>
{{/if}} {{/if}}
</div> </div>
</nav> </nav>

View File

@ -12,7 +12,7 @@ into the {body} of the default.hbs template --}}
{{!-- Everything inside the #post tags pulls data from the post --}} {{!-- Everything inside the #post tags pulls data from the post --}}
{{#post}} {{#post}}
<main id="site-main" class="site-main outer" role="main"> <main id="site-main" class="site-main outer">
<div class="inner"> <div class="inner">
<article class="post-full {{post_class}} {{#unless feature_image}}no-image{{/unless}}"> <article class="post-full {{post_class}} {{#unless feature_image}}no-image{{/unless}}">
@ -28,67 +28,56 @@ into the {body} of the default.hbs template --}}
</header> </header>
{{#if feature_image}} {{#if feature_image}}
<figure class="post-full-image" style="background-image: url({{feature_image}})"> <figure class="post-full-image">
{{!-- This is a responsive image, it loads different sizes depending on device
https://medium.freecodecamp.org/a-guide-to-responsive-images-with-ready-to-use-templates-c400bd65c433 --}}
<img
srcset="{{img_url feature_image size="s"}} 300w,
{{img_url feature_image size="m"}} 600w,
{{img_url feature_image size="l"}} 1000w,
{{img_url feature_image size="xl"}} 2000w"
sizes="(max-width: 800px) 400px,
(max-width: 1170px) 700px,
1400px"
src="{{img_url feature_image size="xl"}}"
alt="{{title}}"
/>
</figure> </figure>
{{/if}} {{/if}}
<section class="post-full-content"> <section class="post-full-content">
{{content}} <div class="post-content">
{{content}}
</div>
</section> </section>
{{!-- Email subscribe form at the bottom of the page --}} {{!-- Email subscribe form at the bottom of the page --}}
{{#if @labs.subscribers}} {{#if @labs.subscribers}}
<section class="subscribe-form"> <section class="subscribe-form">
<h3 class="subscribe-form-title">Subscribe to {{@blog.title}}</h3> <h3 class="subscribe-form-title">Subscribe to {{@site.title}}</h3>
<p>Get the latest posts delivered right to your inbox</p> <p>Get the latest posts delivered right to your inbox</p>
{{subscribe_form placeholder="youremail@example.com"}} {{subscribe_form placeholder="youremail@example.com"}}
</section> </section>
{{/if}} {{/if}}
<footer class="post-full-footer"> <footer class="post-full-footer">
{{!-- Everything inside the #author tags pulls data from the author --}}
{{#author}}
<section class="author-card"> {{!-- There are two options for how we display the byline/author-info.
{{#if profile_image}} If the post has more than one author, we load a specific template
<img class="author-profile-image" src="{{profile_image}}" alt="{{name}}" /> from includes/byline-multiple.hbs, otherwise, we just use the
{{/if}} default byline. --}}
<section class="author-card-content">
<h4 class="author-card-name"><a href="{{url}}">{{name}}</a></h4> {{#has author="count:>1"}}
{{#if bio}} {{> "byline-multiple"}}
<p>{{bio}}</p> {{else}}
{{else}} {{> "byline-single"}}
<p>Read <a href="{{url}}">more posts</a> by this author.</p> {{/has}}
{{/if}}
</section>
</section>
<div class="post-full-footer-right">
<a class="author-card-button" href="{{url}}">Read More</a>
</div>
{{/author}}
</footer> </footer>
{{!-- {{!--
If you use Disqus comments, just uncomment this block.
The only thing you need to change is "test-apkdzgmqhj" - which
should be replaced with your own Disqus site-id.
<section class="post-full-comments"> <section class="post-full-comments">
<div id="disqus_thread"></div> If you want to embed comments, this is a good place to do it!
<script>
var disqus_config = function () {
this.page.url = '{{url absolute="true"}}';
this.page.identifier = 'ghost-{{comment_id}}';
};
(function() {
var d = document, s = d.createElement('script');
s.src = 'https://test-apkdzgmqhj.disqus.com/embed.js';
s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();
</script>
</section> </section>
--}} --}}
@ -101,19 +90,19 @@ into the {body} of the default.hbs template --}}
<aside class="read-next outer"> <aside class="read-next outer">
<div class="inner"> <div class="inner">
<div class="read-next-feed"> <div class="read-next-feed">
{{#if primary_tag}}
{{#get "posts" filter="tags:{{primary_tag.slug}}+id:-{{id}}" limit="3" as |related_posts|}} {{#get "posts" filter="tags:{{primary_tag.slug}}+id:-{{id}}" limit="3" as |related_posts|}}
{{#if related_posts}} {{#if related_posts}}
<article class="read-next-card" <article class="read-next-card"
{{#if ../primary_tag.feature_image}} {{#if ../primary_tag.feature_image}}
style="background-image: url({{../primary_tag.feature_image}})" style="background-image: url({{img_url ../primary_tag.feature_image size="m"}})"
{{else}} {{else}}
{{#if @blog.cover_image}} {{#if @site.cover_image}}
style="background-image: url({{@blog.cover_image}})"{{/if}} style="background-image: url({{img_url @site.cover_image size="m"}})"{{/if}}
{{/if}} {{/if}}
> >
<header class="read-next-card-header"> <header class="read-next-card-header">
<small class="read-next-card-header-sitetitle">&mdash; {{@blog.title}} &mdash;</small> <small class="read-next-card-header-sitetitle">&mdash; {{@site.title}} &mdash;</small>
{{#../primary_tag}} {{#../primary_tag}}
<h3 class="read-next-card-header-title"><a href="{{url}}">{{name}}</a></h3> <h3 class="read-next-card-header-title"><a href="{{url}}">{{name}}</a></h3>
{{/../primary_tag}} {{/../primary_tag}}
@ -132,6 +121,7 @@ into the {body} of the default.hbs template --}}
</article> </article>
{{/if}} {{/if}}
{{/get}} {{/get}}
{{/if}}
{{!-- If there's a next post, display it using the same markup included from - partials/post-card.hbs --}} {{!-- If there's a next post, display it using the same markup included from - partials/post-card.hbs --}}
{{#next_post}} {{#next_post}}
@ -166,7 +156,7 @@ $(document).ready(function () {
$postContent.fitVids(); $postContent.fitVids();
// End fitVids // End fitVids
var progressBar = document.querySelector('progress'); var progressBar = document.querySelector('#reading-progress');
var header = document.querySelector('.floating-header'); var header = document.querySelector('.floating-header');
var title = document.querySelector('.post-full-title'); var title = document.querySelector('.post-full-title');
@ -215,6 +205,7 @@ $(document).ready(function () {
window.addEventListener('resize', onResize, false); window.addEventListener('resize', onResize, false);
update(); update();
}); });
</script> </script>
{{/contentFor}} {{/contentFor}}

22
renovate.json Normal file
View File

@ -0,0 +1,22 @@
{
"extends": [
"config:base",
":maintainLockFilesWeekly",
"schedule:earlyMondays",
":automergeMinor"
],
"travis": { "enabled": true },
"node": {
"supportPolicy": ["lts_latest"]
},
"packageRules": [
{
"packagePatterns": ["^postcss", "css", "autoprefixer"],
"groupName": "css processors"
},
{
"packagePatterns": ["gulp"],
"groupName": "gulp"
}
]
}

View File

@ -1,9 +1,8 @@
{{!< default}} {{!< default}}
{{!-- The tag above means - insert everything in this file into the {body} of the default.hbs template --}} {{!-- The tag above means - insert everything in this file into the {body} of the default.hbs template --}}
{{!-- The big featured header, it uses blog cover image as a BG if available --}}
{{#tag}} {{#tag}}
<header class="site-header outer {{#if feature_image}}" style="background-image: url({{feature_image}}){{else}}no-cover{{/if}}"> {{> header background=feature_image}} {{!--Special header.hbs partial to generate the <header> tag--}}
<div class="inner"> <div class="inner">
{{> "site-nav"}} {{> "site-nav"}}
<div class="site-header-content"> <div class="site-header-content">
@ -21,7 +20,7 @@
{{/tag}} {{/tag}}
{{!-- The main content area --}} {{!-- The main content area --}}
<main id="site-main" class="site-main outer" role="main"> <main id="site-main" class="site-main outer">
<div class="inner"> <div class="inner">
<div class="post-feed"> <div class="post-feed">
{{#foreach posts}} {{#foreach posts}}

4407
yarn.lock Normal file

File diff suppressed because it is too large Load Diff