mirror of
https://github.com/chinchang/web-maker.git
synced 2025-05-09 03:55:19 +02:00
remove unwanted files from build app
This commit is contained in:
parent
0c5943d652
commit
049c0c6368
@ -1,260 +0,0 @@
|
||||
<a d-click="onModalCloseBtnClick" href="" aria-label="Close notifications" title="Close" class="js-modal__close-btn modal__close-btn">
|
||||
<svg>
|
||||
<use xlink:href="#cross-icon"></use>
|
||||
</svg>
|
||||
</a>
|
||||
|
||||
<h1>Whats new?</h1>
|
||||
|
||||
<div class="notification">
|
||||
<span class="notification__version">2.9.3</span>
|
||||
<ul>
|
||||
<li>Choose the save location while exporting your saved creations. Now easily sync them to your Dropbox or any cloud storage.</li>
|
||||
<li>All modals inside the app now have a close button.</li>
|
||||
<li>Checkbox that showed on clicking a boolean value is now removed. Thanks <a href="https://github.com/gauravmuk" target="_blank">Gaurav Nanda</a>.</li>
|
||||
<li><strong>Bugfix</strong> - Screenshots on retina device are now correct. Thanks <a href="https://github.com/AshBardhan" target="_blank">Ashish Bardhan</a>.</li>
|
||||
<li><strong>Bugfix</strong> - Double console log in detached mode fixed.</li>
|
||||
<li><strong>Bugfix</strong> - Console.clear now works in detached mode too.</li>
|
||||
<li><strong>Bugfix</strong> - DOCTYPE added in preview.</li>
|
||||
<li><strong>Bugfix</strong> - Typo correction in README. Thanks <a href="https://github.com/AdilMah" target="_blank">Adil Mahmood</a>.</li>
|
||||
<li>gstatic.com is available to load external JavaScripts from.</li>
|
||||
<li>Popular libraries list updated. Thanks <a href="https://github.com/diomed" target="_blank">diomed</a>.</li>
|
||||
<li>Added <a href="https://github.com/chinchang/web-maker/blob/master/CONTRIBUTING.md" target="_blank">contribution guidelines</a> in the Github repository.</li>
|
||||
|
||||
<br>
|
||||
<li><strong>🚀 Announcement</strong>: Web Maker has a <a href="https://gitter.im/web-maker-app/Lobby" target="_blank">chat lobby on Gitter</a> now - incase you need any help or just want to say Hi!</li>
|
||||
<li><a href="https://github.com/chinchang/web-maker/issues" target="_blank">Suggest features or report bugs.</a></li>
|
||||
<li>Thank you for being a part of this community of thousands of awesome developers. 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://webmakerapp.com/&text=Web Maker - A blazing fast %26 offline web playground! via @webmakerApp&related=webmakerApp&hashtags=web,editor,chrome,extension" target="_blank" target="_blank" class="btn">Share it</a> <a aria-label="Support the developer" href="https://www.paypal.me/kushagragour" target="_blank" class="btn btn-icon">Support the developer</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="notification">
|
||||
<span class="notification__version">2.9.2</span>
|
||||
<ul>
|
||||
<li>Minor bug fixes.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="notification">
|
||||
<span class="notification__version">2.9.1</span>
|
||||
<ul>
|
||||
<li><a href="https://medium.com/web-maker/v2-9-lots-of-goodies-bd1e939571f6" target="_blank">Read blog post about last release.</a></li>
|
||||
<li>Use Ctrl/Cmd+D to select next occurence of matching selection.</li>
|
||||
<li>Improve onboard experience.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="notification">
|
||||
<span class="notification__version">2.9.0</span>
|
||||
<ul>
|
||||
<li><a href="https://medium.com/web-maker/v2-9-lots-of-goodies-bd1e939571f6" target="_blank">Read blog post about this release.</a></li>
|
||||
<li><strong>Detached Preview</strong> - Yes, you read that correct! You can now detach your preview and send it to your secondary monitor.
|
||||
</li>
|
||||
<li><strong>Find & Replace</strong> - Long awaited, now its there. Ctrl/Cmd+f to find and add Alt to replace.</li>
|
||||
<li><strong>Atomic CSS (Atomizer) configurations</strong> - Add custom config for Atomic CSS. <a href="https://github.com/acss-io/atomizer#api" target="_blank">Read more</a>.</li>
|
||||
<li><strong>Light mode</strong> - This new setting makes Web Maker drop some heavy effects like blur etc to gain more performance. Thanks <a href="https://github.com/iamandrewluca" target="_blank">Andrew</a>.</li>
|
||||
<li><strong>Preserve logs setting</strong> - Choose whether or not to preserve logs across preview refreshes. Thanks <a href="https://github.com/BasitAli" target="_blank">Basit</a>.</li>
|
||||
<li><strong>Line wrap setting</strong> - As the name says.</li>
|
||||
<li>Semantic UI added to popular libraries.</li>
|
||||
<li>Bootstrap, Vue, UI-Kit and more updated to latest versions in popular libraries.</li>
|
||||
<li>UX improvements in settings UI</li>
|
||||
|
||||
<li><strong>Bugfix</strong> - Trigger preview refresh anytime with Ctrl/⌘ + Shift + 5. Even with auto-preview on.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="notification">
|
||||
<span class="notification__version">2.8.1</span>
|
||||
<ul>
|
||||
<li>Vue.js & UIKit version updated to latest version in 'Add Library' list.</li>
|
||||
<li>UTF-8 charset added to preview HTML to support universal characters.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="notification">
|
||||
<span class="notification__version">2.8.0</span>
|
||||
<ul>
|
||||
<li><a href="https://medium.com/web-maker/release-v2-8-is-out-f44e6ea5d9c4" target="_blank">Read blog post about this release.</a></li>
|
||||
<li><strong>Auto Save</strong> - Your creations now auto-save after your
|
||||
first manual save. This is configurable from settings.
|
||||
</li>
|
||||
<li><strong>Base2Tone-Meadow Editor Theme</strong> - First user contributed theme.
|
||||
Thanks to Diomed.</li>
|
||||
<li><strong>Use System Fonts</strong> - You can now use any of your existing
|
||||
system fonts in the editor!</li>
|
||||
<li><strong>Matching Tag Highlight</strong> - Cursor over any HTML tag would
|
||||
highlight the matching pair tag.</li>
|
||||
<li>Auto-completion suggestion can now be switched off from settings.</li>
|
||||
<li><strong>Improvement</strong> - Stop white flicker in editor when the app
|
||||
opens.</li>
|
||||
<li><strong>Bugfix</strong> - Add Babel Polyfill to enable use of next-gen
|
||||
built-ins like Promise or WeakMap.
|
||||
</li>
|
||||
<li>Vue.js version updated to 2.4.0 in popular library list.</li>
|
||||
<li>Downloads permission is optional. Asked only when you take screenshot.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="notification">
|
||||
<span class="notification__version">2.7.2</span>
|
||||
<ul>
|
||||
<li><strong>External Libraries</strong> - Add Foundation.js and update UIKit 3 to latest beta.</li>
|
||||
<li><strong>rawgit.com</strong> & <strong>wzrd.in</strong> domains are now allowed for loading external libraries from.</li>
|
||||
<li>Minor booting speed improvements</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="notification">
|
||||
<span class="notification__version">2.7.1</span>
|
||||
<ul>
|
||||
<li><strong>Framer.js support</strong> - You can now load the latest framer.js library from <a href="https://builds.framerjs.com/" target="_blank">framer builds page</a> and start coding framer prototypes.</li>
|
||||
<li><strong>Bugfix</strong>: Edit on CodePen is back in action.</li>
|
||||
<li><strong>Bugfix</strong>: Autocompletion menu doesn't show on cut and paste now.</li>
|
||||
<li><strong>Bugfix</strong>: Updated & fixed urls of some common external libraries to latest versions. UIKit3 & Bootstrap 4α are now in the list.</li>
|
||||
<li>Preprocessor selector are now more accessible.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="notification">
|
||||
<span class="notification__version">2.7.0</span>
|
||||
<ul>
|
||||
<li><strong>Fork any creation!</strong>: Now you can fork any existing creation of yours to start a new work based on it. One big use case of this feature is "Templates"! <a target="_blank" href="https://kushagragour.in/blog/2017/05/web-maker-fork-templates/?utm_source=webmakerapp&utm_medium=referral">Read more about it</a>.</li>
|
||||
<li><strong>Fonts 😍 </strong>: Super-awesome 4 fonts (mostly with ligature support) now available to choose from. Fira Code is the default font now.</li>
|
||||
<li>Updated most used external libraries to latest versions.</li>
|
||||
<li><strong>Bugfix</strong>: Add missing Bootstrap JS file to most used external libraries list.</li>
|
||||
<li>Several other minor bugfixes and improvements to make Web Maker awesome!</li>
|
||||
|
||||
<li>Great news to share with you - Web Maker has been featured on the Chrome Webstore homepage! Thanks for all the love :)</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="notification">
|
||||
<span class="notification__version">2.6.1</span>
|
||||
<ul>
|
||||
<li><strong>Bugfix</strong>: Emojis vanishing while exporting to Codepen has been fixed.</li>
|
||||
<li><strong>Bugfix</strong>: <code>console.clear()</code> now doesn't error and clears the inbuilt console.</li>
|
||||
<li><strong>Bugfix</strong>: External libraries added to the creation are exported as well to Codepen.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="notification">
|
||||
<span class="notification__version">2.6.0</span>
|
||||
<ul>
|
||||
<li><strong>The "Console"</strong>: The most awaited feature is here! There is now an inbuilt console to see your logs, errors and for quickly evaluating JavaScript code inside your preview. Enjoy! I also a <a href="https://kushagragour.in/blog/2017/05/web-maker-console-is-here/?utm_source=webmakerapp&utm_medium=referral"
|
||||
target="_blank">blog post about it</a>.</li>
|
||||
<li>Number slider which popped on clicking any number in the code has been removed due to poor user experience.</li>
|
||||
<li>Minor usability improvements.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="notification">
|
||||
<span class="notification__version">2.5.0</span>
|
||||
<ul>
|
||||
<li><strong>Atomic CSS</strong>: Use can now use Atomic CSS(ACSS) in your work! <a href="https://acss.io/" target="_blank">Read more about it here</a>.</li>
|
||||
<li><strong>Search your saved creations</strong>: Easily search through all your saved creations by title.</li>
|
||||
<li><strong>Configurable Auto-preview</strong> - You can turn off the auto preview in settings if you don't want the preview to update as you type.</li>
|
||||
<li><strong>Configurable refresh on resize</strong> - You can configure whether you want the preview to refresh when you resize the preview panel.</li>
|
||||
<li><strong>Bugfix</strong> - Fix indentation <a href="https://github.com/chinchang/web-maker/issues/104" target="_blank">issue</a> with custom indentation size.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="notification">
|
||||
<span class="notification__version">2.4.2</span>
|
||||
<ul>
|
||||
<li><strong>Improved infinite loop protection</strong>: Infinite loop protection is now faster and more reliable. And works without the need of Escodegen. Thanks to Ariya Hidayat!</li>
|
||||
<li><strong>Bugfix</strong> - Default parameters not working in JavaScript is fixed.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="notification">
|
||||
<span class="notification__version">2.4.0</span>
|
||||
<ul>
|
||||
<li><strong>Import/Export</strong>: Your creations are most important. Now export all your creations into a single file as a backup that can be imported anytime & anywhere.</li>
|
||||
<li><strong>Editor themes</strong>: You have been heard. Now you can choose from a huge list of wonderful editor themes!</li>
|
||||
<li><strong>Identation settings</strong>: Not a spaces fan? Switch to tabs and set your indentation size.</li>
|
||||
<li><strong>Vim key bindings</strong>: Rejoice Vim lovers!</li>
|
||||
<li><strong>Code blast</strong>: Why don't you try coding with this switched on from the settings? Go on...</li>
|
||||
<li><strong>Important</strong>: Due to security policy changes from Chrome 57 onwards, Web Maker now allows loading external JavaScript libraries only from certain whitelisted domains (localhost, https://ajax.googleapis.com, https://code.jquery.com, https://cdnjs.cloudflare.com,
|
||||
https://unpkg.com, https://maxcdn.com, https://cdn77.com, https://maxcdn.bootstrapcdn.com, https://cdn.jsdelivr.net/)</li>
|
||||
<li>Save button now highlights when you have unsaved changes.</li>
|
||||
<li>Jade is now called Pug. Just a name change.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="notification">
|
||||
<span class="notification__version">2.3.2</span>
|
||||
<ul>
|
||||
<li>Update Babel to support latest and coolest ES6 features.</li>
|
||||
<li>Improve onboarding experience at first install.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="notification">
|
||||
<span class="notification__version">2.3.1</span>
|
||||
<ul>
|
||||
<li><strong>Bugfix</strong> - Splitting of code and preview panes is remembered by the editor.</li>
|
||||
<li>Title of the creation is used for the file name when saving as HTML.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="notification">
|
||||
<span class="notification__version">2.3.0</span>
|
||||
<ul>
|
||||
<li><strong>Add Library Autocompletion</strong> - Just start typing the name of library and you'll be shown matching libraries from cdnjs.</li>
|
||||
<li><strong>Preview Screenshot Capture</strong> - Want to grab a nice screenshot of your creation. You have it! Click and capture.</li>
|
||||
<li><strong>Auto Indent Code</strong> - Select your code and hit Shift-Tab to auto-indent it!</li>
|
||||
<li><strong>Keyboard Navigation in Saved List</strong> - Now select your creation using arrow keys and hit ENTER to open it.</li>
|
||||
<li>Highlight active line in code panes.</li>
|
||||
<li><strong>Bugfix</strong> - Fix in generated title of new creation.</li>
|
||||
<li><strong>Bugfix</strong> - HTML autocompletion is manual triggered now with Ctrl+Space.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="notification">
|
||||
<span class="notification__version">2.1.0</span>
|
||||
<ul>
|
||||
<li><strong>TypeScript</strong> - Now you can code in TypeScript too!</li>
|
||||
<li><strong>Stylus Preprocessor</strong> - Stylus supported adding for CSS.</li>
|
||||
<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>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="notification">
|
||||
<span class="notification__version">2.0.0</span>
|
||||
<ul>
|
||||
<li><strong>Save and Load</strong> - Long pending and super-useful, now you can save your creations and resume them anytime later.</li>
|
||||
<li><strong>Insert JS & CSS</strong> - Load popular JavaScript & CSS libraries in your work without writing any code.</li>
|
||||
<li><strong>Collapsed Panes</strong> - Collapse/uncollapse code panes with a single click. Your pane configuration is even saved with every creation!</li>
|
||||
<li><strong>Quick color & number change</strong> - Click on any color or number and experiment with quick values using a slider.</li>
|
||||
<li><strong>Linting</strong> - See your code errors right where you are coding.</li>
|
||||
<li>No more browser hang due to infinite loops!</li>
|
||||
<!-- <li><a href="https://kushagragour.in/blog/web-maker-2">Read more about this big release</a></li> -->
|
||||
</ul>
|
||||
</div>
|
||||
<div class="notification">
|
||||
<span class="notification__version">1.7.0</span>
|
||||
<ul>
|
||||
<li><strong>Preprocessors!</strong> - Enjoy a whole list of preprocessors for HTML(Jade & markdown), CSS(SCSS & LESS) and JavaScript(CoffeeScript & Babel).</li>
|
||||
<li>More awesome font for code.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="notification">
|
||||
<span class="notification__version">1.6.0</span>
|
||||
<ul>
|
||||
<li>You can now configure Web-Maker to not replace new tab page from the settings. It is always accessible from the icon in the top-right.</li>
|
||||
<li>Download current code as HTML file with Ctrl/⌘ + S keyboard shortcut.</li>
|
||||
<li>New notifications panel added so you are always aware of the new changes in Web-Maker.</li>
|
||||
</ul>
|
||||
</div>
|
File diff suppressed because it is too large
Load Diff
7631
app/lib/babel-polyfill.min.js
vendored
7631
app/lib/babel-polyfill.min.js
vendored
File diff suppressed because it is too large
Load Diff
25
app/lib/babel.min.js
vendored
25
app/lib/babel.min.js
vendored
File diff suppressed because one or more lines are too long
@ -1,222 +0,0 @@
|
||||
/*
|
||||
Based on Joel Besada's lovely experiment
|
||||
https://twitter.com/JoelBesada/status/670343885655293952
|
||||
*/
|
||||
|
||||
;(function () {
|
||||
var shakeTime = 0,
|
||||
shakeTimeMax = 0,
|
||||
shakeIntensity = 5,
|
||||
lastTime = 0,
|
||||
particles = [],
|
||||
particlePointer = 0,
|
||||
MAX_PARTICLES = 100,
|
||||
PARTICLE_NUM_RANGE = { min: 2, max: 7 },
|
||||
PARTICLE_GRAVITY = 0.08,
|
||||
PARTICLE_ALPHA_FADEOUT = 0.96,
|
||||
PARTICLE_VELOCITY_RANGE = {
|
||||
x: [-1, 1],
|
||||
y: [-3.5, -1.5]
|
||||
},
|
||||
w = window.innerWidth,
|
||||
h = window.innerHeight,
|
||||
effect,
|
||||
isActive = false;
|
||||
|
||||
var codemirrors = [], cmNode;
|
||||
var canvas, ctx;
|
||||
var current_time, dt, magnitude, shakeX, shakeY; // loop vars
|
||||
var throttledShake = throttle(shake, 100);
|
||||
var throttledSpawnParticles = throttle(spawnParticles, 100);
|
||||
|
||||
function getRGBComponents(node) {
|
||||
var color = getComputedStyle(node).color;
|
||||
if (color) {
|
||||
try {
|
||||
return color.match(/(\d+), (\d+), (\d+)/).slice(1);
|
||||
} catch(e) {
|
||||
return [255, 255, 255];
|
||||
}
|
||||
} else {
|
||||
return [255, 255, 255];
|
||||
}
|
||||
}
|
||||
|
||||
function spawnParticles(cm, type) {
|
||||
var cursorPos = cm.getCursor();
|
||||
var pos = cm.cursorCoords();
|
||||
var node = document.elementFromPoint(pos.left - 5, pos.top + 5);
|
||||
type = cm.getTokenAt(cursorPos);
|
||||
if (type) { type = type.type; };
|
||||
var numParticles = random(PARTICLE_NUM_RANGE.min, PARTICLE_NUM_RANGE.max);
|
||||
var color = getRGBComponents(node);
|
||||
for (var i = numParticles; i--;) {
|
||||
particles[particlePointer] = createParticle(pos.left + 10, pos.top, color);
|
||||
particlePointer = (particlePointer + 1) % MAX_PARTICLES;
|
||||
}
|
||||
}
|
||||
|
||||
function createParticle(x, y, color) {
|
||||
var p = {
|
||||
x: x,
|
||||
y: y + 10,
|
||||
alpha: 1,
|
||||
color: color
|
||||
};
|
||||
if (effect === 1) {
|
||||
p.size = random(2, 4);
|
||||
p.vx = PARTICLE_VELOCITY_RANGE.x[0] + Math.random() *
|
||||
(PARTICLE_VELOCITY_RANGE.x[1] - PARTICLE_VELOCITY_RANGE.x[0]);
|
||||
p.vy = PARTICLE_VELOCITY_RANGE.y[0] + Math.random() *
|
||||
(PARTICLE_VELOCITY_RANGE.y[1] - PARTICLE_VELOCITY_RANGE.y[0]);
|
||||
} else if (effect === 2) {
|
||||
p.size = random(2, 8);
|
||||
p.drag = 0.92;
|
||||
p.vx = random(-3, 3);
|
||||
p.vy = random(-3, 3);
|
||||
p.wander = 0.15;
|
||||
p.theta = random(0, 360) * Math.PI / 180;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
function effect1(particle) {
|
||||
particle.vy += PARTICLE_GRAVITY;
|
||||
particle.x += particle.vx;
|
||||
particle.y += particle.vy;
|
||||
|
||||
particle.alpha *= PARTICLE_ALPHA_FADEOUT;
|
||||
|
||||
ctx.fillStyle = 'rgba('+ particle.color[0] +','+ particle.color[1] +','+ particle.color[2] + ',' + particle.alpha + ')';
|
||||
ctx.fillRect(Math.round(particle.x - 1), Math.round(particle.y - 1), particle.size, particle.size);
|
||||
}
|
||||
|
||||
// Effect based on Soulwire's demo: http://codepen.io/soulwire/pen/foktm
|
||||
function effect2(particle) {
|
||||
particle.x += particle.vx;
|
||||
particle.y += particle.vy;
|
||||
particle.vx *= particle.drag;
|
||||
particle.vy *= particle.drag;
|
||||
particle.theta += random( -0.5, 0.5 );
|
||||
particle.vx += Math.sin( particle.theta ) * 0.1;
|
||||
particle.vy += Math.cos( particle.theta ) * 0.1;
|
||||
particle.size *= 0.96;
|
||||
|
||||
ctx.fillStyle = 'rgba('+ particle.color[0] +','+ particle.color[1] +','+ particle.color[2] + ',' + particle.alpha + ')';
|
||||
ctx.beginPath();
|
||||
ctx.arc(Math.round(particle.x - 1), Math.round(particle.y - 1), particle.size, 0, 2 * Math.PI);
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
function drawParticles(timeDelta) {
|
||||
var particle;
|
||||
for (var i = particles.length; i--;) {
|
||||
particle = particles[i];
|
||||
if (!particle || particle.alpha < 0.01 || particle.size <= 0.5) { continue; }
|
||||
|
||||
if (effect === 1) { effect1(particle); }
|
||||
else if (effect === 2) { effect2(particle); }
|
||||
}
|
||||
}
|
||||
|
||||
function shake(editor, time) {
|
||||
cmNode = editor.getWrapperElement();
|
||||
shakeTime = shakeTimeMax = time;
|
||||
}
|
||||
|
||||
function random(min, max) {
|
||||
if (!max) { max = min; min = 0; }
|
||||
return min + ~~(Math.random() * (max - min + 1))
|
||||
}
|
||||
|
||||
function throttle (callback, limit) {
|
||||
var wait = false;
|
||||
return function () {
|
||||
if (!wait) {
|
||||
callback.apply(this, arguments);
|
||||
wait = true;
|
||||
setTimeout(function () {
|
||||
wait = false;
|
||||
}, limit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function loop() {
|
||||
if (!isActive) { return; }
|
||||
|
||||
ctx.clearRect(0, 0, w, h);
|
||||
|
||||
// get the time past the previous frame
|
||||
current_time = new Date().getTime();
|
||||
if(!lastTime) lastTime = current_time;
|
||||
dt = (current_time - lastTime) / 1000;
|
||||
lastTime = current_time;
|
||||
|
||||
if (shakeTime > 0) {
|
||||
shakeTime -= dt;
|
||||
magnitude = (shakeTime / shakeTimeMax) * shakeIntensity;
|
||||
shakeX = random(-magnitude, magnitude);
|
||||
shakeY = random(-magnitude, magnitude);
|
||||
cmNode.style.transform = 'translate(' + shakeX + 'px,' + shakeY + 'px)';
|
||||
}
|
||||
drawParticles();
|
||||
requestAnimationFrame(loop);
|
||||
}
|
||||
|
||||
function onCodeMirrorChange(editor, change) {
|
||||
if (change.origin !== '+input' && change.origin !== '+delete') { return; }
|
||||
|
||||
if (editor.getOption('blastCode') === true || editor.getOption('blastCode').shake === undefined) {
|
||||
throttledShake(editor, 0.3);
|
||||
}
|
||||
throttledSpawnParticles(editor);
|
||||
}
|
||||
|
||||
|
||||
function init(editor) {
|
||||
isActive = true;
|
||||
|
||||
if (!canvas) {
|
||||
canvas = document.createElement('canvas');
|
||||
ctx = canvas.getContext('2d'),
|
||||
|
||||
canvas.id = 'code-blast-canvas'
|
||||
canvas.style.position = 'absolute';
|
||||
canvas.style.top = 0;
|
||||
canvas.style.left = 0;
|
||||
canvas.style.zIndex = 1;
|
||||
canvas.style.pointerEvents = 'none';
|
||||
canvas.width = w;
|
||||
canvas.height = h;
|
||||
|
||||
document.body.appendChild(canvas);
|
||||
loop();
|
||||
}
|
||||
|
||||
editor.on("change", onCodeMirrorChange);
|
||||
}
|
||||
|
||||
function destroy(editor) {
|
||||
editor.off('change', onCodeMirrorChange);
|
||||
codemirrors.splice(codemirrors.indexOf(editor), 1);
|
||||
if (!codemirrors.length) {
|
||||
isActive = false;
|
||||
if (canvas) {
|
||||
canvas.remove();
|
||||
canvas = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CodeMirror.defineOption('blastCode', false, function(editor, val, old) {
|
||||
if (val) {
|
||||
codemirrors.push(editor);
|
||||
effect = val.effect || 2;
|
||||
init(editor);
|
||||
} else {
|
||||
destroy(editor);
|
||||
}
|
||||
|
||||
});
|
||||
})();
|
@ -1,19 +0,0 @@
|
||||
Copyright (C) 2016 by Marijn Haverbeke <marijnh@gmail.com> and others
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
@ -1,28 +0,0 @@
|
||||
# CodeMirror
|
||||
[](https://travis-ci.org/codemirror/CodeMirror)
|
||||
[](https://www.npmjs.org/package/codemirror)
|
||||
[](https://gitter.im/codemirror/CodeMirror)
|
||||
[Funding status: ](https://marijnhaverbeke.nl/fund/)
|
||||
|
||||
CodeMirror is a versatile text editor implemented in JavaScript for
|
||||
the browser. It is specialized for editing code, and comes with over
|
||||
100 language modes and various addons that implement more advanced
|
||||
editing functionality.
|
||||
|
||||
A rich programming API and a CSS theming system are available for
|
||||
customizing CodeMirror to fit your application, and extending it with
|
||||
new functionality.
|
||||
|
||||
You can find more information (and the
|
||||
[manual](http://codemirror.net/doc/manual.html)) on the [project
|
||||
page](http://codemirror.net). For questions and discussion, use the
|
||||
[discussion forum](https://discuss.codemirror.net/).
|
||||
|
||||
See
|
||||
[CONTRIBUTING.md](https://github.com/codemirror/CodeMirror/blob/master/CONTRIBUTING.md)
|
||||
for contributing guidelines.
|
||||
|
||||
The CodeMirror community aims to be welcoming to everybody. We use the
|
||||
[Contributor Covenant
|
||||
(1.1)](http://contributor-covenant.org/version/1/1/0/) as our code of
|
||||
conduct.
|
@ -1,28 +0,0 @@
|
||||
{
|
||||
"name": "codemirror",
|
||||
"version":"5.14.2",
|
||||
"main": "lib/codemirror.js",
|
||||
"description": "Full-featured in-browser code editor",
|
||||
"license": "MIT",
|
||||
"directories": {"lib": "./lib"},
|
||||
"scripts": {
|
||||
"test": "node ./test/run.js",
|
||||
"lint": "bin/lint"
|
||||
},
|
||||
"devDependencies": {"node-static": "0.6.0",
|
||||
"phantomjs": "1.9.2-5",
|
||||
"blint": ">=0.1.1"},
|
||||
"bugs": "http://github.com/codemirror/CodeMirror/issues",
|
||||
"keywords": ["JavaScript", "CodeMirror", "Editor"],
|
||||
"homepage": "http://codemirror.net",
|
||||
"maintainers":[{"name": "Marijn Haverbeke",
|
||||
"email": "marijnh@gmail.com",
|
||||
"web": "http://marijnhaverbeke.nl"}],
|
||||
"repository": {"type": "git",
|
||||
"url": "https://github.com/codemirror/CodeMirror.git"},
|
||||
"jspm": {
|
||||
"directories": {},
|
||||
"dependencies": {},
|
||||
"devDependencies": {}
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
43080
app/lib/emmet.js
43080
app/lib/emmet.js
File diff suppressed because it is too large
Load Diff
6346
app/lib/esprima.js
6346
app/lib/esprima.js
File diff suppressed because one or more lines are too long
5
app/lib/hint.min.css
vendored
5
app/lib/hint.min.css
vendored
File diff suppressed because one or more lines are too long
@ -1,155 +0,0 @@
|
||||
/*
|
||||
* =========================================================
|
||||
* =========================================================
|
||||
* ColorPicker
|
||||
* =========================================================
|
||||
* =========================================================
|
||||
*
|
||||
*/
|
||||
.inlet_clicker {
|
||||
z-index: 10;
|
||||
}
|
||||
.inlet_slider {
|
||||
opacity: 0.85;
|
||||
z-index: 10;
|
||||
width: 24%;
|
||||
display: block;
|
||||
border-radius: 3px;
|
||||
height: 14px;
|
||||
box-shadow: inset 0px 0px 5px 0px rgba(4, 4, 4, 0.5);
|
||||
background-color: #d6d6d6;
|
||||
background-image: linear-gradient(top, #d6d6d6, #ebebeb);
|
||||
}
|
||||
.inlet_slider:hover {
|
||||
opacity: 0.98;
|
||||
}
|
||||
.inlet_slider .range {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
outline: none;
|
||||
margin-top: 0px;
|
||||
margin-left: 0px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.inlet_slider input[type="range"] {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
@-moz-document url-prefix() {
|
||||
.inlet_slider input[type="range"] {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
.inlet_slider input::-moz-range-track {
|
||||
background: none;
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
.inlet_slider input::-webkit-slider-thumb {
|
||||
cursor: col-resize;
|
||||
-webkit-appearance: none;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 6px;
|
||||
border: 1px solid black;
|
||||
background-color: red;
|
||||
box-shadow: 0px 0px 3px 0px rgba(4, 4, 4, 0.4);
|
||||
background-color: #424242;
|
||||
background-color: crimson;
|
||||
background-image: linear-gradient(top, #424242, #212121);
|
||||
}
|
||||
/*
|
||||
* =========================================================
|
||||
* =========================================================
|
||||
* ColorPicker
|
||||
* =========================================================
|
||||
* =========================================================
|
||||
*
|
||||
*/
|
||||
.ColorPicker {
|
||||
/*
|
||||
border: 1px solid rgba(0,0,0,0.5);
|
||||
border-radius: 6px;
|
||||
background: #0d0d0d;
|
||||
background: -webkit-gradient(linear, left top, left bottom, from(#333), color-stop(0.1, #111), to(#000000));
|
||||
box-shadow: 2px 2px 5px 2px rgba(0,0,0,0.35);
|
||||
color:#AAA;
|
||||
*/
|
||||
text-shadow: 1px 1px 1px #000;
|
||||
color: #050505;
|
||||
cursor: default;
|
||||
display: block;
|
||||
font-family: 'arial', helvetica, sans-serif;
|
||||
font-size: 20px;
|
||||
padding: 7px 8px 20px;
|
||||
position: absolute;
|
||||
top: 100px;
|
||||
left: 700px;
|
||||
width: 229px;
|
||||
z-index: 100;
|
||||
border-radius: 3px;
|
||||
-webkit-box-shadow: inset 0px 0px 5px 0px rgba(4, 4, 4, 0.5);
|
||||
box-shadow: inset 0px 0px 5px 0px rgba(4, 4, 4, 0.5);
|
||||
background-color: rgba(214, 214, 215, 0.85);
|
||||
/*
|
||||
background-image: linear-gradient(top, rgb(214, 214, 214), rgb(235, 235, 235));
|
||||
*/
|
||||
}
|
||||
.ColorPicker br {
|
||||
clear: both;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.ColorPicker input.hexInput:hover,
|
||||
.ColorPicker input.hexInput:focus {
|
||||
color: #aa1212;
|
||||
}
|
||||
.ColorPicker input.hexInput {
|
||||
-webkit-transition-property: color;
|
||||
-webkit-transition-duration: .5s;
|
||||
background: none;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
font-family: courier,monospace;
|
||||
font-size: 20px;
|
||||
position: relative;
|
||||
top: -2px;
|
||||
float: left;
|
||||
color: #050505;
|
||||
cursor: text;
|
||||
}
|
||||
.ColorPicker div.hexBox {
|
||||
border: 1px solid rgba(255, 255, 255, 0.5);
|
||||
border-radius: 2px;
|
||||
background: #FFF;
|
||||
float: left;
|
||||
font-size: 1px;
|
||||
height: 20px;
|
||||
margin: 0 5px 0 2px;
|
||||
width: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.ColorPicker div.hexBox div {
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
}
|
||||
.ColorPicker div.hexClose {
|
||||
display: none;
|
||||
/*
|
||||
-webkit-transition-property: color, text-shadow;
|
||||
-webkit-transition-duration: .5s;
|
||||
position: relative;
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
color:#FFF;
|
||||
cursor:pointer;
|
||||
float:right;
|
||||
padding: 0 5px;
|
||||
margin:0 4px 3px;
|
||||
user-select:none;
|
||||
-webkit-user-select: none;
|
||||
*/
|
||||
}
|
||||
.ColorPicker div.hexClose:hover {
|
||||
text-shadow: 0 0 20px #fff;
|
||||
color: #FF1100;
|
||||
}
|
2
app/lib/inlet.min.js
vendored
2
app/lib/inlet.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
23
app/lib/less.min.js
vendored
23
app/lib/less.min.js
vendored
File diff suppressed because one or more lines are too long
1285
app/lib/marked.js
1285
app/lib/marked.js
File diff suppressed because it is too large
Load Diff
202
app/lib/sass.js
202
app/lib/sass.js
@ -1,202 +0,0 @@
|
||||
/*! sass.js - v0.9.10 (9a781bf) - built 2016-04-24
|
||||
providing libsass 3.3.6 (3ae9a20)
|
||||
via emscripten 1.36.1 (d5085ed)
|
||||
*/
|
||||
|
||||
(function (root, factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define([], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
module.exports = factory();
|
||||
} else {
|
||||
root.Sass = factory();
|
||||
}
|
||||
}(this, function () {/*global document*/
|
||||
// identify the path sass.js is located at in case we're loaded by a simple
|
||||
// <script src="path/to/sass.js"></script>
|
||||
// this path can be used to identify the location of
|
||||
// * sass.worker.js from sass.js
|
||||
// * libsass.js.mem from sass.sync.js
|
||||
// see https://github.com/medialize/sass.js/pull/32#issuecomment-103142214
|
||||
// see https://github.com/medialize/sass.js/issues/33
|
||||
var SASSJS_RELATIVE_PATH = (function() {
|
||||
'use strict';
|
||||
|
||||
// in Node things are rather simple
|
||||
if (typeof __dirname !== 'undefined') {
|
||||
return __dirname;
|
||||
}
|
||||
|
||||
// we can only run this test in the browser,
|
||||
// so make sure we actually have a DOM to work with.
|
||||
if (typeof document === 'undefined' || !document.getElementsByTagName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// http://www.2ality.com/2014/05/current-script.html
|
||||
var currentScript = document.currentScript || (function() {
|
||||
var scripts = document.getElementsByTagName('script');
|
||||
return scripts[scripts.length - 1];
|
||||
})();
|
||||
|
||||
var path = currentScript && currentScript.src;
|
||||
if (!path) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// [worker] make sure we're not running in some concatenated thing
|
||||
if (path.slice(-8) === '/sass.js') {
|
||||
return path.slice(0, -8);
|
||||
}
|
||||
|
||||
// [sync] make sure we're not running in some concatenated thing
|
||||
if (path.slice(-13) === '/sass.sync.js') {
|
||||
return path.slice(0, -13);
|
||||
}
|
||||
|
||||
return null;
|
||||
})() || '.';
|
||||
|
||||
/*global Worker, SASSJS_RELATIVE_PATH*/
|
||||
'use strict';
|
||||
|
||||
var noop = function(){};
|
||||
var slice = [].slice;
|
||||
// defined upon first Sass.initialize() call
|
||||
var globalWorkerUrl;
|
||||
|
||||
function Sass(workerUrl) {
|
||||
if (!workerUrl && !globalWorkerUrl) {
|
||||
/*jshint laxbreak:true */
|
||||
throw new Error(
|
||||
'Sass needs to be initialized with the URL of sass.worker.js - '
|
||||
+ 'either via Sass.setWorkerUrl(url) or by new Sass(url)'
|
||||
);
|
||||
/*jshint laxbreak:false */
|
||||
}
|
||||
|
||||
if (!globalWorkerUrl) {
|
||||
globalWorkerUrl = workerUrl;
|
||||
}
|
||||
|
||||
// bind all functions
|
||||
// we're doing this because we used to have a single hard-wired instance that allowed
|
||||
// [].map(Sass.removeFile) and we need to maintain that for now (at least until 1.0.0)
|
||||
for (var key in this) {
|
||||
if (typeof this[key] === 'function') {
|
||||
this[key] = this[key].bind(this);
|
||||
}
|
||||
}
|
||||
|
||||
this._callbacks = {};
|
||||
this._worker = new Worker(workerUrl || globalWorkerUrl);
|
||||
this._worker.addEventListener('message', this._handleWorkerMessage, false);
|
||||
}
|
||||
|
||||
// allow setting the workerUrl before the first Sass instance is initialized,
|
||||
// where registering the global workerUrl would've happened automatically
|
||||
Sass.setWorkerUrl = function(workerUrl) {
|
||||
globalWorkerUrl = workerUrl;
|
||||
};
|
||||
|
||||
Sass.style = {
|
||||
nested: 0,
|
||||
expanded: 1,
|
||||
compact: 2,
|
||||
compressed: 3
|
||||
};
|
||||
|
||||
Sass.comments = {
|
||||
'none': 0,
|
||||
'default': 1
|
||||
};
|
||||
|
||||
Sass.prototype = {
|
||||
style: Sass.style,
|
||||
comments: Sass.comments,
|
||||
|
||||
destroy: function() {
|
||||
this._worker && this._worker.terminate();
|
||||
this._worker = null;
|
||||
this._callbacks = {};
|
||||
this._importer = null;
|
||||
},
|
||||
|
||||
_handleWorkerMessage: function(event) {
|
||||
if (event.data.command) {
|
||||
this[event.data.command](event.data.args);
|
||||
}
|
||||
|
||||
this._callbacks[event.data.id] && this._callbacks[event.data.id](event.data.result);
|
||||
delete this._callbacks[event.data.id];
|
||||
},
|
||||
|
||||
_dispatch: function(options, callback) {
|
||||
if (!this._worker) {
|
||||
throw new Error('Sass worker has been terminated');
|
||||
}
|
||||
|
||||
options.id = 'cb' + Date.now() + Math.random();
|
||||
this._callbacks[options.id] = callback;
|
||||
this._worker.postMessage(options);
|
||||
},
|
||||
|
||||
_importerInit: function(args) {
|
||||
// importer API done callback pushing results
|
||||
// back to the worker
|
||||
var done = function done(result) {
|
||||
this._worker.postMessage({
|
||||
command: '_importerFinish',
|
||||
args: [result]
|
||||
});
|
||||
}.bind(this);
|
||||
|
||||
try {
|
||||
this._importer(args[0], done);
|
||||
} catch(e) {
|
||||
done({ error: e.message });
|
||||
throw e;
|
||||
}
|
||||
},
|
||||
|
||||
importer: function(importerCallback, callback) {
|
||||
if (typeof importerCallback !== 'function' && importerCallback !== null) {
|
||||
throw new Error('importer callback must either be a function or null');
|
||||
}
|
||||
|
||||
// callback is executed in the main EventLoop
|
||||
this._importer = importerCallback;
|
||||
// tell worker to activate importer callback
|
||||
this._worker.postMessage({
|
||||
command: 'importer',
|
||||
args: [Boolean(importerCallback)]
|
||||
});
|
||||
|
||||
callback && callback();
|
||||
},
|
||||
};
|
||||
|
||||
var commands = 'writeFile readFile listFiles removeFile clearFiles lazyFiles preloadFiles options compile compileFile';
|
||||
commands.split(' ').forEach(function(command) {
|
||||
Sass.prototype[command] = function() {
|
||||
var callback = slice.call(arguments, -1)[0];
|
||||
var args = slice.call(arguments, 0, -1);
|
||||
if (typeof callback !== 'function') {
|
||||
args.push(callback);
|
||||
callback = noop;
|
||||
}
|
||||
|
||||
this._dispatch({
|
||||
command: command,
|
||||
args: args
|
||||
}, callback);
|
||||
};
|
||||
});
|
||||
|
||||
// automatically set the workerUrl in case we're loaded by a simple
|
||||
// <script src="path/to/sass.js"></script>
|
||||
// see https://github.com/medialize/sass.js/pull/32#issuecomment-103142214
|
||||
Sass.setWorkerUrl(SASSJS_RELATIVE_PATH + '/sass.worker.js');
|
||||
return Sass;
|
||||
}));
|
File diff suppressed because one or more lines are too long
569
app/lib/split.js
569
app/lib/split.js
@ -1,569 +0,0 @@
|
||||
// The programming goals of Split.js are to deliver readable, understandable and
|
||||
// maintainable code, while at the same time manually optimizing for tiny minified file size,
|
||||
// browser compatibility without additional requirements, graceful fallback (IE8 is supported)
|
||||
// and very few assumptions about the user's page layout.
|
||||
//
|
||||
// Make sure all browsers handle this JS library correctly with ES5.
|
||||
// More information here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode
|
||||
'use strict';
|
||||
|
||||
// A wrapper function that does a couple things:
|
||||
//
|
||||
// 1. Doesn't pollute the global namespace. This is important for a library.
|
||||
// 2. Allows us to mount the library in different module systems, as well as
|
||||
// directly in the browser.
|
||||
(function() {
|
||||
|
||||
// Save the global `this` for use later. In this case, since the library only
|
||||
// runs in the browser, it will refer to `window`. Also, figure out if we're in IE8
|
||||
// or not. IE8 will still render correctly, but will be static instead of draggable.
|
||||
//
|
||||
// Save a couple long function names that are used frequently.
|
||||
// This optimization saves around 400 bytes.
|
||||
var global = this
|
||||
, isIE8 = global.attachEvent && !global[addEventListener]
|
||||
, document = global.document
|
||||
, addEventListener = 'addEventListener'
|
||||
, removeEventListener = 'removeEventListener'
|
||||
, getBoundingClientRect = 'getBoundingClientRect'
|
||||
|
||||
// This library only needs two helper functions:
|
||||
//
|
||||
// The first determines which prefixes of CSS calc we need.
|
||||
// We only need to do this once on startup, when this anonymous function is called.
|
||||
//
|
||||
// Tests -webkit, -moz and -o prefixes. Modified from StackOverflow:
|
||||
// http://stackoverflow.com/questions/16625140/js-feature-detection-to-detect-the-usage-of-webkit-calc-over-calc/16625167#16625167
|
||||
, calc = (function () {
|
||||
var el
|
||||
, prefixes = ["", "-webkit-", "-moz-", "-o-"]
|
||||
|
||||
for (var i = 0; i < prefixes.length; i++) {
|
||||
el = document.createElement('div')
|
||||
el.style.cssText = "width:" + prefixes[i] + "calc(9px)"
|
||||
|
||||
if (el.style.length) {
|
||||
return prefixes[i] + "calc"
|
||||
}
|
||||
}
|
||||
})()
|
||||
|
||||
// The second helper function allows elements and string selectors to be used
|
||||
// interchangeably. In either case an element is returned. This allows us to
|
||||
// do `Split(elem1, elem2)` as well as `Split('#id1', '#id2')`.
|
||||
, elementOrSelector = function (el) {
|
||||
if (typeof el === 'string' || el instanceof String) {
|
||||
return document.querySelector(el)
|
||||
} else {
|
||||
return el
|
||||
}
|
||||
}
|
||||
|
||||
// The main function to initialize a split. Split.js thinks about each pair
|
||||
// of elements as an independant pair. Dragging the gutter between two elements
|
||||
// only changes the dimensions of elements in that pair. This is key to understanding
|
||||
// how the following functions operate, since each function is bound to a pair.
|
||||
//
|
||||
// A pair object is shaped like this:
|
||||
//
|
||||
// {
|
||||
// a: DOM element,
|
||||
// b: DOM element,
|
||||
// aMin: Number,
|
||||
// bMin: Number,
|
||||
// dragging: Boolean,
|
||||
// parent: DOM element,
|
||||
// isFirst: Boolean,
|
||||
// isLast: Boolean,
|
||||
// direction: 'horizontal' | 'vertical'
|
||||
// }
|
||||
//
|
||||
// The basic sequence:
|
||||
//
|
||||
// 1. Set defaults to something sane. `options` doesn't have to be passed at all.
|
||||
// 2. Initialize a bunch of strings based on the direction we're splitting.
|
||||
// A lot of the behavior in the rest of the library is paramatized down to
|
||||
// rely on CSS strings and classes.
|
||||
// 3. Define the dragging helper functions, and a few helpers to go with them.
|
||||
// 4. Define a few more functions that "balance" the entire split instance.
|
||||
// Split.js tries it's best to cope with min sizes that don't add up.
|
||||
// 5. Loop through the elements while pairing them off. Every pair gets an
|
||||
// `pair` object, a gutter, and special isFirst/isLast properties.
|
||||
// 6. Actually size the pair elements, insert gutters and attach event listeners.
|
||||
// 7. Balance all of the pairs to accomodate min sizes as best as possible.
|
||||
, Split = function (ids, options) {
|
||||
var dimension
|
||||
, i
|
||||
, clientDimension
|
||||
, clientAxis
|
||||
, position
|
||||
, gutterClass
|
||||
, paddingA
|
||||
, paddingB
|
||||
, pairs = []
|
||||
|
||||
// 1. Set defaults to something sane. `options` doesn't have to be passed at all,
|
||||
// so create an options object if none exists. Pixel values 10, 100 and 30 are
|
||||
// arbitrary but feel natural.
|
||||
options = typeof options !== 'undefined' ? options : {}
|
||||
|
||||
if (typeof options.gutterSize === 'undefined') options.gutterSize = 10
|
||||
if (typeof options.minSize === 'undefined') options.minSize = 100
|
||||
if (typeof options.snapOffset === 'undefined') options.snapOffset = 30
|
||||
if (typeof options.direction === 'undefined') options.direction = 'horizontal'
|
||||
|
||||
// 2. Initialize a bunch of strings based on the direction we're splitting.
|
||||
// A lot of the behavior in the rest of the library is paramatized down to
|
||||
// rely on CSS strings and classes.
|
||||
if (options.direction == 'horizontal') {
|
||||
dimension = 'width'
|
||||
clientDimension = 'clientWidth'
|
||||
clientAxis = 'clientX'
|
||||
position = 'left'
|
||||
gutterClass = 'gutter gutter-horizontal'
|
||||
paddingA = 'paddingLeft'
|
||||
paddingB = 'paddingRight'
|
||||
if (!options.cursor) options.cursor = 'ew-resize'
|
||||
} else if (options.direction == 'vertical') {
|
||||
dimension = 'height'
|
||||
clientDimension = 'clientHeight'
|
||||
clientAxis = 'clientY'
|
||||
position = 'top'
|
||||
gutterClass = 'gutter gutter-vertical'
|
||||
paddingA = 'paddingTop'
|
||||
paddingB = 'paddingBottom'
|
||||
if (!options.cursor) options.cursor = 'ns-resize'
|
||||
}
|
||||
|
||||
// 3. Define the dragging helper functions, and a few helpers to go with them.
|
||||
// Each helper is bound to a pair object that contains it's metadata. This
|
||||
// also makes it easy to store references to listeners that that will be
|
||||
// added and removed.
|
||||
//
|
||||
// Even though there are no other functions contained in them, aliasing
|
||||
// this to self saves 50 bytes or so since it's used so frequently.
|
||||
//
|
||||
// The pair object saves metadata like dragging state, position and
|
||||
// event listener references.
|
||||
//
|
||||
// startDragging calls `calculateSizes` to store the inital size in the pair object.
|
||||
// It also adds event listeners for mouse/touch events,
|
||||
// and prevents selection while dragging so avoid the selecting text.
|
||||
var startDragging = function (e) {
|
||||
// Alias frequently used variables to save space. 200 bytes.
|
||||
var self = this
|
||||
, a = self.a
|
||||
, b = self.b
|
||||
|
||||
// Call the onDragStart callback.
|
||||
if (!self.dragging && options.onDragStart) {
|
||||
options.onDragStart()
|
||||
}
|
||||
|
||||
// Don't actually drag the element. We emulate that in the drag function.
|
||||
e.preventDefault()
|
||||
|
||||
// Set the dragging property of the pair object.
|
||||
self.dragging = true
|
||||
|
||||
// Create two event listeners bound to the same pair object and store
|
||||
// them in the pair object.
|
||||
self.move = drag.bind(self)
|
||||
self.stop = stopDragging.bind(self)
|
||||
|
||||
// All the binding. `window` gets the stop events in case we drag out of the elements.
|
||||
global[addEventListener]('mouseup', self.stop)
|
||||
global[addEventListener]('touchend', self.stop)
|
||||
global[addEventListener]('touchcancel', self.stop)
|
||||
|
||||
self.parent[addEventListener]('mousemove', self.move)
|
||||
self.parent[addEventListener]('touchmove', self.move)
|
||||
|
||||
// Disable selection. Disable!
|
||||
a[addEventListener]('selectstart', noop)
|
||||
a[addEventListener]('dragstart', noop)
|
||||
b[addEventListener]('selectstart', noop)
|
||||
b[addEventListener]('dragstart', noop)
|
||||
|
||||
a.style.userSelect = 'none'
|
||||
a.style.webkitUserSelect = 'none'
|
||||
a.style.MozUserSelect = 'none'
|
||||
a.style.pointerEvents = 'none'
|
||||
|
||||
b.style.userSelect = 'none'
|
||||
b.style.webkitUserSelect = 'none'
|
||||
b.style.MozUserSelect = 'none'
|
||||
b.style.pointerEvents = 'none'
|
||||
|
||||
// Set the cursor, both on the gutter and the parent element.
|
||||
// Doing only a, b and gutter causes flickering.
|
||||
self.gutter.style.cursor = options.cursor
|
||||
self.parent.style.cursor = options.cursor
|
||||
|
||||
// Cache the initial sizes of the pair.
|
||||
calculateSizes.call(self)
|
||||
}
|
||||
|
||||
// stopDragging is very similar to startDragging in reverse.
|
||||
, stopDragging = function () {
|
||||
var self = this
|
||||
, a = self.a
|
||||
, b = self.b
|
||||
|
||||
if (self.dragging && options.onDragEnd) {
|
||||
options.onDragEnd()
|
||||
}
|
||||
|
||||
self.dragging = false
|
||||
|
||||
// Remove the stored event listeners. This is why we store them.
|
||||
global[removeEventListener]('mouseup', self.stop)
|
||||
global[removeEventListener]('touchend', self.stop)
|
||||
global[removeEventListener]('touchcancel', self.stop)
|
||||
|
||||
self.parent[removeEventListener]('mousemove', self.move)
|
||||
self.parent[removeEventListener]('touchmove', self.move)
|
||||
|
||||
// Delete them once they are removed. I think this makes a difference
|
||||
// in memory usage with a lot of splits on one page. But I don't know for sure.
|
||||
delete self.stop
|
||||
delete self.move
|
||||
|
||||
a[removeEventListener]('selectstart', noop)
|
||||
a[removeEventListener]('dragstart', noop)
|
||||
b[removeEventListener]('selectstart', noop)
|
||||
b[removeEventListener]('dragstart', noop)
|
||||
|
||||
a.style.userSelect = ''
|
||||
a.style.webkitUserSelect = ''
|
||||
a.style.MozUserSelect = ''
|
||||
a.style.pointerEvents = ''
|
||||
|
||||
b.style.userSelect = ''
|
||||
b.style.webkitUserSelect = ''
|
||||
b.style.MozUserSelect = ''
|
||||
b.style.pointerEvents = ''
|
||||
|
||||
self.gutter.style.cursor = ''
|
||||
self.parent.style.cursor = ''
|
||||
}
|
||||
|
||||
// drag, where all the magic happens. The logic is really quite simple:
|
||||
//
|
||||
// 1. Ignore if the pair is not dragging.
|
||||
// 2. Get the offset of the event.
|
||||
// 3. Snap offset to min if within snappable range (within min + snapOffset).
|
||||
// 4. Actually adjust each element in the pair to offset.
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
// | | <- this.aMin || this.bMin -> | |
|
||||
// | | | <- this.snapOffset || this.snapOffset -> | | |
|
||||
// | | | || | | |
|
||||
// | | | || | | |
|
||||
// ---------------------------------------------------------------------
|
||||
// | <- this.start this.size -> |
|
||||
, drag = function (e) {
|
||||
var offset
|
||||
|
||||
if (!this.dragging) return
|
||||
|
||||
// Get the offset of the event from the first side of the
|
||||
// pair `this.start`. Supports touch events, but not multitouch, so only the first
|
||||
// finger `touches[0]` is counted.
|
||||
if ('touches' in e) {
|
||||
offset = e.touches[0][clientAxis] - this.start
|
||||
} else {
|
||||
offset = e[clientAxis] - this.start
|
||||
}
|
||||
|
||||
// If within snapOffset of min or max, set offset to min or max.
|
||||
// snapOffset buffers aMin and bMin, so logic is opposite for both.
|
||||
// Include the appropriate gutter sizes to prevent overflows.
|
||||
if (offset <= this.aMin + options.snapOffset + this.aGutterSize) {
|
||||
offset = this.aMin + this.aGutterSize
|
||||
} else if (offset >= this.size - (this.bMin + options.snapOffset + this.bGutterSize)) {
|
||||
offset = this.size - (this.bMin + this.bGutterSize)
|
||||
}
|
||||
|
||||
// Actually adjust the size.
|
||||
adjust.call(this, offset)
|
||||
|
||||
// Call the drag callback continously. Don't do anything too intensive
|
||||
// in this callback.
|
||||
if (options.onDrag) {
|
||||
options.onDrag()
|
||||
}
|
||||
}
|
||||
|
||||
// Cache some important sizes when drag starts, so we don't have to do that
|
||||
// continously:
|
||||
//
|
||||
// `size`: The total size of the pair. First element + second element + first gutter + second gutter.
|
||||
// `percentage`: The percentage between 0-100 that the pair occupies in the parent.
|
||||
// `start`: The leading side of the first element.
|
||||
//
|
||||
// ------------------------------------------------ - - - - - - - - - - -
|
||||
// | aGutterSize -> ||| | |
|
||||
// | ||| | |
|
||||
// | ||| | |
|
||||
// | ||| <- bGutterSize | |
|
||||
// ------------------------------------------------ - - - - - - - - - - -
|
||||
// | <- start size -> | parentSize -> |
|
||||
, calculateSizes = function () {
|
||||
// Figure out the parent size minus padding.
|
||||
var computedStyle = global.getComputedStyle(this.parent)
|
||||
, parentSize = this.parent[clientDimension] - parseFloat(computedStyle[paddingA]) - parseFloat(computedStyle[paddingB])
|
||||
|
||||
this.size = this.a[getBoundingClientRect]()[dimension] + this.b[getBoundingClientRect]()[dimension] + this.aGutterSize + this.bGutterSize
|
||||
this.percentage = Math.min(this.size / parentSize * 100, 100)
|
||||
this.start = this.a[getBoundingClientRect]()[position]
|
||||
}
|
||||
|
||||
// Actually adjust the size of elements `a` and `b` to `offset` while dragging.
|
||||
// calc is used to allow calc(percentage + gutterpx) on the whole split instance,
|
||||
// which allows the viewport to be resized without additional logic.
|
||||
// Element a's size is the same as offset. b's size is total size - a size.
|
||||
// Both sizes are calculated from the initial parent percentage, then the gutter size is subtracted.
|
||||
, adjust = function (offset) {
|
||||
this.a.style[dimension] = calc + '(' + (offset / this.size * this.percentage) + '% - ' + this.aGutterSize + 'px)'
|
||||
this.b.style[dimension] = calc + '(' + (this.percentage - (offset / this.size * this.percentage)) + '% - ' + this.bGutterSize + 'px)'
|
||||
}
|
||||
|
||||
// 4. Define a few more functions that "balance" the entire split instance.
|
||||
// Split.js tries it's best to cope with min sizes that don't add up.
|
||||
// At some point this should go away since it breaks out of the calc(% - px) model.
|
||||
// Maybe it's a user error if you pass uncomputable minSizes.
|
||||
, fitMin = function () {
|
||||
var self = this
|
||||
, a = self.a
|
||||
, b = self.b
|
||||
|
||||
if (a[getBoundingClientRect]()[dimension] < self.aMin) {
|
||||
a.style[dimension] = (self.aMin - self.aGutterSize) + 'px'
|
||||
b.style[dimension] = (self.size - self.aMin - self.aGutterSize) + 'px'
|
||||
} else if (b[getBoundingClientRect]()[dimension] < self.bMin) {
|
||||
a.style[dimension] = (self.size - self.bMin - self.bGutterSize) + 'px'
|
||||
b.style[dimension] = (self.bMin - self.bGutterSize) + 'px'
|
||||
}
|
||||
}
|
||||
, fitMinReverse = function () {
|
||||
var self = this
|
||||
, a = self.a
|
||||
, b = self.b
|
||||
|
||||
if (b[getBoundingClientRect]()[dimension] < self.bMin) {
|
||||
a.style[dimension] = (self.size - self.bMin - self.bGutterSize) + 'px'
|
||||
b.style[dimension] = (self.bMin - self.bGutterSize) + 'px'
|
||||
} else if (a[getBoundingClientRect]()[dimension] < self.aMin) {
|
||||
a.style[dimension] = (self.aMin - self.aGutterSize) + 'px'
|
||||
b.style[dimension] = (self.size - self.aMin - self.aGutterSize) + 'px'
|
||||
}
|
||||
}
|
||||
, balancePairs = function (pairs) {
|
||||
for (var i = 0; i < pairs.length; i++) {
|
||||
calculateSizes.call(pairs[i])
|
||||
fitMin.call(pairs[i])
|
||||
}
|
||||
|
||||
for (i = pairs.length - 1; i >= 0; i--) {
|
||||
calculateSizes.call(pairs[i])
|
||||
fitMinReverse.call(pairs[i])
|
||||
}
|
||||
}
|
||||
, setElementSize = function (el, size, gutterSize) {
|
||||
// Split.js allows setting sizes via numbers (ideally), or if you must,
|
||||
// by string, like '300px'. This is less than ideal, because it breaks
|
||||
// the fluid layout that `calc(% - px)` provides. You're on your own if you do that,
|
||||
// make sure you calculate the gutter size by hand.
|
||||
if (typeof size !== 'string' && !(size instanceof String)) {
|
||||
if (!isIE8) {
|
||||
size = calc + '(' + size + '% - ' + gutterSize + 'px)'
|
||||
} else {
|
||||
size = options.sizes[i] + '%'
|
||||
}
|
||||
}
|
||||
|
||||
el.style[dimension] = size
|
||||
}
|
||||
|
||||
// No-op function to prevent default. Used to prevent selection.
|
||||
, noop = function () { return false }
|
||||
|
||||
// All DOM elements in the split should have a common parent. We can grab
|
||||
// the first elements parent and hope users read the docs because the
|
||||
// behavior will be whacky otherwise.
|
||||
, parent = elementOrSelector(ids[0]).parentNode
|
||||
|
||||
// Set default options.sizes to equal percentages of the parent element.
|
||||
if (!options.sizes) {
|
||||
var percent = 100 / ids.length
|
||||
|
||||
options.sizes = []
|
||||
|
||||
for (i = 0; i < ids.length; i++) {
|
||||
options.sizes.push(percent)
|
||||
}
|
||||
}
|
||||
|
||||
// Standardize minSize to an array if it isn't already. This allows minSize
|
||||
// to be passed as a number.
|
||||
if (!Array.isArray(options.minSize)) {
|
||||
var minSizes = []
|
||||
|
||||
for (i = 0; i < ids.length; i++) {
|
||||
minSizes.push(options.minSize)
|
||||
}
|
||||
|
||||
options.minSize = minSizes
|
||||
}
|
||||
|
||||
// 5. Loop through the elements while pairing them off. Every pair gets a
|
||||
// `pair` object, a gutter, and isFirst/isLast properties.
|
||||
//
|
||||
// Basic logic:
|
||||
//
|
||||
// - Starting with the second element `i > 0`, create `pair` objects with
|
||||
// `a = ids[i - 1]` and `b = ids[i]`
|
||||
// - Set gutter sizes based on the _pair_ being first/last. The first and last
|
||||
// pair have gutterSize / 2, since they only have one half gutter, and not two.
|
||||
// - Create gutter elements and add event listeners.
|
||||
// - Set the size of the elements, minus the gutter sizes.
|
||||
//
|
||||
// -----------------------------------------------------------------------
|
||||
// | i=0 | i=1 | i=2 | i=3 |
|
||||
// | | isFirst | | isLast |
|
||||
// | pair 0 pair 1 pair 2 |
|
||||
// | | | | |
|
||||
// -----------------------------------------------------------------------
|
||||
for (i = 0; i < ids.length; i++) {
|
||||
var el = elementOrSelector(ids[i])
|
||||
, isFirstPair = (i == 1)
|
||||
, isLastPair = (i == ids.length - 1)
|
||||
, size = options.sizes[i]
|
||||
, gutterSize = options.gutterSize
|
||||
, pair
|
||||
, parentFlexDirection = window.getComputedStyle(parent).flexDirection
|
||||
, temp
|
||||
|
||||
if (i > 0) {
|
||||
// Create the pair object with it's metadata.
|
||||
pair = {
|
||||
a: elementOrSelector(ids[i - 1]),
|
||||
b: el,
|
||||
aMin: options.minSize[i - 1],
|
||||
bMin: options.minSize[i],
|
||||
dragging: false,
|
||||
parent: parent,
|
||||
isFirst: isFirstPair,
|
||||
isLast: isLastPair,
|
||||
direction: options.direction
|
||||
}
|
||||
|
||||
// For first and last pairs, first and last gutter width is half.
|
||||
pair.aGutterSize = options.gutterSize
|
||||
pair.bGutterSize = options.gutterSize
|
||||
|
||||
if (isFirstPair) {
|
||||
pair.aGutterSize = options.gutterSize / 2
|
||||
}
|
||||
|
||||
if (isLastPair) {
|
||||
pair.bGutterSize = options.gutterSize / 2
|
||||
}
|
||||
|
||||
// if the parent has a reverse flex-direction, switch the pair elements.
|
||||
if (parentFlexDirection === 'row-reverse' || parentFlexDirection === 'column-reverse') {
|
||||
temp = pair.a;
|
||||
pair.a = pair.b;
|
||||
pair.b = temp;
|
||||
}
|
||||
}
|
||||
|
||||
// Determine the size of the current element. IE8 is supported by
|
||||
// staticly assigning sizes without draggable gutters. Assigns a string
|
||||
// to `size`.
|
||||
//
|
||||
// IE9 and above
|
||||
if (!isIE8) {
|
||||
// Create gutter elements for each pair.
|
||||
if (i > 0) {
|
||||
var gutter = document.createElement('div')
|
||||
|
||||
gutter.className = gutterClass
|
||||
gutter.style[dimension] = options.gutterSize + 'px'
|
||||
|
||||
gutter[addEventListener]('mousedown', startDragging.bind(pair))
|
||||
gutter[addEventListener]('touchstart', startDragging.bind(pair))
|
||||
|
||||
parent.insertBefore(gutter, el)
|
||||
|
||||
pair.gutter = gutter
|
||||
}
|
||||
|
||||
// Half-size gutters for first and last elements.
|
||||
if (i === 0 || i == ids.length - 1) {
|
||||
gutterSize = options.gutterSize / 2
|
||||
}
|
||||
}
|
||||
|
||||
// Set the element size to our determined size.
|
||||
setElementSize(el, size, gutterSize)
|
||||
|
||||
// After the first iteration, and we have a pair object, append it to the
|
||||
// list of pairs.
|
||||
if (i > 0) {
|
||||
pairs.push(pair)
|
||||
}
|
||||
}
|
||||
|
||||
// Balance the pairs to try to accomodate min sizes.
|
||||
balancePairs(pairs)
|
||||
|
||||
return {
|
||||
setSizes: function (sizes) {
|
||||
for (var i = 0; i < sizes.length; i++) {
|
||||
if (i > 0) {
|
||||
var pair = pairs[i - 1]
|
||||
|
||||
setElementSize(pair.a, sizes[i - 1], pair.aGutterSize)
|
||||
setElementSize(pair.b, sizes[i], pair.bGutterSize)
|
||||
}
|
||||
}
|
||||
},
|
||||
collapse: function (i) {
|
||||
var pair
|
||||
|
||||
if (i === pairs.length) {
|
||||
pair = pairs[i - 1]
|
||||
|
||||
calculateSizes.call(pair)
|
||||
adjust.call(pair, pair.size - Math.max(pair.bGutterSize, pair.aMin))
|
||||
} else {
|
||||
pair = pairs[i]
|
||||
|
||||
calculateSizes.call(pair)
|
||||
adjust.call(pair, Math.max(pair.aGutterSize, pair.aMin))
|
||||
}
|
||||
},
|
||||
destroy: function () {
|
||||
for (var i = 0; i < pairs.length; i++) {
|
||||
pairs[i].parent.removeChild(pairs[i].gutter)
|
||||
pairs[i].a.style[dimension] = ''
|
||||
pairs[i].b.style[dimension] = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Play nicely with module systems, and the browser too if you include it raw.
|
||||
if (typeof exports !== 'undefined') {
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
exports = module.exports = Split
|
||||
}
|
||||
exports.Split = Split
|
||||
} else {
|
||||
global.Split = Split
|
||||
}
|
||||
|
||||
// Call our wrapper function with the current global. In this case, `window`.
|
||||
}).call(window);
|
6
app/lib/stylus.min.js
vendored
6
app/lib/stylus.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user