🎉 Hello World
14
src/_locales/en/messages.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"appName": {
|
||||
"message": "Ext Starter",
|
||||
"description": "The name of the extension."
|
||||
},
|
||||
"appDescription": {
|
||||
"message": "Boilerplate for building cross browser extensions",
|
||||
"description": "The description of the extension."
|
||||
},
|
||||
"btnTooltip": {
|
||||
"message": "Ext Starter",
|
||||
"description": "Tooltip for the button."
|
||||
}
|
||||
}
|
BIN
src/icons/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
src/icons/favicon-16x16.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
src/icons/favicon-32x32.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
src/icons/favicon-96x96.png
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
src/icons/icon-128.png
Normal file
After Width: | Height: | Size: 8.7 KiB |
BIN
src/icons/icon-16.png
Normal file
After Width: | Height: | Size: 355 B |
BIN
src/icons/icon-19.png
Normal file
After Width: | Height: | Size: 420 B |
BIN
src/icons/icon-38.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
src/icons/icon-64.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
0
src/images/.gitkeep
Normal file
0
src/images/chrome/.gitkeep
Normal file
0
src/images/firefox/.gitkeep
Normal file
0
src/images/opera/.gitkeep
Normal file
0
src/images/shared/.gitkeep
Normal file
53
src/options.html
Normal file
@@ -0,0 +1,53 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link href="styles/options.css" rel="stylesheet">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Options & Settings</title>
|
||||
</head>
|
||||
<body class="wrap">
|
||||
<div class="grid">
|
||||
<div class="unit whole center-on-mobiles">
|
||||
<div class="heading">
|
||||
<h1>Shikiryu Bookmarklet</h1>
|
||||
<p class="lead">Save this page by email for later read</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="content">
|
||||
<div id="msg"></div>
|
||||
</section>
|
||||
|
||||
<section class="content">
|
||||
<div class="grid">
|
||||
<div class="unit whole center-on-mobiles">
|
||||
<div class="option">
|
||||
<h5>URL</h5>
|
||||
<input type="text" name="url" value="https://bookmarklet.shikiryu.com" />
|
||||
</div>
|
||||
|
||||
<div class="option">
|
||||
<h5>Token</h5>
|
||||
<input type="text" name="token" value="" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<footer class="main-footer">
|
||||
<div class="grid">
|
||||
<div class="unit whole center-on-mobiles">
|
||||
<p class="text-center text-muted">
|
||||
© Shikiryu (thanks to https://github.com/EmailThis/extension-boilerplate)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</footer>
|
||||
<script src="scripts/options.js"></script>
|
||||
</body>
|
||||
</html>
|
24
src/popup.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link href="styles/popup.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app" class="popup-content">
|
||||
<h1 class="app-name">Extension Boilerplate</h1>
|
||||
|
||||
<div id="display-container"></div>
|
||||
|
||||
<footer>
|
||||
<p>
|
||||
<small>
|
||||
<a href="#" class="js-options">Options</a>
|
||||
</small>
|
||||
</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script src="scripts/popup.js"></script>
|
||||
</body>
|
||||
</html>
|
31
src/scripts/background.js
Normal file
@@ -0,0 +1,31 @@
|
||||
import ext from "./utils/ext";
|
||||
import storage from "./utils/storage";
|
||||
|
||||
ext.runtime.onMessage.addListener(
|
||||
function(request, sender, sendResponse) {
|
||||
if(request.action === "perform-save") {
|
||||
var data = JSON.parse(request.data);
|
||||
var url;
|
||||
var token;
|
||||
storage.get('url', function(resp) {
|
||||
url = resp.url;
|
||||
storage.get('token', function(resp) {
|
||||
token = resp.token;
|
||||
console.log("Extension Type: ", "/* @echo extension */");
|
||||
console.log("PERFORM AJAX", request.data);
|
||||
var destination = url+"?v=1&u="+encodeURIComponent(data.url)+"&t="+encodeURIComponent(data.title)+"&m="+encodeURIComponent(token);
|
||||
|
||||
console.log("Destination: ", destination);
|
||||
fetch(destination)
|
||||
.then(function(response) {
|
||||
console.log(response);
|
||||
});
|
||||
|
||||
sendResponse({ action: "saved" });
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
);
|
34
src/scripts/contentscript.js
Normal file
@@ -0,0 +1,34 @@
|
||||
import ext from "./utils/ext";
|
||||
|
||||
var extractTags = () => {
|
||||
var url = document.location.href;
|
||||
if(!url || !url.match(/^http/)) return;
|
||||
|
||||
var data = {
|
||||
title: "",
|
||||
description: "",
|
||||
url: document.location.href
|
||||
}
|
||||
|
||||
var ogTitle = document.querySelector("meta[property='og:title']");
|
||||
if(ogTitle) {
|
||||
data.title = ogTitle.getAttribute("content")
|
||||
} else {
|
||||
data.title = document.title
|
||||
}
|
||||
|
||||
var descriptionTag = document.querySelector("meta[property='og:description']") || document.querySelector("meta[name='description']")
|
||||
if(descriptionTag) {
|
||||
data.description = descriptionTag.getAttribute("content")
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
function onRequest(request, sender, sendResponse) {
|
||||
if (request.action === 'process-page') {
|
||||
sendResponse(extractTags())
|
||||
}
|
||||
}
|
||||
|
||||
ext.runtime.onMessage.addListener(onRequest);
|
20
src/scripts/livereload.js
Normal file
@@ -0,0 +1,20 @@
|
||||
'use strict';
|
||||
|
||||
import ext from "./utils/ext";
|
||||
|
||||
var LIVERELOAD_HOST = 'localhost:';
|
||||
var LIVERELOAD_PORT = 35729;
|
||||
var connection = new WebSocket('ws://' + LIVERELOAD_HOST + LIVERELOAD_PORT + '/livereload');
|
||||
|
||||
connection.onerror = function (error) {
|
||||
console.log('reload connection got error:', error);
|
||||
};
|
||||
|
||||
connection.onmessage = function (e) {
|
||||
if (e.data) {
|
||||
var data = JSON.parse(e.data);
|
||||
if (data && data.command === 'reload') {
|
||||
ext.runtime.reload();
|
||||
}
|
||||
}
|
||||
};
|
28
src/scripts/options.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import ext from "./utils/ext";
|
||||
import storage from "./utils/storage";
|
||||
|
||||
var urlInput = document.querySelector("[name=url]");
|
||||
var tokenInput = document.querySelector("[name=token]");
|
||||
var message = document.getElementById("msg");
|
||||
|
||||
storage.get('url', function(resp) {
|
||||
urlInput.value = resp.url || "https://bookmarklet.shikiryu.com";
|
||||
});
|
||||
|
||||
storage.get('token', function(resp) {
|
||||
tokenInput.value = resp.token;
|
||||
});
|
||||
|
||||
urlInput.addEventListener("blur", function(e) {
|
||||
var value = this.value;
|
||||
storage.set({ url: value }, function() {
|
||||
message.innerHTML = "URL changed!";
|
||||
});
|
||||
});
|
||||
|
||||
tokenInput.addEventListener("blur", function(e) {
|
||||
var value = this.value;
|
||||
storage.set({ token: value }, function() {
|
||||
message.innerHTML = "Token saved!";
|
||||
});
|
||||
});
|
63
src/scripts/popup.js
Normal file
@@ -0,0 +1,63 @@
|
||||
import ext from "./utils/ext";
|
||||
import storage from "./utils/storage";
|
||||
|
||||
var popup = document.getElementById("app");
|
||||
storage.get('color', function(resp) {
|
||||
var color = resp.color;
|
||||
if(color) {
|
||||
popup.style.backgroundColor = color
|
||||
}
|
||||
});
|
||||
|
||||
var template = (data) => {
|
||||
var json = JSON.stringify(data);
|
||||
return (`
|
||||
<div class="site-description">
|
||||
<h3 class="title">${data.title}</h3>
|
||||
<p class="description">${data.description}</p>
|
||||
<a href="${data.url}" target="_blank" class="url">${data.url}</a>
|
||||
</div>
|
||||
<div class="action-container">
|
||||
<button data-bookmark='${json}' id="save-btn" class="btn btn-primary">Save</button>
|
||||
</div>
|
||||
`);
|
||||
}
|
||||
var renderMessage = (message) => {
|
||||
var displayContainer = document.getElementById("display-container");
|
||||
displayContainer.innerHTML = `<p class='message'>${message}</p>`;
|
||||
}
|
||||
|
||||
var renderBookmark = (data) => {
|
||||
var displayContainer = document.getElementById("display-container")
|
||||
if(data) {
|
||||
var tmpl = template(data);
|
||||
displayContainer.innerHTML = tmpl;
|
||||
} else {
|
||||
renderMessage("Sorry, could not extract this page's title and URL")
|
||||
}
|
||||
}
|
||||
|
||||
ext.tabs.query({active: true, currentWindow: true}, function(tabs) {
|
||||
var activeTab = tabs[0];
|
||||
chrome.tabs.sendMessage(activeTab.id, { action: 'process-page' }, renderBookmark);
|
||||
});
|
||||
|
||||
popup.addEventListener("click", function(e) {
|
||||
if(e.target && e.target.matches("#save-btn")) {
|
||||
e.preventDefault();
|
||||
var data = e.target.getAttribute("data-bookmark");
|
||||
ext.runtime.sendMessage({ action: "perform-save", data: data }, function(response) {
|
||||
if(response && response.action === "saved") {
|
||||
renderMessage("Your bookmark was saved successfully!");
|
||||
} else {
|
||||
renderMessage("Sorry, there was an error while saving your bookmark.");
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
var optionsLink = document.querySelector(".js-options");
|
||||
optionsLink.addEventListener("click", function(e) {
|
||||
e.preventDefault();
|
||||
ext.tabs.create({'url': ext.extension.getURL('options.html')});
|
||||
})
|
68
src/scripts/utils/ext.js
Normal file
@@ -0,0 +1,68 @@
|
||||
const apis = [
|
||||
'alarms',
|
||||
'bookmarks',
|
||||
'browserAction',
|
||||
'commands',
|
||||
'contextMenus',
|
||||
'cookies',
|
||||
'downloads',
|
||||
'events',
|
||||
'extension',
|
||||
'extensionTypes',
|
||||
'history',
|
||||
'i18n',
|
||||
'idle',
|
||||
'notifications',
|
||||
'pageAction',
|
||||
'runtime',
|
||||
'storage',
|
||||
'tabs',
|
||||
'webNavigation',
|
||||
'webRequest',
|
||||
'windows',
|
||||
]
|
||||
|
||||
function Extension () {
|
||||
const _this = this
|
||||
|
||||
apis.forEach(function (api) {
|
||||
|
||||
_this[api] = null
|
||||
|
||||
try {
|
||||
if (chrome[api]) {
|
||||
_this[api] = chrome[api]
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
try {
|
||||
if (window[api]) {
|
||||
_this[api] = window[api]
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
try {
|
||||
if (browser[api]) {
|
||||
_this[api] = browser[api]
|
||||
}
|
||||
} catch (e) {}
|
||||
try {
|
||||
_this.api = browser.extension[api]
|
||||
} catch (e) {}
|
||||
})
|
||||
|
||||
try {
|
||||
if (browser && browser.runtime) {
|
||||
this.runtime = browser.runtime
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
try {
|
||||
if (browser && browser.browserAction) {
|
||||
this.browserAction = browser.browserAction
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
}
|
||||
|
||||
module.exports = new Extension();
|
3
src/scripts/utils/storage.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import ext from "./ext";
|
||||
|
||||
module.exports = (ext.storage.sync ? ext.storage.sync : ext.storage.local);
|
132
src/styles/modules/_grid.scss
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Gridism
|
||||
* A simple, responsive, and handy CSS grid by @cobyism
|
||||
* https://github.com/cobyism/gridism
|
||||
*/
|
||||
|
||||
/* Preserve some sanity */
|
||||
.grid,
|
||||
.unit {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Set up some rules to govern the grid */
|
||||
.grid {
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
.grid .unit {
|
||||
float: left;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
/* This ensures the outer gutters are equal to the (doubled) inner gutters. */
|
||||
.grid .unit:first-child { padding-left: 20px; }
|
||||
.grid .unit:last-child { padding-right: 20px; }
|
||||
|
||||
/* Nested grids already have padding though, so let's nuke it */
|
||||
.unit .unit:first-child { padding-left: 0; }
|
||||
.unit .unit:last-child { padding-right: 0; }
|
||||
.unit .grid:first-child > .unit { padding-top: 0; }
|
||||
.unit .grid:last-child > .unit { padding-bottom: 0; }
|
||||
|
||||
/* Let people nuke the gutters/padding completely in a couple of ways */
|
||||
.no-gutters .unit,
|
||||
.unit.no-gutters {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/* Wrapping at a maximum width is optional */
|
||||
.wrap .grid,
|
||||
.grid.wrap {
|
||||
max-width: 978px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Width classes also have shorthand versions numbered as fractions
|
||||
* For example: for a grid unit 1/3 (one third) of the parent width,
|
||||
* simply apply class="w-1-3" to the element. */
|
||||
.grid .whole, .grid .w-1-1 { width: 100%; }
|
||||
.grid .half, .grid .w-1-2 { width: 50%; }
|
||||
.grid .one-third, .grid .w-1-3 { width: 33.3332%; }
|
||||
.grid .two-thirds, .grid .w-2-3 { width: 66.6665%; }
|
||||
.grid .one-quarter,
|
||||
.grid .one-fourth, .grid .w-1-4 { width: 25%; }
|
||||
.grid .three-quarters,
|
||||
.grid .three-fourths, .grid .w-3-4 { width: 75%; }
|
||||
.grid .one-fifth, .grid .w-1-5 { width: 20%; }
|
||||
.grid .two-fifths, .grid .w-2-5 { width: 40%; }
|
||||
.grid .three-fifths, .grid .w-3-5 { width: 60%; }
|
||||
.grid .four-fifths, .grid .w-4-5 { width: 80%; }
|
||||
.grid .golden-small, .grid .w-g-s { width: 38.2716%; } /* Golden section: smaller piece */
|
||||
.grid .golden-large, .grid .w-g-l { width: 61.7283%; } /* Golden section: larger piece */
|
||||
|
||||
/* Clearfix after every .grid */
|
||||
.grid {
|
||||
*zoom: 1;
|
||||
}
|
||||
.grid:before, .grid:after {
|
||||
display: table;
|
||||
content: "";
|
||||
line-height: 0;
|
||||
}
|
||||
.grid:after {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/* Utility classes */
|
||||
.align-center { text-align: center; }
|
||||
.align-left { text-align: left; }
|
||||
.align-right { text-align: right; }
|
||||
.pull-left { float: left; }
|
||||
.pull-right { float: right; }
|
||||
|
||||
/* A property for a better rendering of images in units: in
|
||||
this way bigger pictures are just resized if the unit
|
||||
becomes smaller */
|
||||
.unit img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* Hide elements using this class by default */
|
||||
.only-on-mobiles {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Responsive Stuff */
|
||||
@media screen and (max-width: 568px) {
|
||||
/* Stack anything that isn't full-width on smaller screens
|
||||
and doesn't provide the no-stacking-on-mobiles class */
|
||||
.grid:not(.no-stacking-on-mobiles) > .unit {
|
||||
width: 100% !important;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
.unit .grid .unit {
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
/* Sometimes, you just want to be different on small screens */
|
||||
.center-on-mobiles {
|
||||
text-align: center !important;
|
||||
}
|
||||
.hide-on-mobiles {
|
||||
display: none !important;
|
||||
}
|
||||
.only-on-mobiles {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Expand the wrap a bit further on larger screens */
|
||||
@media screen and (min-width: 1180px) {
|
||||
.wider .grid,
|
||||
.grid.wider {
|
||||
max-width: 1180px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
95
src/styles/modules/_layout.scss
Normal file
@@ -0,0 +1,95 @@
|
||||
html, body {
|
||||
box-sizing: border-box;
|
||||
&:before, &:after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: $font-family-base;
|
||||
line-height: $line-height-base;
|
||||
font-size: $font-size-base;
|
||||
color: $text-color;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: $headings-font-family;
|
||||
font-weight: $headings-font-weight;
|
||||
line-height: $headings-line-height;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h1 { font-size: 1.75em; }
|
||||
h2 { font-size: 1.5em; }
|
||||
h3 { font-size: 1.25em; }
|
||||
h4 { font-size: 1.10em; }
|
||||
h5 { font-size: 1em; }
|
||||
h6 { font-size: .85em; }
|
||||
|
||||
nav {
|
||||
margin: 1em 0;
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
li {
|
||||
display: inline-block;
|
||||
margin-right: 1em;
|
||||
margin-bottom: .25em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: $brand-primary;
|
||||
&:hover, &:focus {
|
||||
color: darken($brand-primary, 6.25%);
|
||||
}
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
padding-left: 2.5em;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 1em 0;
|
||||
hyphens: auto;
|
||||
|
||||
&.lead {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
+ ul, + ol {
|
||||
margin-top: -.75em;
|
||||
}
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-bottom: 1em;
|
||||
margin-left: 0;
|
||||
padding-left: 2.5em;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 0;
|
||||
padding-left: 2.5em;
|
||||
}
|
85
src/styles/modules/_reset.scss
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
App reset by Ben Frain @benfrain / benfrain.com
|
||||
Slightly modified by Bharani @bharani91 / github.com/bharani91
|
||||
*/
|
||||
|
||||
/*Hat tip to @thierrykoblentz for this approach: https://css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice/ */
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
* {
|
||||
user-select: none;
|
||||
-webkit-tap-highlight-color: rgba(255,255,255,0);
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
*:before,
|
||||
*:after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
input[type],
|
||||
[contenteditable] {
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
body,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
p {
|
||||
margin: 0;
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
/*IMPORTANT: This removes the focus outline for most browsers. Be aware this is a backwards accessibilty step! Mozilla (i.e. Firefox) also adds a dotted outline around a tags and buttons when they receive tab focus which I haven't found an unhacky way of removing.*/
|
||||
a:focus,
|
||||
button:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
button {
|
||||
appearance: none;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
input,
|
||||
fieldset {
|
||||
appearance: none;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
min-width: 0;
|
||||
font-size: 1rem;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
/*This switches the default outline off when an input receives focus (really important for users tabbing through with a keyboard) so ensure you put something decent in for your input focus instead!!*/
|
||||
input:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/*Removes the default focusring that Mozilla places on select items. From: http://stackoverflow.com/a/18853002/1147859
|
||||
Ensure you set `#000` to the colour you want your text to appear */
|
||||
select:-moz-focusring {
|
||||
color: transparent;
|
||||
text-shadow: 0 0 0 #000;
|
||||
}
|
7
src/styles/modules/_utilities.scss
Normal file
@@ -0,0 +1,7 @@
|
||||
.text-muted {
|
||||
color: $text-secondary;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
17
src/styles/modules/_variables.scss
Normal file
@@ -0,0 +1,17 @@
|
||||
// Colors
|
||||
$black: #111111;
|
||||
$white: #ffffff;
|
||||
$gray: #eeeeee;
|
||||
$brand-primary: #4990E2;
|
||||
$text-color: $black;
|
||||
$text-secondary: #7A7A7A;
|
||||
|
||||
|
||||
// Typography
|
||||
$font-family-base: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
$headings-font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
$font-size-base: 16px;
|
||||
$line-height-base: 1.5;
|
||||
$headings-font-weight: 500;
|
||||
$headings-line-height: 1.1;
|
||||
$headings-color: $text-color;
|
38
src/styles/options.scss
Normal file
@@ -0,0 +1,38 @@
|
||||
@import "modules/reset";
|
||||
@import "modules/variables";
|
||||
@import "modules/grid";
|
||||
@import "modules/layout";
|
||||
@import "modules/utilities";
|
||||
|
||||
.heading {
|
||||
margin: 1em auto;
|
||||
padding-bottom: 1em;
|
||||
border-bottom: 1px solid #eee;
|
||||
|
||||
h1 + .lead {
|
||||
margin-top: 0.2em;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
.option {
|
||||
margin: 1em auto;
|
||||
h5 {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.radio-group {
|
||||
label {
|
||||
display: block;
|
||||
}
|
||||
input[type="radio"] {
|
||||
display: inline-block;
|
||||
margin: 3px 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
88
src/styles/popup.scss
Normal file
@@ -0,0 +1,88 @@
|
||||
@import "modules/reset";
|
||||
@import "modules/variables";
|
||||
@import "modules/layout";
|
||||
|
||||
body, html {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#app {
|
||||
padding: 20px 20px;
|
||||
background: $white;
|
||||
}
|
||||
|
||||
footer {
|
||||
color: $text-secondary;
|
||||
text-align: right;
|
||||
font-size: 0.8em;
|
||||
a {
|
||||
outline: none;
|
||||
color: lighten($text-secondary, 10%);
|
||||
&:hover {
|
||||
color: $text-secondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.popup-content {
|
||||
min-width: 220px;
|
||||
min-height: 100px;
|
||||
max-width: 350px;
|
||||
}
|
||||
|
||||
.app-name {
|
||||
font-size: 14px;
|
||||
text-transform: uppercase;
|
||||
color: $text-secondary;
|
||||
text-align: center;
|
||||
margin: 0 auto 1em auto;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.site-description {
|
||||
padding: 0.5em;
|
||||
border: 1px solid $gray;
|
||||
margin: 0;
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border-bottom: 1px solid $gray;
|
||||
padding-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.description {
|
||||
color: $text-secondary;
|
||||
max-height: 100px;
|
||||
font-size: 0.8em;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.url {
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
line-height: 1.2;
|
||||
font-size: 0.8em;
|
||||
word-break: break-word;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.action-container {
|
||||
margin: 1em auto;
|
||||
}
|
||||
|
||||
.btn {
|
||||
background: none;
|
||||
border: none;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
padding: 0.5em 1.5em;
|
||||
background: $brand-primary;
|
||||
color: $white;
|
||||
font-weight: $headings-font-weight;
|
||||
border-radius: 2px;
|
||||
outline: none;
|
||||
font-size: 1em;
|
||||
}
|