~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebCore/inspector/front-end/CSSCompletions.js

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2010 Nikita Vasilyev. All rights reserved.
 
3
 * Copyright (C) 2010 Joseph Pecoraro. All rights reserved.
 
4
 * Copyright (C) 2010 Google Inc. All rights reserved.
 
5
 *
 
6
 * Redistribution and use in source and binary forms, with or without
 
7
 * modification, are permitted provided that the following conditions are
 
8
 * met:
 
9
 *
 
10
 *     * Redistributions of source code must retain the above copyright
 
11
 * notice, this list of conditions and the following disclaimer.
 
12
 *     * Redistributions in binary form must reproduce the above
 
13
 * copyright notice, this list of conditions and the following disclaimer
 
14
 * in the documentation and/or other materials provided with the
 
15
 * distribution.
 
16
 *     * Neither the name of Google Inc. nor the names of its
 
17
 * contributors may be used to endorse or promote products derived from
 
18
 * this software without specific prior written permission.
 
19
 *
 
20
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
21
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
22
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
23
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 
24
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
25
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
26
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
27
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
28
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
29
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
30
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
31
 */
 
32
 
 
33
/**
 
34
 * @constructor
 
35
 * @param {Array.<CSSAgent.CSSPropertyInfo|string>} properties
 
36
 */
 
37
WebInspector.CSSCompletions = function(properties)
 
38
{
 
39
    this._values = [];
 
40
    this._longhands = {};
 
41
    this._shorthands = {};
 
42
    for (var i = 0; i < properties.length; ++i) {
 
43
        var property = properties[i];
 
44
        if (typeof property === "string") {
 
45
            this._values.push(property);
 
46
            continue;
 
47
        }
 
48
 
 
49
        var propertyName = property.name;
 
50
        this._values.push(propertyName);
 
51
 
 
52
        var longhands = properties[i].longhands;
 
53
        if (longhands) {
 
54
            this._longhands[propertyName] = longhands;
 
55
            for (var j = 0; j < longhands.length; ++j) {
 
56
                var longhandName = longhands[j];
 
57
                var shorthands = this._shorthands[longhandName];
 
58
                if (!shorthands) {
 
59
                    shorthands = [];
 
60
                    this._shorthands[longhandName] = shorthands;
 
61
                }
 
62
                shorthands.push(propertyName);
 
63
            }
 
64
        }
 
65
    }
 
66
    this._values.sort();
 
67
}
 
68
 
 
69
 
 
70
/**
 
71
 * @type {WebInspector.CSSCompletions}
 
72
 */
 
73
WebInspector.CSSCompletions.cssPropertiesMetainfo = null;
 
74
 
 
75
WebInspector.CSSCompletions.requestCSSNameCompletions = function()
 
76
{
 
77
    function propertyNamesCallback(error, properties)
 
78
    {
 
79
        if (!error)
 
80
            WebInspector.CSSCompletions.cssPropertiesMetainfo = new WebInspector.CSSCompletions(properties);
 
81
    }
 
82
    CSSAgent.getSupportedCSSProperties(propertyNamesCallback);
 
83
}
 
84
 
 
85
WebInspector.CSSCompletions.cssPropertiesMetainfoKeySet = function()
 
86
{
 
87
    if (!WebInspector.CSSCompletions._cssPropertiesMetainfoKeySet)
 
88
        WebInspector.CSSCompletions._cssPropertiesMetainfoKeySet = WebInspector.CSSCompletions.cssPropertiesMetainfo.keySet();
 
89
    return WebInspector.CSSCompletions._cssPropertiesMetainfoKeySet;
 
90
}
 
91
 
 
92
// Weight of CSS properties based their usage on few popular websites https://gist.github.com/3751436
 
