1
0
mirror of https://github.com/chinchang/web-maker.git synced 2025-08-01 11:00:28 +02:00

Merge pull request #47 from chinchang/release-2.2

Release 2.2
This commit is contained in:
Kushagra Gour
2017-01-24 01:48:02 +05:30
committed by GitHub
5 changed files with 296 additions and 54 deletions

View File

@@ -4,6 +4,7 @@
<title>Web Maker</title>
<link rel="stylesheet" href="lib/codemirror/lib/codemirror.css">
<link rel="stylesheet" href="lib/codemirror/theme/monokai.css">
<link rel="stylesheet" href="lib/codemirror/addon/hint/show-hint.css">
<link rel="stylesheet" href="lib/codemirror/addon/fold/foldgutter.css">
<link rel="stylesheet" href="lib/hint.min.css">
<link rel="stylesheet" href="lib/inlet.css">
@@ -60,6 +61,7 @@
<ul class="js-modes-menu dropdown__menu">
<li><a data-type="css" data-mode="css">CSS</a></li>
<li><a data-type="css" data-mode="scss">SCSS</a></li>
<li><a data-type="css" data-mode="sass">SASS</a></li>
<li><a data-type="css" data-mode="less">LESS</a></li>
<li><a data-type="css" data-mode="stylus">Stylus</a></li>
</ul>
@@ -126,6 +128,11 @@
<use xlink:href="#mode-icon" />
</svg>
</a>
<a id="layoutBtn4" class="mode-btn hint--top-left hint--rounded" aria-label="Full Screen">
<svg viewBox="0 0 100 100">
<rect x="0" y="0" width="100" height="100" />
</svg>
</a>
<div class="footer__separator"></div>
@@ -187,7 +194,7 @@
<div class="modal" id="helpModal">
<div class="modal__content">
<h1>Web Maker<small style="font-size:14px;"> v2.1.0</small></h1>
<h1>Web Maker<small style="font-size:14px;"> v2.2.0</small></h1>
<div>
<p>Made by <a href="https://twitter.com/chinchang457" target="_blank">Kushagra Gour</a></p>
<p>Tweet out your feature requests, comments & suggestions to <a target="_blank" href="https://twitter.com/webmakerApp">@webmakerApp</a>.</p>
@@ -281,6 +288,20 @@
<div class="modal" id="notificationsModal">
<div class="modal__content">
<h1>Whats new?</h1>
<div class="notification">
<span class="notification__version">2.2.0</span>
<ul>
<li><strong>Code Autocompletion</strong> - See code suggestions while you type!</li>
<li><strong>Full Screen Preview</strong> - Checkout your creation in a full-screen layout.</li>
<li><strong>SASS</strong> - SASS support added for CSS.</li>
<li><strong>Faster CSS update</strong> - Preview updates instantly without refresh when just CSS is changed.</li>
<li><strong>Bugfix</strong> - Indentation fixed while going on new line.</li>
<li><strong>Bugfix</strong> - Works even in Chrome Canary now. Though libraries can be added only through CDNs.</li>
<li><a href="https://github.com/chinchang/web-maker/issues" target="_blank">Suggest a feature.</a></li>
<li>Thank you for being a part of this awesome 4000+ developers community. If you find Web Maker helpful, <a href="https://chrome.google.com/webstore/detail/web-maker/lkfkkhfhhdkiemehlpkgjeojomhpccnh/reviews" target="_blank" class="btn">Please rate Web Maker <span class="star"></span></a> & <a href="http://twitter.com/share?url=https://kushagragour.in/lab/web-maker/&text=Web Maker - Convert your Chrome tabs into a blazing fast offline web playground! via @webmakerApp&related=webmakerApp&hashtags=web,editor" target="_blank" target="_blank" class="btn">share it</a>.</li>
</ul>
</div>
<div class="notification">
<span class="notification__version">2.1.0</span>
<ul>
@@ -289,7 +310,6 @@
<li><strong>Code Folding</strong> - Collapse large code blocks for easy editing.</li>
<li><strong>Bugfix</strong> - Support JSX in JavaScript.</li>
<li>Better onboarding for first time users.</li>
<li>Like it? <a href="https://chrome.google.com/webstore/detail/web-maker/lkfkkhfhhdkiemehlpkgjeojomhpccnh/reviews" target="_blank" class="btn">Please rate Web Maker <span class="star"></span></a></li>
</ul>
</div>
<div class="notification">
@@ -361,6 +381,11 @@
<script src="lib/codemirror/addon/fold/comment-fold.js"></script>
<script src="lib/codemirror/addon/fold/brace-fold.js"></script>
<script src="lib/codemirror/addon/mode/loadmode.js"></script>
<script src="lib/codemirror/addon/hint/show-hint.js"></script>
<script src="lib/codemirror/addon/hint/javascript-hint.js"></script>
<script src="lib/codemirror/addon/hint/xml-hint.js"></script>
<script src="lib/codemirror/addon/hint/html-hint.js"></script>
<script src="lib/codemirror/addon/hint/css-hint.js"></script>
<script src="lib/codemirror/mode/xml/xml.js"></script>
<script src="lib/codemirror/mode/javascript/javascript.js"></script>

