From 682ac820cdb7051bbf1da0597056519de9b7c628 Mon Sep 17 00:00:00 2001
From: Yannick Croissant
Date: Tue, 21 Aug 2012 00:53:19 +0200
Subject: [PATCH 01/26] Fix a graphical bug in Firefox
---
public/js/lib/models/arrow.js | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/public/js/lib/models/arrow.js b/public/js/lib/models/arrow.js
index 7488d0b..88eb512 100644
--- a/public/js/lib/models/arrow.js
+++ b/public/js/lib/models/arrow.js
@@ -36,6 +36,22 @@ if (!('CSSArrowPlease' in window)) window.CSSArrowPlease = {};
else if ( pos === 'right' ) return 'left';
},
+ /**
+ @method hexToRGB
+ @description
+ returns an rgb color from an hex color
+ @returns {Array}
+ **/
+ hexToRGB: function (h) {
+ var rgb = [],
+ i = 1;
+
+ for(; i < 6; i+=2) {
+ rgb.push(parseInt(h.substring(i, i + 2), 16));
+ }
+ return rgb;
+ },
+
/**
@method _baseCSS
@description generates the base css
@@ -87,12 +103,14 @@ if (!('CSSArrowPlease' in window)) window.CSSArrowPlease = {};
_arrowCSS: function (color, size, layer) {
var pos = this.get('position'),
iPos = this.invertedPosition(),
+ rgbColor = this.hexToRGB(color),
css = ".arrow_box:";
layer = layer || 'after';
css += layer + ' {\n';
+ css += '\tborder-color: rgba(' + rgbColor.join(', ') + ', 0);\n';
css += '\tborder-' + iPos + '-color: ' + color + ';\n';
css += '\tborder-width: ' + size + 'px;\n';
From 518399e6983082c62a30ee0407e4afaa4c9170bb Mon Sep 17 00:00:00 2001
From: Yannick Croissant
Date: Tue, 21 Aug 2012 11:53:39 +0200
Subject: [PATCH 02/26] add 3 char hex color support in hexToRGB function add
input checking in hexToRGB function
---
public/js/lib/models/arrow.js | 2 ++
1 file changed, 2 insertions(+)
diff --git a/public/js/lib/models/arrow.js b/public/js/lib/models/arrow.js
index 88eb512..262db02 100644
--- a/public/js/lib/models/arrow.js
+++ b/public/js/lib/models/arrow.js
@@ -43,6 +43,8 @@ if (!('CSSArrowPlease' in window)) window.CSSArrowPlease = {};
@returns {Array}
**/
hexToRGB: function (h) {
+ if ( typeof h !== 'string' || !h.match(/^#([0-9A-F]{3}$)|([0-9A-F]{6}$)/i) ) return [0, 0, 0];
+ else if ( h.match(/^(#[0-9a-f]{3})$/i) ) h = '#' + h[1] + h[1] + h[2] + h[2] + h[3] + h[3];
var rgb = [],
i = 1;
From 142f7a1235bda9208c57649c57aa4c276af032d5 Mon Sep 17 00:00:00 2001
From: Yannick Croissant
Date: Tue, 21 Aug 2012 11:53:49 +0200
Subject: [PATCH 03/26] add tests for hexToRGB function and _arrowCSS border
color
---
public/js/spec/models/arrow_spec.js | 29 +++++++++++++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/public/js/spec/models/arrow_spec.js b/public/js/spec/models/arrow_spec.js
index 6e98ff5..eaa73f7 100644
--- a/public/js/spec/models/arrow_spec.js
+++ b/public/js/spec/models/arrow_spec.js
@@ -96,6 +96,30 @@ describe("CSSArrowPlease.Arrow", function () {
});
+ describe('convert hex color to rgb color', function () {
+
+ it('converts "#888"', function () {
+ expect( arrow.hexToRGB('#888') ).toEqual([136 , 136 , 136]);
+ });
+
+ it('converts "#88B7D5"', function () {
+ expect( arrow.hexToRGB('#88B7D5') ).toEqual([136, 183, 213]);
+ });
+
+ it('converts "#C2E1F5"', function () {
+ expect( arrow.hexToRGB('#C2E1F5') ).toEqual([194, 225, 245]);
+ });
+
+ it('returns [0, 0, 0] if there is no input color', function () {
+ expect( arrow.hexToRGB() ).toEqual([0, 0, 0]);
+ });
+
+ it('returns [0, 0, 0] if the input color is invalid', function () {
+ expect( arrow.hexToRGB('invalid') ).toEqual([0, 0, 0]);
+ });
+
+ });
+
describe('toCSS', function () {
describe('baseCSS', function () {
@@ -177,8 +201,9 @@ describe("CSSArrowPlease.Arrow", function () {
});
it('it has the correct color', function () {
- var expected = 'border-bottom-color: #888';
- expect( arrow._arrowCSS('#888', 20) ).toMatch( expected );
+ var css = arrow._arrowCSS('#888', 20);
+ expect( css ).toMatch( 'border-bottom-color: #888' );
+ expect( css ).toMatch( 'border-color: rgba\\(136, 136, 136, 0\\)' );
});
describe('position top', function () {
From 097d2f14c0a833ca3ea898ec644b4edda1340d1c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simon=20H=C3=B8jberg?=
Date: Sat, 25 Aug 2012 13:14:02 -0400
Subject: [PATCH 04/26] deployed
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index b02dfe2..101c85f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "cssarrowplease",
- "version": "0.2.2-10",
+ "version": "0.2.2-13",
"author": {
"name": "Simon Højberg",
"email": "r.hackr@gmail.com"
From 3f7a9662b85e3f30c0cc29826720dea1b3f1686e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simon=20H=C3=B8jberg?=
Date: Wed, 28 Nov 2012 23:04:11 -0500
Subject: [PATCH 05/26] dont fade fork
---
public/css/app.css | 13 +------------
1 file changed, 1 insertion(+), 12 deletions(-)
diff --git a/public/css/app.css b/public/css/app.css
index c4d0947..5cdc1eb 100644
--- a/public/css/app.css
+++ b/public/css/app.css
@@ -58,15 +58,4 @@ input[type='radio'] { border: 0; }
/* fork_me */
-.fork_me { position: absolute; top: 0; right: 0; display: block; width: 149px; height: 149px; background: url(../img/fork.png);
- opacity: 0.7;
- -webkit-transition: all 0.2s ease-in;
- -moz-transition: all 0.2s ease-in;
- transition: all 0.2s ease-in;
-}
-.fork_me:hover {
- opacity: 1;
- -webkit-transform: scale(1.03);
- -moz-transform: scale(1.03);
- transform: scale(1.03);
-}
+.fork_me { position: absolute; top: 0; right: 0; display: block; width: 149px; height: 149px; background: url(../img/fork.png); }
From a96cb6a8da84e97d945fc275c83c908e01d927ea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simon=20H=C3=B8jberg?=
Date: Wed, 28 Nov 2012 23:05:17 -0500
Subject: [PATCH 06/26] deploy
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 101c85f..17be371 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "cssarrowplease",
- "version": "0.2.2-13",
+ "version": "0.2.2-15",
"author": {
"name": "Simon Højberg",
"email": "r.hackr@gmail.com"
From eb80717ed44cf3c4f140d933bc013c081945d733 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simon=20H=C3=B8jberg?=
Date: Sun, 23 Dec 2012 22:07:51 -0500
Subject: [PATCH 07/26] Use filter dropshadow
---
public/css/app.css | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/public/css/app.css b/public/css/app.css
index 5cdc1eb..d33bd83 100644
--- a/public/css/app.css
+++ b/public/css/app.css
@@ -32,7 +32,11 @@ input[type='radio'] { border: 0; }
/* =MODULES
====================================================== */
/* preview */
-.arrow_box { padding: 40px; width: 280px; height: 100px; border-radius: 6px; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); }
+.arrow_box { padding: 40px; width: 280px; height: 100px; border-radius: 6px;
+ -webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.3));
+ -moz-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.3));
+ filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.3));
+}
/* logo */
.logo { color: #ddf8c6; text-align: center; font-size: 54px; line-height: 54px; font-weight: bold; text-transform: uppercase; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4); }
From 620da6f4bb4abb833656b320fbbbb215c367f183 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simon=20H=C3=B8jberg?=
Date: Sun, 23 Dec 2012 22:09:07 -0500
Subject: [PATCH 08/26] firefox fallback
---
public/css/app.css | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/public/css/app.css b/public/css/app.css
index d33bd83..ea7a844 100644
--- a/public/css/app.css
+++ b/public/css/app.css
@@ -33,8 +33,9 @@ input[type='radio'] { border: 0; }
====================================================== */
/* preview */
.arrow_box { padding: 40px; width: 280px; height: 100px; border-radius: 6px;
+ -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
+
-webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.3));
- -moz-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.3));
filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.3));
}
From 10d9098e0392330bfe04ff453b49fc3f6a2550fc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simon=20H=C3=B8jberg?=
Date: Sun, 23 Dec 2012 22:11:44 -0500
Subject: [PATCH 09/26] deploy
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 17be371..c458abe 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "cssarrowplease",
- "version": "0.2.2-15",
+ "version": "0.2.2-16",
"author": {
"name": "Simon Højberg",
"email": "r.hackr@gmail.com"
From 0e9d69181b25c48638226132b1a28f762ab0530e Mon Sep 17 00:00:00 2001
From: yukulele
Date: Tue, 21 May 2013 11:44:14 +0200
Subject: [PATCH 10/26] add svg drop-shadow filter
-moz-box-shadow dont seam to works anymore
---
public/css/app.css | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/public/css/app.css b/public/css/app.css
index ea7a844..9959457 100644
--- a/public/css/app.css
+++ b/public/css/app.css
@@ -33,10 +33,12 @@ input[type='radio'] { border: 0; }
====================================================== */
/* preview */
.arrow_box { padding: 40px; width: 280px; height: 100px; border-radius: 6px;
- -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
+ /*-moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);*/
+ filter: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%3Cfilter%20id%3D%27drop-shadow%27%3E%3CfeGaussianBlur%20in%3D%27SourceAlpha%27%20stdDeviation%3D%274%27%2F%3E%3CfeOffset%20dx%3D%270%27%20dy%3D%271%27%20result%3D%27offsetblur%27%2F%3E%3CfeFlood%20flood-color%3D%27rgba(0,0,0,0.3)%27%2F%3E%3CfeComposite%20in2%3D%27offsetblur%27%20operator%3D%27in%27%2F%3E%3CfeMerge%3E%3CfeMergeNode%2F%3E%3CfeMergeNode%20in%3D%27SourceGraphic%27%2F%3E%3C%2FfeMerge%3E%3C%2Ffilter%3E%3C%2Fsvg%3E#drop-shadow");
-webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.3));
filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.3));
+
}
/* logo */
From 13c90a66b6b4c608c66d769babe4c5c9ff8673c8 Mon Sep 17 00:00:00 2001
From: bra1n
Date: Fri, 1 Nov 2013 18:35:45 +0100
Subject: [PATCH 11/26] moved redundant absolute positioning to common styles
adjusted unittests to reflect changes
---
public/js/lib/models/arrow.js | 14 +++++++++++---
public/js/spec/models/arrow_spec.js | 29 +++++++++++++++++------------
2 files changed, 28 insertions(+), 15 deletions(-)
diff --git a/public/js/lib/models/arrow.js b/public/js/lib/models/arrow.js
index 262db02..e2f3350 100644
--- a/public/js/lib/models/arrow.js
+++ b/public/js/lib/models/arrow.js
@@ -61,7 +61,8 @@ if (!('CSSArrowPlease' in window)) window.CSSArrowPlease = {};
@protected
**/
_baseCSS: function () {
- var iPos = this.invertedPosition(),
+ var pos = this.get('position'),
+ iPos = this.invertedPosition(),
color = this.get('color'),
borderWidth = this.get('borderWidth'),
borderColor = this.get('borderColor'),
@@ -81,6 +82,13 @@ if (!('CSSArrowPlease' in window)) window.CSSArrowPlease = {};
css += '\t' + iPos +': 100%;\n';
+ if (pos === 'top' || pos === 'bottom') {
+ css += '\tleft: 50%;\n';
+ }
+ else {
+ css += '\ttop: 50%;\n';
+ }
+
css += '\tborder: solid transparent;\n';
css += '\tcontent: " ";\n';
css += '\theight: 0;\n';
@@ -117,10 +125,10 @@ if (!('CSSArrowPlease' in window)) window.CSSArrowPlease = {};
css += '\tborder-width: ' + size + 'px;\n';
if (pos === 'top' || pos === 'bottom') {
- css += '\tleft: 50%;\n\tmargin-left: -' + size + 'px;\n';
+ css += '\tmargin-left: -' + size + 'px;\n';
}
else {
- css += '\ttop: 50%;\n\tmargin-top: -' + size + 'px;\n';
+ css += '\tmargin-top: -' + size + 'px;\n';
}
css += '}';
diff --git a/public/js/spec/models/arrow_spec.js b/public/js/spec/models/arrow_spec.js
index eaa73f7..ff3a7a8 100644
--- a/public/js/spec/models/arrow_spec.js
+++ b/public/js/spec/models/arrow_spec.js
@@ -134,6 +134,7 @@ describe("CSSArrowPlease.Arrow", function () {
expected;
expected = '\tbottom: 100%;\n';
+ expected = '\tleft: 50%;\n';
expected += '\tborder: solid transparent;\n';
expected += '\tcontent: " ";\n';
expected += '\theight: 0;\n';
@@ -210,9 +211,10 @@ describe("CSSArrowPlease.Arrow", function () {
beforeEach(function () { arrow.set('position', 'top'); });
it('is centered', function () {
- var css = arrow._arrowCSS('red', 20);
- expect( css ).toMatch( 'left: 50%' );
- expect( css ).toMatch( 'margin-left: -20px' );
+ var arrowcss = arrow._arrowCSS('red', 20),
+ basecss = arrow._baseCSS();
+ expect( basecss ).toMatch( 'left: 50%' );
+ expect( arrowcss ).toMatch( 'margin-left: -20px' );
});
});
@@ -220,9 +222,10 @@ describe("CSSArrowPlease.Arrow", function () {
beforeEach(function () { arrow.set('position', 'bottom'); });
it('is centered', function () {
- var css = arrow._arrowCSS('red', 20);
- expect( css ).toMatch( 'left: 50%' );
- expect( css ).toMatch( 'margin-left: -20px' );
+ var arrowcss = arrow._arrowCSS('red', 20),
+ basecss = arrow._baseCSS();
+ expect( basecss ).toMatch( 'left: 50%' );
+ expect( arrowcss ).toMatch( 'margin-left: -20px' );
});
});
@@ -230,9 +233,10 @@ describe("CSSArrowPlease.Arrow", function () {
beforeEach(function () { arrow.set('position', 'right'); });
it('is centered', function () {
- var css = arrow._arrowCSS('red', 20);
- expect( css ).toMatch( 'top: 50%' );
- expect( css ).toMatch( 'margin-top: -20px' );
+ var arrowcss = arrow._arrowCSS('red', 20),
+ basecss = arrow._baseCSS();
+ expect( basecss ).toMatch( 'top: 50%' );
+ expect( arrowcss ).toMatch( 'margin-top: -20px' );
});
});
@@ -240,9 +244,10 @@ describe("CSSArrowPlease.Arrow", function () {
beforeEach(function () { arrow.set('position', 'left'); });
it('is centered', function () {
- var css = arrow._arrowCSS('red', 20);
- expect( css ).toMatch( 'top: 50%' );
- expect( css ).toMatch( 'margin-top: -20px' );
+ var arrowcss = arrow._arrowCSS('red', 20),
+ basecss = arrow._baseCSS();
+ expect( basecss ).toMatch( 'top: 50%' );
+ expect( arrowcss ).toMatch( 'margin-top: -20px' );
});
});
From 246dbad2e2c109da30d50cdefe27559f935bfd7e Mon Sep 17 00:00:00 2001
From: bra1n
Date: Fri, 1 Nov 2013 18:59:39 +0100
Subject: [PATCH 12/26] better handling of zero border width case
---
public/js/lib/models/arrow.js | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/public/js/lib/models/arrow.js b/public/js/lib/models/arrow.js
index e2f3350..aced0c3 100644
--- a/public/js/lib/models/arrow.js
+++ b/public/js/lib/models/arrow.js
@@ -96,7 +96,7 @@ if (!('CSSArrowPlease' in window)) window.CSSArrowPlease = {};
css += '\tposition: absolute;\n';
css += '\tpointer-events: none;\n';
- css += '}\n';
+ if(hasBorder) css += '}\n';
return css;
},
@@ -111,14 +111,15 @@ if (!('CSSArrowPlease' in window)) window.CSSArrowPlease = {};
@protected
**/
_arrowCSS: function (color, size, layer) {
- var pos = this.get('position'),
- iPos = this.invertedPosition(),
- rgbColor = this.hexToRGB(color),
- css = ".arrow_box:";
+ var pos = this.get('position'),
+ iPos = this.invertedPosition(),
+ rgbColor = this.hexToRGB(color),
+ borderWidth = this.get('borderWidth'),
+ css = "";
layer = layer || 'after';
- css += layer + ' {\n';
+ if(borderWidth > 0) css += '.arrow_box:' + layer + ' {\n';
css += '\tborder-color: rgba(' + rgbColor.join(', ') + ', 0);\n';
css += '\tborder-' + iPos + '-color: ' + color + ';\n';
@@ -184,7 +185,7 @@ if (!('CSSArrowPlease' in window)) window.CSSArrowPlease = {};
this._arrowBorderCSS()
];
- return css.join('\n');
+ return css.join(css[2] ? '\n':'');
},
/**
From 313058366fe7dd5d26816aca7e579cce9acdd826 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simon=20H=C3=B8jberg?=
Date: Wed, 13 Nov 2013 16:24:04 -0500
Subject: [PATCH 13/26] remove arrow box drop shadow
---
public/css/app.css | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/public/css/app.css b/public/css/app.css
index 9959457..c137a21 100644
--- a/public/css/app.css
+++ b/public/css/app.css
@@ -32,14 +32,7 @@ input[type='radio'] { border: 0; }
/* =MODULES
====================================================== */
/* preview */
-.arrow_box { padding: 40px; width: 280px; height: 100px; border-radius: 6px;
- /*-moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);*/
-
- filter: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%3Cfilter%20id%3D%27drop-shadow%27%3E%3CfeGaussianBlur%20in%3D%27SourceAlpha%27%20stdDeviation%3D%274%27%2F%3E%3CfeOffset%20dx%3D%270%27%20dy%3D%271%27%20result%3D%27offsetblur%27%2F%3E%3CfeFlood%20flood-color%3D%27rgba(0,0,0,0.3)%27%2F%3E%3CfeComposite%20in2%3D%27offsetblur%27%20operator%3D%27in%27%2F%3E%3CfeMerge%3E%3CfeMergeNode%2F%3E%3CfeMergeNode%20in%3D%27SourceGraphic%27%2F%3E%3C%2FfeMerge%3E%3C%2Ffilter%3E%3C%2Fsvg%3E#drop-shadow");
- -webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.3));
- filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.3));
-
-}
+.arrow_box { padding: 40px; width: 280px; height: 100px; border-radius: 6px; }
/* logo */
.logo { color: #ddf8c6; text-align: center; font-size: 54px; line-height: 54px; font-weight: bold; text-transform: uppercase; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4); }
From e9d0b487c4fac8fc45a0efa8b1c99573e08f34ff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simon=20H=C3=B8jberg?=
Date: Wed, 13 Nov 2013 16:26:23 -0500
Subject: [PATCH 14/26] deploy
---
package.json | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/package.json b/package.json
index c458abe..a47cfab 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "cssarrowplease",
- "version": "0.2.2-16",
+ "version": "0.2.2-18",
"author": {
"name": "Simon Højberg",
"email": "r.hackr@gmail.com"
@@ -41,4 +41,4 @@
"cssarrowplease.com",
"www.cssarrowplease.com"
]
-}
\ No newline at end of file
+}
From 598fc92c2ddea3eafe8338d7e1ae96c9ba8580ec Mon Sep 17 00:00:00 2001
From: Stefan Hasenstab
Date: Tue, 8 Jul 2014 15:56:33 +0200
Subject: [PATCH 15/26] sanitize hex colors by prefixing missing # if necessary
---
public/js/lib/models/arrow.js | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/public/js/lib/models/arrow.js b/public/js/lib/models/arrow.js
index aced0c3..4ba0d95 100644
--- a/public/js/lib/models/arrow.js
+++ b/public/js/lib/models/arrow.js
@@ -69,10 +69,15 @@ if (!('CSSArrowPlease' in window)) window.CSSArrowPlease = {};
hasBorder = borderWidth > 0,
css = '.arrow_box {\n';
+ color = this._sanitizeHexColors(color);
+
css += '\tposition: relative;\n';
css += '\tbackground: ' + color + ';\n';
- if (hasBorder) css += '\tborder: ' + borderWidth + 'px solid ' + borderColor + ';\n';
+ if (hasBorder) {
+ borderColor = this._sanitizeHexColors(borderColor);
+ css += '\tborder: ' + borderWidth + 'px solid ' + borderColor + ';\n';
+ }
css += '}\n';
css += '.arrow_box:after';
@@ -111,6 +116,7 @@ if (!('CSSArrowPlease' in window)) window.CSSArrowPlease = {};
@protected
**/
_arrowCSS: function (color, size, layer) {
+ color = this._sanitizeHexColors(color);
var pos = this.get('position'),
iPos = this.invertedPosition(),
rgbColor = this.hexToRGB(color),
@@ -204,6 +210,16 @@ if (!('CSSArrowPlease' in window)) window.CSSArrowPlease = {};
this._attributes = attributes;
},
+ /**
+ @method _sanitizeHexColors
+ @description prefix hexcolors with # if necessary
+ @returns {String} h
+ @protected
+ **/
+ _sanitizeHexColors: function(h) {
+ return (h.charAt(0)==='#')?h:'#' + h;
+ },
+
/**
@method getAttrs
@description returns all the attributes
From a77d696e923b44040675498fbbb542fe3a73e974 Mon Sep 17 00:00:00 2001
From: Stefan Hasenstab
Date: Mon, 14 Jul 2014 10:16:11 +0200
Subject: [PATCH 16/26] changed code indention to 2 spaces
---
public/js/lib/models/arrow.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/public/js/lib/models/arrow.js b/public/js/lib/models/arrow.js
index 4ba0d95..a23af2c 100644
--- a/public/js/lib/models/arrow.js
+++ b/public/js/lib/models/arrow.js
@@ -75,8 +75,8 @@ if (!('CSSArrowPlease' in window)) window.CSSArrowPlease = {};
css += '\tbackground: ' + color + ';\n';
if (hasBorder) {
- borderColor = this._sanitizeHexColors(borderColor);
- css += '\tborder: ' + borderWidth + 'px solid ' + borderColor + ';\n';
+ borderColor = this._sanitizeHexColors(borderColor);
+ css += '\tborder: ' + borderWidth + 'px solid ' + borderColor + ';\n';
}
css += '}\n';
@@ -217,7 +217,7 @@ if (!('CSSArrowPlease' in window)) window.CSSArrowPlease = {};
@protected
**/
_sanitizeHexColors: function(h) {
- return (h.charAt(0)==='#')?h:'#' + h;
+ return (h.charAt(0)==='#')?h:'#' + h;
},
/**
From 486917ec0b11955f77ade992393816cfe3920303 Mon Sep 17 00:00:00 2001
From: Ryan McDermott
Date: Fri, 18 Jul 2014 17:56:25 -0500
Subject: [PATCH 17/26] Add SEO meta description
---
public/index.html | 1 +
1 file changed, 1 insertion(+)
diff --git a/public/index.html b/public/index.html
index 413f523..4159f24 100644
--- a/public/index.html
+++ b/public/index.html
@@ -3,6 +3,7 @@
cssarrowplease
+
From 636e45e02c2db2f4626c61cc9dd0752592aa52ee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simon=20H=C3=B8jberg?=
Date: Sat, 2 Aug 2014 10:26:10 -0700
Subject: [PATCH 18/26] simplify deploymeny and serving
---
.gitignore | 1 -
bin/server | 18 ------------------
package.json | 6 +-----
public/index.html | 2 +-
server.js | 10 ++++++++++
5 files changed, 12 insertions(+), 25 deletions(-)
delete mode 100644 bin/server
create mode 100644 server.js
diff --git a/.gitignore b/.gitignore
index b5b56cf..ac1e8f7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,3 @@
node_modules
-public-min
*.log
.DS_Store
diff --git a/bin/server b/bin/server
deleted file mode 100644
index f1ef1b5..0000000
--- a/bin/server
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env node
-
-var connect = require('connect'),
- http = require('http'),
- port = process.env.PORT || 3000,
- static;
-
-if (process.argv.indexOf('--development') !== -1) {
- console.log('CSS Arrow Please in development on http://localhost:' + port);
- static = connect.static('public');
-}
-else {
- static = connect.static('public-min', {
- maxAge: 365 * 24 * 60 * 60 * 1000
- });
-}
-
-http.createServer( connect().use( static ) ).listen( port );
diff --git a/package.json b/package.json
index a47cfab..ebe8566 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,6 @@
"email": "r.hackr@gmail.com"
},
"description": "Generate the CSS for a tooltip arrow",
- "main": "",
"repository": {
"type": "git",
"url": "git://github.com/hojberg/cssarrowplease.git"
@@ -17,14 +16,11 @@
],
"homepage": "http://cssarrowplease.com/",
"scripts": {
- "start": "node ./bin/server"
+ "start": "node ./server.js"
},
"dependencies": {
"connect": "~2.0.3"
},
- "devDependencies": {
- "assetgraph-builder": ">=0.2.37"
- },
"engines": {
"node": ">=0.6"
},
diff --git a/public/index.html b/public/index.html
index 4159f24..fa3c54c 100644
--- a/public/index.html
+++ b/public/index.html
@@ -56,7 +56,7 @@ Arrow configuration
-
+
Fork me on Github
diff --git a/server.js b/server.js
new file mode 100644
index 0000000..b0e74db
--- /dev/null
+++ b/server.js
@@ -0,0 +1,10 @@
+#!/usr/bin/env node
+
+var connect = require('connect');
+var http = require('http');
+var port = process.env.PORT || 3000;
+var static = connect.static('public');
+
+console.log('CSSArrowPlease on http://localhost:' + port);
+
+http.createServer( connect().use( static ) ).listen( port );
From 1805c42055f89a4d8fd99632bb7fdd996a3ff6cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simon=20H=C3=B8jberg?=
Date: Sat, 2 Aug 2014 10:29:31 -0700
Subject: [PATCH 19/26] deploy version 0.2.2-19
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index ebe8566..822f80d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "cssarrowplease",
- "version": "0.2.2-18",
+ "version": "0.2.2-19",
"author": {
"name": "Simon Højberg",
"email": "r.hackr@gmail.com"
From 02dadb5c9abc64e3864686c2635b15df5b5e6c5a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simon=20H=C3=B8jberg?=
Date: Sat, 2 Aug 2014 11:50:24 -0700
Subject: [PATCH 20/26] add proper testing setup and browserify
---
app/main.js | 49 +
app/models/arrow.js | 291 +
app/views/arrow_configuration_view.js | 108 +
app/views/arrow_css_view.js | 44 +
app/views/arrow_preview_view.js | 39 +
package.json | 15 +-
public/css/app.css | 2 -
public/index.html | 48 +-
public/js/cssarrowplease.js | 9734 +++++++++++++++++
public/js/lib/app.js | 52 -
public/js/lib/models/arrow.js | 297 -
.../js/lib/views/arrow_configuration_view.js | 115 -
public/js/lib/views/arrow_css_view.js | 54 -
public/js/lib/views/arrow_preview_view.js | 47 -
public/js/spec/app_spec.js | 3 -
.../js/spec/views/arrow_preview_view_spec.js | 32 -
public/js/spec_runner.html | 60 -
public/js/vendor/jasmine/jasmine-html.js | 676 --
public/js/vendor/jasmine/jasmine.css | 81 -
public/js/vendor/jasmine/jasmine.js | 2528 -----
.../vendor/jquery.clippy/jquery.clippy.min.js | 1 -
server.js | 2 -
.../arrow_configuration_view_test.js | 40 +-
.../arrow_css_view_test.js | 32 +-
test/arrow_preview_view_test.js | 43 +
.../arrow_spec.js => test/arrow_test.js | 130 +-
test/test_helper.js | 5 +
27 files changed, 10450 insertions(+), 4078 deletions(-)
create mode 100644 app/main.js
create mode 100644 app/models/arrow.js
create mode 100644 app/views/arrow_configuration_view.js
create mode 100644 app/views/arrow_css_view.js
create mode 100644 app/views/arrow_preview_view.js
create mode 100644 public/js/cssarrowplease.js
delete mode 100644 public/js/lib/app.js
delete mode 100644 public/js/lib/models/arrow.js
delete mode 100644 public/js/lib/views/arrow_configuration_view.js
delete mode 100644 public/js/lib/views/arrow_css_view.js
delete mode 100644 public/js/lib/views/arrow_preview_view.js
delete mode 100644 public/js/spec/app_spec.js
delete mode 100644 public/js/spec/views/arrow_preview_view_spec.js
delete mode 100644 public/js/spec_runner.html
delete mode 100644 public/js/vendor/jasmine/jasmine-html.js
delete mode 100644 public/js/vendor/jasmine/jasmine.css
delete mode 100644 public/js/vendor/jasmine/jasmine.js
delete mode 100755 public/js/vendor/jquery.clippy/jquery.clippy.min.js
rename public/js/spec/views/arrow_configuration_view_spec.js => test/arrow_configuration_view_test.js (70%)
rename public/js/spec/views/arrow_css_view_spec.js => test/arrow_css_view_test.js (52%)
create mode 100644 test/arrow_preview_view_test.js
rename public/js/spec/models/arrow_spec.js => test/arrow_test.js (65%)
create mode 100644 test/test_helper.js
diff --git a/app/main.js b/app/main.js
new file mode 100644
index 0000000..54ceca7
--- /dev/null
+++ b/app/main.js
@@ -0,0 +1,49 @@
+var $ = require('jquery');
+var Arrow = require('./models/arrow');
+var ArrowConfigurationView = require('./views/arrow_configuration_view');
+var ArrowPreviewView = require('./views/arrow_preview_view');
+var ArrowCSSView = require('./views/arrow_css_view');
+
+/**
+@class App
+@constructor
+@description
+ Main application object.
+ Acts as view dispatcher
+**/
+var App = function () {
+ this.init.apply(this, arguments);
+};
+
+App.prototype = {
+
+ init: function () {
+ this.model = new Arrow();
+ this._initViews();
+ },
+
+ /**
+ @method _initViews
+ @description initializes views
+ @protected
+ **/
+ _initViews: function () {
+ var model = this.model;
+
+ this.views = [
+ new ArrowConfigurationView({ model: model, container: $('.configuration') }),
+ new ArrowPreviewView({ model: model, container: $('').appendTo('body') }),
+ new ArrowCSSView({ model: model, container: $('.css_result') }),
+ ];
+ },
+
+ render: function () {
+ $.each(this.views, function (i, view) {
+ view.render();
+ });
+ }
+
+};
+
+new App().render();
+
diff --git a/app/models/arrow.js b/app/models/arrow.js
new file mode 100644
index 0000000..fafde4d
--- /dev/null
+++ b/app/models/arrow.js
@@ -0,0 +1,291 @@
+var $ = require('jquery');
+
+/**
+@class Arrow
+@constructor
+**/
+var Arrow = function () {
+ this.init.apply(this, arguments);
+};
+
+Arrow.prototype = {
+
+ init: function () {
+ // jquerify 'this'
+ this._$self = $(this);
+
+ this._createAttrs();
+ },
+
+ /**
+ @method invertedPosition
+ @description
+ returns the opposite of the position
+ so 'top' becomes 'bottom' and 'left' becomes 'right'
+ @returns {String}
+ **/
+ invertedPosition: function () {
+ var pos = this.get('position');
+
+ if ( pos === 'top' ) return 'bottom';
+ else if ( pos === 'bottom') return 'top';
+ else if ( pos === 'left' ) return 'right';
+ else if ( pos === 'right' ) return 'left';
+ },
+
+ /**
+ @method hexToRGB
+ @description
+ returns an rgb color from an hex color
+ @returns {Array}
+ **/
+ hexToRGB: function (h) {
+ if ( typeof h !== 'string' || !h.match(/^#([0-9A-F]{3}$)|([0-9A-F]{6}$)/i) ) return [0, 0, 0];
+ else if ( h.match(/^(#[0-9a-f]{3})$/i) ) h = '#' + h[1] + h[1] + h[2] + h[2] + h[3] + h[3];
+ var rgb = [],
+ i = 1;
+
+ for(; i < 6; i+=2) {
+ rgb.push(parseInt(h.substring(i, i + 2), 16));
+ }
+ return rgb;
+ },
+
+ /**
+ @method _baseCSS
+ @description generates the base css
+ @returns {String} css
+ @protected
+ **/
+ _baseCSS: function () {
+ var pos = this.get('position'),
+ iPos = this.invertedPosition(),
+ color = this.get('color'),
+ borderWidth = this.get('borderWidth'),
+ borderColor = this.get('borderColor'),
+ hasBorder = borderWidth > 0,
+ css = '.arrow_box {\n';
+
+ color = this._sanitizeHexColors(color);
+
+ css += '\tposition: relative;\n';
+ css += '\tbackground: ' + color + ';\n';
+
+ if (hasBorder) {
+ borderColor = this._sanitizeHexColors(borderColor);
+ css += '\tborder: ' + borderWidth + 'px solid ' + borderColor + ';\n';
+ }
+
+ css += '}\n';
+ css += '.arrow_box:after';
+
+ if (hasBorder) css += ', .arrow_box:before {\n';
+ else css += ' {\n';
+
+ css += '\t' + iPos +': 100%;\n';
+
+ if (pos === 'top' || pos === 'bottom') {
+ css += '\tleft: 50%;\n';
+ }
+ else {
+ css += '\ttop: 50%;\n';
+ }
+
+ css += '\tborder: solid transparent;\n';
+ css += '\tcontent: " ";\n';
+ css += '\theight: 0;\n';
+ css += '\twidth: 0;\n';
+ css += '\tposition: absolute;\n';
+ css += '\tpointer-events: none;\n';
+
+ if (hasBorder) css += '}\n';
+
+ return css;
+ },
+
+ /**
+ @method _arrowCSS
+ @description generates arrow css
+ @param {String} color the color of the arrow
+ @param {Integer} size the size of the arrow
+ @param {String} layer :after or :before (defaults to :after)
+ @returns {String} css
+ @protected
+ **/
+ _arrowCSS: function (color, size, layer) {
+ color = this._sanitizeHexColors(color);
+ var pos = this.get('position'),
+ iPos = this.invertedPosition(),
+ rgbColor = this.hexToRGB(color),
+ borderWidth = this.get('borderWidth'),
+ css = "";
+
+ layer = layer || 'after';
+
+ if(borderWidth > 0) css += '.arrow_box:' + layer + ' {\n';
+
+ css += '\tborder-color: rgba(' + rgbColor.join(', ') + ', 0);\n';
+ css += '\tborder-' + iPos + '-color: ' + color + ';\n';
+ css += '\tborder-width: ' + size + 'px;\n';
+
+ if (pos === 'top' || pos === 'bottom') {
+ css += '\tmargin-left: -' + size + 'px;\n';
+ }
+ else {
+ css += '\tmargin-top: -' + size + 'px;\n';
+ }
+
+ css += '}';
+
+ return css;
+ },
+
+ /**
+ @method _baseArrowCSS
+ @description generates the base arrow
+ @returns {String} css
+ @protected
+ **/
+ _baseArrowCSS: function () {
+ return this._arrowCSS(
+ this.get('color'),
+ this.get('size'),
+ 'after'
+ );
+ },
+
+ /**
+ @method _arrowBorderCSS
+ @description generates the border arrow
+ @returns {String} css
+ @protected
+ **/
+ _arrowBorderCSS: function () {
+ var css = '',
+ borderWidth = this.get('borderWidth');
+
+ if (borderWidth > 0) {
+ css = this._arrowCSS(
+ this.get('borderColor'),
+ this.get('size') + Math.round(borderWidth * 1.41421356), // cos(PI/4) * 2
+ 'before'
+ );
+ }
+
+ return css;
+ },
+
+ /**
+ @method toCSS
+ @description returns a CSS representation of the arrow
+ @returns {String} css
+ **/
+ toCSS: function () {
+
+ var css = [
+ this._baseCSS(),
+ this._baseArrowCSS(),
+ this._arrowBorderCSS()
+ ];
+
+ return css.join(css[2] ? '\n':'');
+ },
+
+ /**
+ @method _createAttrs
+ @description creates attributes from the ATTR constant
+ @protected
+ **/
+ _createAttrs: function () {
+ var ATTRS = Arrow.ATTRS,
+ attributes = {};
+
+ $.each(ATTRS, function (attr, value) {
+ attributes[attr] = value;
+ });
+
+ this._attributes = attributes;
+ },
+
+ /**
+ @method _sanitizeHexColors
+ @description prefix hexcolors with # if necessary
+ @returns {String} h
+ @protected
+ **/
+ _sanitizeHexColors: function(h) {
+ return (h.charAt(0)==='#')?h:'#' + h;
+ },
+
+ /**
+ @method getAttrs
+ @description returns all the attributes
+ @returns {Object} all the model attributes
+ **/
+ getAttrs: function () {
+ return this._attributes;
+ },
+
+ /**
+ @method get
+ @description returns the provided attribute
+ @param {String} attr the attribute to return
+ @returns {?} the attribute
+ **/
+ get: function (attr) {
+ return this._attributes[attr];
+ },
+
+ /**
+ @method set
+ @description updates the provided attribute
+ @param {String} attr the attribute to update
+ @param {?} val the value to update with
+ **/
+ set: function (attr, val) {
+ if (!(attr in this._attributes)) return;
+
+ this._attributes[attr] = val;
+ this.fire('change');
+ },
+
+ /**
+ @method on
+ @description adds event listeners
+ @note uses jQuery custom events under the hood
+ @param {String} evType the event type
+ @param {Function} callback the event handler
+ @param {Object} context the 'this' for the callback
+ **/
+ on: function (evType, callback, context) {
+ var $self = this._$self;
+
+ $self.on(
+ evType,
+ $.proxy(callback, context || this)
+ );
+ },
+
+ /**
+ @method fire
+ @description trigger event
+ @note uses jQuery custom events under the hood
+ @param {String} evType the event type
+ **/
+ fire: function (evType) {
+ var $self = this._$self;
+
+ $self.trigger(evType);
+ }
+
+};
+
+Arrow.ATTRS = {
+ position: 'top',
+ size: 30,
+ color: '#88b7d5',
+ borderWidth: 4,
+ borderColor: '#c2e1f5'
+};
+
+module.exports = Arrow;
diff --git a/app/views/arrow_configuration_view.js b/app/views/arrow_configuration_view.js
new file mode 100644
index 0000000..93595c6
--- /dev/null
+++ b/app/views/arrow_configuration_view.js
@@ -0,0 +1,108 @@
+var $ = require('jquery');
+
+/**
+@class ArrowConfigurationView
+@constructor
+**/
+var ArrowConfigurationView = function () {
+ this.init.apply(this, arguments);
+};
+
+ArrowConfigurationView.prototype = {
+
+ init: function (options) {
+ this.container = options.container;
+ this.model = options.model;
+
+ this._attachEvents();
+ },
+
+ /**
+ @method render
+ @chainable
+ **/
+ render: function () {
+ this._setDefaults();
+ return this;
+ },
+
+ /**
+ @method _setDetaults
+ @description update the view with the model defaults
+ **/
+ _setDefaults: function () {
+ var container = this.container,
+ model = this.model;
+
+ container.find('.position').val([ model.get('position') ]);
+ container.find('.size').val( model.get('size') );
+ container.find('.base_color').val( model.get('color') );
+ container.find('.border_width').val( model.get('borderWidth') );
+ container.find('.border_color').val( model.get('borderColor') );
+ },
+
+ /**
+ @method _attachEvents
+ @description attaches dom events
+ @protected
+ **/
+ _attachEvents: function () {
+ var _updateModelProxy = this._updateModel.bind(this),
+ _updateInputProxy = this._updateInput.bind(this),
+ container = this.container,
+ selectors = [ { classname: '.position', keyboard_interactive: false },
+ { classname: '.size', keyboard_interactive: true },
+ { classname: '.base_color', keyboard_interactive: false },
+ { classname: '.border_width', keyboard_interactive: true },
+ { classname: '.border_color', keyboard_interactive: false }
+ ];
+
+ selectors.forEach(function (selector, i) {
+ container.delegate(selector.classname, 'change', _updateModelProxy);
+ if (selector.keyboard_interactive) {
+ container.delegate(selector.classname, 'keydown', _updateInputProxy);
+ }
+ });
+ },
+
+ _updateModel: function (ev) {
+ var target = $(ev.currentTarget),
+ val = target.val(),
+ attr;
+
+
+ if (target.hasClass('border_width')) {
+ attr = 'borderWidth';
+ }
+ else if (target.hasClass('border_color')) {
+ attr = 'borderColor';
+ }
+ else if (target.hasClass('base_color')) {
+ attr = 'color';
+ }
+ else {
+ attr = target.attr('class');
+ }
+
+ if (attr === 'borderWidth' || attr === 'size') val = parseInt(val, 10);
+ this.model.set(attr, val);
+ },
+
+ _updateInput: function (ev) {
+ if (ev.keyCode != 38 && ev.keyCode != 40) return;
+
+ var target = $(ev.currentTarget),
+ val = parseInt(target.val()),
+ increment = ev.keyCode == 38 ? 1 : -1,
+ multiply = ev.shiftKey ? 10 : 1,
+ newVal = val + increment * multiply;
+
+ if (newVal < 0) newVal = 0;
+
+ target.val(newVal);
+ this._updateModel(ev);
+ }
+
+};
+
+module.exports = ArrowConfigurationView;
diff --git a/app/views/arrow_css_view.js b/app/views/arrow_css_view.js
new file mode 100644
index 0000000..efe89ce
--- /dev/null
+++ b/app/views/arrow_css_view.js
@@ -0,0 +1,44 @@
+/**
+@class ArrowCSSView
+@constructor
+**/
+var ArrowCSSView = function () {
+ this.init.apply(this, arguments);
+};
+
+ArrowCSSView.prototype = {
+
+ init: function (options) {
+ this.container = options.container;
+ this._codeNode = this.container.find('.code');
+ this._copyNode = this.container.find('.copy_code');
+
+ this.model = options.model;
+ this.model.on('change', this._handleChange, this);
+ },
+
+ /**
+ @method _handleChange
+ @description handles changes to the model
+ @chainable
+ **/
+ _handleChange: function () {
+ this.render();
+ },
+
+ /**
+ @method render
+ @description renders the model's css
+ @chainable
+ **/
+ render: function () {
+ var css = this.model.toCSS();
+
+ this._codeNode.text( css );
+
+ return this;
+ }
+
+};
+
+module.exports = ArrowCSSView;
diff --git a/app/views/arrow_preview_view.js b/app/views/arrow_preview_view.js
new file mode 100644
index 0000000..61d7941
--- /dev/null
+++ b/app/views/arrow_preview_view.js
@@ -0,0 +1,39 @@
+/**
+@class ArrowPreviewView
+@constructor
+**/
+var ArrowPreviewView = function () {
+ this.init.apply(this, arguments);
+};
+
+ArrowPreviewView.prototype = {
+
+ init: function (options) {
+ this.container = options.container;
+ this.model = options.model;
+
+ this.model.on('change', this._handleChange, this);
+ },
+
+ /**
+ @method _handleChange
+ @description handles changes to the model
+ @chainable
+ **/
+ _handleChange: function () {
+ this.render();
+ },
+
+ /**
+ @method render
+ @description renders the css to style the preview
+ @chainable
+ **/
+ render: function () {
+ this.container.text( this.model.toCSS() );
+ return this;
+ }
+
+};
+
+module.exports = ArrowPreviewView;
diff --git a/package.json b/package.json
index 822f80d..258cd66 100644
--- a/package.json
+++ b/package.json
@@ -16,13 +16,22 @@
],
"homepage": "http://cssarrowplease.com/",
"scripts": {
- "start": "node ./server.js"
+ "start": "node ./server.js",
+ "build": "./node_modules/browserify/bin/cmd.js -e app/main.js -o public/js/cssarrowplease.js",
+ "test": "mocha --require=test/test_helper.js"
},
"dependencies": {
- "connect": "~2.0.3"
+ "connect": "~2.0.3",
+ "browserify": "latest",
+ "jquery": "latest",
+ "jsdom": "latest",
+ "mocha": "latest",
+ "chai": "latest",
+ "sinon": "latest",
+ "sinon-chai": "latest"
},
"engines": {
- "node": ">=0.6"
+ "node": ">=0.10"
},
"licenses": [
{
diff --git a/public/css/app.css b/public/css/app.css
index c137a21..fbf43dc 100644
--- a/public/css/app.css
+++ b/public/css/app.css
@@ -54,8 +54,6 @@ input[type='radio'] { border: 0; }
/* css_result */
.css_result { position: relative; float: right; width: 402px; }
.css_result .code { white-space: pre; padding: 10px; display: block; width: 380px; font-size: 12px; font-family: 'Courier new'; font-weight: bold; background: #8c9196; background: rgba(0, 0, 0, 0.15); border-radius: 4px; color: #fff; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.3); border: 1px solid #696d72; border-color: rgba(0, 0, 0, 0.2); box-shadow: 0 1px 1px 0 rgba(255, 255, 255, 0.3), inset 0 1px 5px rgba(0, 0, 0, 0.1); }
-.css_result .copy_code { position: absolute; bottom: 5px; right: 10px; width: 14px; height: 22px; background: url(../img/clippy.png) no-repeat 0 4px; }
-
/* fork_me */
.fork_me { position: absolute; top: 0; right: 0; display: block; width: 149px; height: 149px; background: url(../img/fork.png); }
diff --git a/public/index.html b/public/index.html
index fa3c54c..c336ad7 100644
--- a/public/index.html
+++ b/public/index.html
@@ -73,50 +73,30 @@ Arrow configuration
-
-
-
-
-
-
-
-
+