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.CSSRule = function(nodeStyles, ownerStyleSheet, id, type, sourceCodeLocation, selectorText, selectors, matchedSelectorIndices, style, mediaList) 27{ 28 WebInspector.Object.call(this); 29 30 console.assert(nodeStyles); 31 this._nodeStyles = nodeStyles; 32 33 this._ownerStyleSheet = ownerStyleSheet || null; 34 this._id = id || null; 35 this._type = type || null; 36 37 this.update(sourceCodeLocation, selectorText, selectors, matchedSelectorIndices, style, mediaList, true); 38}; 39 40WebInspector.Object.addConstructorFunctions(WebInspector.CSSRule); 41 42WebInspector.CSSRule.Event = { 43 Changed: "css-rule-changed" 44}; 45 46WebInspector.CSSRule.Type = { 47 Author: "css-rule-type-author", 48 User: "css-rule-type-user", 49 UserAgent: "css-rule-type-user-agent", 50 Inspector: "css-rule-type-inspector" 51}; 52 53WebInspector.CSSRule.prototype = { 54 constructor: WebInspector.CSSRule, 55 56 // Public 57 58 get id() 59 { 60 return this._id; 61 }, 62 63 get ownerStyleSheet() 64 { 65 return this._ownerStyleSheet; 66 }, 67 68 get editable() 69 { 70 return !!this._id && (this._type === WebInspector.CSSRule.Type.Author || this._type === WebInspector.CSSRule.Type.Inspector); 71 }, 72 73 update: function(sourceCodeLocation, selectorText, selectors, matchedSelectorIndices, style, mediaList, dontFireEvents) 74 { 75 sourceCodeLocation = sourceCodeLocation || null; 76 selectorText = selectorText || ""; 77 selectors = selectors || []; 78 matchedSelectorIndices = matchedSelectorIndices || []; 79 style = style || null; 80 mediaList = mediaList || []; 81 82 var changed = false; 83 if (!dontFireEvents) { 84 changed = this._selectorText !== selectorText || !Object.shallowEqual(this._selectors, selectors) || 85 !Object.shallowEqual(this._matchedSelectorIndices, matchedSelectorIndices) || this._style !== style || 86 !!this._sourceCodeLocation !== !!sourceCodeLocation || this._mediaList.length !== mediaList.length; 87 // FIXME: Look for differences in the media list arrays. 88 } 89 90 if (this._style) 91 this._style.ownerRule = null; 92 93 this._sourceCodeLocation = sourceCodeLocation; 94 this._selectorText = selectorText; 95 this._selectors = selectors; 96 this._matchedSelectorIndices = matchedSelectorIndices; 97 this._style = style; 98 this._mediaList = mediaList; 99 100 delete this._matchedSelectors; 101 delete this._matchedSelectorText; 102 103 if (this._style) 104 this._style.ownerRule = this; 105 106 if (changed) 107 this.dispatchEventToListeners(WebInspector.CSSRule.Event.Changed); 108 }, 109 110 get type() 111 { 112 return this._type; 113 }, 114 115 get sourceCodeLocation() 116 { 117 return this._sourceCodeLocation; 118 }, 119 120 get selectorText() 121 { 122 return this._selectorText; 123 }, 124 125 set selectorText(selectorText) 126 { 127 console.assert(this.editable); 128 if (!this.editable) 129 return; 130 131 if (this._selectorText === selectorText) 132 return; 133 134 this._nodeStyles.changeRuleSelector(this, selectorText); 135 }, 136 137 get selectors() 138 { 139 return this._selectors; 140 }, 141 142 set selectors(selectors) 143 { 144 this.selectorText = (selectors || []).join(", "); 145 }, 146 147 get matchedSelectorIndices() 148 { 149 return this._matchedSelectorIndices; 150 }, 151 152 get matchedSelectors() 153 { 154 // COMPATIBILITY (iOS 6): The selectors array is always empty, so just return an empty array. 155 if (!this._selectors.length) { 156 console.assert(!this._matchedSelectorIndices.length); 157 return []; 158 } 159 160 if (this._matchedSelectors) 161 return this._matchedSelectors; 162 163 this._matchedSelectors = this._selectors.filter(function(element, index) { 164 return this._matchedSelectorIndices.contains(index); 165 }, this); 166 167 return this._matchedSelectors; 168 }, 169 170 get matchedSelectorText() 171 { 172 // COMPATIBILITY (iOS 6): The selectors array is always empty, so just return the whole selector. 173 if (!this._selectors.length) { 174 console.assert(!this._matchedSelectorIndices.length); 175 return this._selectorText; 176 } 177 178 if ("_matchedSelectorText" in this) 179 return this._matchedSelectorText; 180 181 this._matchedSelectorText = this.matchedSelectors.join(", "); 182 183 return this._matchedSelectorText; 184 }, 185 186 get style() 187 { 188 return this._style; 189 }, 190 191 get mediaList() 192 { 193 return this._mediaList; 194 }, 195 196 // Protected 197 198 get nodeStyles() 199 { 200 return this._nodeStyles; 201 } 202}; 203 204WebInspector.CSSRule.prototype.__proto__ = WebInspector.Object.prototype; 205