src/extensions/default/CSSAtRuleCodeHints/main.js
/*
* Copyright (c) 2017 - present Adobe Systems Incorporated. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
define(function (require, exports, module) {
"use strict";
// Load dependent modules
var AppInit = brackets.getModule("utils/AppInit"),
CodeHintManager = brackets.getModule("editor/CodeHintManager"),
AtRulesText = require("text!AtRulesDef.json"),
AtRules = JSON.parse(AtRulesText);
/**
* @constructor
*/
function AtRuleHints() {
}
// As we are only going to provide @rules name hints
// we should claim that we don't have hints for anything else
AtRuleHints.prototype.hasHints = function (editor, implicitChar) {
var pos = editor.getCursorPos(),
token = editor._codeMirror.getTokenAt(pos),
cmState;
this.editor = editor;
if (token.state.base && token.state.base.localState) {
cmState = token.state.base.localState;
} else {
cmState = token.state.localState || token.state;
}
// Check if we are at '@' rule 'def' context
if ((token.type === "def" && cmState.context.type === "at")
|| (token.type === "variable-2" && (cmState.context.type === "top" || cmState.context.type === "block"))) {
this.filter = token.string;
return true;
} else {
this.filter = null;
return false;
}
};
AtRuleHints.prototype.getHints = function (implicitChar) {
var pos = this.editor.getCursorPos(),
token = this.editor._codeMirror.getTokenAt(pos);
this.filter = token.string;
this.token = token;
if (!this.filter) {
return null;
}
// Filter the property list based on the token string
var result = Object.keys(AtRules).filter(function (key) {
if (key.indexOf(token.string) === 0) {
return key;
}
}).sort();
return {
hints: result,
match: this.filter,
selectInitial: true,
defaultDescriptionWidth: true,
handleWideResults: false
};
};
/**
* Inserts a given @<rule> hint into the current editor context.
*
* @param {string} completion
* The hint to be inserted into the editor context.
*
* @return {boolean}
* Indicates whether the manager should follow hint insertion with an
* additional explicit hint request.
*/
AtRuleHints.prototype.insertHint = function (completion) {
var cursor = this.editor.getCursorPos();
this.editor.document.replaceRange(completion, {line: cursor.line, ch: this.token.start}, {line: cursor.line, ch: this.token.end});
return false;
};
AppInit.appReady(function () {
// Register code hint providers
var restrictedBlockHints = new AtRuleHints();
CodeHintManager.registerHintProvider(restrictedBlockHints, ["css", "less", "scss"], 0);
// For unit testing
exports.restrictedBlockHints = restrictedBlockHints;
});
});