|
| 1 | +define(function(require, exports, module) { |
| 2 | + "use strict"; |
| 3 | + |
| 4 | + var Strings = brackets.getModule("strings"); |
| 5 | + var Mustache = brackets.getModule("thirdparty/mustache/mustache"); |
| 6 | + var BorderRadiusUtils = require("BorderRadiusUtils"); |
| 7 | + |
| 8 | + // getting reference to the html template for the border-radius editor UI |
| 9 | + var BorderRadiusTemplate = require("text!BorderRadiusEditorTemplate.html"); |
| 10 | + |
| 11 | + function getIndividualValues(values){ |
| 12 | + // Convert "12px 20px 30px" into an array of individual values like: |
| 13 | + // [{num: 12, unit: "px"}, {num: 20, unit: "px"}, ...] |
| 14 | + var individualValues = []; |
| 15 | + var currentValue; |
| 16 | + |
| 17 | + // We create a new regular expression everytime so that we don't |
| 18 | + // reuse stale data from the old RegExp object. |
| 19 | + var valueRegex = new RegExp(BorderRadiusUtils.BORDER_RADIUS_SINGLE_VALUE_REGEX); |
| 20 | + |
| 21 | + while ((currentValue = valueRegex.exec(values)) !== null) { |
| 22 | + individualValues.push({ |
| 23 | + num: parseFloat(currentValue[1]), |
| 24 | + unit: currentValue[2] || "" |
| 25 | + }); |
| 26 | + } |
| 27 | + |
| 28 | + return individualValues; |
| 29 | + } |
| 30 | + |
| 31 | + function BorderRadiusValue($parentElement, location, value, unit, onChange) { |
| 32 | + var self = this; |
| 33 | + |
| 34 | + self.value = value || 0; |
| 35 | + self.unit = unit || ""; |
| 36 | + |
| 37 | + var $slider = this.$slider = $parentElement.find("#" + location + "-slider"); |
| 38 | + var $unitOptions = $parentElement.find("#" + location + "-radio").children(); |
| 39 | + var $text = $parentElement.find("#" + location + "-text"); |
| 40 | + |
| 41 | + $slider.val(self.value); |
| 42 | + $unitOptions.filter(function() { |
| 43 | + return $(this).text().trim() === self.unit; |
| 44 | + }).addClass("selected"); |
| 45 | + $text.text(self.toString()); |
| 46 | + |
| 47 | + $slider.on("input", function() { |
| 48 | + var newValue = $slider.val().trim(); |
| 49 | + self.value = newValue; |
| 50 | + $text.text(self.toString()); |
| 51 | + onChange(); |
| 52 | + }); |
| 53 | + |
| 54 | + $unitOptions.on("click", function() { |
| 55 | + var $selectedUnit = $(this); |
| 56 | + $selectedUnit.siblings().removeClass("selected"); |
| 57 | + $selectedUnit.addClass("selected"); |
| 58 | + |
| 59 | + self.unit = $selectedUnit.text().trim(); |
| 60 | + $text.text(self.toString()); |
| 61 | + onChange(); |
| 62 | + }); |
| 63 | + } |
| 64 | + |
| 65 | + BorderRadiusValue.prototype.toString = function() { |
| 66 | + return this.value + (this.value === 0 ? "" : this.unit); |
| 67 | + }; |
| 68 | + |
| 69 | + function BorderRadiusEditor($parent, valueString, radiusChangeHandler) { |
| 70 | + var self = this; |
| 71 | + |
| 72 | + // Create the DOM structure, filling in localized strings via Mustache |
| 73 | + self.$element = $(Mustache.render(BorderRadiusTemplate, Strings)); |
| 74 | + $parent.append(self.$element); |
| 75 | + self.radiusChangeHandler = radiusChangeHandler; |
| 76 | + |
| 77 | + this.onChange = this.onChange.bind(this); |
| 78 | + self.updateValues(valueString); |
| 79 | + |
| 80 | + // Attach event listeners to toggle the corner mode UI elements |
| 81 | + var $individualCornerArea = self.$element.find("#individualCornerArea"); |
| 82 | + var $individualCornerButton = self.$element.find("#individualCorners"); |
| 83 | + var $allCornersArea = self.$element.find("#allCornersArea"); |
| 84 | + var $allCornerButton = self.$element.find("#allCorners"); |
| 85 | + |
| 86 | + function toggleCornerOption($showElement, $hideElement) { |
| 87 | + $showElement.show(); |
| 88 | + $hideElement.hide(); |
| 89 | + self.allCorners = $showElement === $allCornersArea; |
| 90 | + self.onChange(); |
| 91 | + } |
| 92 | + |
| 93 | + $allCornerButton.on("click", function() { |
| 94 | + $allCornerButton.addClass("selected"); |
| 95 | + $individualCornerButton.removeClass("selected"); |
| 96 | + toggleCornerOption($allCornersArea, $individualCornerArea); |
| 97 | + }); |
| 98 | + $individualCornerButton.on("click", function() { |
| 99 | + $allCornerButton.removeClass("selected"); |
| 100 | + $individualCornerButton.addClass("selected"); |
| 101 | + toggleCornerOption($individualCornerArea, $allCornersArea); |
| 102 | + }); |
| 103 | + |
| 104 | + // initialize individual corner editing to be disabled if allCorner is set to true |
| 105 | + if(self.allCorners){ |
| 106 | + $allCornerButton.trigger("click"); |
| 107 | + } else { |
| 108 | + $individualCornerButton.trigger("click"); |
| 109 | + } |
| 110 | + } |
| 111 | + |
| 112 | + BorderRadiusEditor.prototype.updateValues = function(valueString) { |
| 113 | + var values = getIndividualValues(valueString); |
| 114 | + var numOfValues = values.length; |
| 115 | + var firstValue = values[0]; |
| 116 | + var secondValue = firstValue; |
| 117 | + var thirdValue = firstValue; |
| 118 | + var fourthValue = firstValue; |
| 119 | + |
| 120 | + this.allCorners = values.length === 1; |
| 121 | + |
| 122 | + if (!this.allCorners) { |
| 123 | + secondValue = values[1]; |
| 124 | + |
| 125 | + if (numOfValues === 2) { |
| 126 | + fourthValue = secondValue; |
| 127 | + } else { |
| 128 | + thirdValue = values[2]; |
| 129 | + |
| 130 | + if (numOfValues === 3) { |
| 131 | + fourthValue = secondValue; |
| 132 | + } else { |
| 133 | + fourthValue = values[3]; |
| 134 | + } |
| 135 | + } |
| 136 | + } |
| 137 | + |
| 138 | + this.topLeft = new BorderRadiusValue( |
| 139 | + this.$element, |
| 140 | + "top-left", |
| 141 | + firstValue.num, |
| 142 | + firstValue.unit, |
| 143 | + this.onChange |
| 144 | + ); |
| 145 | + this.topRight = new BorderRadiusValue( |
| 146 | + this.$element, |
| 147 | + "top-right", |
| 148 | + secondValue.num, |
| 149 | + secondValue.unit, |
| 150 | + this.onChange |
| 151 | + ); |
| 152 | + this.bottomRight = new BorderRadiusValue( |
| 153 | + this.$element, |
| 154 | + "bottom-right", |
| 155 | + thirdValue.num, |
| 156 | + thirdValue.unit, |
| 157 | + this.onChange |
| 158 | + ); |
| 159 | + this.bottomLeft = new BorderRadiusValue( |
| 160 | + this.$element, |
| 161 | + "bottom-left", |
| 162 | + fourthValue.num, |
| 163 | + fourthValue.unit, |
| 164 | + this.onChange |
| 165 | + ); |
| 166 | + this.allCorner = new BorderRadiusValue( |
| 167 | + this.$element, |
| 168 | + "all-corner", |
| 169 | + firstValue.num, |
| 170 | + firstValue.unit, |
| 171 | + this.onChange |
| 172 | + ); |
| 173 | + |
| 174 | + //correctly update the values in the UI. |
| 175 | + this.onChange(); |
| 176 | + }; |
| 177 | + |
| 178 | + BorderRadiusEditor.prototype.onChange = function() { |
| 179 | + if (this.allCorners) { |
| 180 | + this.radiusChangeHandler(this.allCorner.toString()); |
| 181 | + return; |
| 182 | + } |
| 183 | + |
| 184 | + var topLeft = this.topLeft.toString(); |
| 185 | + var topRight = this.topRight.toString(); |
| 186 | + var bottomRight = this.bottomRight.toString(); |
| 187 | + var bottomLeft = this.bottomLeft.toString(); |
| 188 | + var borderRadiusString; |
| 189 | + |
| 190 | + if (topRight === bottomLeft) { |
| 191 | + // We can use a two value border radius if top right and |
| 192 | + // bottom left are equal and top left and bottom right are equal. |
| 193 | + // For e.g. 20px 30px |
| 194 | + borderRadiusString = topLeft + " " + topRight; |
| 195 | + |
| 196 | + if (topLeft !== bottomRight) { |
| 197 | + // We can use a three value border radius if top right and |
| 198 | + // bottom left are equal but the top left and bottom right |
| 199 | + // values are not. |
| 200 | + borderRadiusString += " " + bottomRight; |
| 201 | + } else if (topLeft === topRight) { |
| 202 | + // This means that top left and bottom right are equal (set 1), |
| 203 | + // the top right and bottom left values are equal (set 2), and |
| 204 | + // that set 1 and set 2 are equal - implying that all values |
| 205 | + // are the same. |
| 206 | + borderRadiusString = topLeft; |
| 207 | + } |
| 208 | + } else { |
| 209 | + borderRadiusString = [topLeft, topRight, bottomRight, bottomLeft].join(" "); |
| 210 | + } |
| 211 | + |
| 212 | + this.radiusChangeHandler(borderRadiusString); |
| 213 | + }; |
| 214 | + |
| 215 | + BorderRadiusEditor.prototype.focus = function() { |
| 216 | + this.topLeft.$slider.focus(); |
| 217 | + }; |
| 218 | + |
| 219 | + BorderRadiusEditor.prototype.isValidBorderRadiusString = function(string){ |
| 220 | + var radiusValueRegEx = new RegExp(BorderRadiusUtils.BORDER_RADIUS_VALUE_REGEX); |
| 221 | + return radiusValueRegEx.test(string); |
| 222 | + }; |
| 223 | + |
| 224 | + exports.BorderRadiusEditor = BorderRadiusEditor; |
| 225 | +}); |
0 commit comments