1
0
mirror of https://github.com/adobe/brackets.git synced 2024-11-20 09:53:00 +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:
Valtteri Laitinen 2018-01-14 21:21:37 +02:00 committed by ficristo
parent cad7bd2cdc
commit 45347fe6ae
3 changed files with 56 additions and 51 deletions

View File

@ -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"}
}
}

View File

@ -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

View File

@ -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)",