mirror of
https://github.com/adobe/brackets.git
synced 2024-11-20 18:02:54 +01:00
Update CSS pseudo-selector hints (#14012)
* Update pseudo-selectors Add pseudo-selectors * :any-link * :first * :last * :left * :right * ::backdrop * ::cue * ::cue(). Update * :lang() * :not(). Update descriptions being more correct. (Move opening braces to previous line.) * Use correct term “pseudo-class” + fix spelling error & tests Pseudo-selectors are divided into two categories: pseudo-classes and pseudo-elements. * Remove :last psudo-selector (which doesn’t exist) from CSS Selector Hints
This commit is contained in:
parent
cad7bd2cdc
commit
45347fe6ae
@ -1,52 +1,57 @@
|
||||
{
|
||||
"selectors":
|
||||
{
|
||||
"active": {"desc": "Selects the active link"},
|
||||
"checked": {"desc": "Selects every checked <input> element"},
|
||||
"classes": {
|
||||
"active": {"desc": "Selects the link being pressed"},
|
||||
"any-link": {"desc": "Selects every hyperlink, e.g., <a>, <area> and <link> with href attribute"},
|
||||
"checked": {"desc": "Selects every checked checkbox"},
|
||||
"default": {"desc": "Selects every UI element that is the default among a group of similar elements"},
|
||||
"dir(direction)": {"desc": "Selects every element whose text direction is 'direction'", "text": "dir()"},
|
||||
"disabled": {"desc": "Selects every disabled <input> element"},
|
||||
"empty": {"desc": "Selects every element that has no children/text (including text nodes)"},
|
||||
"enabled": {"desc": "Selects every enabled <input> element"},
|
||||
"disabled": {"desc": "Selects every disabled form element"},
|
||||
"empty": {"desc": "Selects every element that has no any child nodes"},
|
||||
"enabled": {"desc": "Selects every enabled form element"},
|
||||
"first": {"desc": "With @page, selects the first page of a printed document"},
|
||||
"first-child": {"desc": "Selects every element that is the first child of its parent"},
|
||||
"first-of-type": {"desc": "Selects every element that is the first element identified by 'type' of its parent"},
|
||||
"first-of-type": {"desc": "Selects every element that is the first element of the specific type of its parent"},
|
||||
"focus": {"desc": "Selects the input element which has focus"},
|
||||
"focus-within": {"desc": "Selects every element which or whose descendant has focus"},
|
||||
"fullscreen": {"desc": "Selects the element being in full-screen mode"},
|
||||
"hover": {"desc": "Selects elements on mouse over"},
|
||||
"fullscreen": {"desc": "Selects the element being in fullscreen mode"},
|
||||
"hover": {"desc": "Selects elements on pointer over"},
|
||||
"in-range": {"desc": "Selects input elements with a value within a specified range"},
|
||||
"indeterminate": {"desc": "Selects every indeterminate checkbox or radio button"},
|
||||
"indeterminate": {"desc": "Selects every indeterminate checkbox, radio button or progress bar"},
|
||||
"invalid": {"desc": "Selects all input elements with an invalid value"},
|
||||
"lang(language)": {"desc": "Selects every element with a lang attribute equal to 'language'", "text": "lang()"},
|
||||
"lang(languages)": {"desc": "Selects every element whose language is contained by the 'languages' list", "text": "lang()"},
|
||||
"last-child": {"desc": "Selects every element that is the last child of its parent"},
|
||||
"last-of-type": {"desc": "Selects every element that is the last element of its parent"},
|
||||
"last-of-type": {"desc": "Selects every element that is the last element of the specific type of its parent"},
|
||||
"left": {"desc": "With @page, selects every left-hand page of a printed document"},
|
||||
"link": {"desc": "Selects all unvisited links"},
|
||||
"matches(selectors)": {"desc": "Selects every element that is matched by one or more selectors in the 'selectors' list", "text": "matches()"},
|
||||
"not(selector)": {"desc": "Selects every element that is not an element identified by 'selector'", "text": "not()"},
|
||||
"nth-child(n)": {"desc": "Selects every element that is the second child of its parent", "text": "nth-child()"},
|
||||
"nth-last-child(n)": {"desc": "Selects every element that is the second child of its parent, counting from the last child", "text": "nth-last-child()"},
|
||||
"nth-last-of-type(n)": {"desc": "Selects every element that is the nth element of its parent, counting from the last child", "text": "nth-last-of-type()"},
|
||||
"nth-of-type(n)": {"desc": "Selects every element that is the nth element of its parent", "text": "nth-of-type(n)"},
|
||||
"not(selectors)": {"desc": "Selects every element that is not matched by any selector in the 'selectors' list", "text": "not()"},
|
||||
"nth-child(n)": {"desc": "Selects every element that is the nth child of its parent", "text": "nth-child()"},
|
||||
"nth-last-child(n)": {"desc": "Selects every element that is the nth child of its parent, counting from the last child", "text": "nth-last-child()"},
|
||||
"nth-last-of-type(n)": {"desc": "Selects every element that is the nth element of the specific type of its parent, counting from the last child", "text": "nth-last-of-type()"},
|
||||
"nth-of-type(n)": {"desc": "Selects every element that is the nth element of the specific type of its parent", "text": "nth-of-type(n)"},
|
||||
"only-child": {"desc": "Selects every element that is the only child of its parent"},
|
||||
"only-of-type": {"desc": "Selects every element that is the only element of this type of its parent"},
|
||||
"optional": {"desc": "Selects input elements with no 'required' attribute"},
|
||||
"only-of-type": {"desc": "Selects every element that is the only element of the specific type of its parent"},
|
||||
"optional": {"desc": "Selects non-required form elements"},
|
||||
"out-of-range": {"desc": "Selects input elements with a value outside a specified range"},
|
||||
"placeholder-shown": {"desc": "Selects all <input> and <textarea> elements currently showing placeholder text"},
|
||||
"read-only": {"desc": "Selects input elements with the 'readonly' attribute specified"},
|
||||
"read-write": {"desc": "Selects input elements with the 'readonly' attribute NOT specified"},
|
||||
"required": {"desc": "Selects input elements with the 'required' attribute specified"},
|
||||
"read-only": {"desc": "Selects form elements with the 'readonly' attribute specified"},
|
||||
"read-write": {"desc": "Selects form elements with the 'readonly' attribute NOT specified"},
|
||||
"required": {"desc": "Selects required form elements"},
|
||||
"right": {"desc": "With @page, selects every right-hand page of a printed document"},
|
||||
"root": {"desc": "Selects the document's root element"},
|
||||
"target": {"desc": "Selects the current active element (clicked on a URL containing that anchor name)"},
|
||||
"target": {"desc": "Selects the element whose ID matches with the URL hash"},
|
||||
"valid": {"desc": "Selects all input elements with a valid value"},
|
||||
"visited": {"desc": "Selects all visited links"}
|
||||
},
|
||||
"elements":
|
||||
{
|
||||
"after": {"desc": "Insert something after the content of each element identified by this selector"},
|
||||
"before": {"desc": "Insert something before the content of each element identified by this selector"},
|
||||
"first-letter": {"desc": "Selects the first letter of every element identified by this selector"},
|
||||
"first-line": {"desc": "Selects the first line of every element identified by this selector"},
|
||||
"placeholder": {"desc": "Selects the placeholder text of <input> and <textarea> elements"},
|
||||
"selection": {"desc": "Selects the portion of an element identified by this selector that is selected by a user"}
|
||||
"elements": {
|
||||
"after": {"desc": "Insert something after the content of each element matched by this selector"},
|
||||
"backdrop": {"desc": "Selects the box rendered immediately below a <dialog> or an element in fullscreen mode"},
|
||||
"before": {"desc": "Insert something before the content of each element matched by this selector"},
|
||||
"cue": {"desc": "Selects the cues of WebVTT subtitles"},
|
||||
"cue(selector)": {"desc": "Selects the cues of WebVTT subtitles, matched by 'selector'", "text": "cue()"},
|
||||
"first-letter": {"desc": "Selects the first letter of every element matched by this selector"},
|
||||
"first-line": {"desc": "Selects the first line of every element matched by this selector"},
|
||||
"placeholder": {"desc": "Selects the placeholder text of <input> and <textarea> elements"},
|
||||
"selection": {"desc": "Selects the portion of an element that is selected by a user"}
|
||||
}
|
||||
}
|
||||
|
@ -32,9 +32,9 @@ define(function (require, exports, module) {
|
||||
PseudoRules = JSON.parse(PseudoRulesText);
|
||||
|
||||
|
||||
var TOKEN_TYPE_PSEUDO_SELECTOR = 0,
|
||||
TOKEN_TYPE_PSEUDO_ELEMENT = 1,
|
||||
PUNCTUATION_CHAR = ':';
|
||||
var TOKEN_TYPE_PSEUDO_CLASS = 0,
|
||||
TOKEN_TYPE_PSEUDO_ELEMENT = 1,
|
||||
PUNCTUATION_CHAR = ':';
|
||||
|
||||
function _getPseudoContext(token, cursorText, ctx) {
|
||||
var slicedToken,
|
||||
@ -42,7 +42,7 @@ define(function (require, exports, module) {
|
||||
|
||||
// Magic code to get around CM's 'pseudo' identification logic
|
||||
// As per CSS3 spec :
|
||||
// -> ':' identifies pseudo selectors
|
||||
// -> ':' identifies pseudo classes
|
||||
// -> '::' identifies pseudo elements
|
||||
// We should strictly check for single or double occurance of ':' by slicing
|
||||
// the line text till the token start position
|
||||
@ -61,13 +61,13 @@ define(function (require, exports, module) {
|
||||
//We are in pseudo element context ('::')
|
||||
contextType = TOKEN_TYPE_PSEUDO_ELEMENT;
|
||||
} else {
|
||||
contextType = TOKEN_TYPE_PSEUDO_SELECTOR;
|
||||
contextType = TOKEN_TYPE_PSEUDO_CLASS;
|
||||
}
|
||||
} else {
|
||||
if (slicedToken.slice(-2) === "::") {
|
||||
contextType = TOKEN_TYPE_PSEUDO_ELEMENT;
|
||||
} else if (slicedToken.slice(-1) === ":") {
|
||||
contextType = TOKEN_TYPE_PSEUDO_SELECTOR;
|
||||
contextType = TOKEN_TYPE_PSEUDO_CLASS;
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ define(function (require, exports, module) {
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
function PsudoSelectorHints() {
|
||||
function PseudoSelectorHints() {
|
||||
}
|
||||
|
||||
function _validatePseudoContext(token) {
|
||||
@ -86,7 +86,7 @@ define(function (require, exports, module) {
|
||||
|
||||
// As we are only going to provide :<pseudo> name hints
|
||||
// we should claim that we don't have hints for anything else
|
||||
PsudoSelectorHints.prototype.hasHints = function (editor, implicitChar) {
|
||||
PseudoSelectorHints.prototype.hasHints = function (editor, implicitChar) {
|
||||
var pos = editor.getCursorPos(),
|
||||
token = editor._codeMirror.getTokenAt(pos);
|
||||
|
||||
@ -96,7 +96,7 @@ define(function (require, exports, module) {
|
||||
return _validatePseudoContext(token);
|
||||
};
|
||||
|
||||
PsudoSelectorHints.prototype.getHints = function (implicitChar) {
|
||||
PseudoSelectorHints.prototype.getHints = function (implicitChar) {
|
||||
var pos = this.editor.getCursorPos(),
|
||||
token = this.editor._codeMirror.getTokenAt(pos),
|
||||
filter = token.type === "variable-3" ? token.string : "",
|
||||
@ -118,7 +118,7 @@ define(function (require, exports, module) {
|
||||
this.token = token;
|
||||
|
||||
// Filter the property list based on the token string
|
||||
var result = Object.keys(this.context === TOKEN_TYPE_PSEUDO_SELECTOR ? PseudoRules.selectors : PseudoRules.elements).filter(function (key) {
|
||||
var result = Object.keys(this.context === TOKEN_TYPE_PSEUDO_CLASS ? PseudoRules.classes : PseudoRules.elements).filter(function (key) {
|
||||
if (key.indexOf(filter) === 0) {
|
||||
return key;
|
||||
}
|
||||
@ -143,7 +143,7 @@ define(function (require, exports, module) {
|
||||
* Indicates whether the manager should follow hint insertion with an
|
||||
* additional explicit hint request.
|
||||
*/
|
||||
PsudoSelectorHints.prototype.insertHint = function (completion) {
|
||||
PseudoSelectorHints.prototype.insertHint = function (completion) {
|
||||
var cursor = this.editor.getCursorPos();
|
||||
var startPos = {line: cursor.line, ch: this.token.start},
|
||||
endPos = {line: cursor.line, ch: this.token.end};
|
||||
@ -154,10 +154,10 @@ define(function (require, exports, module) {
|
||||
endPos = startPos;
|
||||
}
|
||||
|
||||
if (this.context === TOKEN_TYPE_PSEUDO_SELECTOR) {
|
||||
if (this.context === TOKEN_TYPE_PSEUDO_CLASS) {
|
||||
// If the hint label contains annotated data for illustration, then we might have
|
||||
// different text to be inserted.
|
||||
completion = PseudoRules.selectors[completion].text || completion;
|
||||
completion = PseudoRules.classes[completion].text || completion;
|
||||
}
|
||||
|
||||
this.editor.document.replaceRange(completion, startPos, endPos);
|
||||
@ -172,7 +172,7 @@ define(function (require, exports, module) {
|
||||
|
||||
AppInit.appReady(function () {
|
||||
// Register code hint providers
|
||||
var pseudoSelectorHints = new PsudoSelectorHints();
|
||||
var pseudoSelectorHints = new PseudoSelectorHints();
|
||||
CodeHintManager.registerHintProvider(pseudoSelectorHints, ["css", "scss", "less"], 0);
|
||||
|
||||
// For test
|
||||
|
@ -31,7 +31,7 @@ define(function (require, exports, module) {
|
||||
PseudoStaticDataRaw = require("text!PseudoSelectors.json"),
|
||||
PseudoStaticData = JSON.parse(PseudoStaticDataRaw);
|
||||
|
||||
describe("CSS Pseudo selector/element Code Hinting", function () {
|
||||
describe("CSS Pseudo class/element Code Hinting", function () {
|
||||
|
||||
var defaultContent = ".selector1: { \n" +
|
||||
"} \n" +
|
||||
@ -126,7 +126,7 @@ define(function (require, exports, module) {
|
||||
return modesToTest[modeCounter];
|
||||
};
|
||||
|
||||
describe("Pseudo selectors in different style modes", function () {
|
||||
describe("Pseudo classes in different style modes", function () {
|
||||
beforeEach(function () {
|
||||
// create Editor instance (containing a CodeMirror instance)
|
||||
var mock = SpecRunnerUtils.createMockEditor(defaultContent, selectMode());
|
||||
@ -145,14 +145,14 @@ define(function (require, exports, module) {
|
||||
var hintList = expectHints(CSSPseudoSelectorCodeHints.pseudoSelectorHints);
|
||||
console.log(JSON.stringify(hintList));
|
||||
verifyFirstEntry(hintList, "active"); // filtered on "empty string"
|
||||
verifyListsAreIdentical(hintList, Object.keys(PseudoStaticData.selectors).sort());
|
||||
verifyListsAreIdentical(hintList, Object.keys(PseudoStaticData.classes).sort());
|
||||
},
|
||||
testFilteredHints = function () {
|
||||
testEditor.setCursorPos({ line: 4, ch: 12 }); // after :n
|
||||
var hintList = expectHints(CSSPseudoSelectorCodeHints.pseudoSelectorHints);
|
||||
console.log(JSON.stringify(hintList));
|
||||
verifyFirstEntry(hintList, "not(selector)"); // filtered on "n"
|
||||
verifyListsAreIdentical(hintList, ["not(selector)",
|
||||
verifyFirstEntry(hintList, "not(selectors)"); // filtered on "n"
|
||||
verifyListsAreIdentical(hintList, ["not(selectors)",
|
||||
"nth-child(n)",
|
||||
"nth-last-child(n)",
|
||||
"nth-last-of-type(n)",
|
||||
|
Loading…
Reference in New Issue
Block a user