From 5a2d74a995f330565e51a523ca1cbca305428ebd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simon=20H=C3=B8jberg?=
Date: Sun, 27 May 2012 13:07:48 -0400
Subject: [PATCH 01/30] Moved the github fork image locally
Often the image would not be able to
load when using the external cdn.
Instead we now host the image in
order for it to always load.
Also added some simple transition
styles to the image when you hover.
---
public/css/app.css | 17 +++++++++++++++++
public/img/fork.png | Bin 0 -> 9267 bytes
public/index.html | 6 ++++--
3 files changed, 21 insertions(+), 2 deletions(-)
create mode 100644 public/img/fork.png
diff --git a/public/css/app.css b/public/css/app.css
index 8fdc2fd..c4d0947 100644
--- a/public/css/app.css
+++ b/public/css/app.css
@@ -25,6 +25,8 @@ input[type='radio'] { border: 0; }
#footer a { vertical-align: top; color: #fff; }
.clr:after { clear:both; content:"."; display: block; height:0; visibility: hidden; line-height:0; font-size:0; }
+.ir { border: 0; font: 0/0 a; text-shadow: none; color: transparent; background-color: transparent; }
+
.preview_and_configuration { float: left; width: 395px; }
/* =MODULES
@@ -53,3 +55,18 @@ input[type='radio'] { border: 0; }
.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);
+ 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);
+}
diff --git a/public/img/fork.png b/public/img/fork.png
new file mode 100644
index 0000000000000000000000000000000000000000..7dc1afca60b9d40dcd402703f5b29717583150d7
GIT binary patch
literal 9267
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
V)~XPt9$f$c002ovPDHLkV1fgJi?9Fy
literal 0
HcmV?d00001
diff --git a/public/index.html b/public/index.html
index 2fbe7bf..413f523 100644
--- a/public/index.html
+++ b/public/index.html
@@ -7,8 +7,6 @@
-
-
@@ -57,6 +55,10 @@
Arrow configuration
+
+
+ Fork me on Github
+
From ee62cc0a859e0c9abe3e9a7419e433a4a34a1d7b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simon=20H=C3=B8jberg?=
Date: Sun, 27 May 2012 19:52:52 -0400
Subject: [PATCH 02/30] version 0.2.2-10
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 11ee6e4..a298c3a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "cssarrowplease",
- "version": "0.2.2-9",
+ "version": "0.2.2-10",
"author": {
"name": "Simon Højberg",
"email": "r.hackr@gmail.com"
From 1d54fa161c2ad60269f9129d9bedc2bc54a3501b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Peter=20M=C3=BCller?=
Date: Wed, 13 Jun 2012 12:07:10 +0200
Subject: [PATCH 03/30] Reduced colors in fork.png to 128
---
public/img/fork.png | Bin 9267 -> 3981 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
diff --git a/public/img/fork.png b/public/img/fork.png
index 7dc1afca60b9d40dcd402703f5b29717583150d7..aba9b3965d73d2ca1ba1a57940ffa78be4b8f9f3 100644
GIT binary patch
literal 3981
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
A%K!iX
literal 9267
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
V)~XPt9$f$c002ovPDHLkV1fgJi?9Fy
From 97d866d380c59f35e3d24106cb5613dafa458da0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Peter=20M=C3=BCller?=
Date: Wed, 13 Jun 2012 12:07:56 +0200
Subject: [PATCH 04/30] Upgraded to assetgraph-builder 0.2.37 to gain better IE
support for embedded css backgrounds
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index a298c3a..b02dfe2 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,7 @@
"connect": "~2.0.3"
},
"devDependencies": {
- "assetgraph-builder": "latest"
+ "assetgraph-builder": ">=0.2.37"
},
"engines": {
"node": ">=0.6"
From 682ac820cdb7051bbf1da0597056519de9b7c628 Mon Sep 17 00:00:00 2001
From: Yannick Croissant
Date: Tue, 21 Aug 2012 00:53:19 +0200
Subject: [PATCH 05/30] 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 06/30] 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 07/30] 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 08/30] 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 09/30] 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 10/30] 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 11/30] 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 12/30] 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 13/30] 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 14/30] 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 15/30] 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 16/30] 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 17/30] 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 18/30] 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 19/30] 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 20/30] 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 21/30] 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 22/30] 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 23/30] 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 24/30] 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
-
-
-
-
-
-
-
-
+