148
src/lib/codemirror/mode/jsx/jsx.js vendored Normal file
View File

@@ -0,0 +1,148 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"))
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript"], mod)
else // Plain browser env
mod(CodeMirror)
})(function(CodeMirror) {
"use strict"
// Depth means the amount of open braces in JS context, in XML
// context 0 means not in tag, 1 means in tag, and 2 means in tag
// and js block comment.
function Context(state, mode, depth, prev) {
this.state = state; this.mode = mode; this.depth = depth; this.prev = prev
}
function copyContext(context) {
return new Context(CodeMirror.copyState(context.mode, context.state),
context.mode,
context.depth,
context.prev && copyContext(context.prev))
}
CodeMirror.defineMode("jsx", function(config, modeConfig) {
var xmlMode = CodeMirror.getMode(config, {name: "xml", allowMissing: true, multilineTagIndentPastTag: false})
var jsMode = CodeMirror.getMode(config, modeConfig && modeConfig.base || "javascript")
function flatXMLIndent(state) {
var tagName = state.tagName
state.tagName = null
var result = xmlMode.indent(state, "")
state.tagName = tagName
return result
}
function token(stream, state) {
if (state.context.mode == xmlMode)
return xmlToken(stream, state, state.context)
else
return jsToken(stream, state, state.context)
}
function xmlToken(stream, state, cx) {
if (cx.depth == 2) { // Inside a JS /* */ comment
if (stream.match(/^.*?\*\//)) cx.depth = 1
else stream.skipToEnd()
return "comment"
}
if (stream.peek() == "{") {
xmlMode.skipAttribute(cx.state)
var indent = flatXMLIndent(cx.state), xmlContext = cx.state.context
// If JS starts on same line as tag
if (xmlContext && stream.match(/^[^>]*>\s*$/, false)) {
while (xmlContext.prev && !xmlContext.startOfLine)
xmlContext = xmlContext.prev
// If tag starts the line, use XML indentation level
if (xmlContext.startOfLine) indent -= config.indentUnit
// Else use JS indentation level
else if (cx.prev.state.lexical) indent = cx.prev.state.lexical.indented
// Else if inside of tag
} else if (cx.depth == 1) {
indent += config.indentUnit
}
state.context = new Context(CodeMirror.startState(jsMode, indent),
jsMode, 0, state.context)
return null
}
if (cx.depth == 1) { // Inside of tag
if (stream.peek() == "<") { // Tag inside of tag
xmlMode.skipAttribute(cx.state)
state.context = new Context(CodeMirror.startState(xmlMode, flatXMLIndent(cx.state)),
xmlMode, 0, state.context)
return null
} else if (stream.match("//")) {
stream.skipToEnd()
return "comment"
} else if (stream.match("/*")) {
cx.depth = 2
return token(stream, state)
}
}
var style = xmlMode.token(stream, cx.state), cur = stream.current(), stop
if (/\btag\b/.test(style)) {
if (/>$/.test(cur)) {
if (cx.state.context) cx.depth = 0
else state.context = state.context.prev
} else if (/^</.test(cur)) {
cx.depth = 1
}
} else if (!style && (stop = cur.indexOf("{")) > -1) {
stream.backUp(cur.length - stop)
}
return style
}
function jsToken(stream, state, cx) {
if (stream.peek() == "<" && jsMode.expressionAllowed(stream, cx.state)) {
jsMode.skipExpression(cx.state)
state.context = new Context(CodeMirror.startState(xmlMode, jsMode.indent(cx.state, "")),
xmlMode, 0, state.context)
return null
}
var style = jsMode.token(stream, cx.state)
if (!style && cx.depth != null) {
var cur = stream.current()
if (cur == "{") {
cx.depth++
} else if (cur == "}") {
if (--cx.depth == 0) state.context = state.context.prev
}
}
return style
}
return {
startState: function() {
return {context: new Context(CodeMirror.startState(jsMode), jsMode)}
},
copyState: function(state) {
return {context: copyContext(state.context)}
},
token: token,
indent: function(state, textAfter, fullLine) {
return state.context.mode.indent(state.context.state, textAfter, fullLine)
},
innerMode: function(state) {
return state.context
}
}
}, "xml", "javascript")
CodeMirror.defineMIME("text/jsx", "jsx")
CodeMirror.defineMIME("text/typescript-jsx", {name: "jsx", base: {name: "javascript", typescript: true}})
});

View File

@@ -8,7 +8,7 @@
"storage",
"tabs"
],
"content_security_policy": "script-src 'self' https://www.google-analytics.com 'unsafe-eval'; object-src 'self'",
"content_security_policy": "script-src 'self' https://ajax.googleapis.com https://code.jquery.com https://cdnjs.cloudflare.com https://unpkg.com https://maxcdn.bootstrapcdn.com https://cdn.jsdelivr.net/ https://www.google-analytics.com 'unsafe-eval'; object-src 'self'",
"options_ui": {
"page": "options.html",
"chrome_style": true

View File

@@ -1,6 +1,6 @@
/* global trackEvent */
/* global layoutBtn1, layoutBtn2, layoutBtn3, helpModal, notificationsModal, addLibraryModal,
onboardModal, layoutBtn1, layoutBtn2, layoutBtn3, helpBtn, onboardModal, onboardModal,
onboardModal, layoutBtn1, layoutBtn2, layoutBtn3, layoutBtn4, helpBtn, onboardModal, onboardModal,
addLibraryModal, addLibraryModal, notificationsBtn, notificationsModal, notificationsModal,
notificationsModal, notificationsBtn, codepenBtn, saveHtmlBtn, openBtn, saveBtn, newBtn,
settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardDontShowInTabOptionBtn */
@@ -9,7 +9,7 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
/* eslint-enable no-extra-semi */
var scope = scope || {};
var version = '2.1.0';
var version = '2.2.0';
if (window.DEBUG) {
window.scope = scope;
@@ -23,6 +23,7 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
var CssModes = {
CSS: 'css',
SCSS: 'scss',
SASS: 'sass',
LESS: 'less',
STYLUS: 'stylus'
};
@@ -39,10 +40,11 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
modes[JsModes.JS] = { label: 'JS', cmMode: 'javascript', codepenVal: 'none' };
modes[JsModes.COFFEESCRIPT] = { label: 'CoffeeScript', cmMode: 'coffeescript', codepenVal: 'coffeescript' };
modes[JsModes.ES6] = { label: 'ES6 (Babel)', cmMode: 'jsx', codepenVal: 'babel' };
modes[JsModes.TS] = { label: 'TypeScript', cmMode: 'javascript', codepenVal: 'typescript' };
modes[CssModes.CSS] = { label: 'CSS', cmMode: 'css', codepenVal: 'none' };
modes[CssModes.SCSS] = { label: 'SCSS', cmMode: 'sass', codepenVal: 'scss' };
modes[CssModes.LESS] = { label: 'LESS', cmMode: 'text/x-less', codepenVal: 'less' };
modes[JsModes.TS] = { label: 'TypeScript', cmPath: 'jsx', cmMode: 'text/typescript-jsx', codepenVal: 'typescript' };
modes[CssModes.CSS] = { label: 'CSS', cmPath: 'css', cmMode: 'css', codepenVal: 'none' };
modes[CssModes.SCSS] = { label: 'SCSS', cmPath: 'css', cmMode: 'text/x-scss', codepenVal: 'scss' };
modes[CssModes.SASS] = { label: 'SASS', cmMode: 'sass', codepenVal: 'sass' };
modes[CssModes.LESS] = { label: 'LESS', cmPath: 'css', cmMode: 'text/x-less', codepenVal: 'less' };
modes[CssModes.STYLUS] = { label: 'Stylus', cmMode: 'stylus', codepenVal: 'stylus' };
var updateTimer
@@ -60,6 +62,7 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
, codeSplitInstance
// TODO: for legacy reasons when. Will be refactored as global preferences.
, prefs = {}
, codeInPreview = { html: null, css: null, js: null }
// DOM nodes
, frame = $('#demo-frame')
@@ -137,7 +140,10 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
mainSplitInstance = Split(['#js-code-side', '#js-demo-side' ], {
direction: (currentLayoutMode === 2 ? 'vertical' : 'horizontal'),
minSize: 34,
gutterSize: 6
gutterSize: 6,
onDragEnd: function () {
scope.setPreviewContent(true);
}
});
}
function toggleLayout(mode) {
@@ -151,19 +157,22 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
layoutBtn1.classList.remove('selected');
layoutBtn2.classList.remove('selected');
layoutBtn3.classList.remove('selected');
layoutBtn4.classList.remove('selected');
$('#layoutBtn' + mode).classList.add('selected');
document.body.classList.remove('layout-1');
document.body.classList.remove('layout-2');
document.body.classList.remove('layout-3');
document.body.classList.remove('layout-4');
document.body.classList.add('layout-' + mode);
resetSplitting();
scope.setPreviewContent(true);
}
function onExternalLibChange() {
utils.log('onExternalLibChange');
updateExternalLibUi();
scope.setPreviewContent();
scope.setPreviewContent(true);
}
function updateExternalLibUi() {
@@ -388,7 +397,7 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
loadJS('lib/marked.js').then(setLoadedFlag);
} else if (mode === CssModes.LESS) {
loadJS('lib/less.min.js').then(setLoadedFlag);
} else if (mode === CssModes.SCSS) {
} else if (mode === CssModes.SCSS || mode === CssModes.SASS) {
loadJS('lib/sass.js').then(function () {
sass = new Sass('lib/sass.worker.js');
setLoadedFlag();
@@ -409,7 +418,7 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
htmlModelLabel.textContent = modes[value].label;
handleModeRequirements(value);
scope.cm.html.setOption('mode', modes[value].cmMode);
CodeMirror.autoLoadMode(scope.cm.html, modes[value].cmMode);
CodeMirror.autoLoadMode(scope.cm.html, modes[value].cmPath || modes[value].cmMode);
trackEvent('ui', 'updateCodeMode', 'html', value);
}
function updateCssMode(value) {
@@ -417,7 +426,7 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
cssModelLabel.textContent = modes[value].label;
handleModeRequirements(value);
scope.cm.css.setOption('mode', modes[value].cmMode);
CodeMirror.autoLoadMode(scope.cm.css, modes[value].cmMode);
CodeMirror.autoLoadMode(scope.cm.css, modes[value].cmPath || modes[value].cmMode);
trackEvent('ui', 'updateCodeMode', 'css', value);
}
function updateJsMode(value) {
@@ -425,7 +434,7 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
jsModelLabel.textContent = modes[value].label;
handleModeRequirements(value);
scope.cm.js.setOption('mode', modes[value].cmMode);
CodeMirror.autoLoadMode(scope.cm.js, modes[value].cmMode);
CodeMirror.autoLoadMode(scope.cm.js, modes[value].cmPath || modes[value].cmMode);
trackEvent('ui', 'updateCodeMode', 'js', value);
// FIXME: Will be saved as part of scope settings
/*
@@ -457,9 +466,9 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
if (cssMode === CssModes.CSS) {
d.resolve(code);
} else if (cssMode === CssModes.SCSS) {
sass.compile(code, function(result) {
// Something as wrong
} else if (cssMode === CssModes.SCSS || cssMode === CssModes.SASS) {
sass.compile(code, { indentedSyntax: cssMode === CssModes.SASS }, function(result) {
// Something was wrong
if (result.line && result.message) {
showErrors('css', [ { lineNumber: result.line - 1, message: result.message } ]);
}
@@ -598,7 +607,7 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
});
}
function getCompleteHtml(html, css, js) {
function getCompleteHtml(html, css) {
var externalJs = externalJsTextarea.value.split('\n').reduce(function (scripts, url) {
return scripts + (url ? '\n<script src="' + url + '"></script>' : '');
}, '');
@@ -607,17 +616,47 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
}, '');
var contents = '<html>\n<head>\n'
+ externalCss + '\n'
+ '<style>\n' + css + '\n</style>\n'
+ '<style id="webmakerstyle">\n' + css + '\n</style>\n'
+ '</head>\n'
+ '<body>\n' + html + '\n'
+ externalJs + '\n<script>\n' + js + '\n//# sourceURL=userscript.js</script></body>\n</html>';
+ externalJs + '\n<script src="'
+ 'filesystem:chrome-extension://'
+ chrome.i18n.getMessage('@@extension_id') + '/temporary/' + 'script.js' + '">\n'
+ '</script></body>\n</html>';
return contents;
}
function writeFile(name, blob, cb) {
var fileWritten = false;
function errorHandler() { utils.log(arguments); }
window.webkitRequestFileSystem(window.TEMPORARY, 1024 * 1024 * 5, function(fs){
fs.root.getFile(name, { create: true }, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
function onWriteComplete() {
if (fileWritten) {
return cb();
}
fileWritten = true;
// Set the write pointer to starting of file
fileWriter.seek(0);
fileWriter.write(blob);
return false;
}
fileWriter.onwriteend = onWriteComplete;
// Empty the file contents
fileWriter.truncate(0)
}, errorHandler);
}, errorHandler);
}, errorHandler);
}
function createPreviewFile(html, css, js) {
var contents = getCompleteHtml(html, css, js);
var fileWritten = false;
var blob = new Blob([ contents ], { type: "text/plain;charset=UTF-8" });
var blobjs = new Blob([ js ], { type: "text/plain;charset=UTF-8" });
// Track if people have written code.
if (!trackEvent.hasTrackedCode && (html || css || js)) {
@@ -630,38 +669,41 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
trackEvent('fn', 'usingPreview');
}
function errorHandler() { utils.log(arguments); }
// we need to store user script in external JS file to prevent inline-script
// CSP from affecting it.
writeFile('script.js', blobjs, function () {
writeFile('preview.html', blob, function () {
frame.src = 'filesystem:chrome-extension://'
+ chrome.i18n.getMessage('@@extension_id') + '/temporary/' + 'preview.html';
});
});
window.webkitRequestFileSystem(window.TEMPORARY, 1024 * 1024 * 5, function(fs){
fs.root.getFile('preview.html', { create: true }, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
function onWriteComplete() {
if (fileWritten) {
frame.src = 'filesystem:chrome-extension://'
+ chrome.i18n.getMessage('@@extension_id') + '/temporary/' + 'preview.html';
}
else {
fileWritten = true;
// Set the write pointer to starting of file
fileWriter.seek(0);
fileWriter.write(blob);
}
}
fileWriter.onwriteend = onWriteComplete;
// Empty the file contents
fileWriter.truncate(0)
}, errorHandler);
}, errorHandler);
}, errorHandler);
}
scope.setPreviewContent = function () {
var htmlPromise = computeHtml();
var cssPromise = computeCss();
var jsPromise = computeJs();
Promise.all([htmlPromise, cssPromise, jsPromise]).then(function (result) {
createPreviewFile(result[0], result[1], result[2]);
});
scope.setPreviewContent = function (isForced) {
var currentCode = {
html: scope.cm.html.getValue(),
css: scope.cm.css.getValue(),
js: scope.cm.js.getValue()
};
// If just CSS was changed (and everything shudn't be empty),
// change the styles inside the iframe.
if (!isForced && currentCode.html === codeInPreview.html && currentCode.js === codeInPreview.js) {
computeCss().then(function (css) {
frame.contentDocument.querySelector('#webmakerstyle').textContent = css;
});
} else {
var htmlPromise = computeHtml();
var cssPromise = computeCss();
var jsPromise = computeJs();
Promise.all([htmlPromise, cssPromise, jsPromise]).then(function (result) {
createPreviewFile(result[0], result[1], result[2]);
});
}
codeInPreview.html = currentCode.html;
codeInPreview.css = currentCode.css;
codeInPreview.js = currentCode.js;
};
function saveFile() {
@@ -714,6 +756,10 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
scope.setPreviewContent();
}, updateDelay);
});
cm.on('inputRead', function onChange(editor, input) {
if (input.text[0] === ';') { return; }
CodeMirror.commands.autocomplete(cm, null, { completeSingle: false })
});
return cm;
}
@@ -790,6 +836,7 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
layoutBtn1.addEventListener('click', getToggleLayoutButtonListener(1));
layoutBtn2.addEventListener('click', getToggleLayoutButtonListener(2));
layoutBtn3.addEventListener('click', getToggleLayoutButtonListener(3));
layoutBtn4.addEventListener('click', getToggleLayoutButtonListener(4));
utils.onButtonClick(helpBtn, function () {
helpModal.classList.toggle('is-modal-visible');

View File

@@ -8,6 +8,7 @@
:root {
--color-bg: #252637;
--color-sidebar: #3A2B63;
--code-font-size: 16px;
}
body {
margin: 0;
@@ -106,6 +107,15 @@ select, input[type="text"], textarea {
flex-direction: row;
width: auto;
}
.layout-4 .code-side {
display: none;
}
.layout-4 .code-side + .gutter {
display: none;
}
.layout-4 .demo-side {
width: 100% !important;
}
.code-wrap {
display: flex;
flex-direction: column;
@@ -182,7 +192,7 @@ select, input[type="text"], textarea {
.Codemirror {
width: 100%;
height: calc(100% - 25px); /* 25px for header */
font-size: 16px;
font-size: var(--code-font-size);
}
.layout-2 .is-minimized .Codemirror {
height: calc(100%);
@@ -206,7 +216,19 @@ select, input[type="text"], textarea {
.CodeMirror-gutter-wrapper:hover .CodeMirror-guttermarker-subtle {
/*visibility: visible;*/
}
.CodeMirror-hints {
font-size: var(--code-font-size);
border: 0;
background: #1e1e2c;
}
.CodeMirror-hint {
color: #bbb;
padding: 2px 4px;
}
li.CodeMirror-hint-active {
background: #5b429d;
/*color: white;*/
}
#demo-frame {
border: 0;
width: 100%;
@@ -552,7 +574,7 @@ select, input[type="text"], textarea {
}
.dropdown__menu > li > a {
display: block;
padding: 15px;
padding: 10px 15px;
color: #333;
cursor: pointer;
}