-
-
Notifications
You must be signed in to change notification settings - Fork 8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #66 from eladxxx/master
Style/theme implementation
- Loading branch information
Showing
9 changed files
with
510 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
var styles = {}; // shared styles | ||
|
||
var themes = {}; // shared themes | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,185 @@ | ||
RELS.THEME = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"; | ||
|
||
/* Various RGB/HSL utility functions - might want to put these elsewhere. */ | ||
/* From http://www.javascripter.net/faq/hextorgb.htm, usage: var X = hexToX('FFFFFF') */ | ||
function cutHex(h) {return (h.charAt(0)=="#") ? h.substring(1,7):h} | ||
function hexToR(h) {return parseInt((cutHex(h)).substring(0,2),16)} | ||
function hexToG(h) {return parseInt((cutHex(h)).substring(2,4),16)} | ||
function hexToB(h) {return parseInt((cutHex(h)).substring(4,6),16)} | ||
/* From http://www.javascripter.net/faq/rgbtohex.htm, usage: var RGB = rgbToHex(R, G, B) */ | ||
function toHex(n) { | ||
n = parseInt(n,10); | ||
if (isNaN(n)) return "00"; | ||
n = Math.max(0,Math.min(n,255)); | ||
return "0123456789ABCDEF".charAt((n-n%16)/16) | ||
+ "0123456789ABCDEF".charAt(n%16); | ||
} | ||
function rgbToHex(R,G,B) {return toHex(R)+toHex(G)+toHex(B)} | ||
/* From the specification. */ | ||
var HLSMAX = 255; | ||
/* From https://gist.github.com/mjackson/5311256 via http://stackoverflow.com/a/9493060 */ | ||
/** | ||
* Converts an RGB color value to HSL. Conversion formula | ||
* adapted from http://en.wikipedia.org/wiki/HSL_color_space. | ||
* Assumes r, g, and b are contained in the set [0, 255] and | ||
* returns h, s, and l in the set [0, 1]. | ||
* | ||
* @param Number r The red color value | ||
* @param Number g The green color value | ||
* @param Number b The blue color value | ||
* @return Array The HSL representation | ||
*/ | ||
function rgbToHsl(r, g, b){ | ||
r /= 255, g /= 255, b /= 255; | ||
var max = Math.max(r, g, b), min = Math.min(r, g, b); | ||
var h, s, l = (max + min) / 2; | ||
|
||
if(max == min){ | ||
h = s = 0; // achromatic | ||
}else{ | ||
var d = max - min; | ||
s = l > 0.5 ? d / (2 - max - min) : d / (max + min); | ||
switch(max){ | ||
case r: h = (g - b) / d + (g < b ? 6 : 0); break; | ||
case g: h = (b - r) / d + 2; break; | ||
case b: h = (r - g) / d + 4; break; | ||
} | ||
h /= 6; | ||
} | ||
|
||
return [h, s, l]; | ||
} | ||
/** | ||
* Converts an HSL color value to RGB. Conversion formula | ||
* adapted from http://en.wikipedia.org/wiki/HSL_color_space. | ||
* Assumes h, s, and l are contained in the set [0, 1] and | ||
* returns r, g, and b in the set [0, 255]. | ||
* | ||
* @param Number h The hue | ||
* @param Number s The saturation | ||
* @param Number l The lightness | ||
* @return Array The RGB representation | ||
*/ | ||
function hslToRgb(h, s, l){ | ||
var r, g, b; | ||
|
||
if(s == 0){ | ||
r = g = b = l; // achromatic | ||
}else{ | ||
function hue2rgb(p, q, t){ | ||
if(t < 0) t += 1; | ||
if(t > 1) t -= 1; | ||
if(t < 1/6) return p + (q - p) * 6 * t; | ||
if(t < 1/2) return q; | ||
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6; | ||
return p; | ||
} | ||
|
||
var q = l < 0.5 ? l * (1 + s) : l + s - l * s; | ||
var p = 2 * l - q; | ||
r = hue2rgb(p, q, h + 1/3); | ||
g = hue2rgb(p, q, h); | ||
b = hue2rgb(p, q, h - 1/3); | ||
} | ||
|
||
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; | ||
} | ||
/* Utility function to apply tint to an RGB color. */ | ||
function rgb_tint(rgb, tint) { | ||
var r = hexToR(rgb), | ||
g = hexToG(rgb), | ||
b = hexToB(rgb), | ||
hsl = rgbToHsl(r, g, b); | ||
|
||
/* Apply tint as described in pages 1757-1758 of the ECMA Office Open XML specification. */ | ||
/* NOTE: This is totally messed up... see http://social.msdn.microsoft.com/Forums/en-US/e9d8c136-6d62-4098-9b1b-dac786149f43/excel-color-tint-algorithm-incorrect */ | ||
if (tint < 0) { | ||
hsl[2] = hsl[2] * (1.0 + tint); | ||
} else if (tint > 0) { | ||
hsl[2] = hsl[2] * (1.0 + tint); | ||
|
||
// XXX This doesn't work... | ||
//hsl[2] = hsl[2] * (1.0 - tint) + (HLSMAX - HLSMAX * (1.0 - tint)); | ||
} | ||
|
||
rgb = hslToRgb(hsl[0], hsl[1], hsl[2]); | ||
|
||
return rgbToHex(rgb[0], rgb[1], rgb[2]); | ||
} | ||
|
||
function parse_clrScheme(t, opts) { | ||
themes.themeElements.clrScheme = []; | ||
var color = {}; | ||
t[0].match(/<[^>]*>/g).forEach(function(x) { | ||
var y = parsexmltag(x); | ||
switch(y[0]) { | ||
case '<a:clrScheme': case '<<a:clrScheme>': case '</<a:clrScheme>': break; | ||
|
||
/* 20.1.2.3.32 srgbClr CT_SRgbColor */ | ||
case '<a:srgbClr': color.rgb = y.val; break; | ||
|
||
/* 20.1.2.3.33 sysClr CT_SystemColor */ | ||
case '<a:sysClr': color.rgb = y.lastClr; break; | ||
|
||
/* 20.1.4.1.9 dk1 (Dark 1) */ | ||
case '<a:dk1>': | ||
case '</a:dk1>': | ||
/* 20.1.4.1.10 dk2 (Dark 2) */ | ||
case '<a:dk2>': | ||
case '</a:dk2>': | ||
/* 20.1.4.1.22 lt1 (Light 1) */ | ||
case '<a:lt1>': | ||
case '</a:lt1>': | ||
/* 20.1.4.1.23 lt2 (Light 2) */ | ||
case '<a:lt2>': | ||
case '</a:lt2>': | ||
/* 20.1.4.1.1 accent1 (Accent 1) */ | ||
case '<a:accent1>': | ||
case '</a:accent1>': | ||
/* 20.1.4.1.2 accent2 (Accent 2) */ | ||
case '<a:accent2>': | ||
case '</a:accent2>': | ||
/* 20.1.4.1.3 accent3 (Accent 3) */ | ||
case '<a:accent3>': | ||
case '</a:accent3>': | ||
/* 20.1.4.1.4 accent4 (Accent 4) */ | ||
case '<a:accent4>': | ||
case '</a:accent4>': | ||
/* 20.1.4.1.5 accent5 (Accent 5) */ | ||
case '<a:accent5>': | ||
case '</a:accent5>': | ||
/* 20.1.4.1.6 accent6 (Accent 6) */ | ||
case '<a:accent6>': | ||
case '</a:accent6>': | ||
/* 20.1.4.1.19 hlink (Hyperlink) */ | ||
case '<a:hlink>': | ||
case '</a:hlink>': | ||
/* 20.1.4.1.15 folHlink (Followed Hyperlink) */ | ||
case '<a:folHlink>': | ||
case '</a:folHlink>': | ||
if (y[0][1] === '/') { | ||
themes.themeElements.clrScheme.push(color); | ||
color = {}; | ||
} else { | ||
color.name = y[0].substring(3, y[0].length - 1); | ||
} | ||
break; | ||
|
||
default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in clrScheme'; | ||
} | ||
}); | ||
} | ||
|
||
/* 14.2.7 Theme Part */ | ||
function parse_theme_xml(data, opts) { | ||
themes.themeElements = {}; | ||
|
||
var t; | ||
|
||
/* clrScheme */ | ||
if((t=data.match(/<a:clrScheme([^>]*)>.*<\/a:clrScheme>/))) parse_clrScheme(t, opts); | ||
|
||
return themes; | ||
} | ||
|
||
function write_theme() { return '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme"><a:themeElements><a:clrScheme name="Office"><a:dk1><a:sysClr val="windowText" lastClr="000000"/></a:dk1><a:lt1><a:sysClr val="window" lastClr="FFFFFF"/></a:lt1><a:dk2><a:srgbClr val="1F497D"/></a:dk2><a:lt2><a:srgbClr val="EEECE1"/></a:lt2><a:accent1><a:srgbClr val="4F81BD"/></a:accent1><a:accent2><a:srgbClr val="C0504D"/></a:accent2><a:accent3><a:srgbClr val="9BBB59"/></a:accent3><a:accent4><a:srgbClr val="8064A2"/></a:accent4><a:accent5><a:srgbClr val="4BACC6"/></a:accent5><a:accent6><a:srgbClr val="F79646"/></a:accent6><a:hlink><a:srgbClr val="0000FF"/></a:hlink><a:folHlink><a:srgbClr val="800080"/></a:folHlink></a:clrScheme><a:fontScheme name="Office"><a:majorFont><a:latin typeface="Cambria"/><a:ea typeface=""/><a:cs typeface=""/><a:font script="Jpan" typeface="MS Pゴシック"/><a:font script="Hang" typeface="맑은 고딕"/><a:font script="Hans" typeface="宋体"/><a:font script="Hant" typeface="新細明體"/><a:font script="Arab" typeface="Times New Roman"/><a:font script="Hebr" typeface="Times New Roman"/><a:font script="Thai" typeface="Tahoma"/><a:font script="Ethi" typeface="Nyala"/><a:font script="Beng" typeface="Vrinda"/><a:font script="Gujr" typeface="Shruti"/><a:font script="Khmr" typeface="MoolBoran"/><a:font script="Knda" typeface="Tunga"/><a:font script="Guru" typeface="Raavi"/><a:font script="Cans" typeface="Euphemia"/><a:font script="Cher" typeface="Plantagenet Cherokee"/><a:font script="Yiii" typeface="Microsoft Yi Baiti"/><a:font script="Tibt" typeface="Microsoft Himalaya"/><a:font script="Thaa" typeface="MV Boli"/><a:font script="Deva" typeface="Mangal"/><a:font script="Telu" typeface="Gautami"/><a:font script="Taml" typeface="Latha"/><a:font script="Syrc" typeface="Estrangelo Edessa"/><a:font script="Orya" typeface="Kalinga"/><a:font script="Mlym" typeface="Kartika"/><a:font script="Laoo" typeface="DokChampa"/><a:font script="Sinh" typeface="Iskoola Pota"/><a:font script="Mong" typeface="Mongolian Baiti"/><a:font script="Viet" typeface="Times New Roman"/><a:font script="Uigh" typeface="Microsoft Uighur"/><a:font script="Geor" typeface="Sylfaen"/></a:majorFont><a:minorFont><a:latin typeface="Calibri"/><a:ea typeface=""/><a:cs typeface=""/><a:font script="Jpan" typeface="MS Pゴシック"/><a:font script="Hang" typeface="맑은 고딕"/><a:font script="Hans" typeface="宋体"/><a:font script="Hant" typeface="新細明體"/><a:font script="Arab" typeface="Arial"/><a:font script="Hebr" typeface="Arial"/><a:font script="Thai" typeface="Tahoma"/><a:font script="Ethi" typeface="Nyala"/><a:font script="Beng" typeface="Vrinda"/><a:font script="Gujr" typeface="Shruti"/><a:font script="Khmr" typeface="DaunPenh"/><a:font script="Knda" typeface="Tunga"/><a:font script="Guru" typeface="Raavi"/><a:font script="Cans" typeface="Euphemia"/><a:font script="Cher" typeface="Plantagenet Cherokee"/><a:font script="Yiii" typeface="Microsoft Yi Baiti"/><a:font script="Tibt" typeface="Microsoft Himalaya"/><a:font script="Thaa" typeface="MV Boli"/><a:font script="Deva" typeface="Mangal"/><a:font script="Telu" typeface="Gautami"/><a:font script="Taml" typeface="Latha"/><a:font script="Syrc" typeface="Estrangelo Edessa"/><a:font script="Orya" typeface="Kalinga"/><a:font script="Mlym" typeface="Kartika"/><a:font script="Laoo" typeface="DokChampa"/><a:font script="Sinh" typeface="Iskoola Pota"/><a:font script="Mong" typeface="Mongolian Baiti"/><a:font script="Viet" typeface="Arial"/><a:font script="Uigh" typeface="Microsoft Uighur"/><a:font script="Geor" typeface="Sylfaen"/></a:minorFont></a:fontScheme><a:fmtScheme name="Office"><a:fillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="50000"/><a:satMod val="300000"/></a:schemeClr></a:gs><a:gs pos="35000"><a:schemeClr val="phClr"><a:tint val="37000"/><a:satMod val="300000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:tint val="15000"/><a:satMod val="350000"/></a:schemeClr></a:gs></a:gsLst><a:lin ang="16200000" scaled="1"/></a:gradFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="100000"/><a:shade val="100000"/><a:satMod val="130000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:tint val="50000"/><a:shade val="100000"/><a:satMod val="350000"/></a:schemeClr></a:gs></a:gsLst><a:lin ang="16200000" scaled="0"/></a:gradFill></a:fillStyleLst><a:lnStyleLst><a:ln w="9525" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"><a:shade val="95000"/><a:satMod val="105000"/></a:schemeClr></a:solidFill><a:prstDash val="solid"/></a:ln><a:ln w="25400" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/></a:ln><a:ln w="38100" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst><a:outerShdw blurRad="40000" dist="20000" dir="5400000" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="38000"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad="40000" dist="23000" dir="5400000" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="35000"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad="40000" dist="23000" dir="5400000" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="35000"/></a:srgbClr></a:outerShdw></a:effectLst><a:scene3d><a:camera prst="orthographicFront"><a:rot lat="0" lon="0" rev="0"/></a:camera><a:lightRig rig="threePt" dir="t"><a:rot lat="0" lon="0" rev="1200000"/></a:lightRig></a:scene3d><a:sp3d><a:bevelT w="63500" h="25400"/></a:sp3d></a:effectStyle></a:effectStyleLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="40000"/><a:satMod val="350000"/></a:schemeClr></a:gs><a:gs pos="40000"><a:schemeClr val="phClr"><a:tint val="45000"/><a:shade val="99000"/><a:satMod val="350000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:shade val="20000"/><a:satMod val="255000"/></a:schemeClr></a:gs></a:gsLst><a:path path="circle"><a:fillToRect l="50000" t="-80000" r="50000" b="180000"/></a:path></a:gradFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="80000"/><a:satMod val="300000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:shade val="30000"/><a:satMod val="200000"/></a:schemeClr></a:gs></a:gsLst><a:path path="circle"><a:fillToRect l="50000" t="50000" r="50000" b="50000"/></a:path></a:gradFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements><a:objectDefaults><a:spDef><a:spPr/><a:bodyPr/><a:lstStyle/><a:style><a:lnRef idx="1"><a:schemeClr val="accent1"/></a:lnRef><a:fillRef idx="3"><a:schemeClr val="accent1"/></a:fillRef><a:effectRef idx="2"><a:schemeClr val="accent1"/></a:effectRef><a:fontRef idx="minor"><a:schemeClr val="lt1"/></a:fontRef></a:style></a:spDef><a:lnDef><a:spPr/><a:bodyPr/><a:lstStyle/><a:style><a:lnRef idx="2"><a:schemeClr val="accent1"/></a:lnRef><a:fillRef idx="0"><a:schemeClr val="accent1"/></a:fillRef><a:effectRef idx="1"><a:schemeClr val="accent1"/></a:effectRef><a:fontRef idx="minor"><a:schemeClr val="tx1"/></a:fontRef></a:style></a:lnDef></a:objectDefaults><a:extraClrSchemeLst/></a:theme>'; } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.