Added MacOS SDK
This commit is contained in:
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Nikita Vasilyev. All rights reserved.
|
||||
* Copyright (C) 2010 Joseph Pecoraro. All rights reserved.
|
||||
* Copyright (C) 2010 Google Inc. All rights reserved.
|
||||
* Copyright (C) 2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
WI.CSSCompletions = class CSSCompletions
|
||||
{
|
||||
constructor(values, {acceptEmptyPrefix} = {})
|
||||
{
|
||||
console.assert(Array.isArray(values), values);
|
||||
console.assert(!values.length || typeof values[0] === "string", "Expected an array of string values or an empty array", values);
|
||||
|
||||
this._values = values.slice();
|
||||
this._values.sort();
|
||||
this._acceptEmptyPrefix = !!acceptEmptyPrefix;
|
||||
this._queryController = null;
|
||||
}
|
||||
|
||||
// Static
|
||||
|
||||
static completeUnbalancedValue(value)
|
||||
{
|
||||
const State = {
|
||||
Data: 0,
|
||||
SingleQuoteString: 1,
|
||||
DoubleQuoteString: 2,
|
||||
Comment: 3
|
||||
};
|
||||
|
||||
let state = State.Data;
|
||||
let unclosedParenthesisCount = 0;
|
||||
let trailingBackslash = false;
|
||||
let length = value.length;
|
||||
|
||||
for (let i = 0; i < length; ++i) {
|
||||
switch (value[i]) {
|
||||
case "'":
|
||||
if (state === State.Data)
|
||||
state = State.SingleQuoteString;
|
||||
else if (state === State.SingleQuoteString)
|
||||
state = State.Data;
|
||||
break;
|
||||
|
||||
case "\"":
|
||||
if (state === State.Data)
|
||||
state = State.DoubleQuoteString;
|
||||
else if (state === State.DoubleQuoteString)
|
||||
state = State.Data;
|
||||
break;
|
||||
|
||||
case "(":
|
||||
if (state === State.Data)
|
||||
++unclosedParenthesisCount;
|
||||
break;
|
||||
|
||||
case ")":
|
||||
if (state === State.Data && unclosedParenthesisCount)
|
||||
--unclosedParenthesisCount;
|
||||
break;
|
||||
|
||||
case "/":
|
||||
if (state === State.Data) {
|
||||
if (value[i + 1] === "*")
|
||||
state = State.Comment;
|
||||
}
|
||||
break;
|
||||
|
||||
case "\\":
|
||||
if (i === length - 1)
|
||||
trailingBackslash = true;
|
||||
else
|
||||
++i; // Skip next character.
|
||||
break;
|
||||
|
||||
case "*":
|
||||
if (state === State.Comment) {
|
||||
if (value[i + 1] === "/")
|
||||
state = State.Data;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let suffix = "";
|
||||
|
||||
if (trailingBackslash)
|
||||
suffix += "\\";
|
||||
|
||||
switch (state) {
|
||||
case State.SingleQuoteString:
|
||||
suffix += "'";
|
||||
break;
|
||||
case State.DoubleQuoteString:
|
||||
suffix += "\"";
|
||||
break;
|
||||
case State.Comment:
|
||||
suffix += "*/";
|
||||
break;
|
||||
}
|
||||
|
||||
suffix += ")".repeat(unclosedParenthesisCount);
|
||||
|
||||
return suffix;
|
||||
}
|
||||
|
||||
static getCompletionText(completion)
|
||||
{
|
||||
console.assert(typeof completion === "string" || completion instanceof WI.QueryResult, completion);
|
||||
|
||||
if (typeof completion === "string")
|
||||
return completion;
|
||||
|
||||
if (completion instanceof WI.QueryResult)
|
||||
return completion.value;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
// Public
|
||||
|
||||
get values()
|
||||
{
|
||||
return this._values;
|
||||
}
|
||||
|
||||
executeQuery(query)
|
||||
{
|
||||
if (!query)
|
||||
return this._acceptEmptyPrefix ? this._values.slice() : [];
|
||||
|
||||
this._queryController ||= new WI.CSSQueryController(this._values);
|
||||
|
||||
return this._queryController.executeQuery(query);
|
||||
}
|
||||
|
||||
startsWith(prefix)
|
||||
{
|
||||
if (!prefix)
|
||||
return this._acceptEmptyPrefix ? this._values.slice() : [];
|
||||
|
||||
let firstIndex = this._firstIndexOfPrefix(prefix);
|
||||
if (firstIndex === -1)
|
||||
return [];
|
||||
|
||||
let results = [];
|
||||
while (firstIndex < this._values.length && this._values[firstIndex].startsWith(prefix))
|
||||
results.push(this._values[firstIndex++]);
|
||||
return results;
|
||||
}
|
||||
|
||||
// Protected
|
||||
|
||||
replaceValues(values)
|
||||
{
|
||||
console.assert(Array.isArray(values), values);
|
||||
console.assert(typeof values[0] === "string", "Expect an array of string values", values);
|
||||
|
||||
this._values = values;
|
||||
this._values.sort();
|
||||
|
||||
this._queryController?.reset();
|
||||
this._queryController?.addValues(values);
|
||||
}
|
||||
|
||||
// Private
|
||||
|
||||
_firstIndexOfPrefix(prefix)
|
||||
{
|
||||
if (!this._values.length)
|
||||
return -1;
|
||||
if (!prefix)
|
||||
return this._acceptEmptyPrefix ? 0 : -1;
|
||||
|
||||
var maxIndex = this._values.length - 1;
|
||||
var minIndex = 0;
|
||||
var foundIndex;
|
||||
|
||||
do {
|
||||
var middleIndex = (maxIndex + minIndex) >> 1;
|
||||
if (this._values[middleIndex].startsWith(prefix)) {
|
||||
foundIndex = middleIndex;
|
||||
break;
|
||||
}
|
||||
if (this._values[middleIndex] < prefix)
|
||||
minIndex = middleIndex + 1;
|
||||
else
|
||||
maxIndex = middleIndex - 1;
|
||||
} while (minIndex <= maxIndex);
|
||||
|
||||
if (foundIndex === undefined)
|
||||
return -1;
|
||||
|
||||
while (foundIndex && this._values[foundIndex - 1].startsWith(prefix))
|
||||
foundIndex--;
|
||||
|
||||
return foundIndex;
|
||||
}
|
||||
};
|
||||
|
||||
WI.CSSCompletions.lengthUnits = new Set([
|
||||
"ch",
|
||||
"cm",
|
||||
"dvb",
|
||||
"dvh",
|
||||
"dvi",
|
||||
"dvmax",
|
||||
"dvmin",
|
||||
"dvw",
|
||||
"em",
|
||||
"ex",
|
||||
"in",
|
||||
"lvb",
|
||||
"lvh",
|
||||
"lvi",
|
||||
"lvmax",
|
||||
"lvmin",
|
||||
"lvw",
|
||||
"mm",
|
||||
"pc",
|
||||
"pt",
|
||||
"px",
|
||||
"q",
|
||||
"rem",
|
||||
"svb",
|
||||
"svh",
|
||||
"svi",
|
||||
"svmax",
|
||||
"svmin",
|
||||
"svw",
|
||||
"vb",
|
||||
"vh",
|
||||
"vi",
|
||||
"vmax",
|
||||
"vmin",
|
||||
"vw",
|
||||
]);
|
||||
Reference in New Issue
Block a user