Skip to content

Commit

Permalink
Merge pull request #10 from trendyminds/update/3.0.0
Browse files Browse the repository at this point in the history
3.0.0
  • Loading branch information
aaronbushnell authored Jul 28, 2020
2 parents 13af25a + f5e7847 commit 0626af9
Show file tree
Hide file tree
Showing 17 changed files with 1,478 additions and 1,939 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Release Notes for Visor

## 3.0.0 - 2020-07-27

> {warning} Visor 3 is a full rewrite of the plugin to play nicely with full-page static caching solutions like [Blitz](https://plugins.craftcms.com/blitz). Please ensure you are familiar with the [caveats to providing full-page static caching support](https://github.com/trendyminds/visor#caveats)
### Added
- Support for full-page static caching
- Support for Category detection
- Support for Solspace Events detection

### Changed
- When Visor hook is used, a network request is made to fetch the controls. Please ensure you are familiar with the [caveats introduced in 3.0 to provide full-page static caching support](https://github.com/trendyminds/visor#caveats)

## 2.1.1 - 2020-01-02

### Changed
Expand Down
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Visor is a simple admin overlay to get to the relevant areas of the Craft CMS co

## Requirements

This plugin requires Craft CMS 3.0.0-beta.23 or later.
This plugin requires Craft CMS 3.1.20 or later.

## Installation

Expand All @@ -28,7 +28,6 @@ To install the plugin, follow these instructions.
composer require trendyminds/visor

3. In the Control Panel, go to Settings → Plugins and click the “Install” button for Visor.
4. Add `{% hook "visor" %}` to your template to add Visor to that page. It's recommended to add this code to your main `_layout.html` file

## Keyboard Shortcuts

Expand Down Expand Up @@ -57,6 +56,16 @@ Visor also uses inline SVGs for all graphics. This:

If you'd prefer to replace purple with a different color you can change this by targeting `.Visor--override .Visor__modal`.

## Caveats

Since 3.0 Visor offers support for full-page static caching. In order to offer this a network request is made on every page request to check if the user should see the Visor controls. To ensure this does not impact performance numerous things are done:

1. The JavaScript to make this check is inserted at the bottom of the page
2. The JavaScript used to make the check is _very_ small (< 2 KB)
3. Early returns are used if the user is a guest and should not see anything from Visor

The checks to ensure we return early for guests is documented entirely in [DefaultController.php](https://github.com/trendyminds/visor/tree/master/src/controllers/DefaultController.php). If you see opportunities to improve the performance of these checks (or any other part of Visor) pull requests are welcomed.

## Browser compatibility
This has been tested on Chrome, Firefox and Safari, but [drop in an Issue](https://github.com/trendyminds/visor/issues/new) if you notice any strangeness.

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "trendyminds/visor",
"description": "A simple admin overlay to get to the relevant areas of the Craft CMS control panel",
"type": "craft-plugin",
"version": "2.1.1",
"version": "3.0.0",
"keywords": [
"craft",
"cms",
Expand Down
2,886 changes: 1,165 additions & 1,721 deletions package-lock.json

Large diffs are not rendered by default.

12 changes: 7 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
{
"name": "visor",
"version": "1.0.0",
"version": "3.0.0",
"description": "A simple admin overlay to get to the relevant areas of the Craft CMS control panel",
"main": "index.js",
"scripts": {
"start": "parcel watch resources/visor.js --out-dir src/resources",
"build": "parcel build resources/visor.js --out-dir src/resources"
"start": "parcel watch resources/visor.js --out-dir src/resources --no-source-maps",
"build": "parcel build resources/visor.js --out-dir src/resources --no-source-maps --no-content-hash"
},
"keywords": [],
"author": "",
"license": "ISC",
"prettier": {},
"devDependencies": {
"parcel-bundler": "^1.12.4"
"parcel-bundler": "^1.12.4",
"prettier": "2.0.5"
},
"dependencies": {
"hotkeys-js": "^3.4.3"
"hotkeys-js": "^3.8.1"
}
}
51 changes: 51 additions & 0 deletions resources/init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import hotkeys from "hotkeys-js";
import "./visor.css";

export default class Visor {
constructor() {
this.isOpen = false;
this.$toggle = document.querySelectorAll("[data-visor-toggle]");
this.$modal = document.querySelector("[data-visor]");

this.handleToggle = this.handleToggle.bind(this);
this.open = this.open.bind(this);
this.close = this.close.bind(this);

// Change the initial display: none to display: block after DOM element added.
// This prevents a "flash" of an animation that would've fired if a user clicked the Visor element
this.$modal.querySelector(".Visor__modal").style.display = "block";

this.events();
}

events() {
this.$toggle.forEach(($toggle) =>
$toggle.addEventListener("click", this.handleToggle)
);

hotkeys("`", this.handleToggle);
hotkeys("esc", this.close);
}

handleToggle() {
if (this.isOpen) {
return this.close();
}

return this.open();
}

close() {
this.isOpen = false;
this.$modal.classList.remove("is-open");

return true;
}

open() {
this.isOpen = true;
this.$modal.classList.add("is-open");

return true;
}
}
14 changes: 7 additions & 7 deletions resources/visor.css
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,17 @@
.Visor__toggle svg {
filter: drop-shadow(0 2px 0 #999);
opacity: 0.5;
transition: transform .1s;
transition: transform 0.1s;
}

.Visor__toggle:hover svg {
opacity: .75;
opacity: 0.75;
transform: scale3d(1.2, 1.2, 1);
}

.Visor__toggle:active svg {
opacity: .95;
transform: scale3d(.85, .85, 1);
opacity: 0.95;
transform: scale3d(0.85, 0.85, 1);
}

.Visor__toggle path {
Expand Down Expand Up @@ -96,7 +96,7 @@
top: -0.75rem;
padding: 0;
transform: scale3d(1, 1, 1);
transition: .15s transform;
transition: 0.15s transform;
margin: 0;
z-index: 5;
}
Expand All @@ -106,7 +106,7 @@
}

.Visor__close:active {
transform: scale3d(.95, .95, 1);
transform: scale3d(0.95, 0.95, 1);
}

.Visor__close rect {
Expand Down Expand Up @@ -200,7 +200,7 @@

.Visor__link-icon path {
fill: #ccc;
transition: .15s fill;
transition: 0.15s fill;
}

.Visor__link:hover .Visor__link-icon {
Expand Down
66 changes: 18 additions & 48 deletions resources/visor.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,19 @@
import hotkeys from "hotkeys-js";
import "./visor.css";

class Visor {
constructor() {
this.isOpen = false;
this.$toggle = document.querySelectorAll("[data-visor-toggle]");
this.$modal = document.querySelector("[data-visor]");

this.handleToggle = this.handleToggle.bind(this);
this.open = this.open.bind(this);
this.close = this.close.bind(this);

this.events();
}

events() {
this.$toggle.forEach($toggle => {
$toggle.addEventListener("click", this.handleToggle)
(() => {
fetch("/actions/visor/default/access")
.then((res) => {
// Did we encounter a non 200 status code? If so, exit
if (res.status !== 200) {
return false;
}

// Proceed if the page ran
return res.text();
})
.then((data) => {
// Only output something to the page if we received data
if (data) {
document.body.insertAdjacentHTML("beforeend", data);
import("./init").then((module) => new module.default());
}
});

hotkeys("`", this.handleToggle);
hotkeys("esc", this.close);
}

handleToggle() {
if (this.isOpen) {
return this.close();
}

return this.open();
}

close() {
this.isOpen = false;
this.$modal.classList.remove("is-open");

return true;
}

open() {
this.isOpen = true;
this.$modal.classList.add("is-open");

return true;
}
}

new Visor();
})();
79 changes: 12 additions & 67 deletions src/Visor.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,97 +10,42 @@

namespace trendyminds\visor;

use trendyminds\visor\services\VisorService as VisorServiceService;

use Craft;
use craft\base\Plugin;
use craft\services\Plugins;
use craft\events\PluginEvent;
use craft\web\UrlManager;

use yii\base\Event;
use craft\web\UrlManager;
use craft\events\RegisterUrlRulesEvent;
use yii\base\InvalidConfigException;

use trendyminds\visor\assetbundles\VisorAsset;

/**
* Class Visor
*
* @author TrendyMinds
* @package Visor
* @since 2.0.0
*
* @property VisorServiceService $visorService
* @since 3.0.0
*/
class Visor extends Plugin
{
// Static Properties
// =========================================================================

/**
* @var Visor
*/
public static $plugin;

// Public Properties
// =========================================================================

/**
* @var string
*/
public $schemaVersion = '2.0.0';

// Public Methods
// =========================================================================

/**
* @inheritdoc
*/
public function init()
{
parent::init();
self::$plugin = $this;

Event::on(
Plugins::class,
Plugins::EVENT_AFTER_INSTALL_PLUGIN,
function (PluginEvent $event) {
if ($event->plugin === $this) {
}
}
);

Craft::info(
Craft::t(
'visor',
'{name} plugin loaded',
['name' => $this->name]
),
__METHOD__
);

// Register our site routes
Event::on(
UrlManager::class,
UrlManager::EVENT_REGISTER_SITE_URL_RULES,
function (RegisterUrlRulesEvent $event) {
// If the user isn't logged in, return and move on.
if (Craft::$app->getUser()->getIsGuest())
{
return false;
}

Craft::$app->view->hook('visor', function (array &$context) {
// Set the title to something in case we're not in an entry
$entry = (object) [
"title" => Craft::$app->getConfig()->general->siteName
];

// If we are in an entry context, use it in place of our dummy object
if (isset($context["entry"]))
{
$entry = $context["entry"];
function () {
// When the Visor hook is used, register the asset bundle for the JS functionality
Craft::$app->view->hook('visor', function () {
try {
Craft::$app->getView()->registerAssetBundle(VisorAsset::class);
} catch (InvalidConfigException $e) {
Craft::error('Could not register the Visor asset bundle.');
}

return Visor::$plugin->visorService->render($entry);
});
}
);
Expand Down
5 changes: 1 addition & 4 deletions src/assetbundles/VisorAsset.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,15 @@

use Craft;
use craft\web\AssetBundle;
use craft\web\assets\cp\CpAsset;

class VisorAsset extends AssetBundle
{
// Public Methods
// =========================================================================

public function init()
{
$this->sourcePath = "@trendyminds/visor/resources";
$this->css = ['visor.css'];
$this->js = ['visor.js'];
$this->js = ["visor.js"];

parent::init();
}
Expand Down
Loading

0 comments on commit 0626af9

Please sign in to comment.