93
WebInspector.CSSCompletions.Weight = {
 
94
    "-webkit-animation": 1,
 
95
    "-webkit-animation-duration": 1,
 
96
    "-webkit-animation-iteration-count": 1,
 
97
    "-webkit-animation-name": 1,
 
98
    "-webkit-animation-timing-function": 1,
 
99
    "-webkit-appearance": 1,
 
100
    "-webkit-background-clip": 2,
 
101
    "-webkit-border-horizontal-spacing": 1,
 
102
    "-webkit-border-vertical-spacing": 1,
 
103
    "-webkit-box-shadow": 24,
 
104
    "-webkit-font-smoothing": 2,
 
105
    "-webkit-transform": 1,
 
106
    "-webkit-transition": 8,
 
107
    "-webkit-transition-delay": 7,
 
108
    "-webkit-transition-duration": 7,
 
109
    "-webkit-transition-property": 7,
 
110
    "-webkit-transition-timing-function": 6,
 
111
    "-webkit-user-select": 1,
 
112
    "background": 222,
 
113
    "background-attachment": 144,
 
114
    "background-clip": 143,
 
115
    "background-color": 222,
 
116
    "background-image": 201,
 
117
    "background-origin": 142,
 
118
    "background-size": 25,
 
119
    "border": 121,
 
120
    "border-bottom": 121,
 
121
    "border-bottom-color": 121,
 
122
    "border-bottom-left-radius": 50,
 
123
    "border-bottom-right-radius": 50,
 
124
    "border-bottom-style": 114,
 
125
    "border-bottom-width": 120,
 
126
    "border-collapse": 3,
 
127
    "border-left": 95,
 
128
    "border-left-color": 95,
 
129
    "border-left-style": 89,
 
130
    "border-left-width": 94,
 
131
    "border-radius": 50,
 
132
    "border-right": 93,
 
133
    "border-right-color": 93,
 
134
    "border-right-style": 88,
 
135
    "border-right-width": 93,
 
136
    "border-top": 111,
 
137
    "border-top-color": 111,
 
138
    "border-top-left-radius": 49,
 
139
    "border-top-right-radius": 49,
 
140
    "border-top-style": 104,
 
141
    "border-top-width": 109,
 
142
    "bottom": 16,
 
143
    "box-shadow": 25,
 
144
    "box-sizing": 2,
 
145
    "clear": 23,
 
146
    "color": 237,
 
147
    "cursor": 34,
 
148
    "direction": 4,
 
149
    "display": 210,
 
150
    "fill": 2,
 
151
    "filter": 1,
 
152
    "float": 105,
 
153
    "font": 174,
 
154
    "font-family": 25,
 
155
    "font-size": 174,
 
156
    "font-style": 9,
 
157
    "font-weight": 89,
 
158
    "height": 161,
 
159
    "left": 54,
 
160
    "letter-spacing": 3,
 
161
    "line-height": 75,
 
162
    "list-style": 17,
 
163
    "list-style-image": 8,
 
164
    "list-style-position": 8,
 
165
    "list-style-type": 17,
 
166
    "margin": 241,
 
167
    "margin-bottom": 226,
 
168
    "margin-left": 225,
 
169
    "margin-right": 213,
 
170
    "margin-top": 241,
 
171
    "max-height": 5,
 
172
    "max-width": 11,
 
173
    "min-height": 9,
 
174
    "min-width": 6,
 
175
    "opacity": 24,
 
176
    "outline": 10,
 
177
    "outline-color": 10,
 
178
    "outline-style": 10,
 
179
    "outline-width": 10,
 
180
    "overflow": 57,
 
181
    "overflow-x": 56,
 
182
    "overflow-y": 57,
 
183
    "padding": 216,
 
184
    "padding-bottom": 208,
 
185
    "padding-left": 216,
 
186
    "padding-right": 206,
 
187
    "padding-top": 216,
 
188
    "position": 136,
 
189
    "resize": 1,
 
190
    "right": 29,
 
191
    "stroke": 1,
 
192
    "stroke-width": 1,
 
193
    "table-layout": 1,
 
194
    "text-align": 66,
 
195
    "text-decoration": 53,
 
196
    "text-indent": 9,
 
197
    "text-overflow": 8,
 
198
    "text-shadow": 19,
 
199
    "text-transform": 5,
 
200
    "top": 71,
 
201
    "unicode-bidi": 1,
 
202
    "vertical-align": 37,
 
203
    "visibility": 11,
 
204
    "white-space": 24,
 
205
    "width": 255,
 
206
    "word-wrap": 6,
 
207
    "z-index": 32,
 
208
    "zoom": 10
 
209
};
 
