diff --git a/docs/THIRDPARTY b/docs/THIRDPARTY index ba4173ed83..02e7cfa818 100644 --- a/docs/THIRDPARTY +++ b/docs/THIRDPARTY @@ -139,10 +139,6 @@ Files: static/third/sourcesans/* Copyright: 2010, 2012, 2014 Adobe Systems Incorporated License: SIL-OFL-1.1 -Files: static/third/spectrum/* -Copyright: 2013 Brian Grinstead -License: Expat - Files: zerver/lib/bugdown/fenced_code.py Copyright: 2006-2008 Waylan Limberg License: BSD-3-Clause diff --git a/package.json b/package.json index ea58b3de78..e5c55e8548 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "sortablejs": "1.9.0", "sorttable": "1.0.2", "source-sans-pro": "2.45.0", + "spectrum-colorpicker": "^1.8.0", "style-loader": "0.23.1", "to-markdown": "3.1.0", "ts-loader": "6.0.2", diff --git a/static/js/bundles/app.js b/static/js/bundles/app.js index 9031f2d9f3..c6ab92ec7f 100644 --- a/static/js/bundles/app.js +++ b/static/js/bundles/app.js @@ -7,7 +7,7 @@ import "../../third/jquery-filedrop/jquery.filedrop.js"; import "jquery-caret-plugin/src/jquery.caret.js"; import "../../third/jquery-idle/jquery.idle.js"; import "jquery-autosize"; -import "../../third/spectrum/spectrum.js"; +import "spectrum-colorpicker"; import "../../third/sockjs/sockjs-0.3.4.js"; import "../../third/marked/lib/marked.js"; import "xdate/src/xdate.js"; @@ -205,7 +205,7 @@ import "../stream_ui_updates.js"; // Import Styles import "../../third/bootstrap-notify/css/bootstrap-notify.css"; -import "../../third/spectrum/spectrum.css"; +import "spectrum-colorpicker/spectrum.css"; import "katex/dist/katex.css"; import "flatpickr/dist/flatpickr.css"; import "flatpickr/dist/plugins/confirmDate/confirmDate.css"; diff --git a/static/styles/popovers.scss b/static/styles/popovers.scss index 66dd76a5d9..f63c6c770f 100644 --- a/static/styles/popovers.scss +++ b/static/styles/popovers.scss @@ -41,7 +41,7 @@ } .sp-container { - z-index: 100; + z-index: 106; } .mobile-message-buttons-popover { diff --git a/static/third/spectrum/spectrum.css b/static/third/spectrum/spectrum.css deleted file mode 100644 index 3c4f4fa671..0000000000 --- a/static/third/spectrum/spectrum.css +++ /dev/null @@ -1,490 +0,0 @@ -/*! - Software from "Spectrum Colorpicker v1.0.0" is Copyright (c) Brian Grinstead - and is provided under the following license: - -- - 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. - -- -*/ - -/*** -Spectrum Colorpicker v1.0.0 -https://github.com/bgrins/spectrum -Author: Brian Grinstead -License: MIT -***/ - -.sp-container { - position:absolute; - top:0; - left:0; - display:inline-block; - *display: inline; - *zoom: 1; - z-index: 2147483647; - overflow: hidden; -} -.sp-container.sp-flat { - position: relative; -} - -/* http://ansciath.tumblr.com/post/7347495869/css-aspect-ratio */ -.sp-top { - position:relative; - width: 100%; - display:inline-block; -} -.sp-top-inner { - position:absolute; - top:0; - left:0; - bottom:0; - right:0; -} -.sp-color { - position: absolute; - top:0; - left:0; - bottom:0; - right:20%; -} -.sp-hue { - position: absolute; - top:0; - right:0; - bottom:0; - left:84%; - height: 100%; -} -.sp-fill { - padding-top: 80%; -} -.sp-sat, .sp-val { - position: absolute; - top:0; - left:0; - right:0; - bottom:0; -} - -.sp-alpha-enabled .sp-top -{ - margin-bottom: 18px; -} -.sp-alpha-enabled .sp-alpha -{ - display: block; -} - -.sp-alpha-handle -{ - position:absolute; - top:-4px; - bottom: -4px; - width: 6px; - left: 50%; - cursor: pointer; - border: 1px solid black; - background: white; - opacity: .8; -} - -.sp-alpha -{ - display: none; - position: absolute; - bottom: -14px; - right: 0; - left: 0; - height: 8px; -} -.sp-alpha-inner{ - border: solid 1px #333; -} - -/* Don't allow text selection */ -.sp-container, .sp-replacer, .sp-preview, .sp-dragger, .sp-slider, .sp-alpha, .sp-alpha-handle, .sp-container.sp-dragging .sp-input, .sp-container button { - -webkit-user-select:none; - -moz-user-select: -moz-none; - -o-user-select:none; - user-select: none; -} - -.sp-container.sp-input-disabled .sp-input-container { - display: none; -} -.sp-container.sp-buttons-disabled .sp-button-container { - display: none; -} -.sp-palette-only .sp-picker-container { - display: none; -} -.sp-palette-disabled .sp-palette-container { - display: none; -} - -.sp-initial-disabled .sp-initial { - display: none; -} - - -/* Gradients for hue, saturation and value instead of images. Not pretty... but it works */ -.sp-sat { - background-image: -webkit-gradient(linear, 0 0, 100% 0, from(#FFF), to(rgba(204, 154, 129, 0))); - background-image: -webkit-linear-gradient(left, #FFF, rgba(204, 154, 129, 0)); - background-image: -moz-linear-gradient(left, #fff, rgba(204, 154, 129, 0)); - background-image: -o-linear-gradient(left, #fff, rgba(204, 154, 129, 0)); - background-image: -ms-linear-gradient(left, #fff, rgba(204, 154, 129, 0)); - background-image: linear-gradient(to right, #fff, rgba(204, 154, 129, 0)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr=#FFFFFFFF, endColorstr=#00CC9A81)"; - filter : progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr='#FFFFFFFF', endColorstr='#00CC9A81'); -} -.sp-val { - background-image: -webkit-gradient(linear, 0 100%, 0 0, from(#000000), to(rgba(204, 154, 129, 0))); - background-image: -webkit-linear-gradient(bottom, #000000, rgba(204, 154, 129, 0)); - background-image: -moz-linear-gradient(bottom, #000, rgba(204, 154, 129, 0)); - background-image: -o-linear-gradient(bottom, #000, rgba(204, 154, 129, 0)); - background-image: -ms-linear-gradient(bottom, #000, rgba(204, 154, 129, 0)); - background-image: linear-gradient(to top, #000, rgba(204, 154, 129, 0)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#00CC9A81, endColorstr=#FF000000)"; - filter : progid:DXImageTransform.Microsoft.gradient(startColorstr='#00CC9A81', endColorstr='#FF000000'); -} - -.sp-hue { - background: -moz-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); - background: -ms-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); - background: -o-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); - background: -webkit-gradient(linear, left top, left bottom, from(#ff0000), color-stop(0.17, #ffff00), color-stop(0.33, #00ff00), color-stop(0.5, #00ffff), color-stop(0.67, #0000ff), color-stop(0.83, #ff00ff), to(#ff0000)); - background: -webkit-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); -} - -/* IE filters do not support multiple color stops. - Generate 6 divs, line them up, and do two color gradients for each. - Yes, really. - */ - -.sp-1 { - height:17%; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0000', endColorstr='#ffff00'); -} -.sp-2 { - height:16%; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff00', endColorstr='#00ff00'); -} -.sp-3 { - height:17%; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ff00', endColorstr='#00ffff'); -} -.sp-4 { - height:17%; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ffff', endColorstr='#0000ff'); -} -.sp-5 { - height:16%; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0000ff', endColorstr='#ff00ff'); -} -.sp-6 { - height:17%; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff00ff', endColorstr='#ff0000'); -} - -/* Clearfix hack */ -.sp-cf:before, .sp-cf:after { content: ""; display: table; } -.sp-cf:after { clear: both; } -.sp-cf { *zoom: 1; } - -/* Mobile devices, make hue slider bigger so it is easier to slide */ -@media (max-width: 480px) { - .sp-color { right: 40%; } - .sp-hue { left: 63%; } - .sp-fill { padding-top: 60%; } -} - -.sp-dragger { - border-radius: 5px; - height: 5px; - width: 5px; - border: 1px solid #fff; - background: #000; - cursor: pointer; - position:absolute; - top:0; - left: 0; -} -.sp-slider { - position: absolute; - top:0; - cursor:pointer; - height: 3px; - left: -1px; - right: -1px; - border: 1px solid #000; - background: white; - opacity: .8; -} - -/* Basic display options (colors, fonts, global widths) */ -.sp-container { - border-radius: 0; - background-color: #ECECEC; - border: solid 1px #f0c49B; - padding: 0; -} -.sp-container, .sp-container button, .sp-container input, .sp-color, .sp-hue -{ - font: normal 12px "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - -ms-box-sizing: border-box; - box-sizing: border-box; -} -.sp-top -{ - margin-bottom: 3px; -} -.sp-color, .sp-hue -{ - border: solid 1px #666; -} - -/* Input */ -.sp-input-container { - float:right; - width: 100px; - margin-bottom: 4px; -} -.sp-initial-disabled .sp-input-container { - width: 100%; -} -.sp-input { - font-size: 12px !important; - border: 1px inset; - padding: 4px 5px; - margin: 0; - width: 100%; - background:transparent; - border-radius: 3px; - color: #222; -} -.sp-input:focus { - border: 1px solid orange; -} -.sp-input.sp-validation-error -{ - border: 1px solid red; - background: #fdd; -} -.sp-picker-container , .sp-palette-container -{ - float:left; - position: relative; - padding: 10px; - padding-bottom: 300px; - margin-bottom: -290px; -} -.sp-picker-container -{ - width: 172px; - border-left: solid 1px #fff; -} - -/* Palettes */ -.sp-palette-container -{ - border-right: solid 1px #ccc; -} - -.sp-palette .sp-thumb-el { - display: block; - position:relative; - float:left; - width: 24px; - height: 15px; - margin: 3px; - cursor: pointer; - border:solid 2px transparent; -} -.sp-palette .sp-thumb-el:hover, .sp-palette .sp-thumb-el.sp-thumb-active { - border-color: orange; -} -.sp-thumb-el -{ - position:relative; -} - -/* Initial */ -.sp-initial -{ - float: left; - border: solid 1px #333; -} -.sp-initial span { - width: 30px; - height: 25px; - border:none; - display:block; - float:left; - margin:0; -} - -/* Buttons */ -.sp-button-container { - float: right; -} - -/* Replacer (the little preview div that shows up instead of the ) */ -.sp-replacer { - margin:0; - overflow:hidden; - cursor:pointer; - padding: 4px; - display:inline-block; - *zoom: 1; - *display: inline; - border: solid 1px #91765d; - background: #eee; - color: #333; - vertical-align: middle; -} -.sp-replacer:hover, .sp-replacer.sp-active { - border-color: #F0C49B; - color: #111; -} -.sp-dd { - padding: 2px 0; - height: 16px; - line-height: 16px; - float:left; - font-size:10px; -} -.sp-preview -{ - position:relative; - width:25px; - height: 20px; - border: solid 1px #222; - margin-right: 5px; - float:left; - z-index: 0; -} - -.sp-palette -{ - *width: 220px; - max-width: 220px; -} -.sp-palette .sp-thumb-el -{ - width:16px; - height: 16px; - margin:2px 1px; - border: solid 1px #d0d0d0; -} - -.sp-container -{ - padding-bottom:0; -} - - -/* Buttons: http://hellohappy.org/css3-buttons/ */ -.sp-container button { - background-color: #eeeeee; - background-image: -webkit-linear-gradient(top, #eeeeee, #cccccc); - background-image: -moz-linear-gradient(top, #eeeeee, #cccccc); - background-image: -ms-linear-gradient(top, #eeeeee, #cccccc); - background-image: -o-linear-gradient(top, #eeeeee, #cccccc); - background-image: -ms-linear-gradient(top, #eeeeee, #cccccc); - background-image: linear-gradient(to bottom, #eeeeee, #cccccc); - border: 1px solid #ccc; - border-bottom: 1px solid #bbb; - border-radius: 3px; - color: #333; - font-size: 14px; - line-height: 1; - padding: 5px 4px; - text-align: center; - text-shadow: 0 1px 0 #eee; - vertical-align: middle; -} -.sp-container button:hover { - background-color: #dddddd; - background-image: -webkit-linear-gradient(top, #dddddd, #bbbbbb); - background-image: -moz-linear-gradient(top, #dddddd, #bbbbbb); - background-image: -ms-linear-gradient(top, #dddddd, #bbbbbb); - background-image: -o-linear-gradient(top, #dddddd, #bbbbbb); - background-image: -ms-linear-gradient(top, #dddddd, #bbbbbb); - background-image: linear-gradient(to bottom, #dddddd, #bbbbbb); - border: 1px solid #bbb; - border-bottom: 1px solid #999; - cursor: pointer; - text-shadow: 0 1px 0 #ddd; -} -.sp-container button:active { - border: 1px solid #aaa; - border-bottom: 1px solid #888; - -webkit-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; - -moz-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; - -ms-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; - -o-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; - box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; -} -.sp-cancel -{ - font-size: 11px; - color: #d93f3f !important; - margin:0; - padding:2px; - margin-right: 5px; - vertical-align: middle; - text-decoration:none; - -} -.sp-cancel:hover -{ - color: #d93f3f !important; - text-decoration: underline; -} - - -.sp-palette span:hover, .sp-palette span.sp-thumb-active -{ - border-color: #000; -} - -.sp-preview, .sp-alpha, .sp-thumb-el -{ - position:relative; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==); -} -.sp-preview-inner, .sp-alpha-inner, .sp-thumb-inner -{ - display:block; - position:absolute; - top:0;left:0;bottom:0;right:0; -} - -.sp-palette .sp-thumb-light.sp-thumb-active .sp-thumb-inner -{ - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIVJREFUeNpiYBhsgJFMffxAXABlN5JruT4Q3wfi/0DsT64h8UD8HmpIPCWG/KemIfOJCUB+Aoacx6EGBZyHBqI+WsDCwuQ9mhxeg2A210Ntfo8klk9sOMijaURm7yc1UP2RNCMbKE9ODK1HM6iegYLkfx8pligC9lCD7KmRof0ZhjQACDAAceovrtpVBRkAAAAASUVORK5CYII=); -} - -.sp-palette .sp-thumb-dark.sp-thumb-active .sp-thumb-inner -{ - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAMdJREFUOE+tkgsNwzAMRMugEAahEAahEAZhEAqlEAZhEAohEAYh81X2dIm8fKpEspLGvudPOsUYpxE2BIJCroJmEW9qJ+MKaBFhEMNabSy9oIcIPwrB+afvAUFoK4H0tMaQ3XtlrggDhOVVMuT4E5MMG0FBbCEYzjYT7OxLEvIHQLY2zWwQ3D+9luyOQTfKDiFD3iUIfPk8VqrKjgAiSfGFPecrg6HN6m/iBcwiDAo7WiBeawa+Kwh7tZoSCGLMqwlSAzVDhoK+6vH4G0P5wdkAAAAASUVORK5CYII=); -} \ No newline at end of file diff --git a/static/third/spectrum/spectrum.js b/static/third/spectrum/spectrum.js deleted file mode 100644 index 4e505373ba..0000000000 --- a/static/third/spectrum/spectrum.js +++ /dev/null @@ -1,1665 +0,0 @@ -// Spectrum Colorpicker v1.0.0 -// https://github.com/bgrins/spectrum -// Author: Brian Grinstead -// License: MIT - -(function (window, $, undefined) { - var defaultOpts = { - - // Events - beforeShow: noop, - move: noop, - change: noop, - show: noop, - hide: noop, - - // Options - color: false, - flat: false, - showInput: false, - showButtons: true, - clickoutFiresChange: false, - showInitial: false, - showPalette: false, - showPaletteOnly: false, - showSelectionPalette: true, - localStorageKey: false, - maxSelectionSize: 7, - cancelText: "cancel", - chooseText: "choose", - preferredFormat: false, - className: "", - showAlpha: false, - theme: "sp-light", - palette: ['fff', '000'], - selectionPalette: [], - - // user-specified container - container: null - }, - spectrums = [], - IE = !!/msie/i.exec( window.navigator.userAgent ), - rgbaSupport = (function() { - function contains( str, substr ) { - return !!~('' + str).indexOf(substr); - } - - var elem = document.createElement('div'); - var style = elem.style; - style.cssText = 'background-color:rgba(0,0,0,.5)'; - return contains(style.backgroundColor, 'rgba') || contains(style.backgroundColor, 'hsla'); - })(), - replaceInput = [ - "
", - "
", - "
", - "
" - ].join(''), - markup = (function () { - - // IE does not support gradients with multiple stops, so we need to simulate - // that for the rainbow slider with 8 divs that each have a single gradient - var gradientFix = ""; - if (IE) { - for (var i = 1; i <= 6; i++) { - gradientFix += "
"; - } - } - - return [ - "
", - "
", - "
", - "
", - "
", - "
", - "
", - "
", - "
", - "
", - "
", - "
", - "
", - "
", - "
", - "
", - "
", - gradientFix, - "
", - "
", - "
", - "
", - "
", - "", - "
", - "
", - "
", - "", - "", - "
", - "
", - "
" - ].join(""); - })(); - - function paletteTemplate (p, color, className) { - var html = []; - for (var i = 0; i < p.length; i++) { - var tiny = tinycolor(p[i]); - var c = tiny.toHsl().l < .5 ? "sp-thumb-el sp-thumb-dark" : "sp-thumb-el sp-thumb-light"; - c += (tinycolor.equals(color, p[i])) ? " sp-thumb-active" : ""; - - var swatchStyle = rgbaSupport ? ("background-color:" + tiny.toRgbString()) : "filter:" + tiny.toFilter(); - html.push(''); - } - return "
" + html.join('') + "
"; - }; - - function hideAll() { - for (var i = 0; i < spectrums.length; i++) { - if (spectrums[i]) { - spectrums[i].hide(); - } - } - } - function instanceOptions(o, callbackContext) { - var opts = $.extend({}, defaultOpts, o); - opts.callbacks = { - 'move': bind(opts.move, callbackContext), - 'change': bind(opts.change, callbackContext), - 'show': bind(opts.show, callbackContext), - 'hide': bind(opts.hide, callbackContext), - 'beforeShow': bind(opts.beforeShow, callbackContext) - }; - - return opts; - } - - function spectrum(element, o) { - - var opts = instanceOptions(o, element), - flat = opts.flat, - showPaletteOnly = opts.showPaletteOnly, - showPalette = opts.showPalette || showPaletteOnly, - showInitial = opts.showInitial && !flat, - showInput = opts.showInput, - showAlpha = opts.showAlpha, - showSelectionPalette = opts.showSelectionPalette, - localStorageKey = opts.localStorageKey, - theme = opts.theme, - callbacks = opts.callbacks, - resize = throttle(reflow, 10), - visible = false, - dragWidth = 0, - dragHeight = 0, - dragHelperHeight = 0, - slideHeight = 0, - slideWidth = 0, - alphaWidth = 0, - alphaSlideHelperWidth = 0, - slideHelperHeight = 0, - currentHue = 0, - currentSaturation = 0, - currentValue = 0, - currentAlpha = 1, - palette = opts.palette.slice(0), - paletteArray = $.isArray(palette[0]) ? palette : [palette], - selectionPalette = opts.selectionPalette.slice(0), - draggingClass = "sp-dragging"; - - var doc = element.ownerDocument, - body = opts.container || doc.body, - boundElement = $(element), - container = $(markup, doc).addClass(theme), - dragger = container.find(".sp-color"), - dragHelper = container.find(".sp-dragger"), - slider = container.find(".sp-hue"), - slideHelper = container.find(".sp-slider"), - alphaSliderInner = container.find(".sp-alpha-inner"), - alphaSlider = container.find(".sp-alpha"), - alphaSlideHelper = container.find(".sp-alpha-handle"), - textInput = container.find(".sp-input"), - paletteContainer = container.find(".sp-palette"), - initialColorContainer = container.find(".sp-initial"), - cancelButton = container.find(".sp-cancel"), - chooseButton = container.find(".sp-choose"), - isInput = boundElement.is("input"), - shouldReplace = isInput && !flat, - replacer = (shouldReplace) ? $(replaceInput).addClass(theme) : $([]), - offsetElement = (shouldReplace) ? replacer : boundElement, - previewElement = replacer.find(".sp-preview-inner"), - initialColor = opts.color || (isInput && boundElement.val()), - colorOnShow = false, - preferredFormat = opts.preferredFormat, - currentPreferredFormat = preferredFormat, - clickoutFiresChange = !opts.showButtons || opts.clickoutFiresChange; - - chooseButton.text(opts.chooseText); - cancelButton.text(opts.cancelText); - - function initialize() { - - if (IE) { - container.find("*:not(input)").attr("unselectable", "on"); - } - - container.toggleClass("sp-flat", flat); - container.toggleClass("sp-input-disabled", !showInput); - container.toggleClass("sp-alpha-enabled", showAlpha); - container.toggleClass("sp-buttons-disabled", !opts.showButtons || flat); - container.toggleClass("sp-palette-disabled", !showPalette); - container.toggleClass("sp-palette-only", showPaletteOnly); - container.toggleClass("sp-initial-disabled", !showInitial); - container.addClass(opts.className); - - if (shouldReplace) { - boundElement.hide().after(replacer); - } - - if (flat) { - boundElement.after(container).hide(); - } - else { - $(body).append(container.hide()); - } - if (localStorageKey && window.localStorage) { - try { - selectionPalette = window.localStorage[localStorageKey].split(","); - } - catch (e) { - - } - } - - offsetElement.on("click.spectrum touchstart.spectrum", function (e) { - toggle(); - - e.stopPropagation(); - - if (!$(e.target).is("input")) { - e.preventDefault(); - } - }); - - // Prevent clicks from bubbling up to document. This would cause it to be hidden. - container.click(stopPropagation); - - // Handle user typed input - textInput.change(setFromTextInput); - textInput.on("paste", function () { - setTimeout(setFromTextInput, 1); - }); - textInput.keydown(function (e) { if (e.keyCode == 13) { setFromTextInput(); } }); - - cancelButton.on("click.spectrum", function (e) { - e.stopPropagation(); - e.preventDefault(); - hide("cancel"); - }); - - chooseButton.on("click.spectrum", function (e) { - e.stopPropagation(); - e.preventDefault(); - - if (isValid()) { - updateOriginalInput(true); - hide(); - } - }); - - draggable(alphaSlider, function (dragX, dragY, e) { - currentAlpha = (dragX / alphaWidth); - if (e.shiftKey) { - currentAlpha = Math.round(currentAlpha * 10) / 10; - } - - move(); - }); - - draggable(slider, function (dragX, dragY) { - currentHue = (dragY / slideHeight); - move(); - }, dragStart, dragStop); - - draggable(dragger, function (dragX, dragY) { - currentSaturation = dragX / dragWidth; - currentValue = (dragHeight - dragY) / dragHeight; - move(); - }, dragStart, dragStop); - - if (!!initialColor) { - set(initialColor); - - // In case color was black - update the preview UI and set the format - // since the set function will not run (default color is black). - updateUI(); - currentPreferredFormat = preferredFormat || tinycolor(initialColor).format; - - addColorToSelectionPalette(initialColor); - } - else { - updateUI(); - } - - if (flat) { - show(); - } - - function palletElementClick(e) { - if (e.data && e.data.ignore) { - set($(this).data("color")); - move(); - } - else { - set($(this).data("color")); - updateOriginalInput(true); - move(); - hide(); - } - - return false; - } - - var paletteEvent = IE ? "mousedown.spectrum" : "click.spectrum touchstart.spectrum"; - paletteContainer.on(paletteEvent, ".sp-thumb-el", palletElementClick); - initialColorContainer.on(paletteEvent, ".sp-thumb-el:nth-child(1)", { ignore: true }, palletElementClick); - } - function addColorToSelectionPalette(color) { - if (showSelectionPalette) { - selectionPalette.push(tinycolor(color).toHexString()); - if (localStorageKey && window.localStorage) { - window.localStorage[localStorageKey] = selectionPalette.join(","); - } - } - } - - function getUniqueSelectionPalette() { - var unique = []; - var p = selectionPalette; - var paletteLookup = {}; - - if (showPalette) { - - for (var i = 0; i < paletteArray.length; i++) { - for (var j = 0; j < paletteArray[i].length; j++) { - var hex = tinycolor(paletteArray[i][j]).toHexString(); - paletteLookup[hex] = true; - } - } - - for (var i = 0; i < p.length; i++) { - var color = tinycolor(p[i]); - var hex = color.toHexString(); - - if (!paletteLookup.hasOwnProperty(hex)) { - unique.push(p[i]); - paletteLookup[hex] = true; - } - } - } - - return unique.reverse().slice(0, opts.maxSelectionSize); - } - function drawPalette() { - - var currentColor = get(); - - var html = $.map(paletteArray, function (palette, i) { - return paletteTemplate(palette, currentColor, "sp-palette-row sp-palette-row-" + i); - }); - - if (selectionPalette) { - html.push(paletteTemplate(getUniqueSelectionPalette(), currentColor, "sp-palette-row sp-palette-row-selection")); - } - - paletteContainer.html(html.join("")); - } - function drawInitial() { - if (showInitial) { - var initial = colorOnShow; - var current = get(); - initialColorContainer.html(paletteTemplate([initial, current], current, "sp-palette-row-initial")); - } - } - function dragStart() { - if (dragHeight === 0 || dragWidth === 0 || slideHeight === 0) { - reflow(); - } - container.addClass(draggingClass); - } - function dragStop() { - container.removeClass(draggingClass); - } - function setFromTextInput() { - var tiny = tinycolor(textInput.val()); - if (tiny.ok) { - set(tiny); - } - else { - textInput.addClass("sp-validation-error"); - } - } - - function toggle() { - (visible) ? hide() : show(); - } - - function show() { - if (visible) { - reflow(); - return; - } - if (callbacks.beforeShow(get()) === false) return; - - hideAll(); - visible = true; - - $(doc).on("click.spectrum", hide); - $(window).on("resize.spectrum", resize); - replacer.addClass("sp-active"); - container.show(); - - if (showPalette) { - drawPalette(); - } - reflow(); - updateUI(); - - colorOnShow = get(); - - drawInitial(); - callbacks.show(colorOnShow); - } - - function hide(e) { - - // Return on right click - if (e && e.type == "click" && e.button == 2) { return; } - - // Return if hiding is unnecessary - if (!visible || flat) { return; } - visible = false; - - $(doc).off("click.spectrum", hide); - $(window).off("resize.spectrum", resize); - - replacer.removeClass("sp-active"); - container.hide(); - - var colorHasChanged = !tinycolor.equals(get(), colorOnShow); - - if (colorHasChanged) { - if (clickoutFiresChange && e !== "cancel") { - updateOriginalInput(true); - } - else { - revert(); - } - } - - callbacks.hide(get()); - } - - function revert() { - set(colorOnShow, true); - } - - function set(color, ignoreFormatChange) { - if (tinycolor.equals(color, get())) { - return; - } - - var newColor = tinycolor(color); - var newHsv = newColor.toHsv(); - - currentHue = newHsv.h; - currentSaturation = newHsv.s; - currentValue = newHsv.v; - currentAlpha = newHsv.a; - - updateUI(); - - if (!ignoreFormatChange) { - currentPreferredFormat = preferredFormat || newColor.format; - } - } - - function get() { - return tinycolor.fromRatio({ h: currentHue, s: currentSaturation, v: currentValue, a: Math.round(currentAlpha * 100) / 100 }); - } - - function isValid() { - return !textInput.hasClass("sp-validation-error"); - } - - function move() { - updateUI(); - - callbacks.move(get()); - } - - function updateUI() { - - textInput.removeClass("sp-validation-error"); - - updateHelperLocations(); - - // Update dragger background color (gradients take care of saturation and value). - var flatColor = tinycolor({ h: currentHue, s: "1.0", v: "1.0" }); - dragger.css("background-color", flatColor.toHexString()); - - // Get a format that alpha will be included in (hex and names ignore alpha) - var format = currentPreferredFormat; - if (currentAlpha < 1) { - if (format === "hex" || format === "name") { - format = "rgb"; - } - } - - var realColor = get(), - realHex = realColor.toHexString(), - realRgb = realColor.toRgbString(); - - - // Update the replaced elements background color (with actual selected color) - if (rgbaSupport || realColor.alpha === 1) { - previewElement.css("background-color", realRgb); - } - else { - previewElement.css("background-color", "transparent"); - previewElement.css("filter", realColor.toFilter()); - } - - if (showAlpha) { - var rgb = realColor.toRgb(); - rgb.a = 0; - var realAlpha = tinycolor(rgb).toRgbString(); - var gradient = "linear-gradient(left, " + realAlpha + ", " + realHex + ")"; - - if (IE) { - alphaSliderInner.css("filter", tinycolor(realAlpha).toFilter({ gradientType: 1 }, realHex)); - } - else { - alphaSliderInner.css("background", "-webkit-" + gradient); - alphaSliderInner.css("background", "-moz-" + gradient); - alphaSliderInner.css("background", "-ms-" + gradient); - alphaSliderInner.css("background", gradient); - } - } - - - // Update the text entry input as it changes happen - if (showInput) { - if (currentAlpha < 1) { - if (format === "hex" || format === "name") { - format = "rgb"; - } - } - textInput.val(realColor.toString(format)); - } - - if (showPalette) { - drawPalette(); - } - - drawInitial(); - } - - function updateHelperLocations() { - var h = currentHue; - var s = currentSaturation; - var v = currentValue; - - // Where to show the little circle in that displays your current selected color - var dragX = s * dragWidth; - var dragY = dragHeight - (v * dragHeight); - dragX = Math.max( - -dragHelperHeight, - Math.min(dragWidth - dragHelperHeight, dragX - dragHelperHeight) - ); - dragY = Math.max( - -dragHelperHeight, - Math.min(dragHeight - dragHelperHeight, dragY - dragHelperHeight) - ); - dragHelper.css({ - "top": dragY, - "left": dragX - }); - - var alphaX = currentAlpha * alphaWidth; - alphaSlideHelper.css({ - "left": alphaX - (alphaSlideHelperWidth / 2) - }); - - // Where to show the bar that displays your current selected hue - var slideY = (currentHue) * slideHeight; - slideHelper.css({ - "top": slideY - slideHelperHeight - }); - } - - function updateOriginalInput(fireCallback) { - var color = get(); - - if (isInput) { - boundElement.val(color.toString(currentPreferredFormat)).change(); - } - - var hasChanged = !tinycolor.equals(color, colorOnShow); - colorOnShow = color; - - // Update the selection palette with the current color - addColorToSelectionPalette(color); - if (fireCallback && hasChanged) { - callbacks.change(color); - } - } - - function reflow() { - dragWidth = dragger.width(); - dragHeight = dragger.height(); - dragHelperHeight = dragHelper.height(); - slideWidth = slider.width(); - slideHeight = slider.height(); - slideHelperHeight = slideHelper.height(); - alphaWidth = alphaSlider.width(); - alphaSlideHelperWidth = alphaSlideHelper.width(); - - if (!flat) { - container.offset(getOffset(container, offsetElement)); - } - - updateHelperLocations(); - } - - function destroy() { - boundElement.show(); - offsetElement.off("click.spectrum touchstart.spectrum"); - container.remove(); - replacer.remove(); - spectrums[spect.id] = null; - } - - initialize(); - - var spect = { - show: show, - hide: hide, - toggle: toggle, - reflow: reflow, - set: function (c) { - set(c); - updateOriginalInput(); - }, - get: get, - destroy: destroy, - container: container - }; - - spect.id = spectrums.push(spect) - 1; - - return spect; - } - - /** - * checkOffset - get the offset below/above and left/right element depending on screen position - * Thanks https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.datepicker.js - */ - function getOffset(picker, input) { - var extraY = 0; - var dpWidth = picker.outerWidth(); - var dpHeight = picker.outerHeight(); - var inputWidth = input.outerWidth(); - var inputHeight = input.outerHeight(); - var doc = picker[0].ownerDocument; - var docElem = doc.documentElement; - var viewWidth = docElem.clientWidth + $(doc).scrollLeft(); - var viewHeight = docElem.clientHeight + $(doc).scrollTop(); - var offset = input.offset(); - offset.top += inputHeight; - - offset.left -= - Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? - Math.abs(offset.left + dpWidth - viewWidth) : 0); - - offset.top -= - Math.min(offset.top, ((offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? - Math.abs(dpHeight + inputHeight - extraY) : extraY)); - - return offset; - } - - /** - * noop - do nothing - */ - function noop() { - - } - - /** - * stopPropagation - makes the code only doing this a little easier to read in line - */ - function stopPropagation(e) { - e.stopPropagation(); - } - - /** - * Create a function bound to a given object - * Thanks to underscore.js - */ - function bind(func, obj) { - var slice = Array.prototype.slice; - var args = slice.call(arguments, 2); - return function () { - return func.apply(obj, args.concat(slice.call(arguments))); - } - } - - /** - * Lightweight drag helper. Handles containment within the element, so that - * when dragging, the x is within [0,element.width] and y is within [0,element.height] - */ - function draggable(element, onmove, onstart, onstop) { - onmove = onmove || function () { }; - onstart = onstart || function () { }; - onstop = onstop || function () { }; - var doc = element.ownerDocument || document; - var dragging = false; - var offset = {}; - var maxHeight = 0; - var maxWidth = 0; - var hasTouch = ('ontouchstart' in window); - - var duringDragEvents = {}; - duringDragEvents["selectstart"] = prevent; - duringDragEvents["dragstart"] = prevent; - duringDragEvents[(hasTouch ? "touchmove" : "mousemove")] = move; - duringDragEvents[(hasTouch ? "touchend" : "mouseup")] = stop; - - function prevent(e) { - if (e.stopPropagation) { - e.stopPropagation(); - } - if (e.preventDefault) { - e.preventDefault(); - } - e.returnValue = false; - } - - function move(e) { - if (dragging) { - // Mouseup happened outside of window - if (IE && !(document.documentMode >= 9) && !e.button) { - return stop(); - } - - var touches = e.originalEvent.touches; - var pageX = touches ? touches[0].pageX : e.pageX; - var pageY = touches ? touches[0].pageY : e.pageY; - - var dragX = Math.max(0, Math.min(pageX - offset.left, maxWidth)); - var dragY = Math.max(0, Math.min(pageY - offset.top, maxHeight)); - - if (hasTouch) { - // Stop scrolling in iOS - prevent(e); - } - - onmove.apply(element, [dragX, dragY, e]); - } - } - function start(e) { - var rightclick = (e.which) ? (e.which == 3) : (e.button == 2); - var touches = e.originalEvent.touches; - - if (!rightclick && !dragging) { - if (onstart.apply(element, arguments) !== false) { - dragging = true; - maxHeight = $(element).height(); - maxWidth = $(element).width(); - offset = $(element).offset(); - - $(doc).on(duringDragEvents); - $(doc.body).addClass("sp-dragging"); - - if (!hasTouch) { - move(e); - } - - prevent(e); - } - } - } - function stop() { - if (dragging) { - $(doc).off(duringDragEvents); - $(doc.body).removeClass("sp-dragging"); - onstop.apply(element, arguments); - } - dragging = false; - } - $(element).on(hasTouch ? "touchstart" : "mousedown", start); - } - - function throttle(func, wait, debounce) { - var timeout; - return function () { - var context = this, args = arguments; - var throttler = function () { - timeout = null; - func.apply(context, args); - }; - if (debounce) clearTimeout(timeout); - if (debounce || !timeout) timeout = setTimeout(throttler, wait); - }; - } - - - /** - * Define a jQuery plugin - */ - var dataID = "spectrum.id"; - $.fn.spectrum = function (opts, extra) { - if (typeof opts == "string") { - if (opts == "get") { - return spectrums[this.eq(0).data(dataID)].get(); - } else if (opts == "container") { - return spectrums[$(this).data(dataID)].container; - } - - return this.each(function () { - var spect = spectrums[$(this).data(dataID)]; - if (spect) { - if (opts == "show") { spect.show(); } - if (opts == "hide") { spect.hide(); } - if (opts == "toggle") { spect.toggle(); } - if (opts == "reflow") { spect.reflow(); } - if (opts == "set") { spect.set(extra); } - if (opts == "destroy") { - spect.destroy(); - $(this).removeData(dataID); - } - } - }); - } - - // Initializing a new one - return this.spectrum("destroy").each(function () { - var spect = spectrum(this, opts); - $(this).data(dataID, spect.id); - }); - }; - - $.fn.spectrum.load = true; - $.fn.spectrum.loadOpts = {}; - $.fn.spectrum.draggable = draggable; - $.fn.spectrum.defaults = defaultOpts; - - $.fn.spectrum.processNativeColorInputs = function () { - var colorInput = $("")[0]; - var supportsColor = colorInput.type === "color" && colorInput.value != "#ffffff"; - - if (!supportsColor) { - $("input[type=color]").spectrum({ - preferredFormat: "hex6" - }); - } - }; - - // TinyColor.js - - 2011 Brian Grinstead - v0.5 - - (function (window) { - - var trimLeft = /^[\s,#]+/, - trimRight = /\s+$/, - tinyCounter = 0, - math = Math, - mathRound = math.round, - mathMin = math.min, - mathMax = math.max, - mathRandom = math.random, - parseFloat = window.parseFloat; - - function tinycolor(color, opts) { - - // If input is already a tinycolor, return itself - if (typeof color == "object" && color.hasOwnProperty("_tc_id")) { - return color; - } - - var rgb = inputToRGB(color); - var r = rgb.r, g = rgb.g, b = rgb.b, a = parseFloat(rgb.a), format = rgb.format; - - return { - ok: rgb.ok, - format: format, - _tc_id: tinyCounter++, - alpha: a, - toHsv: function () { - var hsv = rgbToHsv(r, g, b); - return { h: hsv.h, s: hsv.s, v: hsv.v, a: a }; - }, - toHsvString: function () { - var hsv = rgbToHsv(r, g, b); - var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100); - return (a == 1) ? - "hsv(" + h + ", " + s + "%, " + v + "%)" : - "hsva(" + h + ", " + s + "%, " + v + "%, " + a + ")"; - }, - toHsl: function () { - var hsl = rgbToHsl(r, g, b); - return { h: hsl.h, s: hsl.s, l: hsl.l, a: a }; - }, - toHslString: function () { - var hsl = rgbToHsl(r, g, b); - var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100); - return (a == 1) ? - "hsl(" + h + ", " + s + "%, " + l + "%)" : - "hsla(" + h + ", " + s + "%, " + l + "%, " + a + ")"; - }, - toHex: function () { - return rgbToHex(r, g, b); - }, - toHexString: function (force6Char) { - return '#' + rgbToHex(r, g, b, force6Char); - }, - toRgb: function () { - return { r: mathRound(r), g: mathRound(g), b: mathRound(b), a: a }; - }, - toRgbString: function () { - return (a == 1) ? - "rgb(" + mathRound(r) + ", " + mathRound(g) + ", " + mathRound(b) + ")" : - "rgba(" + mathRound(r) + ", " + mathRound(g) + ", " + mathRound(b) + ", " + a + ")"; - }, - toName: function () { - return hexNames[rgbToHex(r, g, b)] || false; - }, - toFilter: function (opts, secondColor) { - - var hex = secondHex = rgbToHex(r, g, b, true); - var alphaHex = secondAlphaHex = Math.round(parseFloat(a) * 255).toString(16); - var gradientType = opts && opts.gradientType ? "GradientType = 1, " : ""; - - if (secondColor) { - var s = tinycolor(secondColor); - secondHex = s.toHex(); - secondAlphaHex = Math.round(parseFloat(s.alpha) * 255).toString(16); - } - - return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr=#" + pad2(alphaHex) + hex + ",endColorstr=#" + pad2(secondAlphaHex) + secondHex + ")"; - }, - toString: function (format) { - format = format || this.format; - var formattedString = false; - if (format === "rgb") { - formattedString = this.toRgbString(); - } - if (format === "hex") { - formattedString = this.toHexString(); - } - if (format === "hex6") { - formattedString = this.toHexString(true); - } - if (format === "name") { - formattedString = this.toName(); - } - if (format === "hsl") { - formattedString = this.toHslString(); - } - if (format === "hsv") { - formattedString = this.toHsvString(); - } - - return formattedString || this.toHexString(); - } - }; - } - - // If input is an object, force 1 into "1.0" to handle ratios properly - // String input requires "1.0" as input, so 1 will be treated as 1 - tinycolor.fromRatio = function (color) { - - if (typeof color == "object") { - for (var i in color) { - if (color[i] === 1) { - color[i] = "1.0"; - } - } - } - - return tinycolor(color); - - } - - // Given a string or object, convert that input to RGB - // Possible string inputs: - // - // "red" - // "#f00" or "f00" - // "#ff0000" or "ff0000" - // "rgb 255 0 0" or "rgb (255, 0, 0)" - // "rgb 1.0 0 0" or "rgb (1, 0, 0)" - // "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1" - // "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1" - // "hsl(0, 100%, 50%)" or "hsl 0 100% 50%" - // "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1" - // "hsv(0, 100%, 100%)" or "hsv 0 100% 100%" - // - function inputToRGB(color) { - - var rgb = { r: 0, g: 0, b: 0 }; - var a = 1; - var ok = false; - var format = false; - - if (typeof color == "string") { - color = stringInputToObject(color); - } - - if (typeof color == "object") { - if (color.hasOwnProperty("r") && color.hasOwnProperty("g") && color.hasOwnProperty("b")) { - rgb = rgbToRgb(color.r, color.g, color.b); - ok = true; - format = "rgb"; - } - else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("v")) { - rgb = hsvToRgb(color.h, color.s, color.v); - ok = true; - format = "hsv"; - } - else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("l")) { - var rgb = hslToRgb(color.h, color.s, color.l); - ok = true; - format = "hsl"; - } - - if (color.hasOwnProperty("a")) { - a = color.a; - } - } - - rgb.r = mathMin(255, mathMax(rgb.r, 0)); - rgb.g = mathMin(255, mathMax(rgb.g, 0)); - rgb.b = mathMin(255, mathMax(rgb.b, 0)); - - - // Don't let the range of [0,255] come back in [0,1]. - // Potentially lose a little bit of precision here, but will fix issues where - // .5 gets interpreted as half of the total, instead of half of 1. - // If it was supposed to be 128, this was already taken care of in the conversion function - if (rgb.r < 1) { rgb.r = mathRound(rgb.r); } - if (rgb.g < 1) { rgb.g = mathRound(rgb.g); } - if (rgb.b < 1) { rgb.b = mathRound(rgb.b); } - - return { - ok: ok, - format: (color && color.format) || format, - r: rgb.r, - g: rgb.g, - b: rgb.b, - a: a - }; - } - - - - // Conversion Functions - // -------------------- - - // `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from: - // - - // `rgbToRgb` - // Handle bounds / percentage checking to conform to CSS color spec - // - // *Assumes:* r, g, b in [0, 255] or [0, 1] - // *Returns:* { r, g, b } in [0, 255] - function rgbToRgb(r, g, b) { - return { - r: bound01(r, 255) * 255, - g: bound01(g, 255) * 255, - b: bound01(b, 255) * 255 - }; - } - - // `rgbToHsl` - // Converts an RGB color value to HSL. - // *Assumes:* r, g, and b are contained in [0, 255] or [0, 1] - // *Returns:* { h, s, l } in [0,1] - function rgbToHsl(r, g, b) { - - r = bound01(r, 255); - g = bound01(g, 255); - b = bound01(b, 255); - - var max = mathMax(r, g, b), min = mathMin(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: h, s: s, l: l }; - } - - // `hslToRgb` - // Converts an HSL color value to RGB. - // *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100] - // *Returns:* { r, g, b } in the set [0, 255] - function hslToRgb(h, s, l) { - var r, g, b; - - h = bound01(h, 360); - s = bound01(s, 100); - l = bound01(l, 100); - - 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; - } - - if (s == 0) { - r = g = b = l; // achromatic - } - else { - 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 { r: r * 255, g: g * 255, b: b * 255 }; - } - - // `rgbToHsv` - // Converts an RGB color value to HSV - // *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1] - // *Returns:* { h, s, v } in [0,1] - function rgbToHsv(r, g, b) { - - r = bound01(r, 255); - g = bound01(g, 255); - b = bound01(b, 255); - - var max = mathMax(r, g, b), min = mathMin(r, g, b); - var h, s, v = max; - - var d = max - min; - s = max == 0 ? 0 : d / max; - - if (max == min) { - h = 0; // achromatic - } - else { - 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: h, s: s, v: v }; - } - - // `hsvToRgb` - // Converts an HSV color value to RGB. - // *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100] - // *Returns:* { r, g, b } in the set [0, 255] - function hsvToRgb(h, s, v) { - var r, g, b; - - h = bound01(h, 360) * 6; - s = bound01(s, 100); - v = bound01(v, 100); - - var i = math.floor(h), - f = h - i, - p = v * (1 - s), - q = v * (1 - f * s), - t = v * (1 - (1 - f) * s), - mod = i % 6, - r = [v, q, p, p, t, v][mod], - g = [t, v, v, q, p, p][mod], - b = [p, p, t, v, v, q][mod]; - - return { r: r * 255, g: g * 255, b: b * 255 }; - } - - // `rgbToHex` - // Converts an RGB color to hex - // Assumes r, g, and b are contained in the set [0, 255] - // Returns a 3 or 6 character hex - function rgbToHex(r, g, b, force6Char) { - - var hex = [ - pad2(mathRound(r).toString(16)), - pad2(mathRound(g).toString(16)), - pad2(mathRound(b).toString(16)) - ]; - - // Return a 3 character hex if possible - if (!force6Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) { - return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0); - } - - return hex.join(""); - } - - // `equals` - // Can be called with any tinycolor input - tinycolor.equals = function (color1, color2) { - if (!color1 || !color2) { return false; } - return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString(); - }; - tinycolor.random = function () { - return tinycolor.fromRatio({ - r: mathRandom(), - g: mathRandom(), - b: mathRandom() - }); - }; - - - // Modification Functions - // ---------------------- - // Thanks to less.js for some of the basics here - // - - - tinycolor.desaturate = function (color, amount) { - var hsl = tinycolor(color).toHsl(); - hsl.s -= ((amount || 10) / 100); - hsl.s = clamp01(hsl.s); - return tinycolor(hsl); - }; - tinycolor.saturate = function (color, amount) { - var hsl = tinycolor(color).toHsl(); - hsl.s += ((amount || 10) / 100); - hsl.s = clamp01(hsl.s); - return tinycolor(hsl); - }; - tinycolor.greyscale = function (color) { - return tinycolor.desaturate(color, 100); - }; - tinycolor.lighten = function (color, amount) { - var hsl = tinycolor(color).toHsl(); - hsl.l += ((amount || 10) / 100); - hsl.l = clamp01(hsl.l); - return tinycolor(hsl); - }; - tinycolor.darken = function (color, amount) { - var hsl = tinycolor(color).toHsl(); - hsl.l -= ((amount || 10) / 100); - hsl.l = clamp01(hsl.l); - return tinycolor(hsl); - }; - tinycolor.complement = function (color) { - var hsl = tinycolor(color).toHsl(); - hsl.h = (hsl.h + .5) % 1; - return tinycolor(hsl); - }; - - - // Combination Functions - // --------------------- - // Thanks to jQuery xColor for some of the ideas behind these - // - - tinycolor.triad = function (color) { - var hsl = tinycolor(color).toHsl(); - var h = hsl.h * 360; - return [ - tinycolor(color), - tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }), - tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l }) - ]; - }; - tinycolor.tetrad = function (color) { - var hsl = tinycolor(color).toHsl(); - var h = hsl.h * 360; - return [ - tinycolor(color), - tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }), - tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }), - tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l }) - ]; - }; - tinycolor.splitcomplement = function (color) { - var hsl = tinycolor(color).toHsl(); - var h = hsl.h * 360; - return [ - tinycolor(color), - tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l }), - tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l }) - ]; - }; - tinycolor.analogous = function (color, results, slices) { - results = results || 6; - slices = slices || 30; - - var hsl = tinycolor(color).toHsl(); - var part = 360 / slices - var ret = [tinycolor(color)]; - - hsl.h *= 360; - - for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) { - hsl.h = (hsl.h + part) % 360; - ret.push(tinycolor(hsl)); - } - return ret; - }; - tinycolor.monochromatic = function (color, results) { - results = results || 6; - var hsv = tinycolor(color).toHsv(); - var h = hsv.h, s = hsv.s, v = hsv.v; - var ret = []; - var modification = 1 / results; - - while (results--) { - ret.push(tinycolor({ h: h, s: s, v: v })); - v = (v + modification) % 1; - } - - return ret; - }; - tinycolor.readable = function (color1, color2) { - var a = tinycolor(color1).toRgb(), b = tinycolor(color2).toRgb(); - return ( - (b.r - a.r) * (b.r - a.r) + - (b.g - a.g) * (b.g - a.g) + - (b.b - a.b) * (b.b - a.b) - ) > 0x28A4; - }; - - // Big List of Colors - // --------- - // - var names = tinycolor.names = { - aliceblue: "f0f8ff", - antiquewhite: "faebd7", - aqua: "0ff", - aquamarine: "7fffd4", - azure: "f0ffff", - beige: "f5f5dc", - bisque: "ffe4c4", - black: "000", - blanchedalmond: "ffebcd", - blue: "00f", - blueviolet: "8a2be2", - brown: "a52a2a", - burlywood: "deb887", - burntsienna: "ea7e5d", - cadetblue: "5f9ea0", - chartreuse: "7fff00", - chocolate: "d2691e", - coral: "ff7f50", - cornflowerblue: "6495ed", - cornsilk: "fff8dc", - crimson: "dc143c", - cyan: "0ff", - darkblue: "00008b", - darkcyan: "008b8b", - darkgoldenrod: "b8860b", - darkgray: "a9a9a9", - darkgreen: "006400", - darkgrey: "a9a9a9", - darkkhaki: "bdb76b", - darkmagenta: "8b008b", - darkolivegreen: "556b2f", - darkorange: "ff8c00", - darkorchid: "9932cc", - darkred: "8b0000", - darksalmon: "e9967a", - darkseagreen: "8fbc8f", - darkslateblue: "483d8b", - darkslategray: "2f4f4f", - darkslategrey: "2f4f4f", - darkturquoise: "00ced1", - darkviolet: "9400d3", - deeppink: "ff1493", - deepskyblue: "00bfff", - dimgray: "696969", - dimgrey: "696969", - dodgerblue: "1e90ff", - firebrick: "b22222", - floralwhite: "fffaf0", - forestgreen: "228b22", - fuchsia: "f0f", - gainsboro: "dcdcdc", - ghostwhite: "f8f8ff", - gold: "ffd700", - goldenrod: "daa520", - gray: "808080", - green: "008000", - greenyellow: "adff2f", - grey: "808080", - honeydew: "f0fff0", - hotpink: "ff69b4", - indianred: "cd5c5c", - indigo: "4b0082", - ivory: "fffff0", - khaki: "f0e68c", - lavender: "e6e6fa", - lavenderblush: "fff0f5", - lawngreen: "7cfc00", - lemonchiffon: "fffacd", - lightblue: "add8e6", - lightcoral: "f08080", - lightcyan: "e0ffff", - lightgoldenrodyellow: "fafad2", - lightgray: "d3d3d3", - lightgreen: "90ee90", - lightgrey: "d3d3d3", - lightpink: "ffb6c1", - lightsalmon: "ffa07a", - lightseagreen: "20b2aa", - lightskyblue: "87cefa", - lightslategray: "789", - lightslategrey: "789", - lightsteelblue: "b0c4de", - lightyellow: "ffffe0", - lime: "0f0", - limegreen: "32cd32", - linen: "faf0e6", - magenta: "f0f", - maroon: "800000", - mediumaquamarine: "66cdaa", - mediumblue: "0000cd", - mediumorchid: "ba55d3", - mediumpurple: "9370db", - mediumseagreen: "3cb371", - mediumslateblue: "7b68ee", - mediumspringgreen: "00fa9a", - mediumturquoise: "48d1cc", - mediumvioletred: "c71585", - midnightblue: "191970", - mintcream: "f5fffa", - mistyrose: "ffe4e1", - moccasin: "ffe4b5", - navajowhite: "ffdead", - navy: "000080", - oldlace: "fdf5e6", - olive: "808000", - olivedrab: "6b8e23", - orange: "ffa500", - orangered: "ff4500", - orchid: "da70d6", - palegoldenrod: "eee8aa", - palegreen: "98fb98", - paleturquoise: "afeeee", - palevioletred: "db7093", - papayawhip: "ffefd5", - peachpuff: "ffdab9", - peru: "cd853f", - pink: "ffc0cb", - plum: "dda0dd", - powderblue: "b0e0e6", - purple: "800080", - red: "f00", - rosybrown: "bc8f8f", - royalblue: "4169e1", - saddlebrown: "8b4513", - salmon: "fa8072", - sandybrown: "f4a460", - seagreen: "2e8b57", - seashell: "fff5ee", - sienna: "a0522d", - silver: "c0c0c0", - skyblue: "87ceeb", - slateblue: "6a5acd", - slategray: "708090", - slategrey: "708090", - snow: "fffafa", - springgreen: "00ff7f", - steelblue: "4682b4", - tan: "d2b48c", - teal: "008080", - thistle: "d8bfd8", - tomato: "ff6347", - turquoise: "40e0d0", - violet: "ee82ee", - wheat: "f5deb3", - white: "fff", - whitesmoke: "f5f5f5", - yellow: "ff0", - yellowgreen: "9acd32" - }; - - // Make it easy to access colors via `hexNames[hex]` - var hexNames = tinycolor.hexNames = flip(names); - - - // Utilities - // --------- - - // `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }` - function flip(o) { - var flipped = {}; - for (var i in o) { - if (o.hasOwnProperty(i)) { - flipped[o[i]] = i; - } - } - return flipped; - } - - // Take input from [0, n] and return it as [0, 1] - function bound01(n, max) { - if (isOnePointZero(n)) { n = "100%"; } - - var processPercent = isPercentage(n); - n = mathMin(max, mathMax(0, parseFloat(n))); - - // Automatically convert percentage into number - if (processPercent) { - n = n * (max / 100); - } - - // Handle floating point rounding errors - if ((math.abs(n - max) < 0.000001)) { - return 1; - } - else if (n >= 1) { - return (n % max) / parseFloat(max); - } - return n; - } - - // Force a number between 0 and 1 - function clamp01(val) { - return mathMin(1, mathMax(0, val)); - } - - // Parse an integer into hex - function parseHex(val) { - return parseInt(val, 16); - } - - // Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1 - // - function isOnePointZero(n) { - return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1; - } - - // Check to see if string passed in is a percentage - function isPercentage(n) { - return typeof n === "string" && n.indexOf('%') != -1; - } - - // Force a hex value to have 2 characters - function pad2(c) { - return c.length == 1 ? '0' + c : '' + c; - } - - var matchers = (function () { - - // - var CSS_INTEGER = "[-\\+]?\\d+%?"; - - // - var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?"; - - // Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome. - var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")"; - - // Actual matching. - // Parentheses and commas are optional, but not required. - // Whitespace can take the place of commas or opening paren - var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?"; - var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?"; - - return { - rgb: new RegExp("rgb" + PERMISSIVE_MATCH3), - rgba: new RegExp("rgba" + PERMISSIVE_MATCH4), - hsl: new RegExp("hsl" + PERMISSIVE_MATCH3), - hsla: new RegExp("hsla" + PERMISSIVE_MATCH4), - hsv: new RegExp("hsv" + PERMISSIVE_MATCH3), - hex3: /^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/, - hex6: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/ - }; - })(); - - // `stringInputToObject` - // Permissive string parsing. Take in a number of formats, and output an object - // based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}` - function stringInputToObject(color) { - - color = color.replace(trimLeft, '').replace(trimRight, '').toLowerCase(); - var named = false; - if (names[color]) { - color = names[color]; - named = true; - } - else if (color == 'transparent') { - return { r: 0, g: 0, b: 0, a: 0 }; - } - - // Try to match string input using regular expressions. - // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360] - // Just return an object and let the conversion functions handle that. - // This way the result will be the same whether the tinycolor is initialized with string or object. - var match; - if ((match = matchers.rgb.exec(color))) { - return { r: match[1], g: match[2], b: match[3] }; - } - if ((match = matchers.rgba.exec(color))) { - return { r: match[1], g: match[2], b: match[3], a: match[4] }; - } - if ((match = matchers.hsl.exec(color))) { - return { h: match[1], s: match[2], l: match[3] }; - } - if ((match = matchers.hsla.exec(color))) { - return { h: match[1], s: match[2], l: match[3], a: match[4] }; - } - if ((match = matchers.hsv.exec(color))) { - return { h: match[1], s: match[2], v: match[3] }; - } - if ((match = matchers.hex6.exec(color))) { - return { - r: parseHex(match[1]), - g: parseHex(match[2]), - b: parseHex(match[3]), - format: named ? "name" : "hex" - }; - } - if ((match = matchers.hex3.exec(color))) { - return { - r: parseHex(match[1] + '' + match[1]), - g: parseHex(match[2] + '' + match[2]), - b: parseHex(match[3] + '' + match[3]), - format: named ? "name" : "hex" - }; - } - - return false; - } - - // Everything is ready, expose to window - window.tinycolor = tinycolor; - - })(this); - - $(function () { - if ($.fn.spectrum.load) { - $.fn.spectrum.processNativeColorInputs(); - } - }); - -})(this, jQuery); diff --git a/tools/webpack-helpers.ts b/tools/webpack-helpers.ts index 62d7c766ee..128f47acfe 100644 --- a/tools/webpack-helpers.ts +++ b/tools/webpack-helpers.ts @@ -8,27 +8,6 @@ export const cacheLoader: RuleSetUseItem = { }, }; -/* Return imports-loader format to the config - For example: - [ - // Adds 'imports-loader?this=>widndow' - {path: './foler/my_module.js', args: '?this=>window'}, - ] -*/ -interface ImportLoaderOptions { - path: string; - args: string; -} -function getImportLoaders(optionsArr: ImportLoaderOptions[]): RuleSetRule[] { - const importsLoaders = []; - for (var loaderEntry of optionsArr) { - importsLoaders.push({ - test: require.resolve(loaderEntry.path), - use: [cacheLoader, "imports-loader?" + loaderEntry.args], - }); - } - return importsLoaders; -} /* Return expose-loader format to the config For example [ @@ -76,5 +55,4 @@ function getExposeLoaders(optionsArr: ExportLoaderOptions[]): RuleSetRule[] { } export { getExposeLoaders, - getImportLoaders, }; diff --git a/tools/webpack.config.ts b/tools/webpack.config.ts index 72ee971d6d..2e171b3271 100644 --- a/tools/webpack.config.ts +++ b/tools/webpack.config.ts @@ -4,7 +4,7 @@ import * as webpack from 'webpack'; // The devServer member of webpack.Configuration is managed by the // webpack-dev-server package. We are only importing the type here. import * as _webpackDevServer from 'webpack-dev-server'; -import { getExposeLoaders, getImportLoaders, cacheLoader } from './webpack-helpers'; +import { getExposeLoaders, cacheLoader } from './webpack-helpers'; import * as MiniCssExtractPlugin from 'mini-css-extract-plugin'; const assets = require('./webpack.assets.json'); @@ -118,16 +118,6 @@ export default (env?: string): webpack.Configuration[] => { devtool: production ? 'source-map' : 'cheap-module-source-map', }; - // Add variables within modules - // Because of code corecing the value of window within the libraries - var importsOptions = [ - { - path: "../static/third/spectrum/spectrum.js", - args: "this=>window", - }, - ]; - config.module.rules.push(...getImportLoaders(importsOptions)); - // Expose Global variables for third party libraries to webpack modules // Use the unminified versions of jquery and underscore so that // Good error messages show up in production and development in the source maps diff --git a/version.py b/version.py index e0b7a63f4d..7dbb53018c 100644 --- a/version.py +++ b/version.py @@ -21,4 +21,4 @@ LATEST_RELEASE_ANNOUNCEMENT = "https://blog.zulip.org/2019/03/01/zulip-2-0-relea # Typically, adding a dependency only requires a minor version bump, and # removing a dependency requires a major version bump. -PROVISION_VERSION = '37.3' +PROVISION_VERSION = '37.4' diff --git a/yarn.lock b/yarn.lock index ac2ca6d9fd..0265b96b4b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9698,6 +9698,11 @@ specificity@^0.4.1: resolved "https://registry.yarnpkg.com/specificity/-/specificity-0.4.1.tgz#aab5e645012db08ba182e151165738d00887b019" integrity sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg== +spectrum-colorpicker@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/spectrum-colorpicker/-/spectrum-colorpicker-1.8.0.tgz#b926cf5002c0a77860b5f8351e1c093c65200107" + integrity sha1-uSbPUALAp3hgtfg1HhwJPGUgAQc= + split-polygon@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/split-polygon/-/split-polygon-1.0.0.tgz#0eacc8a136a76b12a3d95256ea7da45db0c2d247"