1/* 2 * Copyright (C) 2013 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26WebInspector.CSSStyleDeclarationSection = function(style) 27{ 28 WebInspector.Object.call(this); 29 30 console.assert(style); 31 this._style = style || null; 32 33 this._element = document.createElement("div"); 34 this._element.className = WebInspector.CSSStyleDeclarationSection.StyleClassName; 35 36 this._headerElement = document.createElement("div"); 37 this._headerElement.className = WebInspector.CSSStyleDeclarationSection.HeaderElementStyleClassName; 38 39 this._iconElement = document.createElement("img"); 40 this._iconElement.className = WebInspector.CSSStyleDeclarationSection.IconElementStyleClassName; 41 this._headerElement.appendChild(this._iconElement); 42 43 this._selectorElement = document.createElement("span"); 44 this._selectorElement.className = WebInspector.CSSStyleDeclarationSection.SelectorElementStyleClassName; 45 this._selectorElement.setAttribute("spellcheck", "false"); 46 this._headerElement.appendChild(this._selectorElement); 47 48 this._originElement = document.createElement("span"); 49 this._originElement.className = WebInspector.CSSStyleDeclarationSection.OriginElementStyleClassName; 50 this._headerElement.appendChild(this._originElement); 51 52 this._propertiesElement = document.createElement("div"); 53 this._propertiesElement.className = WebInspector.CSSStyleDeclarationSection.PropertiesElementStyleClassName; 54 55 this._propertiesTextEditor = new WebInspector.CSSStyleDeclarationTextEditor(this, style); 56 this._propertiesElement.appendChild(this._propertiesTextEditor.element); 57 58 this._element.appendChild(this._headerElement); 59 this._element.appendChild(this._propertiesElement); 60 61 var iconClassName; 62 switch (style.type) { 63 case WebInspector.CSSStyleDeclaration.Type.Rule: 64 console.assert(style.ownerRule); 65 66 if (style.inherited) 67 iconClassName = WebInspector.CSSStyleDeclarationSection.InheritedStyleRuleIconStyleClassName; 68 else if (style.ownerRule.type === WebInspector.CSSRule.Type.Author) 69 iconClassName = WebInspector.CSSStyleDeclarationSection.AuthorStyleRuleIconStyleClassName; 70 else if (style.ownerRule.type === WebInspector.CSSRule.Type.User) 71 iconClassName = WebInspector.CSSStyleDeclarationSection.UserStyleRuleIconStyleClassName; 72 else if (style.ownerRule.type === WebInspector.CSSRule.Type.UserAgent) 73 iconClassName = WebInspector.CSSStyleDeclarationSection.UserAgentStyleRuleIconStyleClassName; 74 else if (style.ownerRule.type === WebInspector.CSSRule.Type.Inspector) 75 iconClassName = WebInspector.CSSStyleDeclarationSection.InspectorStyleRuleIconStyleClassName; 76 break; 77 78 case WebInspector.CSSStyleDeclaration.Type.Inline: 79 case WebInspector.CSSStyleDeclaration.Type.Attribute: 80 if (style.inherited) 81 iconClassName = WebInspector.CSSStyleDeclarationSection.InheritedElementStyleRuleIconStyleClassName; 82 else 83 iconClassName = WebInspector.DOMTreeElementPathComponent.DOMElementIconStyleClassName; 84 break; 85 } 86 87 console.assert(iconClassName); 88 this._element.classList.add(iconClassName); 89 90 if (!style.editable) 91 this._element.classList.add(WebInspector.CSSStyleDeclarationSection.LockedStyleClassName); 92 else if (style.ownerRule) { 93 this._commitSelectorKeyboardShortcut = new WebInspector.KeyboardShortcut(null, WebInspector.KeyboardShortcut.Key.Enter, this._commitSelector.bind(this), this._selectorElement); 94 this._selectorElement.addEventListener("blur", this._commitSelector.bind(this)); 95 } else 96 this._element.classList.add(WebInspector.CSSStyleDeclarationSection.SelectorLockedStyleClassName); 97 98 if (!WebInspector.CSSStyleDeclarationSection._generatedLockImages) { 99 WebInspector.CSSStyleDeclarationSection._generatedLockImages = true; 100 101 var specifications = {"style-lock-normal": {fillColor: [0, 0, 0, 0.5]}}; 102 generateColoredImagesForCSS("Images/Locked.svg", specifications, 8, 10); 103 } 104 105 this.refresh(); 106}; 107 108WebInspector.CSSStyleDeclarationSection.StyleClassName = "style-declaration-section"; 109WebInspector.CSSStyleDeclarationSection.LockedStyleClassName = "locked"; 110WebInspector.CSSStyleDeclarationSection.SelectorLockedStyleClassName = "selector-locked"; 111WebInspector.CSSStyleDeclarationSection.LastInGroupStyleClassName = "last-in-group"; 112WebInspector.CSSStyleDeclarationSection.HeaderElementStyleClassName = "header"; 113WebInspector.CSSStyleDeclarationSection.IconElementStyleClassName = "icon"; 114WebInspector.CSSStyleDeclarationSection.SelectorElementStyleClassName = "selector"; 115WebInspector.CSSStyleDeclarationSection.OriginElementStyleClassName = "origin"; 116WebInspector.CSSStyleDeclarationSection.PropertiesElementStyleClassName = "properties"; 117WebInspector.CSSStyleDeclarationSection.MatchedSelectorElementStyleClassName = "matched"; 118 119WebInspector.CSSStyleDeclarationSection.AuthorStyleRuleIconStyleClassName = "author-style-rule-icon"; 120WebInspector.CSSStyleDeclarationSection.UserStyleRuleIconStyleClassName = "user-style-rule-icon"; 121WebInspector.CSSStyleDeclarationSection.UserAgentStyleRuleIconStyleClassName = "user-agent-style-rule-icon"; 122WebInspector.CSSStyleDeclarationSection.InspectorStyleRuleIconStyleClassName = "inspector-style-rule-icon"; 123WebInspector.CSSStyleDeclarationSection.InheritedStyleRuleIconStyleClassName = "inherited-style-rule-icon"; 124WebInspector.CSSStyleDeclarationSection.InheritedElementStyleRuleIconStyleClassName = "inherited-element-style-rule-icon"; 125 126WebInspector.CSSStyleDeclarationSection.prototype = { 127 constructor: WebInspector.CSSStyleDeclarationSection, 128 129 // Public 130 131 get element() 132 { 133 return this._element; 134 }, 135 136 get style() 137 { 138 return this._style; 139 }, 140 141 get lastInGroup() 142 { 143 return this._element.classList.contains(WebInspector.CSSStyleDeclarationSection.LastInGroupStyleClassName); 144 }, 145 146 set lastInGroup(last) 147 { 148 if (last) 149 this._element.classList.add(WebInspector.CSSStyleDeclarationSection.LastInGroupStyleClassName); 150 else 151 this._element.classList.remove(WebInspector.CSSStyleDeclarationSection.LastInGroupStyleClassName); 152 }, 153 154 get focused() 155 { 156 return this._propertiesTextEditor.focused; 157 }, 158 159 focus: function() 160 { 161 this._propertiesTextEditor.focus(); 162 }, 163 164 refresh: function() 165 { 166 this._selectorElement.removeChildren(); 167 this._originElement.removeChildren(); 168 169 this._originElement.appendChild(document.createTextNode(" \u2014 ")); 170 171 function appendSelector(selectorText, matched) 172 { 173 var selectorElement = document.createElement("span"); 174 if (matched) 175 selectorElement.className = WebInspector.CSSStyleDeclarationSection.MatchedSelectorElementStyleClassName; 176 selectorElement.textContent = selectorText; 177 this._selectorElement.appendChild(selectorElement); 178 } 179 180 switch (this._style.type) { 181 case WebInspector.CSSStyleDeclaration.Type.Rule: 182 console.assert(this._style.ownerRule); 183 184 var selectors = this._style.ownerRule.selectors; 185 var matchedSelectorIndices = this._style.ownerRule.matchedSelectorIndices; 186 if (selectors.length && matchedSelectorIndices.length) { 187 for (var i = 0; i < selectors.length; ++i) { 188 appendSelector.call(this, selectors[i], matchedSelectorIndices.contains(i)); 189 if (i < selectors.length - 1) 190 this._selectorElement.appendChild(document.createTextNode(", ")); 191 } 192 } else 193 appendSelector.call(this, this._style.ownerRule.selectorText, true); 194 195 if (this._style.ownerRule.sourceCodeLocation) { 196 var sourceCodeLink = WebInspector.createSourceCodeLocationLink(this._style.ownerRule.sourceCodeLocation, true); 197 this._originElement.appendChild(sourceCodeLink); 198 } else { 199 var originString; 200 switch (this._style.ownerRule.type) { 201 case WebInspector.CSSRule.Type.Author: 202 originString = WebInspector.UIString("Author Stylesheet"); 203 break; 204 205 case WebInspector.CSSRule.Type.User: 206 originString = WebInspector.UIString("User Stylesheet"); 207 break; 208 209 case WebInspector.CSSRule.Type.UserAgent: 210 originString = WebInspector.UIString("User Agent Stylesheet"); 211 break; 212 213 case WebInspector.CSSRule.Type.Inspector: 214 originString = WebInspector.UIString("Web Inspector"); 215 break; 216 } 217 218 console.assert(originString); 219 if (originString) 220 this._originElement.appendChild(document.createTextNode(originString)); 221 } 222 223 break; 224 225 case WebInspector.CSSStyleDeclaration.Type.Inline: 226 appendSelector.call(this, WebInspector.displayNameForNode(this._style.node), true); 227 this._originElement.appendChild(document.createTextNode(WebInspector.UIString("Style Attribute"))); 228 break; 229 230 case WebInspector.CSSStyleDeclaration.Type.Attribute: 231 appendSelector.call(this, WebInspector.displayNameForNode(this._style.node), true); 232 this._originElement.appendChild(document.createTextNode(WebInspector.UIString("HTML Attributes"))); 233 break; 234 } 235 }, 236 237 updateLayout: function() 238 { 239 this._propertiesTextEditor.updateLayout(); 240 }, 241 242 // Private 243 244 _commitSelector: function(mutations) 245 { 246 console.assert(this._style.ownerRule); 247 if (!this._style.ownerRule) 248 return; 249 250 var newSelectorText = this._selectorElement.textContent.trim(); 251 if (!newSelectorText) { 252 // Revert to the current selector (by doing a refresh) since the new selector is empty. 253 this.refresh(); 254 return; 255 } 256 257 this._style.ownerRule.selectorText = newSelectorText; 258 } 259}; 260 261WebInspector.CSSStyleDeclarationSection.prototype.__proto__ = WebInspector.StyleDetailsPanel.prototype; 262