main interface ok
added grunt-svg2png and set svg 2 png fall back mixin added bubbles and stars added nav_pos move on chapter preview
@@ -34,12 +34,24 @@ module.exports = function (grunt) {
|
||||
},
|
||||
dist: { src: 'css/*.css' }
|
||||
},
|
||||
svg2png: {
|
||||
assets: {
|
||||
// specify files in array format with multiple src-dest mapping
|
||||
files: [
|
||||
// rasterize all SVG files in "img" and its subdirectories to "img/png"
|
||||
// { src: ['assets/img/*.svg'], dest: 'assets/img/png/' },
|
||||
// rasterize SVG file to same directory
|
||||
{ src: ['assets/img/*.svg'] }
|
||||
]
|
||||
}
|
||||
}
|
||||
});
|
||||
grunt.loadNpmTasks('grunt-contrib-compass');
|
||||
grunt.loadNpmTasks('grunt-contrib-sass');
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
grunt.loadNpmTasks('grunt-postcss');
|
||||
grunt.loadNpmTasks('grunt-svg2png');
|
||||
|
||||
|
||||
grunt.registerTask('default', ['compass', 'postcss']);
|
||||
grunt.registerTask('default', ['compass', 'postcss', 'svg2png']);
|
||||
};
|
||||
|
After Width: | Height: | Size: 214 KiB |
|
After Width: | Height: | Size: 232 KiB |
|
After Width: | Height: | Size: 326 KiB |
|
After Width: | Height: | Size: 341 KiB |
|
After Width: | Height: | Size: 305 KiB |
|
After Width: | Height: | Size: 240 KiB |
|
After Width: | Height: | Size: 284 KiB |
|
After Width: | Height: | Size: 60 KiB |
@@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="425"
|
||||
height="425"
|
||||
viewBox="0 0 425 425.00001"
|
||||
id="svg15765"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="bubble-01.svg">
|
||||
<defs
|
||||
id="defs15767">
|
||||
<radialGradient
|
||||
id="SVGID_17_"
|
||||
cx="-6706.2617"
|
||||
cy="-2725.1895"
|
||||
r="172.1931"
|
||||
gradientTransform="matrix(1.2340828,0,0,1.2340828,8488.5815,4202.9728)"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#CBBBA0"
|
||||
id="stop4338" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#cbbba0;stop-opacity:0"
|
||||
id="stop4346" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.4"
|
||||
inkscape:cx="217.66355"
|
||||
inkscape:cy="155.53537"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1155"
|
||||
inkscape:window-x="-2"
|
||||
inkscape:window-y="22"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid16331" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata15770">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Calque 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-627.36216)">
|
||||
<circle
|
||||
style="fill:url(#SVGID_17_)"
|
||||
cx="212.5"
|
||||
cy="839.86212"
|
||||
id="circle4348"
|
||||
r="212.5" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 129 KiB |
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="885"
|
||||
height="885"
|
||||
viewBox="0 0 885.00001 885.00001"
|
||||
id="svg16367"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="bubble-02.svg">
|
||||
<defs
|
||||
id="defs16369">
|
||||
<radialGradient
|
||||
id="SVGID_18_"
|
||||
cx="-5383.5928"
|
||||
cy="-1752.0127"
|
||||
r="276.7793"
|
||||
gradientTransform="matrix(1.5987427,0,0,1.5987428,9049.4803,3410.8796)"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#B6C38D"
|
||||
id="stop4351" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#b6c38d;stop-opacity:0"
|
||||
id="stop4359" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.98994949"
|
||||
inkscape:cx="436.0424"
|
||||
inkscape:cy="437.90703"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1155"
|
||||
inkscape:window-x="-2"
|
||||
inkscape:window-y="22"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata16372">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Calque 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-167.36216)">
|
||||
<circle
|
||||
style="opacity:0.86000001;fill:url(#SVGID_18_)"
|
||||
cx="442.5"
|
||||
cy="609.86218"
|
||||
id="circle4361"
|
||||
r="442.5" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 169 KiB |
|
After Width: | Height: | Size: 113 KiB |
|
After Width: | Height: | Size: 596 B |
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 15 KiB |
@@ -46,7 +46,7 @@
|
||||
spreadMethod="pad">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#0066b1;stop-opacity:0.71"
|
||||
style="stop-color:#0066b1;stop-opacity:0.506"
|
||||
id="stop5359-9-7" />
|
||||
<stop
|
||||
offset="1"
|
||||
@@ -62,8 +62,8 @@
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="3.959798"
|
||||
inkscape:cx="33.732485"
|
||||
inkscape:cy="127.15041"
|
||||
inkscape:cx="120.98441"
|
||||
inkscape:cy="79.925779"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
|
||||
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 14 KiB |
@@ -45,7 +45,7 @@
|
||||
fy="-2661.446">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#cecd00;stop-opacity:0.698"
|
||||
style="stop-color:#cecd00;stop-opacity:0.545"
|
||||
id="stop5359-9-7" />
|
||||
<stop
|
||||
offset="1"
|
||||
@@ -61,8 +61,8 @@
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="3.959798"
|
||||
inkscape:cx="23.883498"
|
||||
inkscape:cy="84.471467"
|
||||
inkscape:cx="74.012318"
|
||||
inkscape:cy="82.956238"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
|
||||
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 17 KiB |
@@ -45,7 +45,7 @@
|
||||
fy="-2661.446">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#62a530;stop-opacity:0.698"
|
||||
style="stop-color:#62a530;stop-opacity:0.506"
|
||||
id="stop5359-9-7" />
|
||||
<stop
|
||||
offset="1"
|
||||
@@ -61,8 +61,8 @@
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="3.959798"
|
||||
inkscape:cx="80.45204"
|
||||
inkscape:cy="85.986696"
|
||||
inkscape:cx="105.07451"
|
||||
inkscape:cy="83.713853"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
|
||||
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 16 KiB |
@@ -45,7 +45,7 @@
|
||||
fy="-2661.446">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#33b4b5;stop-opacity:0.702"
|
||||
style="stop-color:#33b4b5;stop-opacity:0.502"
|
||||
id="stop5359-9-7" />
|
||||
<stop
|
||||
offset="1"
|
||||
@@ -61,8 +61,8 @@
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="3.959798"
|
||||
inkscape:cx="79.694426"
|
||||
inkscape:cy="100.63391"
|
||||
inkscape:cx="78.305466"
|
||||
inkscape:cy="88.51208"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
|
||||
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 16 KiB |
@@ -45,7 +45,7 @@
|
||||
fy="-2661.446">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#af1380;stop-opacity:0.706"
|
||||
style="stop-color:#af1380;stop-opacity:0.518"
|
||||
id="stop5359-9-7" />
|
||||
<stop
|
||||
offset="1"
|
||||
@@ -61,8 +61,8 @@
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="3.959798"
|
||||
inkscape:cx="64.542138"
|
||||
inkscape:cy="93.815379"
|
||||
inkscape:cx="92.70014"
|
||||
inkscape:cy="89.522231"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
|
||||
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 15 KiB |
@@ -45,7 +45,7 @@
|
||||
fy="-2661.446">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#ea5b0c;stop-opacity:0.702"
|
||||
style="stop-color:#ea5b0c;stop-opacity:0.502"
|
||||
id="stop5359-9-7" />
|
||||
<stop
|
||||
offset="1"
|
||||
@@ -61,8 +61,8 @@
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="3.959798"
|
||||
inkscape:cx="72.37082"
|
||||
inkscape:cy="113.76589"
|
||||
inkscape:cx="97.498364"
|
||||
inkscape:cy="88.007"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
|
||||
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 15 KiB |
@@ -45,7 +45,7 @@
|
||||
fy="-2661.446">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#de003a;stop-opacity:0.7"
|
||||
style="stop-color:#de003a;stop-opacity:0.502"
|
||||
id="stop5359-9-7" />
|
||||
<stop
|
||||
offset="1"
|
||||
@@ -61,8 +61,8 @@
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="3.959798"
|
||||
inkscape:cx="49.642388"
|
||||
inkscape:cy="79.704082"
|
||||
inkscape:cx="92.70014"
|
||||
inkscape:cy="84.502307"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
|
||||
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 202 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 259 B |
@@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="10"
|
||||
height="10"
|
||||
viewBox="0 0 10 10"
|
||||
id="svg16952"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="star.svg">
|
||||
<defs
|
||||
id="defs16954">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient17510">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0.69142854"
|
||||
offset="0"
|
||||
id="stop17512" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0"
|
||||
offset="1"
|
||||
id="stop17514" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient17510"
|
||||
id="radialGradient17516"
|
||||
cx="5"
|
||||
cy="1047.3622"
|
||||
fx="5"
|
||||
fy="1047.3622"
|
||||
r="5"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="63.356767"
|
||||
inkscape:cx="2.8741085"
|
||||
inkscape:cy="6.230448"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1155"
|
||||
inkscape:window-x="-2"
|
||||
inkscape:window-y="22"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid17508" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata16957">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Calque 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1042.3621)">
|
||||
<circle
|
||||
style="opacity:0.92142202;fill:url(#radialGradient17516);fill-opacity:1;stroke:none;stroke-width:0.13;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path17506"
|
||||
cx="5"
|
||||
cy="1047.3622"
|
||||
r="5" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -3726,12 +3726,26 @@ p.heading {
|
||||
font-size: 1.25em !important;
|
||||
}
|
||||
|
||||
/* line 28, jee.scss */
|
||||
/*
|
||||
__ ________ __ _____ _______
|
||||
/ |/ / _/ |/ // _/ | / / ___/
|
||||
/ /|_/ // / | / / // |/ /\__ \
|
||||
/ / / // / / |_/ // /| /___/ /
|
||||
/_/ /_/___//_/|_/___/_/ |_//____/
|
||||
*/
|
||||
/*
|
||||
___ ____ ____
|
||||
/ | / __ \/ __ \
|
||||
/ /| | / /_/ / /_/ /
|
||||
/ ___ |/ ____/ ____/
|
||||
/_/ |_/_/ /_/
|
||||
*/
|
||||
/* line 46, jee.scss */
|
||||
html {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* line 34, jee.scss */
|
||||
/* line 52, jee.scss */
|
||||
body {
|
||||
position: relative;
|
||||
-webkit-user-select: none;
|
||||
@@ -3743,7 +3757,7 @@ body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* line 43, jee.scss */
|
||||
/* line 61, jee.scss */
|
||||
#root {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
@@ -3857,8 +3871,9 @@ body {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
/* line 91, jee.scss */
|
||||
/* line 109, jee.scss */
|
||||
#header {
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
width: 700px;
|
||||
@@ -3870,18 +3885,18 @@ body {
|
||||
-webkit-animation-fill-mode: forwards;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
/* line 104, jee.scss */
|
||||
/* line 123, jee.scss */
|
||||
#header h1 {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
/* line 107, jee.scss */
|
||||
/* line 126, jee.scss */
|
||||
#header h1 a {
|
||||
display: block;
|
||||
margin-top: -500%;
|
||||
}
|
||||
/* line 109, jee.scss */
|
||||
/* line 128, jee.scss */
|
||||
#header h1:after, #header h1:before {
|
||||
content: "";
|
||||
display: block;
|
||||
@@ -3892,25 +3907,28 @@ body {
|
||||
left: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
/* line 117, jee.scss */
|
||||
/* line 136, jee.scss */
|
||||
#header h1:before {
|
||||
background: transparent url("../assets/img/logo.svg") no-repeat center center;
|
||||
background: transparent url("../assets/img/logo.png") no-repeat center center;
|
||||
background: none, url("../assets/img/logo.svg") no-repeat center center;
|
||||
-webkit-animation: introLogo 8s linear 0s;
|
||||
animation: introLogo 8s linear 0s;
|
||||
-webkit-animation-fill-mode: forwards;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
/* line 122, jee.scss */
|
||||
/* line 141, jee.scss */
|
||||
#header h1:after {
|
||||
background: transparent url("../assets/img/logo-blured.svg") no-repeat center center;
|
||||
background: transparent url("../assets/img/logo-blured.png") no-repeat center center;
|
||||
background: none, url("../assets/img/logo-blured.svg") no-repeat center center;
|
||||
-webkit-animation: introLogoBlured 8s linear 0s;
|
||||
animation: introLogoBlured 8s linear 0s;
|
||||
-webkit-animation-fill-mode: forwards;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
/* line 129, jee.scss */
|
||||
/* line 149, jee.scss */
|
||||
#header h2 {
|
||||
background: transparent url("../assets/img/slogan.svg") no-repeat center center;
|
||||
background: transparent url("../assets/img/slogan.png") no-repeat center center;
|
||||
background: none, url("../assets/img/slogan.svg") no-repeat center center;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -3920,13 +3938,13 @@ body {
|
||||
-webkit-animation-fill-mode: forwards;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
/* line 133, jee.scss */
|
||||
/* line 154, jee.scss */
|
||||
#header h2 a {
|
||||
display: block;
|
||||
margin-top: -500%;
|
||||
}
|
||||
|
||||
/* line 140, jee.scss */
|
||||
/* line 161, jee.scss */
|
||||
div.messages {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
@@ -3937,7 +3955,7 @@ div.messages {
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
/* line 148, jee.scss */
|
||||
/* line 169, jee.scss */
|
||||
#main {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
@@ -3949,16 +3967,178 @@ div.messages {
|
||||
| --| | | |__| | | -|__ | | __ -|_ _| | | | | | | | | __|
|
||||
|_____|_____|_____|_____|__|__|_____| |_____| |_| |_|___|_____|____/|_____|
|
||||
*/
|
||||
/*
|
||||
_____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____
|
||||
| | | | _ | _ |_ _| __| __ | __| | __| __| | | __| __ | | | | | __|
|
||||
| --| | | __| | | | __| -|__ | | | | __| | | | __| -|- -| | | | | __|
|
||||
|_____|__|__|__|__|__| |_| |_____|__|__|_____| |_____|_____|_|___|_____|__|__|_____|__ _|_____|_____|
|
||||
|__|
|
||||
*/
|
||||
}
|
||||
/* line 153, jee.scss */
|
||||
/* line 174, jee.scss */
|
||||
#main > .region, #main > .region > .block-system, #main > .region > .block-system > .content {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
/* line 159, jee.scss */
|
||||
/* line 189, jee.scss */
|
||||
#main #node-2::after {
|
||||
background: transparent url("../assets/img/bgd-sol.png") no-repeat center center;
|
||||
background: none, url("../assets/img/bgd-sol.svg") no-repeat center center;
|
||||
}
|
||||
/* line 190, jee.scss */
|
||||
#main #node-2, #main #node-2 a {
|
||||
color: #b24c14;
|
||||
}
|
||||
/* line 191, jee.scss */
|
||||
#main #node-2 h2.node-title, #main #node-2 h2.node-title a {
|
||||
color: #d85509;
|
||||
}
|
||||
/* line 192, jee.scss */
|
||||
#main #node-2 .field-name-field-vignette {
|
||||
background: transparent url("../assets/img/shadow-sol.png") no-repeat center center;
|
||||
background: none, url("../assets/img/shadow-sol.svg") no-repeat center center;
|
||||
}
|
||||
/* line 193, jee.scss */
|
||||
#main #node-2 .line {
|
||||
background-color: #ea5b0c;
|
||||
}
|
||||
/* line 197, jee.scss */
|
||||
#main #node-3::after {
|
||||
background: transparent url("../assets/img/bgd-dph.png") no-repeat center center;
|
||||
background: none, url("../assets/img/bgd-dph.svg") no-repeat center center;
|
||||
}
|
||||
/* line 198, jee.scss */
|
||||
#main #node-3, #main #node-3 a {
|
||||
color: #686b00;
|
||||
}
|
||||
/* line 199, jee.scss */
|
||||
#main #node-3 h2.node-title, #main #node-3 h2.node-title a {
|
||||
color: #afaf00;
|
||||
}
|
||||
/* line 200, jee.scss */
|
||||
#main #node-3 .field-name-field-vignette {
|
||||
background: transparent url("../assets/img/shadow-dph.png") no-repeat center center;
|
||||
background: none, url("../assets/img/shadow-dph.svg") no-repeat center center;
|
||||
}
|
||||
/* line 201, jee.scss */
|
||||
#main #node-3 .line {
|
||||
background-color: #cecd00;
|
||||
}
|
||||
/* line 205, jee.scss */
|
||||
#main #node-4::after {
|
||||
background: transparent url("../assets/img/bgd-sub.png") no-repeat center center;
|
||||
background: none, url("../assets/img/bgd-sub.svg") no-repeat center center;
|
||||
}
|
||||
/* line 206, jee.scss */
|
||||
#main #node-4, #main #node-4 a {
|
||||
color: #b71330;
|
||||
}
|
||||
/* line 207, jee.scss */
|
||||
#main #node-4 h2.node-title, #main #node-4 h2.node-title a {
|
||||
color: #cd0734;
|
||||
}
|
||||
/* line 208, jee.scss */
|
||||
#main #node-4 .field-name-field-vignette {
|
||||
background: transparent url("../assets/img/shadow-sub.png") no-repeat center center;
|
||||
background: none, url("../assets/img/shadow-sub.svg") no-repeat center center;
|
||||
}
|
||||
/* line 209, jee.scss */
|
||||
#main #node-4 .line {
|
||||
background-color: #de003a;
|
||||
}
|
||||
/* line 213, jee.scss */
|
||||
#main #node-5::after {
|
||||
background: transparent url("../assets/img/bgd-bc.png") no-repeat center center;
|
||||
background: none, url("../assets/img/bgd-bc.svg") no-repeat center center;
|
||||
}
|
||||
/* line 214, jee.scss */
|
||||
#main #node-5, #main #node-5 a {
|
||||
color: #033d6f;
|
||||
}
|
||||
/* line 215, jee.scss */
|
||||
#main #node-5 h2.node-title, #main #node-5 h2.node-title a {
|
||||
color: #024b87;
|
||||
}
|
||||
/* line 216, jee.scss */
|
||||
#main #node-5 .field-name-field-vignette {
|
||||
background: transparent url("../assets/img/shadow-bc.png") no-repeat center center;
|
||||
background: none, url("../assets/img/shadow-bc.svg") no-repeat center center;
|
||||
}
|
||||
/* line 217, jee.scss */
|
||||
#main #node-5 .line {
|
||||
background-color: #0066b1;
|
||||
}
|
||||
/* line 221, jee.scss */
|
||||
#main #node-6::after {
|
||||
background: transparent url("../assets/img/bgd-opp.png") no-repeat center center;
|
||||
background: none, url("../assets/img/bgd-opp.svg") no-repeat center center;
|
||||
}
|
||||
/* line 222, jee.scss */
|
||||
#main #node-6, #main #node-6 a {
|
||||
color: #7f1965;
|
||||
}
|
||||
/* line 223, jee.scss */
|
||||
#main #node-6 h2.node-title, #main #node-6 h2.node-title a {
|
||||
color: #941b80;
|
||||
}
|
||||
/* line 224, jee.scss */
|
||||
#main #node-6 .field-name-field-vignette {
|
||||
background: transparent url("../assets/img/shadow-opp.png") no-repeat center center;
|
||||
background: none, url("../assets/img/shadow-opp.svg") no-repeat center center;
|
||||
}
|
||||
/* line 225, jee.scss */
|
||||
#main #node-6 .line {
|
||||
background-color: #af1380;
|
||||
}
|
||||
/* line 229, jee.scss */
|
||||
#main #node-7::after {
|
||||
background: transparent url("../assets/img/bgd-dub.png") no-repeat center center;
|
||||
background: none, url("../assets/img/bgd-dub.svg") no-repeat center center;
|
||||
}
|
||||
/* line 230, jee.scss */
|
||||
#main #node-7, #main #node-7 a {
|
||||
color: #22742c;
|
||||
}
|
||||
/* line 231, jee.scss */
|
||||
#main #node-7 h2.node-title, #main #node-7 h2.node-title a {
|
||||
color: #288d80;
|
||||
}
|
||||
/* line 232, jee.scss */
|
||||
#main #node-7 .field-name-field-vignette {
|
||||
background: transparent url("../assets/img/shadow-dub.png") no-repeat center center;
|
||||
background: none, url("../assets/img/shadow-dub.svg") no-repeat center center;
|
||||
}
|
||||
/* line 233, jee.scss */
|
||||
#main #node-7 .line {
|
||||
background-color: #62a530;
|
||||
}
|
||||
/* line 237, jee.scss */
|
||||
#main #node-8::after {
|
||||
background: transparent url("../assets/img/bgd-juso.png") no-repeat center center;
|
||||
background: none, url("../assets/img/bgd-juso.svg") no-repeat center center;
|
||||
}
|
||||
/* line 238, jee.scss */
|
||||
#main #node-8, #main #node-8 a {
|
||||
color: #0b7f8a;
|
||||
}
|
||||
/* line 239, jee.scss */
|
||||
#main #node-8 h2.node-title, #main #node-8 h2.node-title a {
|
||||
color: #009aa8;
|
||||
}
|
||||
/* line 240, jee.scss */
|
||||
#main #node-8 .field-name-field-vignette {
|
||||
background: transparent url("../assets/img/shadow-juso.png") no-repeat center center;
|
||||
background: none, url("../assets/img/shadow-juso.svg") no-repeat center center;
|
||||
}
|
||||
/* line 241, jee.scss */
|
||||
#main #node-8 .line {
|
||||
background-color: #33b4b5;
|
||||
}
|
||||
/* line 251, jee.scss */
|
||||
#main .node-chapitre.node-teaser {
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
/*
|
||||
_____ __________________ ___ _________________ __________________
|
||||
@@ -3974,6 +4154,11 @@ div.messages {
|
||||
|____/|_____|__| |__|__|_____|_____|_| |_|_|_|_____|____/|_____|
|
||||
|
||||
*/
|
||||
opacity: 1;
|
||||
-webkit-transition: 1s ease-out;
|
||||
transition: 1s ease-out;
|
||||
-webkit-transition-property: opacity;
|
||||
transition-property: opacity;
|
||||
/*
|
||||
_____ _____ _____ _____ _____ _____ _ _ _ _____ _____ ____ _____
|
||||
| _ | __ | __| | | | __| | | | | | | \| __|
|
||||
@@ -3981,6 +4166,12 @@ div.messages {
|
||||
|__| |__|__|_____|\___/|_____|_____|_____| |_|_|_|_____|____/|_____|
|
||||
|
||||
*/
|
||||
/*
|
||||
_____ _____ _____ _____ _____ _____ _____ _____ _____ _____ ____ _____
|
||||
| | |_ _| | __| _ |_ _| __| | | | \| __|
|
||||
| | | |- -| | | |- -| | | | | | | __| | | | | | | | | __|
|
||||
|_|_|_|_____| |_| |_____|_____|__|__| |_| |_____| |_|_|_|_____|____/|_____|
|
||||
*/
|
||||
/*
|
||||
_____________ ____________ ___ __ _____ __ _ __ __ _ _
|
||||
/ ____/ ____/ | / / ____/ __ \/ | / / / ___/ _/_/___ ____ ____ (_)___ / /____ _________ ______/ /_(_) _____ | |
|
||||
@@ -3990,7 +4181,7 @@ div.messages {
|
||||
|_| /_/
|
||||
*/
|
||||
}
|
||||
/* line 177, jee.scss */
|
||||
/* line 274, jee.scss */
|
||||
#main .node-chapitre.node-teaser h2.node-title {
|
||||
-webkit-transform: none;
|
||||
-ms-transform: none;
|
||||
@@ -4004,11 +4195,11 @@ div.messages {
|
||||
transition-property: transform;
|
||||
z-index: 5;
|
||||
}
|
||||
/* line 184, jee.scss */
|
||||
/* line 281, jee.scss */
|
||||
#main .node-chapitre.node-teaser > .content {
|
||||
position: relative;
|
||||
}
|
||||
/* line 185, jee.scss */
|
||||
/* line 282, jee.scss */
|
||||
#main .node-chapitre.node-teaser .texts {
|
||||
opacity: 0;
|
||||
height: 1px;
|
||||
@@ -4019,7 +4210,7 @@ div.messages {
|
||||
transition-property: opacity height;
|
||||
position: absolute;
|
||||
}
|
||||
/* line 191, jee.scss */
|
||||
/* line 288, jee.scss */
|
||||
#main .node-chapitre.node-teaser .field-name-field-partie {
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
@@ -4028,12 +4219,12 @@ div.messages {
|
||||
-webkit-transition-property: opacity -webkit-transform;
|
||||
transition-property: opacity transform;
|
||||
}
|
||||
/* line 197, jee.scss */
|
||||
/* line 294, jee.scss */
|
||||
#main .node-chapitre.node-teaser .field-name-field-partie:nth-child(2) {
|
||||
z-index: 2;
|
||||
opacity: 1;
|
||||
}
|
||||
/* line 201, jee.scss */
|
||||
/* line 298, jee.scss */
|
||||
#main .node-chapitre.node-teaser .field-name-field-partie:nth-child(2) > .field-type-text {
|
||||
opacity: 0;
|
||||
-webkit-transition: 1s ease-out 0.9s;
|
||||
@@ -4041,12 +4232,12 @@ div.messages {
|
||||
-webkit-transition-property: opacity;
|
||||
transition-property: opacity;
|
||||
}
|
||||
/* line 206, jee.scss */
|
||||
/* line 303, jee.scss */
|
||||
#main .node-chapitre.node-teaser .field-name-field-partie:nth-child(2) > .field-name-field-vignette {
|
||||
cursor: pointer;
|
||||
z-index: 2;
|
||||
}
|
||||
/* line 209, jee.scss */
|
||||
/* line 306, jee.scss */
|
||||
#main .node-chapitre.node-teaser:after {
|
||||
opacity: 0;
|
||||
-webkit-transition: 2s ease-in;
|
||||
@@ -4058,7 +4249,11 @@ div.messages {
|
||||
bottom: 2px;
|
||||
right: 2px;
|
||||
}
|
||||
/* line 228, jee.scss */
|
||||
/* line 324, jee.scss */
|
||||
#main .node-chapitre.node-teaser.previewed {
|
||||
z-index: 100;
|
||||
}
|
||||
/* line 326, jee.scss */
|
||||
#main .node-chapitre.node-teaser.previewed:after {
|
||||
opacity: 1;
|
||||
top: 2em;
|
||||
@@ -4066,37 +4261,40 @@ div.messages {
|
||||
right: -12em;
|
||||
bottom: -30em;
|
||||
}
|
||||
/* line 235, jee.scss */
|
||||
/* line 333, jee.scss */
|
||||
#main .node-chapitre.node-teaser.previewed h2.node-title {
|
||||
-webkit-transform: scale(2, 2);
|
||||
-ms-transform: scale(2, 2);
|
||||
transform: scale(2, 2);
|
||||
}
|
||||
/* line 236, jee.scss */
|
||||
/* line 334, jee.scss */
|
||||
#main .node-chapitre.node-teaser.previewed .texts {
|
||||
opacity: 1;
|
||||
height: 8em;
|
||||
}
|
||||
/* line 237, jee.scss */
|
||||
/* line 335, jee.scss */
|
||||
#main .node-chapitre.node-teaser.previewed .field-name-field-partie {
|
||||
opacity: 1;
|
||||
z-index: 0;
|
||||
}
|
||||
/* line 240, jee.scss */
|
||||
/* line 338, jee.scss */
|
||||
#main .node-chapitre.node-teaser.previewed .field-name-field-partie > .field {
|
||||
opacity: 1;
|
||||
z-index: -1;
|
||||
cursor: default;
|
||||
}
|
||||
/* line 254, jee.scss */
|
||||
/* line 348, jee.scss */
|
||||
#main .node-chapitre.node-teaser.mitigated {
|
||||
opacity: 0.3;
|
||||
}
|
||||
/* line 361, jee.scss */
|
||||
#main .node-chapitre.node-teaser:after {
|
||||
content: " ";
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain !important;
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
}
|
||||
/* line 262, jee.scss */
|
||||
/* line 368, jee.scss */
|
||||
#main .node-chapitre.node-teaser h2.node-title {
|
||||
font-family: "epflulb";
|
||||
font-weight: normal;
|
||||
@@ -4107,30 +4305,30 @@ div.messages {
|
||||
z-index: 5;
|
||||
}
|
||||
@media only screen and (min-width: 64.063em) {
|
||||
/* line 262, jee.scss */
|
||||
/* line 368, jee.scss */
|
||||
#main .node-chapitre.node-teaser h2.node-title {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: 90.063em) {
|
||||
/* line 262, jee.scss */
|
||||
/* line 368, jee.scss */
|
||||
#main .node-chapitre.node-teaser h2.node-title {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
}
|
||||
/* line 282, jee.scss */
|
||||
/* line 388, jee.scss */
|
||||
#main .node-chapitre.node-teaser .field-name-field-comprendre {
|
||||
min-width: 16em;
|
||||
}
|
||||
/* line 283, jee.scss */
|
||||
/* line 389, jee.scss */
|
||||
#main .node-chapitre.node-teaser .field-name-field-comprendre h1, #main .node-chapitre.node-teaser .field-name-field-comprendre h2, #main .node-chapitre.node-teaser .field-name-field-comprendre h3, #main .node-chapitre.node-teaser .field-name-field-comprendre h4, #main .node-chapitre.node-teaser .field-name-field-comprendre h5, #main .node-chapitre.node-teaser .field-name-field-comprendre h6 {
|
||||
display: none !important;
|
||||
}
|
||||
/* line 285, jee.scss */
|
||||
/* line 391, jee.scss */
|
||||
#main .node-chapitre.node-teaser .field-name-field-comprendre p {
|
||||
margin: 0;
|
||||
}
|
||||
/* line 289, jee.scss */
|
||||
/* line 395, jee.scss */
|
||||
#main .node-chapitre.node-teaser ul.links {
|
||||
display: block;
|
||||
margin: 0;
|
||||
@@ -4139,11 +4337,11 @@ div.messages {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
/* line 291, jee.scss */
|
||||
/* line 397, jee.scss */
|
||||
#main .node-chapitre.node-teaser ul.links li.node-readmore {
|
||||
padding: 0;
|
||||
}
|
||||
/* line 293, jee.scss */
|
||||
/* line 399, jee.scss */
|
||||
#main .node-chapitre.node-teaser ul.links li.node-readmore a {
|
||||
display: inline-block;
|
||||
height: 25px;
|
||||
@@ -4152,14 +4350,15 @@ div.messages {
|
||||
color: #000 !important;
|
||||
width: 8em;
|
||||
text-align: left;
|
||||
background: transparent url(../assets/img/readmore-btn.svg) no-repeat right center;
|
||||
background: transparent url("../assets/img/readmore-btn.png") no-repeat right center;
|
||||
background: none, url("../assets/img/readmore-btn.svg") no-repeat right center;
|
||||
}
|
||||
/* line 305, jee.scss */
|
||||
/* line 412, jee.scss */
|
||||
#main .node-chapitre.node-teaser .field-name-field-partie {
|
||||
clear: both;
|
||||
padding-top: 1em;
|
||||
}
|
||||
/* line 309, jee.scss */
|
||||
/* line 416, jee.scss */
|
||||
#main .node-chapitre.node-teaser .field-name-field-vignette {
|
||||
position: relative;
|
||||
float: left;
|
||||
@@ -4169,31 +4368,29 @@ div.messages {
|
||||
margin-bottom: 0;
|
||||
margin-left: 0;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-origin: center center;
|
||||
}
|
||||
/* line 322, jee.scss */
|
||||
/* line 429, jee.scss */
|
||||
#main .node-chapitre.node-teaser .field-type-text {
|
||||
min-width: 16em;
|
||||
}
|
||||
/* line 323, jee.scss */
|
||||
/* line 430, jee.scss */
|
||||
#main .node-chapitre.node-teaser .field-name-field-titre {
|
||||
font-family: "epflul";
|
||||
font-size: 1.6em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
/* line 328, jee.scss */
|
||||
/* line 435, jee.scss */
|
||||
#main .node-chapitre.node-teaser .field-name-field-sous-titre {
|
||||
font-family: "epflul";
|
||||
font-size: 1.4em;
|
||||
line-height: 1.2;
|
||||
}
|
||||
/* line 333, jee.scss */
|
||||
/* line 440, jee.scss */
|
||||
#main .node-chapitre.node-teaser .field-name-field-description {
|
||||
font-size: 0.88em;
|
||||
line-height: 1.2;
|
||||
}
|
||||
/* line 339, jee.scss */
|
||||
/* line 446, jee.scss */
|
||||
#main .node-chapitre.node-teaser .line {
|
||||
z-index: -1;
|
||||
position: absolute;
|
||||
@@ -4203,150 +4400,9 @@ div.messages {
|
||||
-ms-transform-origin: top left;
|
||||
transform-origin: top left;
|
||||
width: 2px;
|
||||
background-color: red;
|
||||
opacity: 0.4;
|
||||
}
|
||||
/* line 358, jee.scss */
|
||||
#main #node-2::after {
|
||||
background-image: url(../assets/img/bgd-sol.svg);
|
||||
}
|
||||
/* line 359, jee.scss */
|
||||
#main #node-2, #main #node-2 a {
|
||||
color: #b24c14;
|
||||
}
|
||||
/* line 360, jee.scss */
|
||||
#main #node-2 h2.node-title, #main #node-2 h2.node-title a {
|
||||
color: #d85509;
|
||||
}
|
||||
/* line 361, jee.scss */
|
||||
#main #node-2 .field-name-field-vignette {
|
||||
background-image: url(../assets/img/shadow-sol.svg);
|
||||
}
|
||||
/* line 362, jee.scss */
|
||||
#main #node-2 .line {
|
||||
background-color: #ea5b0c;
|
||||
}
|
||||
/* line 366, jee.scss */
|
||||
#main #node-3::after {
|
||||
background-image: url(../assets/img/bgd-dph.svg);
|
||||
}
|
||||
/* line 367, jee.scss */
|
||||
#main #node-3, #main #node-3 a {
|
||||
color: #686b00;
|
||||
}
|
||||
/* line 368, jee.scss */
|
||||
#main #node-3 h2.node-title, #main #node-3 h2.node-title a {
|
||||
color: #afaf00;
|
||||
}
|
||||
/* line 369, jee.scss */
|
||||
#main #node-3 .field-name-field-vignette {
|
||||
background-image: url(../assets/img/shadow-dph.svg);
|
||||
}
|
||||
/* line 370, jee.scss */
|
||||
#main #node-3 .line {
|
||||
background-color: #cecd00;
|
||||
}
|
||||
/* line 374, jee.scss */
|
||||
#main #node-4::after {
|
||||
background-image: url(../assets/img/bgd-sub.svg);
|
||||
}
|
||||
/* line 375, jee.scss */
|
||||
#main #node-4, #main #node-4 a {
|
||||
color: #b71330;
|
||||
}
|
||||
/* line 376, jee.scss */
|
||||
#main #node-4 h2.node-title, #main #node-4 h2.node-title a {
|
||||
color: #cd0734;
|
||||
}
|
||||
/* line 377, jee.scss */
|
||||
#main #node-4 .field-name-field-vignette {
|
||||
background-image: url(../assets/img/shadow-sub.svg);
|
||||
}
|
||||
/* line 378, jee.scss */
|
||||
#main #node-4 .line {
|
||||
background-color: #de003a;
|
||||
}
|
||||
/* line 382, jee.scss */
|
||||
#main #node-5::after {
|
||||
background-image: url(../assets/img/bgd-bc.svg);
|
||||
}
|
||||
/* line 383, jee.scss */
|
||||
#main #node-5, #main #node-5 a {
|
||||
color: #033d6f;
|
||||
}
|
||||
/* line 384, jee.scss */
|
||||
#main #node-5 h2.node-title, #main #node-5 h2.node-title a {
|
||||
color: #024b87;
|
||||
}
|
||||
/* line 385, jee.scss */
|
||||
#main #node-5 .field-name-field-vignette {
|
||||
background-image: url(../assets/img/shadow-bc.svg);
|
||||
}
|
||||
/* line 386, jee.scss */
|
||||
#main #node-5 .line {
|
||||
background-color: #0066b1;
|
||||
}
|
||||
/* line 390, jee.scss */
|
||||
#main #node-6::after {
|
||||
background-image: url(../assets/img/bgd-opp.svg);
|
||||
}
|
||||
/* line 391, jee.scss */
|
||||
#main #node-6, #main #node-6 a {
|
||||
color: #7f1965;
|
||||
}
|
||||
/* line 392, jee.scss */
|
||||
#main #node-6 h2.node-title, #main #node-6 h2.node-title a {
|
||||
color: #941b80;
|
||||
}
|
||||
/* line 393, jee.scss */
|
||||
#main #node-6 .field-name-field-vignette {
|
||||
background-image: url(../assets/img/shadow-opp.svg);
|
||||
}
|
||||
/* line 394, jee.scss */
|
||||
#main #node-6 .line {
|
||||
background-color: #af1380;
|
||||
}
|
||||
/* line 398, jee.scss */
|
||||
#main #node-7::after {
|
||||
background-image: url(../assets/img/bgd-dub.svg);
|
||||
}
|
||||
/* line 399, jee.scss */
|
||||
#main #node-7, #main #node-7 a {
|
||||
color: #22742c;
|
||||
}
|
||||
/* line 400, jee.scss */
|
||||
#main #node-7 h2.node-title, #main #node-7 h2.node-title a {
|
||||
color: #288d80;
|
||||
}
|
||||
/* line 401, jee.scss */
|
||||
#main #node-7 .field-name-field-vignette {
|
||||
background-image: url(../assets/img/shadow-dub.svg);
|
||||
}
|
||||
/* line 402, jee.scss */
|
||||
#main #node-7 .line {
|
||||
background-color: #62a530;
|
||||
}
|
||||
/* line 406, jee.scss */
|
||||
#main #node-8::after {
|
||||
background-image: url(../assets/img/bgd-juso.svg);
|
||||
}
|
||||
/* line 407, jee.scss */
|
||||
#main #node-8, #main #node-8 a {
|
||||
color: #0b7f8a;
|
||||
}
|
||||
/* line 408, jee.scss */
|
||||
#main #node-8 h2.node-title, #main #node-8 h2.node-title a {
|
||||
color: #009aa8;
|
||||
}
|
||||
/* line 409, jee.scss */
|
||||
#main #node-8 .field-name-field-vignette {
|
||||
background-image: url(../assets/img/shadow-juso.svg);
|
||||
}
|
||||
/* line 410, jee.scss */
|
||||
#main #node-8 .line {
|
||||
background-color: #33b4b5;
|
||||
}
|
||||
/* line 413, jee.scss */
|
||||
/* line 457, jee.scss */
|
||||
#main .chapter-wrapper {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@@ -4361,13 +4417,13 @@ div.messages {
|
||||
/ __/ / /_/ / /_/ / / / / /___/ _, _/
|
||||
/_/ \____/\____/ /_/ /_____/_/ |_|
|
||||
*/
|
||||
/* line 426, jee.scss */
|
||||
/* line 470, jee.scss */
|
||||
#footer {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
/* line 429, jee.scss */
|
||||
/* line 473, jee.scss */
|
||||
#footer .block {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
@@ -4380,7 +4436,7 @@ div.messages {
|
||||
/ / / // / ___/ / /___
|
||||
/_/ /_/___//____/\____/
|
||||
*/
|
||||
/* line 441, jee.scss */
|
||||
/* line 485, jee.scss */
|
||||
#fullscreen-btn {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
@@ -4388,13 +4444,51 @@ div.messages {
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
/* line 499, jee.scss */
|
||||
.bubble-1 {
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
display: block;
|
||||
width: 425px;
|
||||
height: 425px;
|
||||
background: transparent url("../assets/img/bubble-01.png") no-repeat center center;
|
||||
background: none, url("../assets/img/bubble-01.svg") no-repeat center center;
|
||||
top: -200px;
|
||||
left: -200px;
|
||||
}
|
||||
|
||||
/* line 503, jee.scss */
|
||||
.bubble-2 {
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
display: block;
|
||||
width: 885px;
|
||||
height: 885px;
|
||||
background: transparent url("../assets/img/bubble-02.png") no-repeat center center;
|
||||
background: none, url("../assets/img/bubble-02.svg") no-repeat center center;
|
||||
bottom: -400px;
|
||||
right: -400px;
|
||||
}
|
||||
|
||||
/* line 508, jee.scss */
|
||||
.star {
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
display: block;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
opacity: 1;
|
||||
background: transparent url("../assets/img/star.png") no-repeat center center;
|
||||
background: none, url("../assets/img/star.svg") no-repeat center center;
|
||||
}
|
||||
|
||||
/* ____ __________ __ ________
|
||||
/ __ \/ ____/ __ )/ / / / ____/
|
||||
/ / / / __/ / __ / / / / / __
|
||||
/ /_/ / /___/ /_/ / /_/ / /_/ /
|
||||
/_____/_____/_____/\____/\____/
|
||||
*/
|
||||
/* line 454, jee.scss */
|
||||
/* line 522, jee.scss */
|
||||
#fps {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
@@ -4402,7 +4496,7 @@ div.messages {
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
/* line 460, jee.scss */
|
||||
/* line 528, jee.scss */
|
||||
#nav-cursor {
|
||||
position: absolute;
|
||||
width: 6px;
|
||||
|
||||
@@ -25,6 +25,24 @@ $column-gutter: rem-calc(20);
|
||||
@import "misc.scss";
|
||||
|
||||
|
||||
/*
|
||||
__ ________ __ _____ _______
|
||||
/ |/ / _/ |/ // _/ | / / ___/
|
||||
/ /|_/ // / | / / // |/ /\__ \
|
||||
/ / / // / / |_/ // /| /___/ /
|
||||
/_/ /_/___//_/|_/___/_/ |_//____/
|
||||
*/
|
||||
@mixin bg-svg-png($img, $r:no-repeat, $x:center, $y:center) {
|
||||
background: transparent url('../assets/img/#{$img}.png') $r $x $y;
|
||||
background: none, url('../assets/img/#{$img}.svg') $r $x $y;
|
||||
}
|
||||
/*
|
||||
___ ____ ____
|
||||
/ | / __ \/ __ \
|
||||
/ /| | / /_/ / /_/ /
|
||||
/ ___ |/ ____/ ____/
|
||||
/_/ |_/_/ /_/
|
||||
*/
|
||||
html{
|
||||
position:relative;
|
||||
// overflow:hidden;
|
||||
@@ -89,6 +107,7 @@ body{
|
||||
$animeLogoDuration:8s;
|
||||
|
||||
#header{
|
||||
z-index:1;
|
||||
position:absolute;
|
||||
overflow:hidden;
|
||||
width:700px;
|
||||
@@ -115,19 +134,21 @@ $animeLogoDuration:8s;
|
||||
opacity:0;
|
||||
}
|
||||
&:before{
|
||||
background: transparent url('../assets/img/logo.svg') no-repeat center center;
|
||||
@include bg-svg-png('logo');
|
||||
animation: introLogo $animeLogoDuration linear 0s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&:after{
|
||||
background: transparent url('../assets/img/logo-blured.svg') no-repeat center center;
|
||||
// background: transparent url('../assets/img/logo-blured.svg') no-repeat center center;
|
||||
@include bg-svg-png('logo-blured');
|
||||
animation: introLogoBlured $animeLogoDuration linear 0s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
}
|
||||
|
||||
h2{
|
||||
background: transparent url('../assets/img/slogan.svg') no-repeat center center;
|
||||
// background: transparent url('../assets/img/slogan.svg') no-repeat center center;
|
||||
@include bg-svg-png('slogan');
|
||||
position:absolute;
|
||||
width:100%; height:100%;
|
||||
a{display:block;margin-top:-500%;}
|
||||
@@ -156,7 +177,79 @@ div.messages{
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
_____ _____ __ _____ _____ _____ _____ __ __ _____ _____ ____ _____
|
||||
| | | | | | __ | __| | __ | | | | | | | \| __|
|
||||
| --| | | |__| | | -|__ | | __ -|_ _| | | | | | | | | __|
|
||||
|_____|_____|_____|_____|__|__|_____| |_____| |_| |_|___|_____|____/|_____|
|
||||
*/
|
||||
//SOL
|
||||
#node-2{
|
||||
&::after{ @include bg-svg-png('bgd-sol');}
|
||||
&, a{color:$SOL-col-txt;}
|
||||
h2.node-title{&,a{color:$SOL-color;}}
|
||||
.field-name-field-vignette{@include bg-svg-png('shadow-sol');}
|
||||
.line{background-color:$SOL-col-active;}
|
||||
}
|
||||
//DPH
|
||||
#node-3{
|
||||
&::after{ @include bg-svg-png('bgd-dph');}
|
||||
&, a{color:$DPH-col-txt;}
|
||||
h2.node-title{&,a{color:$DPH-color;}}
|
||||
.field-name-field-vignette{@include bg-svg-png('shadow-dph');}
|
||||
.line{background-color:$DPH-col-active;}
|
||||
}
|
||||
// SUB
|
||||
#node-4{
|
||||
&::after{ @include bg-svg-png('bgd-sub');}
|
||||
&, a{color:$SUB-col-txt;}
|
||||
h2.node-title{&,a{color:$SUB-color;}}
|
||||
.field-name-field-vignette{@include bg-svg-png('shadow-sub');}
|
||||
.line{background-color:$SUB-col-active;}
|
||||
}
|
||||
// BC
|
||||
#node-5{
|
||||
&::after{ @include bg-svg-png('bgd-bc');}
|
||||
&, a{color:$BC-col-txt;}
|
||||
h2.node-title{&,a{color:$BC-color;}}
|
||||
.field-name-field-vignette{@include bg-svg-png('shadow-bc');}
|
||||
.line{background-color:$BC-col-active;}
|
||||
}
|
||||
//OPP
|
||||
#node-6{
|
||||
&::after{ @include bg-svg-png('bgd-opp');}
|
||||
&, a{color:$OPP-col-txt;}
|
||||
h2.node-title{&,a{color:$OPP-color;}}
|
||||
.field-name-field-vignette{@include bg-svg-png('shadow-opp');}
|
||||
.line{background-color:$OPP-col-active;}
|
||||
}
|
||||
//DUB
|
||||
#node-7{
|
||||
&::after{ @include bg-svg-png('bgd-dub');}
|
||||
&, a{color:$DUB-col-txt;}
|
||||
h2.node-title{&,a{color:$DUB-color;}}
|
||||
.field-name-field-vignette{@include bg-svg-png('shadow-dub');}
|
||||
.line{background-color:$DUB-col-active;}
|
||||
}
|
||||
// JUSO
|
||||
#node-8{
|
||||
&::after{ @include bg-svg-png('bgd-juso');}
|
||||
&, a{color:$JUSO-col-txt;}
|
||||
h2.node-title{&,a{color:$JUSO-color;}}
|
||||
.field-name-field-vignette{@include bg-svg-png('shadow-juso');}
|
||||
.line{background-color:$JUSO-col-active;}
|
||||
}
|
||||
|
||||
/*
|
||||
_____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____
|
||||
| | | | _ | _ |_ _| __| __ | __| | __| __| | | __| __ | | | | | __|
|
||||
| --| | | __| | | | __| -|__ | | | | __| | | | __| -|- -| | | | | __|
|
||||
|_____|__|__|__|__|__| |_| |_____|__|__|_____| |_____|_____|_|___|_____|__|__|_____|__ _|_____|_____|
|
||||
|__|
|
||||
*/
|
||||
.node-chapitre.node-teaser{
|
||||
z-index: 2;
|
||||
position:absolute;
|
||||
|
||||
/*
|
||||
@@ -174,6 +267,10 @@ div.messages{
|
||||
|____/|_____|__| |__|__|_____|_____|_| |_|_|_|_____|____/|_____|
|
||||
|
||||
*/
|
||||
opacity:1;
|
||||
transition:1s ease-out;
|
||||
transition-property:opacity;
|
||||
|
||||
h2.node-title{
|
||||
transform:none;
|
||||
transform-origin:bottom center;
|
||||
@@ -225,6 +322,7 @@ div.messages{
|
||||
|
||||
*/
|
||||
&.previewed{
|
||||
z-index:100;
|
||||
&:after{
|
||||
opacity:1;
|
||||
$pad:-2em;
|
||||
@@ -241,6 +339,15 @@ div.messages{
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
_____ _____ _____ _____ _____ _____ _____ _____ _____ _____ ____ _____
|
||||
| | |_ _| | __| _ |_ _| __| | | | \| __|
|
||||
| | | |- -| | | |- -| | | | | | | __| | | | | | | | | __|
|
||||
|_|_|_|_____| |_| |_____|_____|__|__| |_| |_____| |_|_|_|_____|____/|_____|
|
||||
*/
|
||||
&.mitigated{
|
||||
opacity:0.3;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@@ -253,8 +360,7 @@ div.messages{
|
||||
*/
|
||||
&:after{ // background
|
||||
content:" ";
|
||||
background-size:contain;
|
||||
background-repeat: no-repeat;
|
||||
background-size:contain!important;
|
||||
position:absolute;
|
||||
z-index:-1;
|
||||
}
|
||||
@@ -297,7 +403,8 @@ div.messages{
|
||||
font-weight: 900;
|
||||
color:#000!important;
|
||||
width:8em; text-align: left;
|
||||
background: transparent url(../assets/img/readmore-btn.svg) no-repeat right center;
|
||||
// background: transparent url(../assets/img/readmore-btn.svg) no-repeat right center;
|
||||
@include bg-svg-png('readmore-btn', no-repeat, right, center);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -316,8 +423,8 @@ div.messages{
|
||||
margin-bottom:0;
|
||||
margin-left:0;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-origin: center center;
|
||||
// background-repeat: no-repeat;
|
||||
// background-origin: center center;
|
||||
}
|
||||
.field-type-text{ min-width:16em; }
|
||||
.field-name-field-titre{
|
||||
@@ -341,75 +448,12 @@ div.messages{
|
||||
position:absolute;
|
||||
top:$shadow-size - 0.5em; left:$shadow-size+2.5em;
|
||||
transform-origin:top left;
|
||||
width:2px; background-color:red;
|
||||
width:2px; //background-color:red;
|
||||
opacity:0.4;
|
||||
}
|
||||
|
||||
} // node-chapitre
|
||||
|
||||
/*
|
||||
_____ _____ __ _____ _____ _____ _____ __ __ _____ _____ ____ _____
|
||||
| | | | | | __ | __| | __ | | | | | | | \| __|
|
||||
| --| | | |__| | | -|__ | | __ -|_ _| | | | | | | | | __|
|
||||
|_____|_____|_____|_____|__|__|_____| |_____| |_| |_|___|_____|____/|_____|
|
||||
*/
|
||||
//SOL
|
||||
#node-2{
|
||||
&::after{ background-image : url(../assets/img/bgd-sol.svg); }
|
||||
&, a{color:$SOL-col-txt;}
|
||||
h2.node-title{&,a{color:$SOL-color;}}
|
||||
.field-name-field-vignette{ background-image:url(../assets/img/shadow-sol.svg); }
|
||||
.line{background-color:$SOL-col-active;}
|
||||
}
|
||||
//DPH
|
||||
#node-3{
|
||||
&::after{ background-image : url(../assets/img/bgd-dph.svg); }
|
||||
&, a{color:$DPH-col-txt;}
|
||||
h2.node-title{&,a{color:$DPH-color;}}
|
||||
.field-name-field-vignette{ background-image:url(../assets/img/shadow-dph.svg); }
|
||||
.line{background-color:$DPH-col-active;}
|
||||
}
|
||||
// SUB
|
||||
#node-4{
|
||||
&::after{ background-image : url(../assets/img/bgd-sub.svg); }
|
||||
&, a{color:$SUB-col-txt;}
|
||||
h2.node-title{&,a{color:$SUB-color;}}
|
||||
.field-name-field-vignette{ background-image:url(../assets/img/shadow-sub.svg); }
|
||||
.line{background-color:$SUB-col-active;}
|
||||
}
|
||||
// BC
|
||||
#node-5{
|
||||
&::after{ background-image : url(../assets/img/bgd-bc.svg); }
|
||||
&, a{color:$BC-col-txt;}
|
||||
h2.node-title{&,a{color:$BC-color;}}
|
||||
.field-name-field-vignette{ background-image:url(../assets/img/shadow-bc.svg); }
|
||||
.line{background-color:$BC-col-active;}
|
||||
}
|
||||
//OPP
|
||||
#node-6{
|
||||
&::after{ background-image : url(../assets/img/bgd-opp.svg); }
|
||||
&, a{color:$OPP-col-txt;}
|
||||
h2.node-title{&,a{color:$OPP-color;}}
|
||||
.field-name-field-vignette{ background-image:url(../assets/img/shadow-opp.svg); }
|
||||
.line{background-color:$OPP-col-active;}
|
||||
}
|
||||
//DUB
|
||||
#node-7{
|
||||
&::after{ background-image : url(../assets/img/bgd-dub.svg); }
|
||||
&, a{color:$DUB-col-txt;}
|
||||
h2.node-title{&,a{color:$DUB-color;}}
|
||||
.field-name-field-vignette{ background-image:url(../assets/img/shadow-dub.svg); }
|
||||
.line{background-color:$DUB-col-active;}
|
||||
}
|
||||
// JUSO
|
||||
#node-8{
|
||||
&::after{ background-image : url(../assets/img/bgd-juso.svg); }
|
||||
&, a{color:$JUSO-col-txt;}
|
||||
h2.node-title{&,a{color:$JUSO-color;}}
|
||||
.field-name-field-vignette{ background-image:url(../assets/img/shadow-juso.svg); }
|
||||
.line{background-color:$JUSO-col-active;}
|
||||
}
|
||||
|
||||
.chapter-wrapper{
|
||||
position:absolute;
|
||||
top:0; left:0; bottom:0; right:0;
|
||||
@@ -444,6 +488,30 @@ div.messages{
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
@mixin bubble($w,$h,$bg){
|
||||
position:absolute;
|
||||
z-index:0;
|
||||
display:block;
|
||||
width:$w; height:$h;
|
||||
// border:1px solid blue;
|
||||
@include bg-svg-png($bg);
|
||||
}
|
||||
.bubble-1{
|
||||
@include bubble(425px, 425px, 'bubble-01');
|
||||
top:-200px; left:-200px;
|
||||
}
|
||||
.bubble-2{
|
||||
@include bubble(885px, 885px, 'bubble-02');
|
||||
bottom:-400px; right:-400px;
|
||||
}
|
||||
|
||||
.star{
|
||||
position:absolute;
|
||||
z-index: 0; display:block;
|
||||
width:10px; height:10px;
|
||||
opacity:1;
|
||||
@include bg-svg-png('star');
|
||||
}
|
||||
/* ____ __________ __ ________
|
||||
/ __ \/ ____/ __ )/ / / / ____/
|
||||
/ / / / __/ / __ / / / / / __
|
||||
|
||||
@@ -30,10 +30,15 @@ jQuery(document).ready(function($) {
|
||||
},
|
||||
_center = {x:_container.w/2,y:_container.h/2},
|
||||
_nav_pos = {x:0, y:0},
|
||||
_mouse_down_pos = {x:0,y:0},
|
||||
_prev_mouse_pos = {x:0,y:0},
|
||||
_fps = 1000/12,
|
||||
_dragging = false, _timeout_dragging;
|
||||
|
||||
var _bubbles = new Array(),
|
||||
_stars = new Array();
|
||||
|
||||
|
||||
function init(){
|
||||
if(_debug)
|
||||
initDebug();
|
||||
@@ -47,6 +52,22 @@ jQuery(document).ready(function($) {
|
||||
// launchIntoFullscreen(document.documentElement); // the whole page
|
||||
launchIntoFullscreen(document.getElementById("root")); // any individual element
|
||||
});
|
||||
|
||||
for (var i = 2; i > 0; i--) {
|
||||
_bubbles.push($('<div>').addClass('bubble bubble-'+i).prependTo(_$container));
|
||||
};
|
||||
|
||||
for (var i = 20; i > 0; i--) {
|
||||
_stars.push(
|
||||
$('<div>')
|
||||
.addClass('star star-'+i)
|
||||
.css({
|
||||
left:randB(-400, _container.w+400),
|
||||
top:randB(-400, _container.h+400)
|
||||
})
|
||||
.prependTo(_$container)
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
function initDebug(){
|
||||
@@ -88,11 +109,18 @@ jQuery(document).ready(function($) {
|
||||
function launchNav(){
|
||||
|
||||
$(document)
|
||||
// DESKTOP EVENTS
|
||||
/*
|
||||
____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____
|
||||
| \| __| __| | |_ _| | _ | | __| | | __| | |_ _| __|
|
||||
| | | __|__ | -| | | | | | __| | __| | | __| | | | | | |__ |
|
||||
|____/|_____|_____|__|__| |_| |_____|__| |_____|\___/|_____|_|___| |_| |_____|
|
||||
*/
|
||||
.bind('mousedown', function(e){
|
||||
console.log('mousedown');
|
||||
clearTimeout(_timeout_dragging);
|
||||
// set initial cursor pos
|
||||
_mouse_down_pos.x = e.clientX;
|
||||
_mouse_down_pos.y = e.clientY;
|
||||
updateNavPos(e.clientX, e.clientY, true);
|
||||
|
||||
$(this).bind('mousemove', function(e){
|
||||
@@ -103,17 +131,25 @@ jQuery(document).ready(function($) {
|
||||
// activate dragging if already activated
|
||||
if(!_dragging){
|
||||
_dragging = true;
|
||||
window.requestAnimationFrame(moveNav);
|
||||
startMoveNav();
|
||||
}
|
||||
})
|
||||
.bind('mouseup', function(e){
|
||||
console.log('mouseup');
|
||||
stopMoveNav();
|
||||
$(this).unbind('mousemove');
|
||||
// close all preview
|
||||
if(Math.abs(e.clientX - _mouse_down_pos.x) < 2
|
||||
&& Math.abs(e.clientY - _mouse_down_pos.y) < 2)
|
||||
for (var i = _chapitres_len - 1; i >= 0; i--)
|
||||
_chapters[i].closePreview().unMitigate();
|
||||
})
|
||||
//
|
||||
// TOUCH EVENTS - - - - - - - - - - - - - -
|
||||
//
|
||||
/*
|
||||
_____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____
|
||||
|_ _| | | | | | | | __| | | __| | |_ _| __|
|
||||
| | | | | | | --| | | __| | | __| | | | | | |__ |
|
||||
|_| |_____|_____|_____|__|__| |_____|\___/|_____|_|___| |_| |_____|
|
||||
*/
|
||||
.bind('touchstart', function(e){
|
||||
console.log('touchstart');
|
||||
clearTimeout(_timeout_dragging);
|
||||
@@ -123,7 +159,7 @@ jQuery(document).ready(function($) {
|
||||
// activate dragging if already activated
|
||||
if(!_dragging){
|
||||
_dragging = true;
|
||||
window.requestAnimationFrame(moveNav);
|
||||
startMoveNav();
|
||||
}
|
||||
})
|
||||
.bind('touchmove', function(e){
|
||||
@@ -141,15 +177,15 @@ jQuery(document).ready(function($) {
|
||||
_nav_pos.x += x - _prev_mouse_pos.x;
|
||||
_nav_pos.y += y - _prev_mouse_pos.y;
|
||||
// constrain nav pos on container
|
||||
_nav_pos.x = _nav_pos.x < -_center.x
|
||||
? -_center.x
|
||||
: _nav_pos.x > _center.x
|
||||
? _center.x
|
||||
_nav_pos.x = _nav_pos.x < -_center.x*2
|
||||
? -_center.x*2
|
||||
: _nav_pos.x > _center.x*2
|
||||
? _center.x*2
|
||||
: _nav_pos.x;
|
||||
_nav_pos.y = _nav_pos.y < -_center.y
|
||||
? -_center.y
|
||||
: _nav_pos.y > _center.y
|
||||
? _center.y
|
||||
_nav_pos.y = _nav_pos.y < -_center.y*2
|
||||
? -_center.y*2
|
||||
: _nav_pos.y > _center.y*2
|
||||
? _center.y*2
|
||||
: _nav_pos.y;
|
||||
}
|
||||
_prev_mouse_pos.x = x;
|
||||
@@ -160,6 +196,10 @@ jQuery(document).ready(function($) {
|
||||
moveDebugCursor();
|
||||
};
|
||||
|
||||
function startMoveNav(){
|
||||
window.requestAnimationFrame(moveNav);
|
||||
};
|
||||
|
||||
function moveNav(){
|
||||
// console.log("moveNav");
|
||||
if(!_dragging) return;
|
||||
@@ -174,6 +214,23 @@ jQuery(document).ready(function($) {
|
||||
_$header.css({
|
||||
transform:"translate3d("+(_nav_pos.x)*0.2+"px, "+(_nav_pos.y)*0.2+"px,0)"
|
||||
});
|
||||
|
||||
// bubbles and stars dont move so smoothly on tablette ...
|
||||
// should keep it only on desktop
|
||||
|
||||
// move bubbles
|
||||
// for (var i = _bubbles.length - 1; i >= 0; i--) {
|
||||
// _bubbles[i].css({
|
||||
// transform:"translate3d("+(_nav_pos.x)*0.4+"px, "+(_nav_pos.y)*0.4+"px,0)"
|
||||
// });
|
||||
// };
|
||||
|
||||
// move stars
|
||||
// for (var i = _stars.length - 1; i >= 0; i--) {
|
||||
// _stars[i].css({
|
||||
// transform:"translate3d("+(_nav_pos.x)*-0.3+"px, "+(_nav_pos.y)*-0.3+"px,0)"
|
||||
// });
|
||||
// };
|
||||
};
|
||||
|
||||
function stopMoveNav(){
|
||||
@@ -185,6 +242,20 @@ jQuery(document).ready(function($) {
|
||||
},3000);
|
||||
};
|
||||
|
||||
function moveToChapter(chapter){
|
||||
|
||||
// fake a mousdown by providing first pos as current pos
|
||||
_prev_mouse_pos.x = _nav_pos.x;
|
||||
_prev_mouse_pos.y = _nav_pos.y;
|
||||
|
||||
// calculate the second pos of faked mousemove
|
||||
var xl = _center.x - chapter.pos.x - chapter.geom.w/2;
|
||||
var yl = 100 - chapter.pos.y;
|
||||
updateNavPos(xl, yl, false);
|
||||
startMoveNav();
|
||||
stopMoveNav();
|
||||
};
|
||||
|
||||
/*
|
||||
________ __
|
||||
/ ____/ /_ ____ _____ / /____ _____
|
||||
@@ -200,19 +271,23 @@ jQuery(document).ready(function($) {
|
||||
this.e = e;
|
||||
this.$e = $(e);
|
||||
this.nid = this.$e.attr("id").match(/^node-(\d+)/)[1];
|
||||
this.$backdom = $('<div>').attr('id', 'backdom-'+this.nid).addClass('backdom').appendTo(_$body);
|
||||
this.geom = {
|
||||
base_a:base_a,
|
||||
a:0,
|
||||
r:0
|
||||
r:0,
|
||||
w:this.$e.outerWidth(true),
|
||||
h:this.$e.outerHeight(true)
|
||||
}
|
||||
this.pos = {x:0,y:0};
|
||||
this.trans = {x:0, y:0};
|
||||
this.trans = {x:0, y:0,z:0};
|
||||
this.ease = randB(0.05, 0.3);
|
||||
|
||||
//preview
|
||||
this.is_previewed = false;
|
||||
|
||||
//mitigate
|
||||
this.is_mitigated = false;
|
||||
|
||||
//parties
|
||||
this.$parties = $('.field-name-field-partie', e);
|
||||
this.parts_pos = {xs:new Array(), ys:new Array()};
|
||||
@@ -248,10 +323,14 @@ jQuery(document).ready(function($) {
|
||||
}
|
||||
|
||||
// change randomly radius
|
||||
this.geom.r = randB(this.geom.r, this.geom.r*2);
|
||||
if(this.i%2){
|
||||
this.geom.r = randB(this.geom.r*2, this.geom.r*3);
|
||||
}else{
|
||||
this.geom.r = randB(this.geom.r, this.geom.r*2);
|
||||
}
|
||||
|
||||
this.pos.x = Math.round(_center.x+this.geom.r * this.geom.c) - this.$e.outerWidth(true)/2;
|
||||
this.pos.y = Math.round(_center.y+this.geom.r * -this.geom.s) - this.$e.outerHeight(true)/2;
|
||||
this.pos.x = Math.round(_center.x+this.geom.r * this.geom.c) - this.geom.w/2;
|
||||
this.pos.y = Math.round(_center.y+this.geom.r * -this.geom.s) - this.geom.h/2;
|
||||
|
||||
console.log('this', this);
|
||||
this.$e.css({
|
||||
@@ -265,6 +344,7 @@ jQuery(document).ready(function($) {
|
||||
// click to preview chapter
|
||||
$('h2.node-title, .field-name-field-partie:first>.field-name-field-vignette', this.$e)
|
||||
.on('click', this, function(e){
|
||||
// e.stopImmediatePropagation();
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
e.data.preview(e);
|
||||
@@ -284,25 +364,48 @@ jQuery(document).ready(function($) {
|
||||
this.trans.x += (_nav_pos.x - this.trans.x)*this.ease;
|
||||
this.trans.y += (_nav_pos.y - this.trans.y)*this.ease;
|
||||
|
||||
// this.trans.z = Math.floor(Math.sqrt(
|
||||
// Math.pow(
|
||||
// _center.x-(this.pos.x+this.trans.x)
|
||||
// ,2
|
||||
// )
|
||||
// +
|
||||
// Math.pow(
|
||||
// _center.y-(this.pos.y+this.trans.y)
|
||||
// ,2
|
||||
// )
|
||||
// ));
|
||||
|
||||
if(this.i === 0)
|
||||
console.log(this.i+" this.trans.z", this.trans.z);
|
||||
|
||||
this.$e.css({
|
||||
transform:'translate3d('+this.trans.x+'px,'+this.trans.y+'px,0)'
|
||||
// scale:this.trans.z
|
||||
});
|
||||
};
|
||||
|
||||
Chapter.prototype.preview = function(e){
|
||||
Chapter.prototype.preview = function(){
|
||||
// don't relaunch preview more that one time
|
||||
if(this.is_previewed) return;
|
||||
|
||||
console.log('preview', this.i);
|
||||
|
||||
this.unMitigate();
|
||||
|
||||
this.is_previewed = true;
|
||||
|
||||
// close other chapters
|
||||
for (var i = _chapitres_len - 1; i >= 0; i--) {
|
||||
for (var i = _chapitres_len - 1; i >= 0; i--)
|
||||
if(i !== this.i)
|
||||
_chapters[i].closePreview();
|
||||
};
|
||||
_chapters[i].closePreview().mitigate();
|
||||
|
||||
this.displayPreview();
|
||||
|
||||
moveToChapter(this);
|
||||
};
|
||||
|
||||
Chapter.prototype.displayPreview = function(e){
|
||||
// define randomly position of parties
|
||||
this.resetPartsPos();
|
||||
|
||||
@@ -343,11 +446,26 @@ jQuery(document).ready(function($) {
|
||||
};
|
||||
|
||||
Chapter.prototype.closePreview = function(){
|
||||
if(!this.is_previewed) return this;
|
||||
|
||||
this.$e.removeClass('previewed')
|
||||
.find('.field-name-field-partie')
|
||||
.css({transform:"none"});
|
||||
requestAnimationFrame(this.animeLines.bind(this));
|
||||
this.is_previewed = false;
|
||||
return this;
|
||||
};
|
||||
|
||||
Chapter.prototype.mitigate = function(){
|
||||
if(this.is_mitigated) return this;
|
||||
this.$e.addClass('mitigated');
|
||||
return this;
|
||||
};
|
||||
|
||||
Chapter.prototype.unMitigate = function(){
|
||||
if(this.is_mitigated) return this;
|
||||
this.$e.removeClass('mitigated');
|
||||
return this;
|
||||
};
|
||||
|
||||
Chapter.prototype.drawLines = function(){
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "Jeunes et engagés",
|
||||
"short_name": "Jee",
|
||||
// "icons": [{
|
||||
// "src": "icon/lowres",
|
||||
// "sizes": "64x64",
|
||||
// "type": "image/webp"
|
||||
// }, {
|
||||
// "src": "icon/hd_small",
|
||||
// "sizes": "64x64"
|
||||
// }, {
|
||||
// "src": "icon/hd_hi",
|
||||
// "sizes": "128x128",
|
||||
// "density": 2
|
||||
// }],
|
||||
// "scope": "/racer/",
|
||||
// "start_url": "/racer/start.html",
|
||||
"display": "fullscreen",
|
||||
"orientation": "landscape",
|
||||
"chrome": { "navigation": true }
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"curly": true,
|
||||
"eqeqeq": true,
|
||||
"immed": true,
|
||||
"latedef": true,
|
||||
"newcap": true,
|
||||
"noarg": true,
|
||||
"sub": true,
|
||||
"undef": true,
|
||||
"boss": true,
|
||||
"eqnull": true,
|
||||
"node": true,
|
||||
"es5": true,
|
||||
"globals": {
|
||||
"phantom": true,
|
||||
"window": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
node_modules
|
||||
npm-debug.log
|
||||
tmp
|
||||
@@ -0,0 +1,59 @@
|
||||
/*!
|
||||
* grunt-svg2png
|
||||
* https://github.com/dbushell/grunt-svg2png
|
||||
*
|
||||
* Copyright (c) 2013 David Bushell
|
||||
* Licensed under The MIT License (MIT)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function(grunt)
|
||||
{
|
||||
|
||||
grunt.initConfig({
|
||||
|
||||
jshint: {
|
||||
all: [
|
||||
'Gruntfile.js',
|
||||
'tasks/**/*.js',
|
||||
'<%= nodeunit.tests %>'
|
||||
],
|
||||
options: {
|
||||
jshintrc: '.jshintrc'
|
||||
}
|
||||
},
|
||||
|
||||
clean: {
|
||||
tests: ['test/**/*.png']
|
||||
},
|
||||
|
||||
nodeunit: {
|
||||
tests: ['test/*_test.js']
|
||||
},
|
||||
|
||||
svg2png: {
|
||||
all: {
|
||||
files: [
|
||||
{ cwd: 'test/svg/', src: ['**/*.svg'], dest: 'test/png/' }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
grunt.loadTasks('tasks');
|
||||
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
grunt.loadNpmTasks('grunt-contrib-clean');
|
||||
grunt.loadNpmTasks('grunt-contrib-nodeunit');
|
||||
|
||||
grunt.registerTask('unset_clearline', 'Unset stdout.clearLine for testing', function(){
|
||||
process.stdout.clearLine = undefined;
|
||||
});
|
||||
|
||||
grunt.registerTask('test', ['clean', 'svg2png', 'nodeunit']);
|
||||
grunt.registerTask('test_noterminal', ['unset_clearline', 'test']);
|
||||
grunt.registerTask('default', ['jshint', 'test']);
|
||||
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 David Bushell
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,37 @@
|
||||
grunt-svg2png
|
||||
=============
|
||||
|
||||
Grunt plugin to rasterize SVG to PNG images using PhantomJS
|
||||
|
||||
## Getting Started
|
||||
|
||||
This plugin requires [Grunt](http://gruntjs.com/) `~0.4.1`
|
||||
|
||||
````javascript
|
||||
// Gruntfile.js configuration
|
||||
grunt.loadNpmTasks('grunt-svg2png');
|
||||
|
||||
grunt.initConfig({
|
||||
svg2png: {
|
||||
all: {
|
||||
// specify files in array format with multiple src-dest mapping
|
||||
files: [
|
||||
// rasterize all SVG files in "img" and its subdirectories to "img/png"
|
||||
{ cwd: 'img/', src: ['**/*.svg'], dest: 'img/png/' }
|
||||
]
|
||||
}
|
||||
}
|
||||
});
|
||||
````
|
||||
|
||||
This task works well between [SVGO Grunt](https://github.com/svg/svgo-grunt) and [Grunt ImageOptim](https://github.com/JamieMason/grunt-imageoptim)!
|
||||
|
||||
## Updates
|
||||
|
||||
**2014-06-23** pulled in [path fix](https://github.com/dbushell/grunt-svg2png/pull/9) and option for [use case without terminal](https://github.com/dbushell/grunt-svg2png/pull/13). You may need to update your `files` config to include `cwd` and `dest` options.
|
||||
|
||||
* * *
|
||||
|
||||
Created by [David Bushell](http://dbushell.com) | [@dbushell](http://twitter.com/dbushell)
|
||||
|
||||
Copyright © 2013 David Bushell | MIT license
|
||||
@@ -0,0 +1 @@
|
||||
../phantomjs/bin/phantomjs
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
asi: false
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/node_modules
|
||||
/lib/phantom
|
||||
/lib/location.js
|
||||
/tmp
|
||||
npm-debug.log
|
||||
@@ -0,0 +1,7 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.10"
|
||||
- "0.8"
|
||||
|
||||
before_install:
|
||||
- npm install -g npm
|
||||
@@ -0,0 +1,194 @@
|
||||
Copyright 2012 The Obvious Corporation.
|
||||
http://obvious.com/
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
@@ -0,0 +1,199 @@
|
||||
phantomjs
|
||||
=========
|
||||
|
||||
An NPM wrapper for [PhantomJS](http://phantomjs.org/), headless webkit with JS API.
|
||||
|
||||
[](https://travis-ci.org/Medium/phantomjs)
|
||||
|
||||
Building and Installing
|
||||
-----------------------
|
||||
|
||||
```shell
|
||||
npm install phantomjs
|
||||
```
|
||||
|
||||
Or grab the source and
|
||||
|
||||
```shell
|
||||
node ./install.js
|
||||
```
|
||||
|
||||
What this installer is really doing is just grabbing a particular "blessed" (by
|
||||
this module) version of Phantom. As new versions of Phantom are released
|
||||
and vetted, this module will be updated accordingly.
|
||||
|
||||
The package has been set up to fetch and run Phantom for MacOS (darwin),
|
||||
Linux based platforms (as identified by nodejs), and -- as of version 0.2.0 --
|
||||
Windows (thanks to [Domenic Denicola](https://github.com/domenic)). If you
|
||||
spot any platform weirdnesses, let us know or send a patch.
|
||||
|
||||
### Custom binaries url
|
||||
To use a mirror of the phantomjs binaries use npm config property `phantomjs_cdnurl`.
|
||||
Default is `https://bitbucket.org/ariya/phantomjs/downloads`.
|
||||
|
||||
```shell
|
||||
npm install phantomjs --phantomjs_cdnurl=http://cnpmjs.org/downloads
|
||||
```
|
||||
|
||||
Or add property into your `.npmrc` file (https://www.npmjs.org/doc/files/npmrc.html)
|
||||
|
||||
```
|
||||
phantomjs_cdnurl=http://cnpmjs.org/downloads
|
||||
```
|
||||
|
||||
Another option is to use PATH variable `PHANTOMJS_CDNURL`.
|
||||
```shell
|
||||
PHANTOMJS_CDNURL=http://cnpmjs.org/downloads npm install phantomjs
|
||||
```
|
||||
|
||||
|
||||
Running
|
||||
-------
|
||||
|
||||
```shell
|
||||
bin/phantomjs [phantom arguments]
|
||||
```
|
||||
|
||||
And npm will install a link to the binary in `node_modules/.bin` as
|
||||
it is wont to do.
|
||||
|
||||
Running via node
|
||||
----------------
|
||||
|
||||
The package exports a `path` string that contains the path to the
|
||||
phantomjs binary/executable.
|
||||
|
||||
Below is an example of using this package via node.
|
||||
|
||||
```javascript
|
||||
var path = require('path')
|
||||
var childProcess = require('child_process')
|
||||
var phantomjs = require('phantomjs')
|
||||
var binPath = phantomjs.path
|
||||
|
||||
var childArgs = [
|
||||
path.join(__dirname, 'phantomjs-script.js'),
|
||||
'some other argument (passed to phantomjs script)'
|
||||
]
|
||||
|
||||
childProcess.execFile(binPath, childArgs, function(err, stdout, stderr) {
|
||||
// handle results
|
||||
})
|
||||
|
||||
```
|
||||
|
||||
Versioning
|
||||
----------
|
||||
|
||||
The major and minor number tracks the version of PhantomJS that will be
|
||||
installed. The patch number is incremented when there is either an installer
|
||||
update or a patch build of the phantom binary.
|
||||
|
||||
A Note on PhantomJS
|
||||
-------------------
|
||||
|
||||
PhantomJS is not a library for NodeJS. It's a separate environment and code
|
||||
written for node is unlikely to be compatible. In particular PhantomJS does
|
||||
not expose a Common JS package loader.
|
||||
|
||||
This is an _NPM wrapper_ and can be used to conveniently make Phantom available
|
||||
It is not a Node JS wrapper.
|
||||
|
||||
I have had reasonable experiences writing standalone Phantom scripts which I
|
||||
then drive from within a node program by spawning phantom in a child process.
|
||||
|
||||
Read the PhantomJS FAQ for more details: http://phantomjs.org/faq.html
|
||||
|
||||
### Linux Note
|
||||
|
||||
An extra note on Linux usage, from the PhantomJS download page:
|
||||
|
||||
> This package is built on CentOS 5.8. It should run successfully on Lucid or
|
||||
> more modern systems (including other distributions). There is no requirement
|
||||
> to install Qt, WebKit, or any other libraries. It is however expected that
|
||||
> some base libraries necessary for rendering (FreeType, Fontconfig) and the
|
||||
> basic font files are available in the system.
|
||||
|
||||
Troubleshooting
|
||||
---------------
|
||||
|
||||
##### Installation fails with `spawn ENOENT`
|
||||
|
||||
This is NPM's way of telling you that it was not able to start a `node` process. It usually means
|
||||
Node is not on your PATH, or otherwise not properly installed.
|
||||
|
||||
##### Installation fails with `Error: EPERM` or `operation not permitted`
|
||||
|
||||
This error means that NPM was not able to install phantomjs to the file system. There are three
|
||||
major reasons why this could happen:
|
||||
|
||||
- You don't have write access to the installation directory.
|
||||
- The permissions in the NPM cache got messed up, and you need to run `npm cache clean` to fix them.
|
||||
- You have over-zealous anti-virus software installed, and it's blocking file system writes.
|
||||
|
||||
##### Installation fails with `Error: read ECONNRESET` or `Error: connect ETIMEDOUT`
|
||||
|
||||
This error means that something went wrong with your internet connection, and the installer
|
||||
was not able to download the PhantomJS binary for your platform. Please try again.
|
||||
|
||||
##### I tried again, but I get `ECONNRESET` or `ETIMEDOUT` consistently.
|
||||
|
||||
Do you live in China, or a country with an authoritarian government? We've seen problems where
|
||||
the GFW or local ISP blocks bitbucket, preventing the installer from downloading the binary.
|
||||
|
||||
Try visiting the [the download page](http://cdn.bitbucket.org/ariya/phantomjs/downloads) manually.
|
||||
If that page is blocked, you can try using a different CDN with the `PHANTOMJS_CDNURL`
|
||||
env variable described above.
|
||||
|
||||
##### I am behind a corporate proxy that uses self-signed SSL certificates to intercept encrypted traffic.
|
||||
|
||||
You can tell NPM and the PhantomJS installer to skip validation of ssl keys with NPM's
|
||||
[strict-ssl](https://www.npmjs.org/doc/misc/npm-config.html#strict-ssl) setting:
|
||||
|
||||
```
|
||||
npm set strict-ssl false
|
||||
```
|
||||
|
||||
WARNING: Turning off `strict-ssl` leaves you vulnerable to attackers reading
|
||||
your encrypted traffic, so run this at your own risk!
|
||||
|
||||
##### I tried everything, but my network is b0rked. What do I do?
|
||||
|
||||
If you install PhantomJS manually, and put it on PATH, the installer will try to
|
||||
use the manually-installed binaries.
|
||||
|
||||
##### I'm on Debian or Ubuntu, and the installer failed because it couldn't find `node`
|
||||
|
||||
Some Linux distros tried to rename `node` to `nodejs` due to a package
|
||||
conflict. This is a non-portable change, and we do not try to support this. The
|
||||
[official documentation](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os)
|
||||
recommends that you run `apt-get install nodejs-legacy` to symlink `node` to `nodejs`
|
||||
on those platforms, or many NodeJS programs won't work properly.
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
Questions, comments, bug reports, and pull requests are all welcome. Submit them at
|
||||
[the project on GitHub](https://github.com/Obvious/phantomjs/). If you haven't contributed to an
|
||||
[Obvious](http://github.com/Obvious/) project before please head over to the
|
||||
[Open Source Project](https://github.com/Obvious/open-source#note-to-external-contributors) and fill
|
||||
out an OCLA (it should be pretty painless).
|
||||
|
||||
Bug reports that include steps-to-reproduce (including code) are the
|
||||
best. Even better, make them in the form of pull requests.
|
||||
|
||||
Author
|
||||
------
|
||||
|
||||
[Dan Pupius](https://github.com/dpup)
|
||||
([personal website](http://pupius.co.uk)), supported by
|
||||
[The Obvious Corporation](http://obvious.com/).
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
Copyright 2012 [The Obvious Corporation](http://obvious.com/).
|
||||
|
||||
Licensed under the Apache License, Version 2.0.
|
||||
See the top-level file `LICENSE.txt` and
|
||||
(http://www.apache.org/licenses/LICENSE-2.0).
|
||||
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Script that will execute the downloaded phantomjs binary. stdio are
|
||||
* forwarded to and from the child process.
|
||||
*
|
||||
* The following is for an ugly hack to avoid a problem where the installer
|
||||
* finds the bin script npm creates during global installation.
|
||||
*
|
||||
* {NPM_INSTALL_MARKER}
|
||||
*/
|
||||
|
||||
var path = require('path')
|
||||
var spawn = require('child_process').spawn
|
||||
|
||||
var binPath = require(path.join(__dirname, '..', 'lib', 'phantomjs')).path
|
||||
|
||||
var args = process.argv.slice(2)
|
||||
|
||||
// For Node 0.6 compatibility, pipe the streams manually, instead of using
|
||||
// `{ stdio: 'inherit' }`.
|
||||
var cp = spawn(binPath, args)
|
||||
cp.stdout.pipe(process.stdout)
|
||||
cp.stderr.pipe(process.stderr)
|
||||
process.stdin.pipe(cp.stdin)
|
||||
|
||||
cp.on('error', function (err) {
|
||||
console.error('Error executing phantom at', binPath)
|
||||
console.error(err.stack)
|
||||
})
|
||||
|
||||
cp.on('exit', function(code){
|
||||
// Wait few ms for error to be printed.
|
||||
setTimeout(function(){
|
||||
process.exit(code)
|
||||
}, 20)
|
||||
});
|
||||
|
||||
process.on('SIGTERM', function() {
|
||||
cp.kill('SIGTERM')
|
||||
process.exit(1)
|
||||
})
|
||||
@@ -0,0 +1,354 @@
|
||||
// Copyright 2012 The Obvious Corporation.
|
||||
|
||||
/*
|
||||
* This simply fetches the right version of phantom for the current platform.
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
|
||||
var requestProgress = require('request-progress')
|
||||
var progress = require('progress')
|
||||
var AdmZip = require('adm-zip')
|
||||
var cp = require('child_process')
|
||||
var fs = require('fs-extra')
|
||||
var helper = require('./lib/phantomjs')
|
||||
var kew = require('kew')
|
||||
var npmconf = require('npmconf')
|
||||
var path = require('path')
|
||||
var request = require('request')
|
||||
var url = require('url')
|
||||
var util = require('util')
|
||||
var which = require('which')
|
||||
|
||||
var cdnUrl = process.env.npm_config_phantomjs_cdnurl || process.env.PHANTOMJS_CDNURL || 'https://bitbucket.org/ariya/phantomjs/downloads'
|
||||
var downloadUrl = cdnUrl + '/phantomjs-' + helper.version + '-'
|
||||
|
||||
var originalPath = process.env.PATH
|
||||
|
||||
// If the process exits without going through exit(), then we did not complete.
|
||||
var validExit = false
|
||||
|
||||
process.on('exit', function () {
|
||||
if (!validExit) {
|
||||
console.log('Install exited unexpectedly')
|
||||
exit(1)
|
||||
}
|
||||
})
|
||||
|
||||
// NPM adds bin directories to the path, which will cause `which` to find the
|
||||
// bin for this package not the actual phantomjs bin. Also help out people who
|
||||
// put ./bin on their path
|
||||
process.env.PATH = helper.cleanPath(originalPath)
|
||||
|
||||
var libPath = path.join(__dirname, 'lib')
|
||||
var pkgPath = path.join(libPath, 'phantom')
|
||||
var phantomPath = null
|
||||
var tmpPath = null
|
||||
|
||||
// If the user manually installed PhantomJS, we want
|
||||
// to use the existing version.
|
||||
//
|
||||
// Do not re-use a manually-installed PhantomJS with
|
||||
// a different version.
|
||||
//
|
||||
// Do not re-use an npm-installed PhantomJS, because
|
||||
// that can lead to weird circular dependencies between
|
||||
// local versions and global versions.
|
||||
// https://github.com/Obvious/phantomjs/issues/85
|
||||
// https://github.com/Medium/phantomjs/pull/184
|
||||
var whichDeferred = kew.defer()
|
||||
which('phantomjs', whichDeferred.makeNodeResolver())
|
||||
whichDeferred.promise
|
||||
.then(function (result) {
|
||||
phantomPath = result
|
||||
|
||||
// Horrible hack to avoid problems during global install. We check to see if
|
||||
// the file `which` found is our own bin script.
|
||||
if (phantomPath.indexOf(path.join('npm', 'phantomjs')) !== -1) {
|
||||
console.log('Looks like an `npm install -g` on windows; unable to check for already installed version.')
|
||||
throw new Error('Global install')
|
||||
}
|
||||
|
||||
var contents = fs.readFileSync(phantomPath, 'utf8')
|
||||
if (/NPM_INSTALL_MARKER/.test(contents)) {
|
||||
console.log('Looks like an `npm install -g`; unable to check for already installed version.')
|
||||
throw new Error('Global install')
|
||||
} else {
|
||||
var checkVersionDeferred = kew.defer()
|
||||
cp.execFile(phantomPath, ['--version'], checkVersionDeferred.makeNodeResolver())
|
||||
return checkVersionDeferred.promise
|
||||
}
|
||||
})
|
||||
.then(function (stdout) {
|
||||
var version = stdout.trim()
|
||||
if (helper.version == version) {
|
||||
writeLocationFile(phantomPath);
|
||||
console.log('PhantomJS is already installed at', phantomPath + '.')
|
||||
exit(0)
|
||||
|
||||
} else {
|
||||
console.log('PhantomJS detected, but wrong version', stdout.trim(), '@', phantomPath + '.')
|
||||
throw new Error('Wrong version')
|
||||
}
|
||||
})
|
||||
.fail(function (err) {
|
||||
// Trying to use a local file failed, so initiate download and install
|
||||
// steps instead.
|
||||
var npmconfDeferred = kew.defer()
|
||||
npmconf.load(npmconfDeferred.makeNodeResolver())
|
||||
return npmconfDeferred.promise
|
||||
})
|
||||
.then(function (conf) {
|
||||
tmpPath = findSuitableTempDirectory(conf)
|
||||
|
||||
// Can't use a global version so start a download.
|
||||
if (process.platform === 'linux' && process.arch === 'x64') {
|
||||
downloadUrl += 'linux-x86_64.tar.bz2'
|
||||
} else if (process.platform === 'linux') {
|
||||
downloadUrl += 'linux-i686.tar.bz2'
|
||||
} else if (process.platform === 'darwin' || process.platform === 'openbsd' || process.platform === 'freebsd') {
|
||||
downloadUrl += 'macosx.zip'
|
||||
} else if (process.platform === 'win32') {
|
||||
downloadUrl += 'windows.zip'
|
||||
} else {
|
||||
console.error('Unexpected platform or architecture:', process.platform, process.arch)
|
||||
exit(1)
|
||||
}
|
||||
|
||||
var fileName = downloadUrl.split('/').pop()
|
||||
var downloadedFile = path.join(tmpPath, fileName)
|
||||
|
||||
// Start the install.
|
||||
if (!fs.existsSync(downloadedFile)) {
|
||||
console.log('Downloading', downloadUrl)
|
||||
console.log('Saving to', downloadedFile)
|
||||
return requestBinary(getRequestOptions(conf), downloadedFile)
|
||||
} else {
|
||||
console.log('Download already available at', downloadedFile)
|
||||
return downloadedFile
|
||||
}
|
||||
})
|
||||
.then(function (downloadedFile) {
|
||||
return extractDownload(downloadedFile)
|
||||
})
|
||||
.then(function (extractedPath) {
|
||||
return copyIntoPlace(extractedPath, pkgPath)
|
||||
})
|
||||
.then(function () {
|
||||
var location = process.platform === 'win32' ?
|
||||
path.join(pkgPath, 'phantomjs.exe') :
|
||||
path.join(pkgPath, 'bin' ,'phantomjs')
|
||||
var relativeLocation = path.relative(libPath, location)
|
||||
writeLocationFile(relativeLocation)
|
||||
|
||||
// Ensure executable is executable by all users
|
||||
fs.chmodSync(location, '755')
|
||||
|
||||
console.log('Done. Phantomjs binary available at', location)
|
||||
exit(0)
|
||||
})
|
||||
.fail(function (err) {
|
||||
console.error('Phantom installation failed', err, err.stack)
|
||||
exit(1)
|
||||
})
|
||||
|
||||
|
||||
function writeLocationFile(location) {
|
||||
console.log('Writing location.js file')
|
||||
if (process.platform === 'win32') {
|
||||
location = location.replace(/\\/g, '\\\\')
|
||||
}
|
||||
fs.writeFileSync(path.join(libPath, 'location.js'),
|
||||
'module.exports.location = "' + location + '"')
|
||||
}
|
||||
|
||||
function exit(code) {
|
||||
validExit = true
|
||||
process.env.PATH = originalPath
|
||||
process.exit(code || 0)
|
||||
}
|
||||
|
||||
|
||||
function findSuitableTempDirectory(npmConf) {
|
||||
var now = Date.now()
|
||||
var candidateTmpDirs = [
|
||||
process.env.TMPDIR || process.env.TEMP || npmConf.get('tmp'),
|
||||
'/tmp',
|
||||
path.join(process.cwd(), 'tmp')
|
||||
]
|
||||
|
||||
for (var i = 0; i < candidateTmpDirs.length; i++) {
|
||||
var candidatePath = path.join(candidateTmpDirs[i], 'phantomjs')
|
||||
|
||||
try {
|
||||
fs.mkdirsSync(candidatePath, '0777')
|
||||
// Make double sure we have 0777 permissions; some operating systems
|
||||
// default umask does not allow write by default.
|
||||
fs.chmodSync(candidatePath, '0777')
|
||||
var testFile = path.join(candidatePath, now + '.tmp')
|
||||
fs.writeFileSync(testFile, 'test')
|
||||
fs.unlinkSync(testFile)
|
||||
return candidatePath
|
||||
} catch (e) {
|
||||
console.log(candidatePath, 'is not writable:', e.message)
|
||||
}
|
||||
}
|
||||
|
||||
console.error('Can not find a writable tmp directory, please report issue ' +
|
||||
'on https://github.com/Obvious/phantomjs/issues/59 with as much ' +
|
||||
'information as possible.')
|
||||
exit(1)
|
||||
}
|
||||
|
||||
|
||||
function getRequestOptions(conf) {
|
||||
var strictSSL = conf.get('strict-ssl')
|
||||
if (process.version == 'v0.10.34') {
|
||||
console.log('Node v0.10.34 detected, turning off strict ssl due to https://github.com/joyent/node/issues/8894')
|
||||
strictSSL = false
|
||||
}
|
||||
|
||||
|
||||
var options = {
|
||||
uri: downloadUrl,
|
||||
encoding: null, // Get response as a buffer
|
||||
followRedirect: true, // The default download path redirects to a CDN URL.
|
||||
headers: {},
|
||||
strictSSL: strictSSL
|
||||
}
|
||||
|
||||
var proxyUrl = conf.get('https-proxy') || conf.get('http-proxy') || conf.get('proxy')
|
||||
if (proxyUrl) {
|
||||
|
||||
// Print using proxy
|
||||
var proxy = url.parse(proxyUrl)
|
||||
if (proxy.auth) {
|
||||
// Mask password
|
||||
proxy.auth = proxy.auth.replace(/:.*$/, ':******')
|
||||
}
|
||||
console.log('Using proxy ' + url.format(proxy))
|
||||
|
||||
// Enable proxy
|
||||
options.proxy = proxyUrl
|
||||
|
||||
// If going through proxy, use the user-agent string from the npm config
|
||||
options.headers['User-Agent'] = conf.get('user-agent')
|
||||
}
|
||||
|
||||
// Use certificate authority settings from npm
|
||||
var ca = conf.get('ca')
|
||||
if (ca) {
|
||||
console.log('Using npmconf ca')
|
||||
options.ca = ca
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
|
||||
function requestBinary(requestOptions, filePath) {
|
||||
var deferred = kew.defer()
|
||||
|
||||
var count = 0
|
||||
var notifiedCount = 0
|
||||
var writePath = filePath + '-download-' + Date.now()
|
||||
|
||||
console.log('Receiving...')
|
||||
var bar = null
|
||||
requestProgress(request(requestOptions, function (error, response, body) {
|
||||
console.log('');
|
||||
if (!error && response.statusCode === 200) {
|
||||
fs.writeFileSync(writePath, body)
|
||||
console.log('Received ' + Math.floor(body.length / 1024) + 'K total.')
|
||||
fs.renameSync(writePath, filePath)
|
||||
deferred.resolve(filePath)
|
||||
|
||||
} else if (response) {
|
||||
console.error('Error requesting archive.\n' +
|
||||
'Status: ' + response.statusCode + '\n' +
|
||||
'Request options: ' + JSON.stringify(requestOptions, null, 2) + '\n' +
|
||||
'Response headers: ' + JSON.stringify(response.headers, null, 2) + '\n' +
|
||||
'Make sure your network and proxy settings are correct.\n\n' +
|
||||
'If you continue to have issues, please report this full log at ' +
|
||||
'https://github.com/Medium/phantomjs')
|
||||
exit(1)
|
||||
} else if (error && error.stack && error.stack.indexOf('SELF_SIGNED_CERT_IN_CHAIN') != -1) {
|
||||
console.error('Error making request, SELF_SIGNED_CERT_IN_CHAIN. Please read https://github.com/Medium/phantomjs#i-am-behind-a-corporate-proxy-that-uses-self-signed-ssl-certificates-to-intercept-encrypted-traffic')
|
||||
exit(1)
|
||||
} else if (error) {
|
||||
console.error('Error making request.\n' + error.stack + '\n\n' +
|
||||
'Please report this full log at https://github.com/Medium/phantomjs')
|
||||
exit(1)
|
||||
} else {
|
||||
console.error('Something unexpected happened, please report this full ' +
|
||||
'log at https://github.com/Medium/phantomjs')
|
||||
exit(1)
|
||||
}
|
||||
})).on('progress', function (state) {
|
||||
if (!bar) {
|
||||
bar = new progress(' [:bar] :percent :etas', {total: state.total, width: 40})
|
||||
}
|
||||
bar.curr = state.received
|
||||
bar.tick(0)
|
||||
})
|
||||
|
||||
return deferred.promise
|
||||
}
|
||||
|
||||
|
||||
function extractDownload(filePath) {
|
||||
var deferred = kew.defer()
|
||||
// extract to a unique directory in case multiple processes are
|
||||
// installing and extracting at once
|
||||
var extractedPath = filePath + '-extract-' + Date.now()
|
||||
var options = {cwd: extractedPath}
|
||||
|
||||
fs.mkdirsSync(extractedPath, '0777')
|
||||
// Make double sure we have 0777 permissions; some operating systems
|
||||
// default umask does not allow write by default.
|
||||
fs.chmodSync(extractedPath, '0777')
|
||||
|
||||
if (filePath.substr(-4) === '.zip') {
|
||||
console.log('Extracting zip contents')
|
||||
|
||||
try {
|
||||
var zip = new AdmZip(filePath)
|
||||
zip.extractAllTo(extractedPath, true)
|
||||
deferred.resolve(extractedPath)
|
||||
} catch (err) {
|
||||
console.error('Error extracting zip')
|
||||
deferred.reject(err)
|
||||
}
|
||||
|
||||
} else {
|
||||
console.log('Extracting tar contents (via spawned process)')
|
||||
cp.execFile('tar', ['jxf', filePath], options, function (err, stdout, stderr) {
|
||||
if (err) {
|
||||
console.error('Error extracting archive')
|
||||
deferred.reject(err)
|
||||
} else {
|
||||
deferred.resolve(extractedPath)
|
||||
}
|
||||
})
|
||||
}
|
||||
return deferred.promise
|
||||
}
|
||||
|
||||
|
||||
function copyIntoPlace(extractedPath, targetPath) {
|
||||
console.log('Removing', targetPath)
|
||||
return kew.nfcall(fs.remove, targetPath).then(function () {
|
||||
// Look for the extracted directory, so we can rename it.
|
||||
var files = fs.readdirSync(extractedPath)
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
var file = path.join(extractedPath, files[i])
|
||||
if (fs.statSync(file).isDirectory() && file.indexOf(helper.version) != -1) {
|
||||
console.log('Copying extracted folder', file, '->', targetPath)
|
||||
return kew.nfcall(fs.move, file, targetPath)
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Could not find extracted file', files)
|
||||
throw new Error('Could not find extracted file')
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
module.exports.location = "phantom/bin/phantomjs"
|
||||
@@ -0,0 +1,368 @@
|
||||
Please see also http://phantomjs.org/releases.html.
|
||||
|
||||
2014-10-22: Version 1.9.8
|
||||
|
||||
* Change default SSL protocol to TLSv1 to address POODLE (issue 12655)
|
||||
To use the old default protocol of SSLv3 which is vulnerable to POODLE
|
||||
add the --ssl-protocol=SSLv3 flag. Reference: http://poodlebleed.com/
|
||||
* Fixed building on OS X 10.10 Yosemite (issue 12622)
|
||||
* Backported crash fix when exit (issue 11642, 12431)
|
||||
|
||||
2014-01-25: Version 1.9.7
|
||||
|
||||
* Reverted to GhostDriver 1.1.0 instead of 1.1.1 (issue 11915)
|
||||
* Fixed another warning of obsolete userSpaceScaleFactor on OS X 10.9 (issue 11612)
|
||||
|
||||
2014-01-20: Version 1.9.6
|
||||
|
||||
* Updated GhostDriver to version 1.1.1 (issue 11877, 11893)
|
||||
|
||||
2014-01-19: Version 1.9.3
|
||||
|
||||
* Fixed CoreText performance note on OS X 10.9 (issue 11418)
|
||||
* Fixed warning of obsolete userSpaceScaleFactor on OS X 10.9 (issue 11612)
|
||||
|
||||
2013-09-06: Version 1.9.2
|
||||
|
||||
* Fixed graphical artifacts with transparent background on Windows (issue 11276, 11007, 11366)
|
||||
* Updated GhostDriver to version 1.0.4 (issue 11452)
|
||||
|
||||
2013-06-04: Version 1.9.1
|
||||
|
||||
Critical bug fixes:
|
||||
|
||||
* Fixed problems with specifying proxy server (issue 10811, 11117)
|
||||
* Fixed UTF-8 encoding with system.stdout and system.stderr (issue 11162)
|
||||
* Ensured that onResourceReceived will be always invoked (issue 11163)
|
||||
* Fixed module loading from an absolute path on Windows (issue 11165)
|
||||
* Fixed typo in the command-line option for setting the cache size (11219)
|
||||
* Fixed possible crash when handling network requests (issue 11252, 11388)
|
||||
|
||||
2013-03-20: Version 1.9.0 "Sakura"
|
||||
|
||||
New features
|
||||
|
||||
* Added spawn and execFile to execute external programs (issue 10219)
|
||||
* Added the ability to abort network requests (issue 10230)
|
||||
* Added system access to stdin, stdout, and stderr (issue 10333)
|
||||
* Added support for custom CA certificates location (issue 10916)
|
||||
* Added seek function to the File stream (issue 10937)
|
||||
* Implemented file read for a specified number of bytes (issue 10938)
|
||||
* Added a callback to handle network error (issue 10954, 10997)
|
||||
* Added custom encoding support when opening a page (issue 11043)
|
||||
* Implemented require.stub() support for a factory function (issue 11044)
|
||||
* Added page loading indicator and progress (issue 11091)
|
||||
* Added a timeout option for network requests (issue 11129)
|
||||
|
||||
Improvements
|
||||
|
||||
* Fixed the build on FreeBSD (issue 10597)
|
||||
* Ensured a consistent 72 dpi for Linux headless rendering (issue 10659)
|
||||
* Fixed possible PDF error due to invalid CreationDate field (issue 10663)
|
||||
* Fixed crash when uploading non existing files (issue 10941)
|
||||
* Improved the autocomplete internal of the interactive/REPL mode (issue 10943)
|
||||
* Fixed possible crash when accessing inline frames (issue 10947)
|
||||
* Changed Linux binary package setup to be built on CentOS 5 (issue 10963)
|
||||
* Extended SSL ignore setting to synchronous XHR (issue 10985)
|
||||
* Added convenient constants for modifier keys (issue 11056)
|
||||
* Fixed incorrect date handling in the cookies (issue 11068)
|
||||
* Updated GhostDriver to version 1.0.3 (issue 11146)
|
||||
|
||||
Examples
|
||||
|
||||
* Fixed invalid data URI in the netsniff example (issue 10740)
|
||||
* Implemented a new weather example (issue 10794)
|
||||
* Fixed rendering issues in render_multi_url (issue 11021)
|
||||
* Fixed proper event sequence in page_events example (issue 11028)
|
||||
* Miscellanous tweaks (issue 11082)
|
||||
|
||||
2013-03-02: Version 1.8.2
|
||||
|
||||
Critical bug fixes:
|
||||
|
||||
* Fixed possible PDF error due to invalid CreationDate field (issue 663)
|
||||
* Fixed crash when uploading non existing files (issue 941)
|
||||
* Fixed possible crash when accessing inline frames (issue 947)
|
||||
* Extended SSL ignore setting to synchronous XHR (issue 985)
|
||||
* Fixed incorrect date handling in the cookies (issue 1068)
|
||||
|
||||
2013-01-06: Version 1.8.1
|
||||
|
||||
Critical bug fix:
|
||||
|
||||
* Mac OS X: Fix possible crash when using some TrueType fonts (issue 690)
|
||||
|
||||
2012-12-21: Version 1.8.0 "Blue Winter Rose"
|
||||
|
||||
New features
|
||||
|
||||
* Integrated GhostDriver as the WebDriver implementation (issue 49)
|
||||
* Added an option to specify the SSL protocol (issue 174)
|
||||
* Added encoding support for WebServer's response (issue 505)
|
||||
* Added process ID (PID) to the System module (issue 769)
|
||||
* Added properties to obtain page and frame title (issue 799)
|
||||
* Added page navigation methods (issue 808)
|
||||
* Added support for modifier keys in keyboard events (issue 835)
|
||||
* Added onFilePicker callback for more generic file upload API (issue 843)
|
||||
* Added the ability to set the page content and location (issue 909)
|
||||
|
||||
Improvements
|
||||
|
||||
* Fixed date parsing in ISO8601 format (issue 187, 267)
|
||||
* Fixed window.location (issue 530, 632)
|
||||
* Deregistered multiple callback handler (issue 807)
|
||||
* Fixed sending of double-click events (issue 848)
|
||||
* Increases maximum number of redirects (issue 849)
|
||||
* Fixed keycodes sent for lowercase characters (issue 852)
|
||||
* Fixed a regression in table row page break (issue 880)
|
||||
* Completed the CoffeeScript version of the examples (issue 907)
|
||||
* Updated Qt to version 4.8.4 (issue 918)
|
||||
* Fixed potential hang in some example scripts (issue 922)
|
||||
|
||||
2012-09-22: Version 1.7.0 "Blazing Star"
|
||||
|
||||
New features
|
||||
|
||||
* Added a module system modelled after CommonJS/Node.js (issue 47)
|
||||
* Added support for window pop-up (issue 151)
|
||||
* Static build on Linux (issue 413)
|
||||
* Added run-time detection of SSL support (issue 484)
|
||||
* Added more events support (issue 492, 712)
|
||||
* Added support for disabling automatic proxy detection (issue 580)
|
||||
* Provided page closing callback (issue 678)
|
||||
* Added methods to access URL, frames URL, frame Content (issue 758)
|
||||
* Added more cookies-related API (issue 761)
|
||||
|
||||
Improvements
|
||||
|
||||
* Refactored command-line options handling (issue 55)
|
||||
* Improved the workflow for producing release builds (issue 599)
|
||||
* Improved cookies API and implementation (issue 603, 761)
|
||||
* Improved frame switching API (issue 654)
|
||||
* Fixed iframe handling regression (issue 683)
|
||||
* Fixed OS version number with Windows 8 and Mountain Lion (issue 684, 688)
|
||||
* Fixed HAR navigation info in the netsniff example (issue 733)
|
||||
* Fixed compile warnings with Visual Studio (issue 744)
|
||||
* Removed hacks for static linking on Windows (issue 753)
|
||||
* Added ICO image handling on Windows (issue 779)
|
||||
* Fixed font antialiasing on Windows (issue 785)
|
||||
* Improved Jasmine test runner for Jasmine 1.2 (issue 792)
|
||||
|
||||
2012-07-22: Version 1.6.1
|
||||
|
||||
Bug fixes
|
||||
|
||||
* Don't build the deploy in debug mode (issue 599)
|
||||
* Fixed building on Windows (issue 424)
|
||||
* Fixed remote inspector when building statically (issue 430)
|
||||
|
||||
2012-06-20: Version 1.6.0 "Lavender"
|
||||
|
||||
New features
|
||||
|
||||
* Added support for passing arguments to WebPage's evaluate (issue 132)
|
||||
* Added callbacks for JavaScript onConfirm and onPrompt (issue 133)
|
||||
* Added stack trace when error occurs (issue 166)
|
||||
* Added support for local storage path and quota (issue 300)
|
||||
* Added initial support for cookies handling (issue 354)
|
||||
* Added support for header footer when printing the page (issue 410, 512)
|
||||
* Added headers support in the loading request (issue 452)
|
||||
* Added support to render the web page as base64-encoded string (issue 547)
|
||||
* Added hooks for navigation event (issue 562)
|
||||
* Added command-line option to show debug messages (issue 575)
|
||||
* Added support for the zoom factor for web page rendering (issue 579)
|
||||
* Added crash reporter for Mac OS X and Linux, based on Google Breakpad (issue 576)
|
||||
* Added 'os' object to the system module (issue 585)
|
||||
* Added support for asynchronous evaluation (issue 593)
|
||||
|
||||
Improvements
|
||||
|
||||
* Fixed remote debugging to work on Mac OS X and Windows (issue 430)
|
||||
* Fixed web server getting the dropped connection for empty response (issue 451)
|
||||
* Fixed text rendered as boxes (squares) on headless Linux (issue 460)
|
||||
* Updated Qt to version 4.8.2 (issue 495)
|
||||
* Updated CoffeeScript compiler to version 1.3.3 (issue 496)
|
||||
* Fixed the build script to detect and use MAKEFLAGS (issue 503)
|
||||
* Fixed the build script to properly pass Qt config flags (issue 507)
|
||||
* Changed Info.plist to be embedded in Mac OS X executable (issue 528)
|
||||
* Fixed wrong module require in the imagebin example (issue 536)
|
||||
* Fixed example scripts to exit with the right exit code (issue 544)
|
||||
* Fixed build failure with glib 2.31.0+ (issue 559)
|
||||
* Fixed error handler failures in some cases (issue 589)
|
||||
* Fixed Twitter-related examples to work with the new site (issue 609)
|
||||
|
||||
2012-03-20: Version 1.5.0 "Ghost Flower"
|
||||
|
||||
New features
|
||||
|
||||
* Added interactive mode, also known as REPL (issue 252)
|
||||
* Added setting for web security, to allow cross domain XHR (issue 28)
|
||||
* Added error handler for WebPage object (issue 166)
|
||||
* Added support for custom HTTP header in the network request (issue 77)
|
||||
* Added support for read write encoding in the file system module (issue 367)
|
||||
* Added remote debugging support on Linux (issue 6)
|
||||
* Added support for proxy authentication (issue 105)
|
||||
* Added System module, to retrieve environment variables (issue 271) and arguments (issue 276)
|
||||
* Added fs.readLink function (issue 329)
|
||||
* Added support for reading and writing binary data (issue 400)
|
||||
* Added support to retrieve request data in the WebServer? module (issue 340)
|
||||
* Added support for individual top/bottom/left/right print margins (issue 388)
|
||||
* Added command-line option --help (issue 347)
|
||||
* Added short command-line options -v and -h (issue 408)
|
||||
* Removed support for Flash and other plugins (issue 418)
|
||||
|
||||
Bug fixes
|
||||
|
||||
* Fixed multiple console.log arguments (issue 36)
|
||||
* Fixed file upload (issue 307)
|
||||
* Fixed the web server instance to be asynchronous (issue 326) and still support Keep Alive (issue 416)
|
||||
* Workaround Qt 4.8.0 crash due to empty URL scheme (issue 365)
|
||||
* Fixed a Content-Type problem where POST does not work (issue 337)
|
||||
* Fixed reading body request in the web server even without specific Content-Type (issue 439)
|
||||
* Fixed Jasmine test runner with Jasmine 1.1 (issue 402)
|
||||
* Fixed request URL formatting in the web server (issue 437)
|
||||
* Don't display debugging and warning messages (issue 323)
|
||||
|
||||
2011-12-31: Version 1.4.1
|
||||
|
||||
Bug fixes
|
||||
|
||||
* Fix setting the proxy type (issue 266)
|
||||
* Workaround for file upload regression (issue 307)
|
||||
* Fix extraneous messsages in non-debug mode (issue 323)
|
||||
|
||||
2011-12-22: Version 1.4.0 "Glory of the Snow"
|
||||
|
||||
New features
|
||||
|
||||
* Added embedded HTTP server (issue 115)
|
||||
* Added convenient build script for Linux (issue 197)
|
||||
* Added support for SOCKS5 proxy (issue 266)
|
||||
* Updated CoffeeScript compiler to version 1.2 (issue 312)
|
||||
|
||||
Bug fixes
|
||||
|
||||
* Fix potential crash in QUrl with Qt 4.8 (issue 304)
|
||||
* Fix bug in CookieJar with QSettings and string (PyPhantomJS issue 10)
|
||||
* Prevent showing the icon on Mac OS X Dock (issue 281)
|
||||
|
||||
Examples
|
||||
|
||||
* Added a new example to detect browsers sniffing (issue 263)
|
||||
* Added HTTP server example (issue 115)
|
||||
|
||||
2011-09-23: Version 1.3.0 "Water Lily"
|
||||
|
||||
Bug fixes
|
||||
|
||||
* Fixed open() and POST method, without specifying the finished handler
|
||||
* Fixed script execution warning dialog (issue 165)
|
||||
* Added WebPage.release() to free the web page from memory (issue 154)
|
||||
* Added special handling of about:blank (issue 235)
|
||||
* Made a separate network access manager for each page (issue 190)
|
||||
|
||||
New features
|
||||
|
||||
* Introduced file system API based on CommonJS Filesystem proposal (issue 129)
|
||||
* Added support for persistent cookies (issue 91)
|
||||
* Added event handling, currently only for mouse events (issue 234)
|
||||
* Added page scroll position (issue 162)
|
||||
* Added HTTP authentication support (issue 45)
|
||||
* Added callback for page initialization (issue 143)
|
||||
* Added support to specify script and output encoding (issue 186)
|
||||
* Added option to allow local content to do cross-domain access (issue 28)
|
||||
* Added support to apply configurations from a JSON file (issue 180)
|
||||
* Added a convenient WebPage initialization construction (issue 206)
|
||||
* Added option to limit the size of disk cache (issue 220)
|
||||
|
||||
Examples
|
||||
|
||||
* Added a new example on using Modernizr to detect features (issue 144)
|
||||
* Fixed pizza.js example to use Mobile Yelp (issue 200)
|
||||
* Fixed netsniff.coffee example due to wrong indentation (issue 225)
|
||||
* Added an example to show live network traffic (issue 227)
|
||||
* Added an example demonstrating different output encodings (issue 186)
|
||||
|
||||
2011-06-21: Version 1.2.0 "Birds of Paradise"
|
||||
|
||||
Version 1.2.0 is a major update. It introduces a whole set of new API.
|
||||
|
||||
Bug fixes
|
||||
|
||||
* Fixed rendering a very large web page (issue 54)
|
||||
* Fixed reporting of CoffeeScript compile error (issue 125)
|
||||
|
||||
New features
|
||||
|
||||
* Added callback for console message (issue 12)
|
||||
* Improved security model via WebPage object (issue 41)
|
||||
* Added support for POST, HEAD, PUT, and DELETE (issue 88)
|
||||
* Scripts filename is now passed as phantom.scriptName
|
||||
* Added callback to capture resource requests and responses (issue 2)
|
||||
* Added the ability to load external JavaScript (issue 32)
|
||||
|
||||
Examples
|
||||
|
||||
* Ported examples to use WebPage object
|
||||
* Added a new example to upload an image to imagebin.org
|
||||
* Added a new example to show HTTP POST feature
|
||||
* Added a new example to sniff network traffic and save it in HAR format
|
||||
|
||||
|
||||
2011-04-27: Version 1.1.0 "Cherry Blossom"
|
||||
|
||||
Fixed the script loading to use UTF-8 encoding (Yasuhiro Matsumoto).
|
||||
|
||||
Added check for system proxy setting (Yasuhiro Matsumoto).
|
||||
|
||||
Fixed building with Cygwin and Qt 4.5 (John Dalton).
|
||||
|
||||
Added a new example: driver for QUnit tests (Łukasz Korecki).
|
||||
|
||||
Fixed issue #20: problem with JPG transparent color (Alessandro Portale).
|
||||
|
||||
Fixed issue #9: ignore first line starting with #! (Matthias, aka fourplusone).
|
||||
|
||||
Fixed issue #7: support for file upload for form submission (Matthias, aka fourplusone).
|
||||
|
||||
Fixed issue #35: support for disabling images loading (Ariya Hidayat).
|
||||
|
||||
Fixed issue #14: enable or disable plugins (Ariya Hidayat).
|
||||
|
||||
Added a new example: using Canvas to produce the color wheel (Ariya Hidayat).
|
||||
|
||||
Added support for rasterizing as GIF image (Ariya Hidayat).
|
||||
|
||||
Added support for CoffeeScript (Ariya Hidayat).
|
||||
|
||||
Fixed issue #19: option for setting the proxy (Clint Berry, Ariya Hidayat).
|
||||
|
||||
Python implementation using PyQt (James Roe).
|
||||
|
||||
Fixed issue #17: Specify paper size for PDF export (Alessandro Portale).
|
||||
|
||||
Fixed issue #60: Win32 and OS/2 icon files (Salvador Parra Camacho).
|
||||
|
||||
Added clipping rectangle to the render function (Wouter de Bie).
|
||||
|
||||
Added an example on sychronous waiting (Gabor Torok).
|
||||
|
||||
Added command line option to use disk cache (Jon Turner).
|
||||
|
||||
Added text extracting example (Weston Ruter).
|
||||
|
||||
Fixed issue #93: Build with Qt < 4.7 (Ariya Hidayat).
|
||||
|
||||
Ported all examples to CoffeeScript (Robert Gieseke).
|
||||
|
||||
2011-01-17: Version 1.0.0
|
||||
|
||||
Initial launch.
|
||||
|
||||
The API is centralized at the 'phantom' object (as child of
|
||||
window object) which has the properties: args, content,
|
||||
loadStatus, state, userAgent, version, viewportSize, and
|
||||
the following functions: exit, open, render, sleep.
|
||||
|
||||
Several examples are included, among others: web page rasterizer,
|
||||
weather service, headless test framework driver, and many others.
|
||||
@@ -0,0 +1,22 @@
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,45 @@
|
||||
# [PhantomJS](http://phantomjs.org) - Scriptable Headless WebKit
|
||||
|
||||
PhantomJS ([www.phantomjs.org](http://phantomjs.org)) is a headless WebKit scriptable with JavaScript or CoffeeScript. It is used by hundreds of [developers](https://github.com/ariya/phantomjs/wiki/Buzz) and dozens of [organizations](https://github.com/ariya/phantomjs/wiki/Users) for web-related development workflow.
|
||||
|
||||
The latest [stable release](http://phantomjs.org/release-1.9.html) is version 1.9 (codenamed <a href="http://phantomjs.org/release-names.html">"Sakura"</a>). Follow the official Twitter stream [@PhantomJS](http://twitter.com/PhantomJS) to get the frequent development updates.
|
||||
|
||||
**Note**: Please **do not** create a GitHub pull request **without** reading the [Contribution Guide](https://github.com/ariya/phantomjs/blob/master/CONTRIBUTING.md) first. Failure to do so may result in the rejection of the pull request.
|
||||
|
||||
## Use Cases
|
||||
|
||||
- **Headless web testing**. Lightning-fast testing without the browser is now possible! Various [test frameworks](https://github.com/ariya/phantomjs/wiki/Headless-Testing) such as Jasmine, Capybara, QUnit, Mocha, WebDriver, YUI Test, BusterJS, FuncUnit, Robot Framework, and many others are supported.
|
||||
- **Page automation**. [Access and manipulate](https://github.com/ariya/phantomjs/wiki/Page-Automation) web pages with the standard DOM API, or with usual libraries like jQuery.
|
||||
- **Screen capture**. Programmatically [capture web contents](https://github.com/ariya/phantomjs/wiki/Screen-Capture), including CSs, SVG and Canvas. Build server-side web graphics apps, from a screenshot service to a vector chart rasterizer.
|
||||
- **Network monitoring**. Automate performance analysis, track [page loading](https://github.com/ariya/phantomjs/wiki/Network-Monitoring) and export as standard HAR format.
|
||||
|
||||
## Features
|
||||
|
||||
- **Multiplatform**, available on major operating systems: Windows, Mac OS X, Linux, other Unices.
|
||||
- **Fast and native implementation** of web standards: DOM, CSS, JavaScript, Canvas, SVG. No emulation!
|
||||
- **Pure headless (no X11) on Linux**, ideal for continuous integration systems. Also runs on Amazon EC2, Heroku, Iron.io.
|
||||
- **Easy to install**: [Download](http://phantomjs.org/download.html), unpack, and start having fun in just 5 minutes.
|
||||
|
||||
## Ecosystem
|
||||
|
||||
PhantomJS needs not be used only as a stand-alone tool. Check also some excellent related projects:
|
||||
|
||||
- [CasperJS](http://casperjs.org) enables easy navigation scripting and common high-level testing.
|
||||
- [Poltergeist](https://github.com/jonleighton/poltergeist) allows running Capybara tests headlessly.
|
||||
- [Guard::Jasmine](https://github.com/netzpirat/guard-jasmine) automatically tests Jasmine specs on Rails when files are modified.
|
||||
- [GhostDriver](http://github.com/detro/ghostdriver/) complements Selenium tests with a PhantomJS WebDriver implementation.
|
||||
- [PhantomRobot](https://github.com/datakurre/phantomrobot) runs Robot Framework acceptance tests in the background via PhantomJS.
|
||||
- [Mocha-PhantomJS](https://github.com/metaskills/mocha-phantomjs) run Mocha tests using PhantomJS.
|
||||
|
||||
and many others [related projects](https://github.com/ariya/phantomjs/wiki/Related-Projects).
|
||||
|
||||
## Questions?
|
||||
|
||||
- Explore the complete [documentation](https://github.com/ariya/phantomjs/wiki)
|
||||
- Read tons of [user articles](https://github.com/ariya/phantomjs/wiki/Buzz) on using PhantomJS.
|
||||
- Join the [mailing-list](http://groups.google.com/group/phantomjs) and discuss with other PhantomJS fans.
|
||||
|
||||
PhantomJS is free software/open source, and is distributed under the [BSD license](http://opensource.org/licenses/BSD-3-Clause). It contains third-party code, see the included `third-party.txt` file for the license information on third-party code.
|
||||
|
||||
PhantomJS is created and maintained by [Ariya Hidayat](http://ariya.ofilabs.com/about) (Twitter: [@ariyahidayat](http://twitter.com/ariyahidayat)), with the help of [many contributors](https://github.com/ariya/phantomjs/contributors).
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
system = require 'system'
|
||||
if system.args.length is 1
|
||||
console.log 'Try to pass some args when invoking this script!'
|
||||
else
|
||||
for arg, i in system.args
|
||||
console.log i + ': ' + arg
|
||||
phantom.exit()
|
||||
@@ -0,0 +1,9 @@
|
||||
var system = require('system');
|
||||
if (system.args.length === 1) {
|
||||
console.log('Try to pass some args when invoking this script!');
|
||||
} else {
|
||||
system.args.forEach(function (arg, i) {
|
||||
console.log(i + ': ' + arg);
|
||||
});
|
||||
}
|
||||
phantom.exit();
|
||||
@@ -0,0 +1,20 @@
|
||||
{spawn, execFile} = require "child_process"
|
||||
|
||||
child = spawn "ls", ["-lF", "/rooot"]
|
||||
|
||||
child.stdout.on "data", (data) ->
|
||||
console.log "spawnSTDOUT:", JSON.stringify data
|
||||
|
||||
child.stderr.on "data", (data) ->
|
||||
console.log "spawnSTDERR:", JSON.stringify data
|
||||
|
||||
child.on "exit", (code) ->
|
||||
console.log "spawnEXIT:", code
|
||||
|
||||
#child.kill "SIGKILL"
|
||||
|
||||
execFile "ls", ["-lF", "/usr"], null, (err, stdout, stderr) ->
|
||||
console.log "execFileSTDOUT:", JSON.stringify stdout
|
||||
console.log "execFileSTDERR:", JSON.stringify stderr
|
||||
|
||||
setTimeout (-> phantom.exit 0), 2000
|
||||
@@ -0,0 +1,27 @@
|
||||
var spawn = require("child_process").spawn
|
||||
var execFile = require("child_process").execFile
|
||||
|
||||
var child = spawn("ls", ["-lF", "/rooot"])
|
||||
|
||||
child.stdout.on("data", function (data) {
|
||||
console.log("spawnSTDOUT:", JSON.stringify(data))
|
||||
})
|
||||
|
||||
child.stderr.on("data", function (data) {
|
||||
console.log("spawnSTDERR:", JSON.stringify(data))
|
||||
})
|
||||
|
||||
child.on("exit", function (code) {
|
||||
console.log("spawnEXIT:", code)
|
||||
})
|
||||
|
||||
//child.kill("SIGKILL")
|
||||
|
||||
execFile("ls", ["-lF", "/usr"], null, function (err, stdout, stderr) {
|
||||
console.log("execFileSTDOUT:", JSON.stringify(stdout))
|
||||
console.log("execFileSTDERR:", JSON.stringify(stderr))
|
||||
})
|
||||
|
||||
setTimeout(function () {
|
||||
phantom.exit(0)
|
||||
}, 2000)
|
||||
@@ -0,0 +1,46 @@
|
||||
page = require('webpage').create()
|
||||
|
||||
page.viewportSize = { width: 400, height : 400 }
|
||||
page.content = '<html><body><canvas id="surface"></canvas></body></html>'
|
||||
|
||||
page.evaluate ->
|
||||
el = document.getElementById 'surface'
|
||||
context = el.getContext '2d'
|
||||
width = window.innerWidth
|
||||
height = window.innerHeight
|
||||
cx = width / 2
|
||||
cy = height / 2
|
||||
radius = width / 2.3
|
||||
i = 0
|
||||
|
||||
el.width = width
|
||||
el.height = height
|
||||
imageData = context.createImageData(width, height)
|
||||
pixels = imageData.data
|
||||
|
||||
for y in [0...height]
|
||||
for x in [0...width]
|
||||
i = i + 4
|
||||
rx = x - cx
|
||||
ry = y - cy
|
||||
d = rx * rx + ry * ry
|
||||
if d < radius * radius
|
||||
hue = 6 * (Math.atan2(ry, rx) + Math.PI) / (2 * Math.PI)
|
||||
sat = Math.sqrt(d) / radius
|
||||
g = Math.floor(hue)
|
||||
f = hue - g
|
||||
u = 255 * (1 - sat)
|
||||
v = 255 * (1 - sat * f)
|
||||
w = 255 * (1 - sat * (1 - f))
|
||||
pixels[i] = [255, v, u, u, w, 255, 255][g]
|
||||
pixels[i + 1] = [w, 255, 255, v, u, u, w][g]
|
||||
pixels[i + 2] = [u, u, w, 255, 255, v, u][g]
|
||||
pixels[i + 3] = 255
|
||||
|
||||
context.putImageData imageData, 0, 0
|
||||
document.body.style.backgroundColor = 'white'
|
||||
document.body.style.margin = '0px'
|
||||
|
||||
page.render('colorwheel.png')
|
||||
|
||||
phantom.exit()
|
||||
@@ -0,0 +1,51 @@
|
||||
var page = require('webpage').create();
|
||||
page.viewportSize = { width: 400, height : 400 };
|
||||
page.content = '<html><body><canvas id="surface"></canvas></body></html>';
|
||||
page.evaluate(function() {
|
||||
var el = document.getElementById('surface'),
|
||||
context = el.getContext('2d'),
|
||||
width = window.innerWidth,
|
||||
height = window.innerHeight,
|
||||
cx = width / 2,
|
||||
cy = height / 2,
|
||||
radius = width / 2.3,
|
||||
imageData,
|
||||
pixels,
|
||||
hue, sat, value,
|
||||
i = 0, x, y, rx, ry, d,
|
||||
f, g, p, u, v, w, rgb;
|
||||
|
||||
el.width = width;
|
||||
el.height = height;
|
||||
imageData = context.createImageData(width, height);
|
||||
pixels = imageData.data;
|
||||
|
||||
for (y = 0; y < height; y = y + 1) {
|
||||
for (x = 0; x < width; x = x + 1, i = i + 4) {
|
||||
rx = x - cx;
|
||||
ry = y - cy;
|
||||
d = rx * rx + ry * ry;
|
||||
if (d < radius * radius) {
|
||||
hue = 6 * (Math.atan2(ry, rx) + Math.PI) / (2 * Math.PI);
|
||||
sat = Math.sqrt(d) / radius;
|
||||
g = Math.floor(hue);
|
||||
f = hue - g;
|
||||
u = 255 * (1 - sat);
|
||||
v = 255 * (1 - sat * f);
|
||||
w = 255 * (1 - sat * (1 - f));
|
||||
pixels[i] = [255, v, u, u, w, 255, 255][g];
|
||||
pixels[i + 1] = [w, 255, 255, v, u, u, w][g];
|
||||
pixels[i + 2] = [u, u, w, 255, 255, v, u][g];
|
||||
pixels[i + 3] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.putImageData(imageData, 0, 0);
|
||||
document.body.style.backgroundColor = 'white';
|
||||
document.body.style.margin = '0px';
|
||||
});
|
||||
|
||||
page.render('colorwheel.png');
|
||||
|
||||
phantom.exit();
|
||||
@@ -0,0 +1,8 @@
|
||||
t = 10
|
||||
interval = setInterval ->
|
||||
if t > 0
|
||||
console.log t--
|
||||
else
|
||||
console.log 'BLAST OFF!'
|
||||
phantom.exit()
|
||||
, 1000
|
||||
@@ -0,0 +1,9 @@
|
||||
var t = 10,
|
||||
interval = setInterval(function(){
|
||||
if ( t > 0 ) {
|
||||
console.log(t--);
|
||||
} else {
|
||||
console.log("BLAST OFF!");
|
||||
phantom.exit();
|
||||
}
|
||||
}, 1000);
|
||||
@@ -0,0 +1,42 @@
|
||||
page = require('webpage').create()
|
||||
system = require 'system'
|
||||
|
||||
page.onInitialized = ->
|
||||
page.evaluate ->
|
||||
userAgent = window.navigator.userAgent
|
||||
platform = window.navigator.platform
|
||||
window.navigator =
|
||||
appCodeName: 'Mozilla'
|
||||
appName: 'Netscape'
|
||||
cookieEnabled: false
|
||||
sniffed: false
|
||||
|
||||
window.navigator.__defineGetter__ 'userAgent', ->
|
||||
window.navigator.sniffed = true
|
||||
userAgent
|
||||
|
||||
window.navigator.__defineGetter__ 'platform', ->
|
||||
window.navigator.sniffed = true
|
||||
platform
|
||||
|
||||
if system.args.length is 1
|
||||
console.log 'Usage: detectsniff.coffee <some URL>'
|
||||
phantom.exit 1
|
||||
else
|
||||
address = system.args[1]
|
||||
console.log 'Checking ' + address + '...'
|
||||
page.open address, (status) ->
|
||||
if status isnt 'success'
|
||||
console.log 'FAIL to load the address'
|
||||
phantom.exit()
|
||||
else
|
||||
window.setTimeout ->
|
||||
sniffed = page.evaluate(->
|
||||
navigator.sniffed
|
||||
)
|
||||
if sniffed
|
||||
console.log 'The page tried to sniff the user agent.'
|
||||
else
|
||||
console.log 'The page did not try to sniff the user agent.'
|
||||
phantom.exit()
|
||||
, 1500
|
||||
@@ -0,0 +1,59 @@
|
||||
// Detect if a web page sniffs the user agent or not.
|
||||
|
||||
var page = require('webpage').create(),
|
||||
system = require('system'),
|
||||
sniffed,
|
||||
address;
|
||||
|
||||
page.onInitialized = function () {
|
||||
page.evaluate(function () {
|
||||
|
||||
(function () {
|
||||
var userAgent = window.navigator.userAgent,
|
||||
platform = window.navigator.platform;
|
||||
|
||||
window.navigator = {
|
||||
appCodeName: 'Mozilla',
|
||||
appName: 'Netscape',
|
||||
cookieEnabled: false,
|
||||
sniffed: false
|
||||
};
|
||||
|
||||
window.navigator.__defineGetter__('userAgent', function () {
|
||||
window.navigator.sniffed = true;
|
||||
return userAgent;
|
||||
});
|
||||
|
||||
window.navigator.__defineGetter__('platform', function () {
|
||||
window.navigator.sniffed = true;
|
||||
return platform;
|
||||
});
|
||||
})();
|
||||
});
|
||||
};
|
||||
|
||||
if (system.args.length === 1) {
|
||||
console.log('Usage: detectsniff.js <some URL>');
|
||||
phantom.exit(1);
|
||||
} else {
|
||||
address = system.args[1];
|
||||
console.log('Checking ' + address + '...');
|
||||
page.open(address, function (status) {
|
||||
if (status !== 'success') {
|
||||
console.log('FAIL to load the address');
|
||||
phantom.exit();
|
||||
} else {
|
||||
window.setTimeout(function () {
|
||||
sniffed = page.evaluate(function () {
|
||||
return navigator.sniffed;
|
||||
});
|
||||
if (sniffed) {
|
||||
console.log('The page tried to sniff the user agent.');
|
||||
} else {
|
||||
console.log('The page did not try to sniff the user agent.');
|
||||
}
|
||||
phantom.exit();
|
||||
}, 1500);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
# Get driving direction using Google Directions API.
|
||||
|
||||
page = require('webpage').create()
|
||||
system = require 'system'
|
||||
|
||||
if system.args.length < 3
|
||||
console.log 'Usage: direction.coffee origin destination'
|
||||
console.log 'Example: direction.coffee "San Diego" "Palo Alto"'
|
||||
phantom.exit 1
|
||||
else
|
||||
origin = system.args[1]
|
||||
dest = system.args[2]
|
||||
page.open encodeURI('http://maps.googleapis.com/maps/api/directions/xml?origin=' + origin +
|
||||
'&destination=' + dest + '&units=imperial&mode=driving&sensor=false'),
|
||||
(status) ->
|
||||
if status isnt 'success'
|
||||
console.log 'Unable to access network'
|
||||
else
|
||||
steps = page.content.match(/<html_instructions>(.*)<\/html_instructions>/ig)
|
||||
if not steps
|
||||
console.log 'No data available for ' + origin + ' to ' + dest
|
||||
else
|
||||
for ins in steps
|
||||
ins = ins.replace(/\</ig, '<').replace(/\>/ig, '>')
|
||||
ins = ins.replace(/\<div/ig, '\n<div')
|
||||
ins = ins.replace(/<.*?>/g, '')
|
||||
console.log(ins)
|
||||
console.log ''
|
||||
console.log page.content.match(/<copyrights>.*<\/copyrights>/ig).join('').replace(/<.*?>/g, '')
|
||||
phantom.exit()
|
||||
@@ -0,0 +1,35 @@
|
||||
// Get driving direction using Google Directions API.
|
||||
|
||||
var page = require('webpage').create(),
|
||||
system = require('system'),
|
||||
origin, dest, steps;
|
||||
|
||||
if (system.args.length < 3) {
|
||||
console.log('Usage: direction.js origin destination');
|
||||
console.log('Example: direction.js "San Diego" "Palo Alto"');
|
||||
phantom.exit(1);
|
||||
} else {
|
||||
origin = system.args[1];
|
||||
dest = system.args[2];
|
||||
page.open(encodeURI('http://maps.googleapis.com/maps/api/directions/xml?origin=' + origin +
|
||||
'&destination=' + dest + '&units=imperial&mode=driving&sensor=false'), function (status) {
|
||||
if (status !== 'success') {
|
||||
console.log('Unable to access network');
|
||||
} else {
|
||||
steps = page.content.match(/<html_instructions>(.*)<\/html_instructions>/ig);
|
||||
if (steps == null) {
|
||||
console.log('No data available for ' + origin + ' to ' + dest);
|
||||
} else {
|
||||
steps.forEach(function (ins) {
|
||||
ins = ins.replace(/\</ig, '<').replace(/\>/ig, '>');
|
||||
ins = ins.replace(/\<div/ig, '\n<div');
|
||||
ins = ins.replace(/<.*?>/g, '');
|
||||
console.log(ins);
|
||||
});
|
||||
console.log('');
|
||||
console.log(page.content.match(/<copyrights>.*<\/copyrights>/ig).join('').replace(/<.*?>/g, ''));
|
||||
}
|
||||
}
|
||||
phantom.exit();
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
# echoToFile.coffee - Write in a given file all the parameters passed on the CLI
|
||||
fs = require 'fs'
|
||||
system = require 'system'
|
||||
|
||||
if system.args.length < 3
|
||||
console.log "Usage: echoToFile.coffee DESTINATION_FILE <arguments to echo...>"
|
||||
phantom.exit 1
|
||||
else
|
||||
content = ""
|
||||
f = null
|
||||
i = 2
|
||||
while i < system.args.length
|
||||
content += system.args[i] + (if i == system.args.length - 1 then "" else " ")
|
||||
++i
|
||||
try
|
||||
fs.write system.args[1], content, "w"
|
||||
catch e
|
||||
console.log e
|
||||
phantom.exit()
|
||||
@@ -0,0 +1,23 @@
|
||||
// echoToFile.js - Write in a given file all the parameters passed on the CLI
|
||||
var fs = require('fs'),
|
||||
system = require('system');
|
||||
|
||||
if (system.args.length < 3) {
|
||||
console.log("Usage: echoToFile.js DESTINATION_FILE <arguments to echo...>");
|
||||
phantom.exit(1);
|
||||
} else {
|
||||
var content = '',
|
||||
f = null,
|
||||
i;
|
||||
for ( i= 2; i < system.args.length; ++i ) {
|
||||
content += system.args[i] + (i === system.args.length-1 ? '' : ' ');
|
||||
}
|
||||
|
||||
try {
|
||||
fs.write(system.args[1], content, 'w');
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
phantom.exit();
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
feature = undefined
|
||||
supported = []
|
||||
unsupported = []
|
||||
phantom.injectJs "modernizr.js"
|
||||
console.log "Detected features (using Modernizr " + Modernizr._version + "):"
|
||||
for feature of Modernizr
|
||||
if Modernizr.hasOwnProperty(feature)
|
||||
if feature[0] isnt "_" and typeof Modernizr[feature] isnt "function" and feature isnt "input" and feature isnt "inputtypes"
|
||||
if Modernizr[feature]
|
||||
supported.push feature
|
||||
else
|
||||
unsupported.push feature
|
||||
console.log ""
|
||||
console.log "Supported:"
|
||||
supported.forEach (e) ->
|
||||
console.log " " + e
|
||||
|
||||
console.log ""
|
||||
console.log "Not supported:"
|
||||
unsupported.forEach (e) ->
|
||||
console.log " " + e
|
||||
|
||||
phantom.exit()
|
||||
@@ -0,0 +1,30 @@
|
||||
var feature, supported = [], unsupported = [];
|
||||
|
||||
phantom.injectJs('modernizr.js');
|
||||
console.log('Detected features (using Modernizr ' + Modernizr._version + '):');
|
||||
for (feature in Modernizr) {
|
||||
if (Modernizr.hasOwnProperty(feature)) {
|
||||
if (feature[0] !== '_' && typeof Modernizr[feature] !== 'function' &&
|
||||
feature !== 'input' && feature !== 'inputtypes') {
|
||||
if (Modernizr[feature]) {
|
||||
supported.push(feature);
|
||||
} else {
|
||||
unsupported.push(feature);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log('');
|
||||
console.log('Supported:');
|
||||
supported.forEach(function (e) {
|
||||
console.log(' ' + e);
|
||||
});
|
||||
|
||||
console.log('');
|
||||
console.log('Not supported:');
|
||||
unsupported.forEach(function (e) {
|
||||
console.log(' ' + e);
|
||||
});
|
||||
phantom.exit();
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
fibs = [0, 1]
|
||||
f = ->
|
||||
console.log fibs[fibs.length - 1]
|
||||
fibs.push fibs[fibs.length - 1] + fibs[fibs.length - 2]
|
||||
if fibs.length > 10
|
||||
window.clearInterval ticker
|
||||
phantom.exit()
|
||||
ticker = window.setInterval(f, 300)
|
||||
@@ -0,0 +1,9 @@
|
||||
var fibs = [0, 1];
|
||||
var ticker = window.setInterval(function () {
|
||||
console.log(fibs[fibs.length - 1]);
|
||||
fibs.push(fibs[fibs.length - 1] + fibs[fibs.length - 2]);
|
||||
if (fibs.length > 10) {
|
||||
window.clearInterval(ticker);
|
||||
phantom.exit();
|
||||
}
|
||||
}, 300);
|
||||
@@ -0,0 +1,33 @@
|
||||
# List following and followers from several accounts
|
||||
|
||||
users = [
|
||||
'PhantomJS'
|
||||
'ariyahidayat'
|
||||
'detronizator'
|
||||
'KDABQt'
|
||||
'lfranchi'
|
||||
'jonleighton'
|
||||
'_jamesmgreene'
|
||||
'Vitalliumm'
|
||||
]
|
||||
|
||||
follow = (user, callback) ->
|
||||
page = require('webpage').create()
|
||||
page.open 'http://mobile.twitter.com/' + user, (status) ->
|
||||
if status is 'fail'
|
||||
console.log user + ': ?'
|
||||
else
|
||||
data = page.evaluate -> document.querySelector('div.profile td.stat.stat-last div.statnum').innerText;
|
||||
console.log user + ': ' + data
|
||||
page.close()
|
||||
callback.apply()
|
||||
|
||||
process = () ->
|
||||
if (users.length > 0)
|
||||
user = users[0]
|
||||
users.splice(0, 1)
|
||||
follow(user, process)
|
||||
else
|
||||
phantom.exit()
|
||||
|
||||
process()
|
||||
@@ -0,0 +1,38 @@
|
||||
// List following and followers from several accounts
|
||||
|
||||
var users = ['PhantomJS',
|
||||
'ariyahidayat',
|
||||
'detronizator',
|
||||
'KDABQt',
|
||||
'lfranchi',
|
||||
'jonleighton',
|
||||
'_jamesmgreene',
|
||||
'Vitalliumm'];
|
||||
|
||||
function follow(user, callback) {
|
||||
var page = require('webpage').create();
|
||||
page.open('http://mobile.twitter.com/' + user, function (status) {
|
||||
if (status === 'fail') {
|
||||
console.log(user + ': ?');
|
||||
} else {
|
||||
var data = page.evaluate(function () {
|
||||
return document.querySelector('div.profile td.stat.stat-last div.statnum').innerText;
|
||||
});
|
||||
console.log(user + ': ' + data);
|
||||
}
|
||||
page.close();
|
||||
callback.apply();
|
||||
});
|
||||
}
|
||||
|
||||
function process() {
|
||||
if (users.length > 0) {
|
||||
var user = users[0];
|
||||
users.splice(0, 1);
|
||||
follow(user, process);
|
||||
} else {
|
||||
phantom.exit();
|
||||
}
|
||||
}
|
||||
|
||||
process();
|
||||
@@ -0,0 +1,2 @@
|
||||
console.log 'Hello, world!'
|
||||
phantom.exit()
|
||||
@@ -0,0 +1,2 @@
|
||||
console.log('Hello, world!');
|
||||
phantom.exit();
|
||||
@@ -0,0 +1,20 @@
|
||||
# Upload an image to imagebin.org
|
||||
|
||||
page = require('webpage').create()
|
||||
system = require 'system'
|
||||
|
||||
if system.args.length isnt 2
|
||||
console.log 'Usage: imagebin.coffee filename'
|
||||
phantom.exit 1
|
||||
else
|
||||
fname = system.args[1]
|
||||
page.open 'http://imagebin.org/index.php?page=add', ->
|
||||
page.uploadFile 'input[name=image]', fname
|
||||
page.evaluate ->
|
||||
document.querySelector('input[name=nickname]').value = 'phantom'
|
||||
document.querySelector('input[name=disclaimer_agree]').click()
|
||||
document.querySelector('form').submit()
|
||||
|
||||
window.setTimeout ->
|
||||
phantom.exit()
|
||||
, 3000
|
||||
@@ -0,0 +1,23 @@
|
||||
// Upload an image to imagebin.org
|
||||
|
||||
var page = require('webpage').create(),
|
||||
system = require('system'),
|
||||
fname;
|
||||
|
||||
if (system.args.length !== 2) {
|
||||
console.log('Usage: imagebin.js filename');
|
||||
phantom.exit(1);
|
||||
} else {
|
||||
fname = system.args[1];
|
||||
page.open("http://imagebin.org/index.php?page=add", function () {
|
||||
page.uploadFile('input[name=image]', fname);
|
||||
page.evaluate(function () {
|
||||
document.querySelector('input[name=nickname]').value = 'phantom';
|
||||
document.querySelector('input[name=disclaimer_agree]').click()
|
||||
document.querySelector('form').submit();
|
||||
});
|
||||
window.setTimeout(function () {
|
||||
phantom.exit();
|
||||
}, 3000);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
# Use 'page.injectJs()' to load the script itself in the Page context
|
||||
|
||||
if phantom?
|
||||
page = require('webpage').create()
|
||||
|
||||
# Route "console.log()" calls from within the Page context to the main
|
||||
# Phantom context (i.e. current "this")
|
||||
page.onConsoleMessage = (msg) -> console.log(msg)
|
||||
|
||||
page.onAlert = (msg) -> console.log(msg)
|
||||
|
||||
console.log "* Script running in the Phantom context."
|
||||
console.log "* Script will 'inject' itself in a page..."
|
||||
page.open "about:blank", (status) ->
|
||||
if status is "success"
|
||||
if page.injectJs("injectme.coffee")
|
||||
console.log "... done injecting itself!"
|
||||
else
|
||||
console.log "... fail! Check the $PWD?!"
|
||||
phantom.exit()
|
||||
else
|
||||
alert "* Script running in the Page context."
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// Use 'page.injectJs()' to load the script itself in the Page context
|
||||
|
||||
if ( typeof(phantom) !== "undefined" ) {
|
||||
var page = require('webpage').create();
|
||||
|
||||
// Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this")
|
||||
page.onConsoleMessage = function(msg) {
|
||||
console.log(msg);
|
||||
};
|
||||
|
||||
page.onAlert = function(msg) {
|
||||
console.log(msg);
|
||||
};
|
||||
|
||||
console.log("* Script running in the Phantom context.");
|
||||
console.log("* Script will 'inject' itself in a page...");
|
||||
page.open("about:blank", function(status) {
|
||||
if ( status === "success" ) {
|
||||
console.log(page.injectJs("injectme.js") ? "... done injecting itself!" : "... fail! Check the $PWD?!");
|
||||
}
|
||||
phantom.exit();
|
||||
});
|
||||
} else {
|
||||
alert("* Script running in the Page context.");
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
# Give the estimated location based on the IP address.
|
||||
|
||||
window.cb = (data) ->
|
||||
loc = data.city
|
||||
if data.region_name.length > 0
|
||||
loc = loc + ', ' + data.region_name
|
||||
console.log 'IP address: ' + data.ip
|
||||
console.log 'Estimated location: ' + loc
|
||||
phantom.exit()
|
||||
|
||||
el = document.createElement 'script'
|
||||
el.src = 'http://freegeoip.net/json/?callback=window.cb'
|
||||
document.body.appendChild el
|
||||
@@ -0,0 +1,14 @@
|
||||
// Give the estimated location based on the IP address.
|
||||
|
||||
cb = function (data) {
|
||||
var loc = data.city;
|
||||
if (data.region_name.length > 0)
|
||||
loc = loc + ', ' + data.region_name;
|
||||
console.log('IP address: ' + data.ip);
|
||||
console.log('Estimated location: ' + loc);
|
||||
phantom.exit();
|
||||
};
|
||||
|
||||
var el = document.createElement('script');
|
||||
el.src = 'http://freegeoip.net/json/?callback=cb';
|
||||
document.body.appendChild(el);
|
||||
@@ -0,0 +1,18 @@
|
||||
page = require('webpage').create()
|
||||
system = require 'system'
|
||||
|
||||
if system.args.length is 1
|
||||
console.log 'Usage: loadspeed.coffee <some URL>'
|
||||
phantom.exit 1
|
||||
else
|
||||
t = Date.now()
|
||||
address = system.args[1]
|
||||
page.open address, (status) ->
|
||||
if status isnt 'success'
|
||||
console.log('FAIL to load the address')
|
||||
else
|
||||
t = Date.now() - t
|
||||
console.log('Page title is ' + page.evaluate( (-> document.title) ))
|
||||
console.log('Loading time ' + t + ' msec')
|
||||
phantom.exit()
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
var page = require('webpage').create(),
|
||||
system = require('system'),
|
||||
t, address;
|
||||
|
||||
if (system.args.length === 1) {
|
||||
console.log('Usage: loadspeed.js <some URL>');
|
||||
phantom.exit(1);
|
||||
} else {
|
||||
t = Date.now();
|
||||
address = system.args[1];
|
||||
page.open(address, function (status) {
|
||||
if (status !== 'success') {
|
||||
console.log('FAIL to load the address');
|
||||
} else {
|
||||
t = Date.now() - t;
|
||||
console.log('Page title is ' + page.evaluate(function () {
|
||||
return document.title;
|
||||
}));
|
||||
console.log('Loading time ' + t + ' msec');
|
||||
}
|
||||
phantom.exit();
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
page = require("webpage").create()
|
||||
system = require("system")
|
||||
|
||||
if system.args.length < 2
|
||||
console.log "Usage: loadurlwithoutcss.js URL"
|
||||
phantom.exit()
|
||||
|
||||
address = system.args[1]
|
||||
|
||||
page.onResourceRequested = (requestData, request) ->
|
||||
if (/http:\/\/.+?\.css/g).test(requestData["url"]) or requestData["Content-Type"] is "text/css"
|
||||
console.log "The url of the request is matching. Aborting: " + requestData["url"]
|
||||
request.abort()
|
||||
|
||||
page.open address, (status) ->
|
||||
if status is "success"
|
||||
phantom.exit()
|
||||
else
|
||||
console.log "Unable to load the address!"
|
||||
phantom.exit()
|
||||
@@ -0,0 +1,25 @@
|
||||
var page = require('webpage').create(),
|
||||
system = require('system');
|
||||
|
||||
if (system.args.length < 2) {
|
||||
console.log('Usage: loadurlwithoutcss.js URL');
|
||||
phantom.exit();
|
||||
}
|
||||
|
||||
var address = system.args[1];
|
||||
|
||||
page.onResourceRequested = function(requestData, request) {
|
||||
if ((/http:\/\/.+?\.css/gi).test(requestData['url']) || requestData['Content-Type'] == 'text/css') {
|
||||
console.log('The url of the request is matching. Aborting: ' + requestData['url']);
|
||||
request.abort();
|
||||
}
|
||||
};
|
||||
|
||||
page.open(address, function(status) {
|
||||
if (status === 'success') {
|
||||
phantom.exit();
|
||||
} else {
|
||||
console.log('Unable to load the address!');
|
||||
phantom.exit();
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,4 @@
|
||||
universe = require './universe'
|
||||
universe.start()
|
||||
console.log 'The answer is' + universe.answer
|
||||
phantom.exit()
|
||||
@@ -0,0 +1,4 @@
|
||||
var universe = require('./universe');
|
||||
universe.start();
|
||||
console.log('The answer is' + universe.answer);
|
||||
phantom.exit();
|
||||
@@ -0,0 +1,13 @@
|
||||
# List movies from kids-in-mind.com
|
||||
|
||||
window.cbfunc = (data) ->
|
||||
globaldata = data
|
||||
list = data.query.results.movie
|
||||
for item in list
|
||||
console.log item.title + ' [' + item.rating.MPAA.content + ']'
|
||||
phantom.exit()
|
||||
|
||||
el = document.createElement 'script'
|
||||
el.src =
|
||||
"http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20movies.kids-in-mind&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=window.cbfunc"
|
||||
document.body.appendChild el
|
||||
@@ -0,0 +1,14 @@
|
||||
// List movies from kids-in-mind.com
|
||||
|
||||
var cbfunc = function (data) {
|
||||
globaldata= data;
|
||||
var list = data.query.results.movie;
|
||||
list.forEach(function (item) {
|
||||
console.log(item.title + ' [' + item.rating.MPAA.content + ']');
|
||||
});
|
||||
phantom.exit();
|
||||
};
|
||||
|
||||
var el = document.createElement('script');
|
||||
el.src = 'http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20movies.kids-in-mind&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=cbfunc';
|
||||
document.body.appendChild(el);
|
||||
@@ -0,0 +1,18 @@
|
||||
page = require('webpage').create()
|
||||
system = require 'system'
|
||||
|
||||
if system.args.length is 1
|
||||
console.log 'Usage: netlog.coffee <some URL>'
|
||||
phantom.exit 1
|
||||
else
|
||||
address = system.args[1]
|
||||
page.onResourceRequested = (req) ->
|
||||
console.log 'requested ' + JSON.stringify(req, undefined, 4)
|
||||
|
||||
page.onResourceReceived = (res) ->
|
||||
console.log 'received ' + JSON.stringify(res, undefined, 4)
|
||||
|
||||
page.open address, (status) ->
|
||||
if status isnt 'success'
|
||||
console.log 'FAIL to load the address'
|
||||
phantom.exit()
|
||||
@@ -0,0 +1,25 @@
|
||||
var page = require('webpage').create(),
|
||||
system = require('system'),
|
||||
address;
|
||||
|
||||
if (system.args.length === 1) {
|
||||
console.log('Usage: netlog.js <some URL>');
|
||||
phantom.exit(1);
|
||||
} else {
|
||||
address = system.args[1];
|
||||
|
||||
page.onResourceRequested = function (req) {
|
||||
console.log('requested: ' + JSON.stringify(req, undefined, 4));
|
||||
};
|
||||
|
||||
page.onResourceReceived = function (res) {
|
||||
console.log('received: ' + JSON.stringify(res, undefined, 4));
|
||||
};
|
||||
|
||||
page.open(address, function (status) {
|
||||
if (status !== 'success') {
|
||||
console.log('FAIL to load the address');
|
||||
}
|
||||
phantom.exit();
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
if not Date::toISOString
|
||||
Date::toISOString = ->
|
||||
pad = (n) ->
|
||||
if n < 10 then '0' + n else n
|
||||
ms = (n) ->
|
||||
if n < 10 then '00' + n else (if n < 100 then '0' + n else n)
|
||||
@getFullYear() + '-' +
|
||||
pad(@getMonth() + 1) + '-' +
|
||||
pad(@getDate()) + 'T' +
|
||||
pad(@getHours()) + ':' +
|
||||
pad(@getMinutes()) + ':' +
|
||||
pad(@getSeconds()) + '.' +
|
||||
ms(@getMilliseconds()) + 'Z'
|
||||
|
||||
createHAR = (address, title, startTime, resources) ->
|
||||
entries = []
|
||||
|
||||
resources.forEach (resource) ->
|
||||
request = resource.request
|
||||
startReply = resource.startReply
|
||||
endReply = resource.endReply
|
||||
|
||||
if not request or not startReply or not endReply
|
||||
return
|
||||
|
||||
entries.push
|
||||
startedDateTime: request.time.toISOString()
|
||||
time: endReply.time - request.time
|
||||
request:
|
||||
method: request.method
|
||||
url: request.url
|
||||
httpVersion: 'HTTP/1.1'
|
||||
cookies: []
|
||||
headers: request.headers
|
||||
queryString: []
|
||||
headersSize: -1
|
||||
bodySize: -1
|
||||
|
||||
response:
|
||||
status: endReply.status
|
||||
statusText: endReply.statusText
|
||||
httpVersion: 'HTTP/1.1'
|
||||
cookies: []
|
||||
headers: endReply.headers
|
||||
redirectURL: ''
|
||||
headersSize: -1
|
||||
bodySize: startReply.bodySize
|
||||
content:
|
||||
size: startReply.bodySize
|
||||
mimeType: endReply.contentType
|
||||
|
||||
cache: {}
|
||||
timings:
|
||||
blocked: 0
|
||||
dns: -1
|
||||
connect: -1
|
||||
send: 0
|
||||
wait: startReply.time - request.time
|
||||
receive: endReply.time - startReply.time
|
||||
ssl: -1
|
||||
pageref: address
|
||||
|
||||
log:
|
||||
version: '1.2'
|
||||
creator:
|
||||
name: 'PhantomJS'
|
||||
version: phantom.version.major + '.' + phantom.version.minor + '.' + phantom.version.patch
|
||||
|
||||
pages: [
|
||||
startedDateTime: startTime.toISOString()
|
||||
id: address
|
||||
title: title
|
||||
pageTimings:
|
||||
onLoad: page.endTime - page.startTime
|
||||
]
|
||||
entries: entries
|
||||
|
||||
page = require('webpage').create()
|
||||
system = require 'system'
|
||||
|
||||
if system.args.length is 1
|
||||
console.log 'Usage: netsniff.coffee <some URL>'
|
||||
phantom.exit 1
|
||||
else
|
||||
page.address = system.args[1]
|
||||
page.resources = []
|
||||
|
||||
page.onLoadStarted = ->
|
||||
page.startTime = new Date()
|
||||
|
||||
page.onResourceRequested = (req) ->
|
||||
page.resources[req.id] =
|
||||
request: req
|
||||
startReply: null
|
||||
endReply: null
|
||||
|
||||
page.onResourceReceived = (res) ->
|
||||
if res.stage is 'start'
|
||||
page.resources[res.id].startReply = res
|
||||
if res.stage is 'end'
|
||||
page.resources[res.id].endReply = res
|
||||
|
||||
page.open page.address, (status) ->
|
||||
if status isnt 'success'
|
||||
console.log 'FAIL to load the address'
|
||||
phantom.exit(1)
|
||||
else
|
||||
page.endTime = new Date()
|
||||
page.title = page.evaluate ->
|
||||
document.title
|
||||
|
||||
har = createHAR page.address, page.title, page.startTime, page.resources
|
||||
console.log JSON.stringify har, undefined, 4
|
||||
phantom.exit()
|
||||
@@ -0,0 +1,143 @@
|
||||
if (!Date.prototype.toISOString) {
|
||||
Date.prototype.toISOString = function () {
|
||||
function pad(n) { return n < 10 ? '0' + n : n; }
|
||||
function ms(n) { return n < 10 ? '00'+ n : n < 100 ? '0' + n : n }
|
||||
return this.getFullYear() + '-' +
|
||||
pad(this.getMonth() + 1) + '-' +
|
||||
pad(this.getDate()) + 'T' +
|
||||
pad(this.getHours()) + ':' +
|
||||
pad(this.getMinutes()) + ':' +
|
||||
pad(this.getSeconds()) + '.' +
|
||||
ms(this.getMilliseconds()) + 'Z';
|
||||
}
|
||||
}
|
||||
|
||||
function createHAR(address, title, startTime, resources)
|
||||
{
|
||||
var entries = [];
|
||||
|
||||
resources.forEach(function (resource) {
|
||||
var request = resource.request,
|
||||
startReply = resource.startReply,
|
||||
endReply = resource.endReply;
|
||||
|
||||
if (!request || !startReply || !endReply) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Exclude Data URI from HAR file because
|
||||
// they aren't included in specification
|
||||
if (request.url.match(/(^data:image\/.*)/i)) {
|
||||
return;
|
||||
}
|
||||
|
||||
entries.push({
|
||||
startedDateTime: request.time.toISOString(),
|
||||
time: endReply.time - request.time,
|
||||
request: {
|
||||
method: request.method,
|
||||
url: request.url,
|
||||
httpVersion: "HTTP/1.1",
|
||||
cookies: [],
|
||||
headers: request.headers,
|
||||
queryString: [],
|
||||
headersSize: -1,
|
||||
bodySize: -1
|
||||
},
|
||||
response: {
|
||||
status: endReply.status,
|
||||
statusText: endReply.statusText,
|
||||
httpVersion: "HTTP/1.1",
|
||||
cookies: [],
|
||||
headers: endReply.headers,
|
||||
redirectURL: "",
|
||||
headersSize: -1,
|
||||
bodySize: startReply.bodySize,
|
||||
content: {
|
||||
size: startReply.bodySize,
|
||||
mimeType: endReply.contentType
|
||||
}
|
||||
},
|
||||
cache: {},
|
||||
timings: {
|
||||
blocked: 0,
|
||||
dns: -1,
|
||||
connect: -1,
|
||||
send: 0,
|
||||
wait: startReply.time - request.time,
|
||||
receive: endReply.time - startReply.time,
|
||||
ssl: -1
|
||||
},
|
||||
pageref: address
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
log: {
|
||||
version: '1.2',
|
||||
creator: {
|
||||
name: "PhantomJS",
|
||||
version: phantom.version.major + '.' + phantom.version.minor +
|
||||
'.' + phantom.version.patch
|
||||
},
|
||||
pages: [{
|
||||
startedDateTime: startTime.toISOString(),
|
||||
id: address,
|
||||
title: title,
|
||||
pageTimings: {
|
||||
onLoad: page.endTime - page.startTime
|
||||
}
|
||||
}],
|
||||
entries: entries
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var page = require('webpage').create(),
|
||||
system = require('system');
|
||||
|
||||
if (system.args.length === 1) {
|
||||
console.log('Usage: netsniff.js <some URL>');
|
||||
phantom.exit(1);
|
||||
} else {
|
||||
|
||||
page.address = system.args[1];
|
||||
page.resources = [];
|
||||
|
||||
page.onLoadStarted = function () {
|
||||
page.startTime = new Date();
|
||||
};
|
||||
|
||||
page.onResourceRequested = function (req) {
|
||||
page.resources[req.id] = {
|
||||
request: req,
|
||||
startReply: null,
|
||||
endReply: null
|
||||
};
|
||||
};
|
||||
|
||||
page.onResourceReceived = function (res) {
|
||||
if (res.stage === 'start') {
|
||||
page.resources[res.id].startReply = res;
|
||||
}
|
||||
if (res.stage === 'end') {
|
||||
page.resources[res.id].endReply = res;
|
||||
}
|
||||
};
|
||||
|
||||
page.open(page.address, function (status) {
|
||||
var har;
|
||||
if (status !== 'success') {
|
||||
console.log('FAIL to load the address');
|
||||
phantom.exit(1);
|
||||
} else {
|
||||
page.endTime = new Date();
|
||||
page.title = page.evaluate(function () {
|
||||
return document.title;
|
||||
});
|
||||
har = createHAR(page.address, page.title, page.startTime, page.resources);
|
||||
console.log(JSON.stringify(har, undefined, 4));
|
||||
phantom.exit();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
helloWorld = () -> console.log phantom.outputEncoding + ": こんにちは、世界!"
|
||||
|
||||
console.log "Using default encoding..."
|
||||
helloWorld()
|
||||
|
||||
console.log "\nUsing other encodings..."
|
||||
for enc in ["euc-jp", "sjis", "utf8", "System"]
|
||||
do (enc) ->
|
||||
phantom.outputEncoding = enc
|
||||
helloWorld()
|
||||
|
||||
phantom.exit()
|
||||
@@ -0,0 +1,16 @@
|
||||
function helloWorld() {
|
||||
console.log(phantom.outputEncoding + ": こんにちは、世界!");
|
||||
}
|
||||
|
||||
console.log("Using default encoding...");
|
||||
helloWorld();
|
||||
|
||||
console.log("\nUsing other encodings...");
|
||||
|
||||
var encodings = ["euc-jp", "sjis", "utf8", "System"];
|
||||
for (var i = 0; i < encodings.length; i++) {
|
||||
phantom.outputEncoding = encodings[i];
|
||||
helloWorld();
|
||||
}
|
||||
|
||||
phantom.exit()
|
||||
@@ -0,0 +1,132 @@
|
||||
# The purpose of this is to show how and when events fire, considering 5 steps
|
||||
# happening as follows:
|
||||
#
|
||||
# 1. Load URL
|
||||
# 2. Load same URL, but adding an internal FRAGMENT to it
|
||||
# 3. Click on an internal Link, that points to another internal FRAGMENT
|
||||
# 4. Click on an external Link, that will send the page somewhere else
|
||||
# 5. Close page
|
||||
#
|
||||
# Take particular care when going through the output, to understand when
|
||||
# things happen (and in which order). Particularly, notice what DOESN'T
|
||||
# happen during step 3.
|
||||
#
|
||||
# If invoked with "-v" it will print out the Page Resources as they are
|
||||
# Requested and Received.
|
||||
#
|
||||
# NOTE.1: The "onConsoleMessage/onAlert/onPrompt/onConfirm" events are
|
||||
# registered but not used here. This is left for you to have fun with.
|
||||
# NOTE.2: This script is not here to teach you ANY JavaScript. It's aweful!
|
||||
# NOTE.3: Main audience for this are people new to PhantomJS.
|
||||
printArgs = ->
|
||||
i = undefined
|
||||
ilen = undefined
|
||||
i = 0
|
||||
ilen = arguments_.length
|
||||
|
||||
while i < ilen
|
||||
console.log " arguments[" + i + "] = " + JSON.stringify(arguments_[i])
|
||||
++i
|
||||
console.log ""
|
||||
sys = require("system")
|
||||
page = require("webpage").create()
|
||||
logResources = false
|
||||
step1url = "http://en.wikipedia.org/wiki/DOM_events"
|
||||
step2url = "http://en.wikipedia.org/wiki/DOM_events#Event_flow"
|
||||
logResources = true if sys.args.length > 1 and sys.args[1] is "-v"
|
||||
|
||||
#//////////////////////////////////////////////////////////////////////////////
|
||||
page.onInitialized = ->
|
||||
console.log "page.onInitialized"
|
||||
printArgs.apply this, arguments_
|
||||
|
||||
page.onLoadStarted = ->
|
||||
console.log "page.onLoadStarted"
|
||||
printArgs.apply this, arguments_
|
||||
|
||||
page.onLoadFinished = ->
|
||||
console.log "page.onLoadFinished"
|
||||
printArgs.apply this, arguments_
|
||||
|
||||
page.onUrlChanged = ->
|
||||
console.log "page.onUrlChanged"
|
||||
printArgs.apply this, arguments_
|
||||
|
||||
page.onNavigationRequested = ->
|
||||
console.log "page.onNavigationRequested"
|
||||
printArgs.apply this, arguments_
|
||||
|
||||
if logResources is true
|
||||
page.onResourceRequested = ->
|
||||
console.log "page.onResourceRequested"
|
||||
printArgs.apply this, arguments_
|
||||
|
||||
page.onResourceReceived = ->
|
||||
console.log "page.onResourceReceived"
|
||||
printArgs.apply this, arguments_
|
||||
page.onClosing = ->
|
||||
console.log "page.onClosing"
|
||||
printArgs.apply this, arguments_
|
||||
|
||||
|
||||
# window.console.log(msg);
|
||||
page.onConsoleMessage = ->
|
||||
console.log "page.onConsoleMessage"
|
||||
printArgs.apply this, arguments_
|
||||
|
||||
|
||||
# window.alert(msg);
|
||||
page.onAlert = ->
|
||||
console.log "page.onAlert"
|
||||
printArgs.apply this, arguments_
|
||||
|
||||
|
||||
# var confirmed = window.confirm(msg);
|
||||
page.onConfirm = ->
|
||||
console.log "page.onConfirm"
|
||||
printArgs.apply this, arguments_
|
||||
|
||||
|
||||
# var user_value = window.prompt(msg, default_value);
|
||||
page.onPrompt = ->
|
||||
console.log "page.onPrompt"
|
||||
printArgs.apply this, arguments_
|
||||
|
||||
|
||||
#//////////////////////////////////////////////////////////////////////////////
|
||||
setTimeout (->
|
||||
console.log ""
|
||||
console.log "### STEP 1: Load '" + step1url + "'"
|
||||
page.open step1url
|
||||
), 0
|
||||
setTimeout (->
|
||||
console.log ""
|
||||
console.log "### STEP 2: Load '" + step2url + "' (load same URL plus FRAGMENT)"
|
||||
page.open step2url
|
||||
), 5000
|
||||
setTimeout (->
|
||||
console.log ""
|
||||
console.log "### STEP 3: Click on page internal link (aka FRAGMENT)"
|
||||
page.evaluate ->
|
||||
ev = document.createEvent("MouseEvents")
|
||||
ev.initEvent "click", true, true
|
||||
document.querySelector("a[href='#Event_object']").dispatchEvent ev
|
||||
|
||||
), 10000
|
||||
setTimeout (->
|
||||
console.log ""
|
||||
console.log "### STEP 4: Click on page external link"
|
||||
page.evaluate ->
|
||||
ev = document.createEvent("MouseEvents")
|
||||
ev.initEvent "click", true, true
|
||||
document.querySelector("a[title='JavaScript']").dispatchEvent ev
|
||||
|
||||
), 15000
|
||||
setTimeout (->
|
||||
console.log ""
|
||||
console.log "### STEP 5: Close page and shutdown (with a delay)"
|
||||
page.close()
|
||||
setTimeout (->
|
||||
phantom.exit()
|
||||
), 100
|
||||
), 20000
|
||||
@@ -0,0 +1,142 @@
|
||||
// The purpose of this is to show how and when events fire, considering 5 steps
|
||||
// happening as follows:
|
||||
//
|
||||
// 1. Load URL
|
||||
// 2. Load same URL, but adding an internal FRAGMENT to it
|
||||
// 3. Click on an internal Link, that points to another internal FRAGMENT
|
||||
// 4. Click on an external Link, that will send the page somewhere else
|
||||
// 5. Close page
|
||||
//
|
||||
// Take particular care when going through the output, to understand when
|
||||
// things happen (and in which order). Particularly, notice what DOESN'T
|
||||
// happen during step 3.
|
||||
//
|
||||
// If invoked with "-v" it will print out the Page Resources as they are
|
||||
// Requested and Received.
|
||||
//
|
||||
// NOTE.1: The "onConsoleMessage/onAlert/onPrompt/onConfirm" events are
|
||||
// registered but not used here. This is left for you to have fun with.
|
||||
// NOTE.2: This script is not here to teach you ANY JavaScript. It's aweful!
|
||||
// NOTE.3: Main audience for this are people new to PhantomJS.
|
||||
|
||||
var sys = require("system"),
|
||||
page = require("webpage").create(),
|
||||
logResources = false,
|
||||
step1url = "http://en.wikipedia.org/wiki/DOM_events",
|
||||
step2url = "http://en.wikipedia.org/wiki/DOM_events#Event_flow";
|
||||
|
||||
if (sys.args.length > 1 && sys.args[1] === "-v") {
|
||||
logResources = true;
|
||||
}
|
||||
|
||||
function printArgs() {
|
||||
var i, ilen;
|
||||
for (i = 0, ilen = arguments.length; i < ilen; ++i) {
|
||||
console.log(" arguments[" + i + "] = " + JSON.stringify(arguments[i]));
|
||||
}
|
||||
console.log("");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
page.onInitialized = function() {
|
||||
console.log("page.onInitialized");
|
||||
printArgs.apply(this, arguments);
|
||||
};
|
||||
page.onLoadStarted = function() {
|
||||
console.log("page.onLoadStarted");
|
||||
printArgs.apply(this, arguments);
|
||||
};
|
||||
page.onLoadFinished = function() {
|
||||
console.log("page.onLoadFinished");
|
||||
printArgs.apply(this, arguments);
|
||||
};
|
||||
page.onUrlChanged = function() {
|
||||
console.log("page.onUrlChanged");
|
||||
printArgs.apply(this, arguments);
|
||||
};
|
||||
page.onNavigationRequested = function() {
|
||||
console.log("page.onNavigationRequested");
|
||||
printArgs.apply(this, arguments);
|
||||
};
|
||||
|
||||
if (logResources === true) {
|
||||
page.onResourceRequested = function() {
|
||||
console.log("page.onResourceRequested");
|
||||
printArgs.apply(this, arguments);
|
||||
};
|
||||
page.onResourceReceived = function() {
|
||||
console.log("page.onResourceReceived");
|
||||
printArgs.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
page.onClosing = function() {
|
||||
console.log("page.onClosing");
|
||||
printArgs.apply(this, arguments);
|
||||
};
|
||||
|
||||
// window.console.log(msg);
|
||||
page.onConsoleMessage = function() {
|
||||
console.log("page.onConsoleMessage");
|
||||
printArgs.apply(this, arguments);
|
||||
};
|
||||
|
||||
// window.alert(msg);
|
||||
page.onAlert = function() {
|
||||
console.log("page.onAlert");
|
||||
printArgs.apply(this, arguments);
|
||||
};
|
||||
// var confirmed = window.confirm(msg);
|
||||
page.onConfirm = function() {
|
||||
console.log("page.onConfirm");
|
||||
printArgs.apply(this, arguments);
|
||||
};
|
||||
// var user_value = window.prompt(msg, default_value);
|
||||
page.onPrompt = function() {
|
||||
console.log("page.onPrompt");
|
||||
printArgs.apply(this, arguments);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
setTimeout(function() {
|
||||
console.log("");
|
||||
console.log("### STEP 1: Load '" + step1url + "'");
|
||||
page.open(step1url);
|
||||
}, 0);
|
||||
|
||||
setTimeout(function() {
|
||||
console.log("");
|
||||
console.log("### STEP 2: Load '" + step2url + "' (load same URL plus FRAGMENT)");
|
||||
page.open(step2url);
|
||||
}, 5000);
|
||||
|
||||
setTimeout(function() {
|
||||
console.log("");
|
||||
console.log("### STEP 3: Click on page internal link (aka FRAGMENT)");
|
||||
page.evaluate(function() {
|
||||
var ev = document.createEvent("MouseEvents");
|
||||
ev.initEvent("click", true, true);
|
||||
document.querySelector("a[href='#Event_object']").dispatchEvent(ev);
|
||||
});
|
||||
}, 10000);
|
||||
|
||||
setTimeout(function() {
|
||||
console.log("");
|
||||
console.log("### STEP 4: Click on page external link");
|
||||
page.evaluate(function() {
|
||||
var ev = document.createEvent("MouseEvents");
|
||||
ev.initEvent("click", true, true);
|
||||
document.querySelector("a[title='JavaScript']").dispatchEvent(ev);
|
||||
});
|
||||
}, 15000);
|
||||
|
||||
setTimeout(function() {
|
||||
console.log("");
|
||||
console.log("### STEP 5: Close page and shutdown (with a delay)");
|
||||
page.close();
|
||||
setTimeout(function(){
|
||||
phantom.exit();
|
||||
}, 100);
|
||||
}, 20000);
|
||||