210
 
 
211
 
 
212
WebInspector.CSSCompletions.prototype = {
 
213
    startsWith: function(prefix)
 
214
    {
 
215
        var firstIndex = this._firstIndexOfPrefix(prefix);
 
216
        if (firstIndex === -1)
 
217
            return [];
 
218
 
 
219
        var results = [];
 
220
        while (firstIndex < this._values.length && this._values[firstIndex].startsWith(prefix))
 
221
            results.push(this._values[firstIndex++]);
 
222
        return results;
 
223
    },
 
224
 
 
225
    /**
 
226
     * @param {Array.<string>} properties
 
227
     * @return {number}
 
228
     */
 
229
    mostUsedOf: function(properties)
 
230
    {
 
231
        var maxWeight = 0;
 
232
        var index = 0;
 
233
        for (var i = 0; i < properties.length; i++) {
 
234
            var weight = WebInspector.CSSCompletions.Weight[properties[i]];
 
235
            if (weight > maxWeight) {
 
236
                maxWeight = weight;
 
237
                index = i;
 
238
            }
 
239
        }
 
240
        return index;
 
241
    },
 
242
 
 
243
    _firstIndexOfPrefix: function(prefix)
 
244
    {
 
245
        if (!this._values.length)
 
246
            return -1;
 
247
        if (!prefix)
 
248
            return 0;
 
249
 
 
250
        var maxIndex = this._values.length - 1;
 
251
        var minIndex = 0;
 
252
        var foundIndex;
 
253
 
 
254
        do {
 
255
            var middleIndex = (maxIndex + minIndex) >> 1;
 
256
            if (this._values[middleIndex].startsWith(prefix)) {
 
257
                foundIndex = middleIndex;
 
258
                break;
 
259
            }
 
260
            if (this._values[middleIndex] < prefix)
 
261
                minIndex = middleIndex + 1;
 
262
            else
 
263
                maxIndex = middleIndex - 1;
 
264
        } while (minIndex <= maxIndex);
 
265
 
 
266
        if (foundIndex === undefined)
 
267
            return -1;
 
268
 
 
269
        while (foundIndex && this._values[foundIndex - 1].startsWith(prefix))
 
270
            foundIndex--;
 
271
 
 
272
        return foundIndex;
 
273
    },
 
274
 
 
275
    keySet: function()
 
276
    {
 
277
        if (!this._keySet)
 
278
            this._keySet = this._values.keySet();
 
279
        return this._keySet;
 
280
    },
 
281
 
 
282
    next: function(str, prefix)
 
283
    {
 
284
        return this._closest(str, prefix, 1);
 
285
    },
 
286
 
 
287
    previous: function(str, prefix)
 
288
    {
 
289
        return this._closest(str, prefix, -1);
 
290
    },
 
291
 
 
292
    _closest: function(str, prefix, shift)
 
293
    {
 
294
        if (!str)
 
295
            return "";
 
296
 
 
297
        var index = this._values.indexOf(str);
 
298
        if (index === -1)
 
299
            return "";
 
300
 
 
301
        if (!prefix) {
 
302
            index = (index + this._values.length + shift) % this._values.length;
 
303
            return this._values[index];
 
304
        }
 
305
 
 
306
        var propertiesWithPrefix = this.startsWith(prefix);
 
307
        var j = propertiesWithPrefix.indexOf(str);
 
308
        j = (j + propertiesWithPrefix.length + shift) % propertiesWithPrefix.length;
 
309
        return propertiesWithPrefix[j];
 
310
    },
 
311
 
 
312
    /**
 
313
     * @param {string} shorthand
 
314
     * @return {?Array.<string>}
 
315
     */
 
316
    longhands: function(shorthand)
 
317
    {
 
318
        return this._longhands[shorthand];
 
319
    },
 
320
 
 
321
    /**
 
322
     * @param {string} longhand
 
323
     * @return {?Array.<string>}
 
324
     */
 
325
    shorthands: function(longhand)
 
326
    {
 
327
        return this._shorthands[longhand];
 
328
    }
 
329
}