Sorry, there are no scripts tagged wars;msg5422
There are 11 previous versions of this script.
Add Syntax Highlighting (this will take a few seconds, probably freezing your browser while it works)
// ==UserScript==
// @name Google Reader - Colorful List View
// @namespace http://google.reader.colorful.list.view/kepp
// @include http://www.google.com/reader/*
// @include https://www.google.com/reader/*
// @include http://userscripts.org/scripts/source/8782.meta.js
// @description Colorizes the item headers in Google Reader list view and the entries in expanded view.
// @version 20091122
// @jsversion 1.6
// ==/UserScript==
/**
*
* XXXXXXXX Not done yet
* Fix settings messages being partially hidden in Chrome.
* Fix for updates not showing in Chrome
* Added prefs for customizable color scheme.
* - Selectable background color hue, lightness ranges and saturation.
* - Selectable text color hue, lightness ranges and saturation.
*
* 20091122
* Fix for breakage on expanded view.
* CSS modified to increase selector priority to ensure colors get applied.
*
* 20091120
* Fix pref settings when DOM Storage is used.
* Fix for GM_getValue detection on Google Chrome dev channel.
* Fix for not working after encountering a shared item. Script also works on
* the "Your stuff", Shared Items and Notes pages with this.
* Switch code bracing style.
*
* 20091117
* Added prefs to select what is colored in expanded view, entry body or
* outline.
* Fix for update version check being in the wrong direction.
* Fix for coloring unread items only in list view.
* Added Google Chrome support.
*
* 20090822
* Fix to ensure that all items get colored.
* Fixes for Google Reader update.
* Added script update notification to the settings page.
* Added Opera compatibility.
* - Remove use of "for each".
* - Add alternatives to GM_ functions (GM_addStyle, GM_setValue, GM_getValue).
* - Modify coloring CSS.
* Cleaned up some code.
* Also added DOM Storage fallback option.
*
*
* 20081214
* Prefs split out into independent items and updated to apply instantly.
* Pref notification messages are also fixed to work properly.
* Fix for script not working if Google Gears was installed (my bad design).
* Works on expanded view too now. Possible/easier with Google Reader now using
* CSS for rounded borders.
**
* 20081104
* Added settings for coloring read/unread items.
* Adjusted things in the settings.
**
* 20080730
* Fixed css mistake of read items not being colored.
* Added https:// url to the include list.
* Added coloring option on settings page, added settings page to the exclude
* list.
**/
// var script = document.createElement("script");
// script.innerHTML = "(" +
(function() {
// info used to check for script updates
const SCRIPT_INFO = {
version: "20091122",
date: "Sat Nov 22 2009 00:00:00 GMT",
updateUrl: "http://userscripts.org/scripts/source/8782.meta.js",
installUrl: "http://userscripts.org/scripts/source/8782.user.js"
};
// CSS to allow items to be colored
const BASE_CSS = "\
#enctires.list .entry-likers, /* like count */\
#entries.list .collapsed .entry-source-title,\
#entries.list .collapsed .entry-secondary,\
#entries.list .collapsed .entry-title {\
background-color: transparent !important;\
}\
.gm-color-lv .collapsed /* list view headers */ {\
border-color: transparent !important;\
}\
#entries.list.gm-color-lv #current-entry .collapsed {\
border: 2px solid #8181DC !important;\
}\
#entries.list.gm-color-lv #current-entry.expanded .collapsed {\
border-bottom-color: transparent !important;\
border-width: 2px 0 !important;\
}\
#entries .entry {\
padding: 5px 0;\
}\
#entries.list .collapsed {\
line-height: 2.4ex !important; /* hide entry snippet 2nd line */\
}";
const STRINGS = {
// pref labels
color: "Color these items:",
list: "List view headers.",
expanded: "Expanded view entry bodies.",
frame: "Expanded view entry frames.",
read: "Read items.",
unread: "Unread items.",
// pref messages
msgWill: "will",
msgWillNot: "will not",
msgColored: " be colored.",
msgList: "List view items ",
msgExpanded: "Expanded view entry bodies ",
msgFrame: "Expanded view entry frames ",
msgUnread: "Unread items ",
msgRead: "Read items ",
msgUndef: "Undefined",
scheme: "Color Scheme: ",
def: "Default",
custom: "Custom",
update: "Userscript Update Available",
install: "Install"
};
//=============================================================================
function $id( id ) {
return document.getElementById( id );
}
function $x( query, context ) {
var doc = ( context ) ? context.ownerDocument : document
return doc.evaluate( query, ( context || doc ), null,
XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue;
}
function $xa( query ) {
var res = document.evaluate( query, document, null,
XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null );
var element, array = [];
while ( element = res.iterateNext() )
array.push( element );
return array;
}
function addStyle( css ) {
var style = document.createElement( "style" );
style.type = "text/css";
style.textContent = css; // innerHTML throws NO_MODIFICATION_ALLOWED_ERR
document.getElementsByTagName( "head" )[0].appendChild( style );
return style;
}
//=============================================================================
// script updater
var updater = {
loader: null,
version: 0,
homeUrl: "",
updateUrl: "",
installUrl: "",
init: function() {
for ( var prop in SCRIPT_INFO )
this[ prop ] = SCRIPT_INFO[ prop ];
// test if this is the script meta info page that loaded
if ( location.href == SCRIPT_INFO.updateUrl ) {
// running on userscripts.org domain
document.body.setAttribute( "style", "visibility: hidden;\
overflow: hidden;" );
// there's an update, update link not inserted yet
if ( !document.getElementsByTagName( "a" ).length ) {
if ( this.parseMetaInfo() )
// this will reload the page
this.insertUpdateLink( this.installUrl );
}
else {
document.body.setAttribute( "style", "visibility: visible;\
overflow: hidden;font-family: Arial, sans-serif;color: #2244BB;" );
}
return true; // notify that this was the script meta page
}
var loader = document.createElement( "iframe" );
loader.setAttribute( "style", "position: absolute;\
height: 0; width: 0;" );
this.loader = document.body.appendChild( loader );
},
parseMetaInfo: function() {
var scriptInfo = document.body.innerHTML;
var updateAvailable;
// compare script versions
if ( /@version\s*([\S]+)/.test( scriptInfo ) )
updateAvailable = this.version < RegExp.$1;
// compare script dates
else if ( /@uso:timestamp\s*(\S.+)/.test( scriptInfo ) )
updateAvailable = new Date( this.date ) < new Date( RegExp.$1 );
return updateAvailable;
},
insertUpdateLink: function( url ) { // insert link to newer script version
document.open( "text/html" );
document.write( "<html><head><meta http-equiv=\"Content-Type\"\
content=\"text/html; charset=windows-1251\"></head>\
<body>" + STRINGS.update + ": <a href=\"" +
url + "\" target=\"_blank\">" +
STRINGS.install + "</a><body></html>" );
document.close();
},
check: function() { // runs on google.com domain
var lastCheck = storage.getItem( "last-check", 0 );
if ( new Date().getTime() - lastCheck < 3*24*60*60*1000 ) // 3 days
return false;
this.loader.setAttribute( "style", "visibility: visible;\
overflow: hidden;\
position: absolute; right: 2em;\
height: 2em; width: 20em;" );
this.loader.src = this.updateUrl;
// just check it every time the settings page is opened
// storage.setItem( "last-check", new Date().getTime() + "" );
return this.loader;
}
};
// user interface for script settings added on settings page
var settings = {
timeoutID: 0,
entries: null,
init: function() { // insert page color options into the settings page
// ascend out of iframe
this.entries = frameElement.ownerDocument.getElementById( "entries" );
var sect = this.addPrefs();
// check for userscript updates
// comment this section out if you want to disable update checks
var check = updater.check();
if ( check )
sect.insertBefore( check, sect.firstChild );
},
addPrefs: function() {
var sect = document.createElement( "div" );
sect.className = "extra";
// two column list, yay <_<
sect.innerHTML = "<div class=\"extra-header\">Colors</div>" +
STRINGS.color +
"<div style=\"width: 30em; margin: 0pt 0pt 1em 1em;\">\
<ul style=\"list-style-type: none; padding-left: 0;\
float: right;\">\
</ul>\
<ul style=\"list-style-type: none; padding-left: 0;\">\
</ul></div>";// + STRINGS.scheme;
$id( "setting-extras-body" ).appendChild( sect );
var lists = sect.getElementsByTagName( "ul" );
var me = this;
function tc( event ) {
me.toggleColors( event.target.id, event.target.checked );
}
this.addColorPref( lists[ 0 ], "gm-color-ri", STRINGS.read, tc );
this.addColorPref( lists[ 0 ], "gm-color-ui", STRINGS.unread, tc );
this.addColorPref( lists[ 1 ], "gm-color-lv", STRINGS.list, tc );
this.addColorPref( lists[ 1 ], "gm-color-ev", STRINGS.expanded, tc );
this.addColorPref( lists[ 1 ], "gm-color-ef", STRINGS.frame, tc, 0 );
// this.addSchemePref( sect );
return sect;
},
addColorPref: function ( list, id, text, handler, def ) {
var pref = document.createElement( "li" );
var selected = storage.getItem( id, ( def == undefined ) ? 1 : def );
pref.innerHTML = "<label><input id=\"" + id + "\" type=\"checkbox\" " +
( ( selected ) ? "checked=\"on\"" : "" ) +
"\"/>" + text + "</label>";
list.appendChild( pref );
var label = pref.firstChild.firstChild;
label.addEventListener( "change", handler, false );
},
toggleColors: function( id, curr ) {
var msg, newPref = "", cName = "";
if ( curr ) {
newPref = id;
cName = id + " ";
msg = "<em>" + STRINGS.msgWill + "</em>";
}
else {
msg = "<em>" + STRINGS.msgWillNot + "</em>";
}
var re = new RegExp( id + " |^", "g" );
this.entries.className = this.entries.className.replace( re, cName );
storage.setItem( id, newPref );
this.setMessage( id, msg );
},
togglePref: function( event ) {
if ( this.value == STRINGS.custom ) {
this.style.fontStyle = "italic";
addButton.removeAttribute( "disabled" );
}
else {
this.style.fontStyle = "";
addButton.setAttribute( "disabled", "true" );
}
},
setMessage: function( id, msg ) {
clearTimeout( this.timeoutID );
var inner = $x( "id( 'message-area-inner' )" );
var outer = $x( "id( 'message-area-outer' )" );
// get the message string to insert into the page
var type = ( id == "gm-color-lv" ) ? STRINGS.msgList :
( id == "gm-color-ev" ) ? STRINGS.msgExpanded :
( id == "gm-color-ef" ) ? STRINGS.msgFrame :
( id == "gm-color-ui" ) ? STRINGS.msgUnread :
( id == "gm-color-ri" ) ? STRINGS.msgRead : STRINGS.msgUndef;
var newMsg = type + msg + STRINGS.msgColored;
inner.innerHTML = newMsg; // set the message
// force display and set position and width
outer.setAttribute( "style", "display: block !important;" +
"margin-left:" +
Math.round( inner.offsetWidth/-2 ) + "px;" +
"width:" + (inner.offsetWidth + 10) + "px;" );
outer.className = "message-area info-message";
this.timeoutID = setTimeout( function() {
outer.style.display = "";
// test if the same message is still showing.
// force lowercase to handle any (tag name) capitalization change
if ( inner.innerHTML.toLowerCase() == newMsg.toLowerCase() )
outer.className = outer.className.replace( / hidden|$/, " hidden" );
}, 7*1000 );
},
getColorPrefs: function() {
var prefs = "";
prefs += storage.getItem( "gm-color-lv", "gm-color-lv" ) + " ";
prefs += storage.getItem( "gm-color-ev", "gm-color-ev" ) + " ";
prefs += storage.getItem( "gm-color-ef", "" ) + " ";
prefs += storage.getItem( "gm-color-ui", "gm-color-ui" ) + " ";
prefs += storage.getItem( "gm-color-ri", "gm-color-ri" ) + " ";
return prefs;
}
};
// provide local data storage
var storage = {
cookie: {},
init: function() { // initialize methods for data storage access
// Google Chrome dev channel stubs GM_ functions with error messages
// test it's the real deal by looking for "arguments" in stingified version
if ( typeof GM_getValue != "undefined" &&
/arguments/.test( GM_getValue.toString() ) ) {
this.getItem = GM_getValue;
this.setItem = GM_setValue;
return;
}
// Google Chrome gives null for localStorage if not enabled by switch,
// Opera gives undefined
// http://www.w3.org/TR/webstorage/#the-storage-interface
if ( typeof localStorage != "undefined" && localStorage != null ) {
this.getItem = function( key, def ) {
var value = localStorage.getItem( key );
return ( value == null ) ? def : value;
};
this.setItem = function( key, value ) {
localStorage.setItem( key, value );
};
return;
}
var pairs = {};
if ( /gm-color=([^;]*)/.test( unescape( document.cookie ) ) ) {
var cookie = RegExp.$1;
cookie.split( "/" ).forEach( function( pair ) {
var set = pair.split( ":" );
pairs[ set[ 0 ] ] = set[ 1 ];
} );
}
this.cookie = pairs;
},
getItem: function( name, def ) {
var cookieVal = this.cookie[ name ];
return ( typeof cookieVal == "undefined" ) ? def : cookieVal;
},
setItem: function( name, value ) {
this.cookie[ name ] = value;
var strCookie = "gm-color=";
for ( var prop in this.cookie )
strCookie += prop + ":" + this.cookie[ prop ] + "/";
var future = new Date( ( new Date().getTime() + 10*365*24*60*60*1000 ) );
strCookie += ";path=/reader;expires=" + future.toGMTString();
document.cookie = strCookie;
},
};
// used to keep track of all the calculated colors
var colors = {};
//=============================================================================
// calculate item hue
function getHue( title ) {
var hue = 0;
for ( var i = 0, ch; ch = title[ i ]; i++ )
hue += ch.charCodeAt( 0 );
hue %= 360;
colors[ title ] = hue;
return hue;
}
function getColorCss( title ) {
var hue = getHue( title );
return getLvCss( title, hue ) + getEvCss( title, hue ) +
getEfCss( title, hue );
}
function getLvCss( ttl, hue ) { // css for coloring items in list view
// this selector should be take priority over any other selector
var lvUi = "#entries.gm-color-lv.gm-color-ui div[ colored='";
var lvRi = "#entries.gm-color-lv.gm-color-ri div[ colored='";
return "" +
lvUi + ttl + "' ] .collapsed {\
background-color: hsl(" + hue + ", 70%, 80% ) !important;\
}" +
lvUi + ttl + "' ]:hover .collapsed {\
background-color: hsl(" + hue + ", 90%, 85% ) !important;\
}" +
lvUi + ttl + "' ].read .collapsed," +
lvUi + ttl + "' ].read:hover .collapsed {\
background-color: white !important; /* override to force no color */\
}" +
lvRi + ttl + "' ].read .collapsed {\
/* color read items. overrides the unread item setting. */\
background-color: hsl(" + hue + ", 50%, 90% ) !important;\
}" +
lvRi + ttl + "' ].read:hover\
.collapsed {\
/* color read items. overrides the unread item setting. */\
background-color: hsl(" + hue + ", 70%, 95% ) !important;\
}";
}
function getEvCss( ttl, hue ) { // css for coloring expanded view item bodies
var evUi = "#entries.gm-color-ev.gm-color-ui div[ colored='";
var evRi = "#entries.gm-color-ev.gm-color-ri div[ colored='";
return "" +
evUi + ttl + "' ] .card," +
/* .ccard, .t2, .t3 in Opera expanded view */
evUi + ttl + "' ] .ccard," +
evUi + ttl + "' ] .t2," +
evUi + ttl + "' ] .t3 {\
background-color: hsl(" + hue + ", 70%, 80% ) !important;\
}" +
evUi + ttl + "' ]:hover .card," +
evUi + ttl + "' ]:hover .ccard," +
evUi + ttl + "' ]:hover .t2," +
evUi + ttl + "' ]:hover .t3 {\
background-color: hsl(" + hue + ", 90%, 85% ) !important;\
}" +
evUi + ttl + "' ].read .card," +
evUi + ttl + "' ].read .ccard," +
evUi + ttl + "' ].read .t2," +
evUi + ttl + "' ].read .t3," +
evUi + ttl + "' ].read:hover .card," +
evUi + ttl + "' ].read:hover .ccard," +
evUi + ttl + "' ].read:hover .t2," +
evUi + ttl + "' ].read:hover .t3 {\
background-color: white !important; /* override to force no color */\
}" +
evRi + ttl + "' ].read .card," +
evRi + ttl + "' ].read .ccard," +
evRi + ttl + "' ].read .t2," +
evRi + ttl + "' ].read .t3 {\
/* color read items. overrides the unread item setting. */\
background-color: hsl(" + hue + ", 50%, 90% ) !important;\
}" +
evRi + ttl + "' ].read:hover .card," +
evRi + ttl + "' ].read:hover .ccard," +
evRi + ttl + "' ].read:hover .t2," +
evRi + ttl + "' ].read:hover .t3 {\
/* color read items. overrides the unread item setting. */\
background-color: hsl(" + hue + ", 70%, 95% ) !important;\
}";
}
function getEfCss( ttl, hue ) { // css for coloring expanded view item frames
var efUi = "#entries.gm-color-ef.gm-color-ui div[ colored='";
var efRi = "#entries.gm-color-ef.gm-color-ri div[ colored='";
return "" +
efUi + ttl + "' ] {\
background: hsl(" + hue + ", 70%, 80% ) !important;\
}" +
efUi + ttl + "' ]:hover {\
background: hsl(" + hue + ", 90%, 85% ) !important;\
}" +
efUi + ttl + "' ].read," +
efUi + ttl + "' ].read:hover {\
background: #F3F5FC !important; /* override to force no color */\
}" +
efRi + ttl + "' ].read {\
/* color read items. overrides the unread item setting. */\
background: hsl(" + hue + ", 50%, 90% ) !important;\
}" +
efRi + ttl + "' ].read:hover {\
/* color read items. overrides the unread item setting. */\
background: hsl(" + hue + ", 70%, 95% ) !important;\
}";
}
// inject color css into the page
function setColor() {
// pick up all uncolored entries, including ones missed previously
var nocolor = $xa( "id( 'entries' )/div[ contains( @class, 'entry' ) ]" +
"[ not( @colored ) ]" );
if ( !nocolor.length )
return;
nocolor.forEach( function( nc ) {
// source in header is an "<a>" for expanded view, "<span>" for list view
// if "Shared by [xxx]" is there this will grab that
// search for a node that has 'entry-source-title' class name
var src = $x( ".//*[ contains(" +
"concat( ' ', normalize-space( @class ), ' ')," +
"' entry-source-title ' ) ]", nc )
src = src.textContent.replace( /\W/g, "-" );
nc.setAttribute( "colored", src );
if ( colors[ src ] == undefined )
addStyle( getColorCss( src ) );
} );
}
function watchLoading( chrome ) {
// pull this out here out of unsafeWindow context
var prefs = settings.getColorPrefs();
function setup( event ) {
var entries = $id( "entries" );
if ( entries ) {
chrome.removeEventListener( "DOMNodeInserted", setup, false );
// initial setup and toggling of settings
entries.className = prefs + entries.className;
entries.addEventListener( "DOMNodeInserted", setColor, false );
}
}
chrome.addEventListener( "DOMNodeInserted", setup, false );
}
(function() {
var chrome = $id( "chrome" );
storage.init();
if ( chrome )
watchLoading( chrome ); // watch for the loading of rss entries
else { // settings and script meta info page have no "chrome" element
if ( updater.init() ) // script meta info page
return;
settings.init();
}
addStyle( BASE_CSS );
} )();
})();
// .toString() + ")();";
// document.body.appendChild(script);
/* IN PROGRESS CODE
// units in px
const FULL_WIDTH = 360;
const BORDER = 1;
*/
// const STYLE = "\
// .arrow-bg {\
// width: 0;\
// border-bottom: 4px solid #000000; /* 1/2*handle width */\
// border-left: 4px solid transparent;\
// border-right: 4px solid transparent;\
// float: left;\
// margin: 1px 0 0 1px; /* handle border widths */\
// }\
// .arrow-border {\
// width: 0;\
// border-bottom: 5px solid black; /* arrow-bg + border */\
// border-left: 5px solid transparent;\
// border-right: 5px solid transparent;\
// }\
// .handle {\
// height: 8px;\
// width: 8px; /* handle width */\
// border: 1px solid black;\
// }\
// #gm-grad-colors-box {\
// width: 366px; /* width + 2*border + handle width */\
// }\
// #gm-grad-box {\
// height: 20px;\
// width: 360px; /* width */\
// border: 1px solid black; /* border */\
// margin-left: 4px; /* handle width/2 */\
// }";
/*
function addStyle( css ) {
var style = document.createElement( "style" );
style.textContent = css;
document.getElementsByTagName( "head" )[0].appendChild( style );
}
function bind( func, thisArg ) {
var args = Array.prototype.slice.call( arguments, 2 );
return function() {
func.apply( thisArg, args.concat( arguments ) );
}
}
function Color( rgbArr, posFraction, callback ) {
// for signalling the gradient should be updated
this.callback = bind( callback, callback );
this.posFraction = posFraction;
var el = document.createElement( "div" );
el.innerHTML = "<div class=\"arrow-bg\"></div>\
<div class=\"arrow-border\"></div>\
<div class=\"handle\" style=\"background: rgb(" + rgbArr + ");\">\
<div style=\"float: left; width: 6px; height: 6px; border: 1px solid white;\"></div></div>";
el.setAttribute( "style", "position: absolute; margin-left:" +
FULL_WIDTH*posFraction + ";" );
var divs = el.getElementsByTagName( "div" );
this.bg = divs[0];
this.handle = divs[2];
el.addEventListener( "mouseup", bind( this.endDrag, this ), false );
el.addEventListener( "mouseout", bind( this.endDrag, this ), false );
el.addEventListener( "mousedown", bind( this.startDrag, this ), false );
this.element = el;
}
Color.prototype = {
selColor: "rgb( 200, 200, 200 )",
unselColor: "rgb( 0, 0, 0 )",
startDrag: function( event ) {
this.bg.style.borderBottomColor = this.selColor;
this.callback( "select", this );
this.element.addEventListener( "mousemove", this.followDrag, false );
},
endDrag: function( event ) {
this.element.removeEventListener( "mousemove", this.followDrag, false );
},
followDrag: function( event ) {
this.callback( "move", this );
}
};
// ============================================================================
function Gradient() {
this.editor = document.createElement( "div" );
this.editor.id = "gm-grad-editor";
this.editor.innerHTML = "<div id=\"gm-grad-box\"></div>\
<div id=\"gm-grad-colors-box\"></div>";
this.gradBox = this.editor.firstChild; // displays the generated gradient
this.colorBox = this.editor.lastChild; // holds the color stops
}
Gradient.prototype = {
gradBox: null,
colorBox: null,
selected: null,
colors: [],
addColor: function( rgbArr, posFraction, update ) {
var color = new Color( rgbArr, posFraction, bind( this.update, this ) );
this.colors.push( color );
this.colorBox.appendChild( color.element );
if ( update )
this.update.call(this, "add", color );
},
update: function( msg, msgSrc ) {alert(msg);
switch( msg ) {
case "select":
if ( this.selected != msgSrc ) {
this.selected.bg.style.borderBottomColor = this.selected.unselColor;
this.selected = msgSrc;
}
break;
case "add":
case "move":
default: // "change"
this.colors.sort( this.posCompare );
this.rebuild();
break;
}
},
rebuild: function() {
},
posCompare: function( color1, color2 ) {
return color1.posFraction - color2.posFraction;
},
insert: function( node ) {
node.appendChild( this.editor );
}
};
var grad = new Gradient();
// ============================================================================
addStyle( STYLE );
grad.addColor( [0, 0, 0], 0 )
grad.addColor( [255, 255, 255], 1 );
grad.insert( document.body );
*/
/* OLD CODE
addSchemePref: function( sect ) {
var sel = document.createElement("select");
var addButton = document.createElement( "input" );
sel.addEventListener( "change", this.togglePref, false )
sel.innerHTML = "<option style=\"font-style: normal;\">" +
STRINGS.def + "</option>\
<option style=\"font-style: italic;\">" +
STRINGS.custom + "</option>";
addButton.type = "button";
addButton.disabled = "true";
addButton.value = "Save";
addButton.style.marginLeft = "1em";
sect.appendChild( sel );
sect.appendChild( addButton );
this.addColorPickers( sect );
},
addColorPickers: function( section ) {
var bgRange = this.makeColorRange();
var fontRange = this.makeColorRange();
section.appendChild( bgRange );
// section.appendChild( fontRange );
},
makeColorRange: function() {
var range = document.createElement( "div" );
range.setAttribute( "style", "width: 360px; height: 10px;\
margin-top: 1em; border: 1px solid #FFCC66;" );
for ( var i = 360; i; i-- ) {
var color = document.createElement( "div" );
color.setAttribute( "style", "float: left; width: 1px; height: 100%; \
background-color: hsl(" + i + ",100%,50%" );
range.appendChild( color );
}
var rangeContainer = document.createElement( "div" );
rangeContainer.setAttribute( "style", "height: 19px; width: 362px;" );
var rangeBegin = document.createElement( "div" );
rangeBegin.setAttribute( "style", "position: absolute; width: 1px; \
height: 13px; border: 1px solid black; \
background: transparent;" );
var rangeEnd = rangeBegin.cloneNode( true );
rangeBegin.style.marginLeft = "-1px";
rangeEnd.style.marginLeft = "359px";
rangeBegin.style.borderLeftWidth = "2px";
rangeEnd.style.borderRightWidth = "2px";
rangeContainer.appendChild( rangeBegin );
rangeContainer.appendChild( rangeEnd );
rangeContainer.appendChild( range );
return rangeContainer;
},
*/
