Modules (181)

CSSDocument

Description

CSSDocument manages a single CSS source document

EDITING

Editing the document will cause the style sheet to be reloaded via the CSSAgent, which immediately updates the appearance of the rendered document.

HIGHLIGHTING

CSSDocument supports highlighting nodes from the HighlightAgent and highlighting all DOMNode corresponding to the rule at the cursor position in the editor.

EVENTS

CSSDocument dispatches these events:

  • deleted -- When the file for the underlying Document has been deleted. The 2nd argument to the listener will be this CSSDocument.

Dependencies

Classes

Constructor

CSSDocument

doc Document
The source document from Brackets
editor Editor
The editor for this document
    var CSSDocument = function CSSDocument(doc, editor) {
        this.doc = doc;

        this._highlight = [];
        this.onHighlight = this.onHighlight.bind(this);
        this.onCursorActivity = this.onCursorActivity.bind(this);

        // Add a ref to the doc since we're listening for change events
        this.doc.addRef();
        this.onChange = this.onChange.bind(this);
        this.onDeleted = this.onDeleted.bind(this);

        this.doc.on("change.CSSDocument", this.onChange);
        this.doc.on("deleted.CSSDocument", this.onDeleted);

        this.onActiveEditorChange = this.onActiveEditorChange.bind(this);
        EditorManager.on("activeEditorChange", this.onActiveEditorChange);

        if (editor) {
            // Attach now
            this.attachToEditor(editor);
        }
    };
    EventDispatcher.makeEventDispatcher(CSSDocument.prototype);

Methods

Private

_getStyleSheetHeader

    CSSDocument.prototype._getStyleSheetHeader = function () {
        return CSSAgent.styleForURL(this.doc.url);
    };
Private

_updateBrowser

    CSSDocument.prototype._updateBrowser = function () {
        var reloadPromise = CSSAgent.reloadCSSForDocument(this.doc);

        if (Inspector.config.highlight) {
            reloadPromise.done(HighlightAgent.redraw);
        }
    };

    CSSDocument.prototype.attachToEditor = function (editor) {
        this.editor = editor;

        if (this.editor) {
            HighlightAgent.on("highlight", this.onHighlight);
            this.editor.on("cursorActivity.CSSDocument", this.onCursorActivity);
            this.updateHighlight();
        }
    };

    CSSDocument.prototype.detachFromEditor = function () {
        if (this.editor) {
            HighlightAgent.hide();
            HighlightAgent.off("highlight", this.onHighlight);
            this.editor.off(".CSSDocument");
            this.onHighlight();
            this.editor = null;
        }
    };

    CSSDocument.prototype.updateHighlight = function () {
        if (Inspector.config.highlight && this.editor) {
            var editor = this.editor,
                selectors = [];
            _.each(this.editor.getSelections(), function (sel) {
                var selector = CSSUtils.findSelectorAtDocumentPos(editor, (sel.reversed ? sel.end : sel.start));
                if (selector) {
                    selectors.push(selector);
                }
            });
            if (selectors.length) {
                HighlightAgent.rule(selectors.join(","));
            } else {
                HighlightAgent.hide();
            }
        }
    };

close

Close the document

    CSSDocument.prototype.close = function close() {
        this.doc.off(".CSSDocument");
        EditorManager.off("activeEditorChange", this.onActiveEditorChange);
        this.doc.releaseRef();
        this.detachFromEditor();
    };

getResponseData

Returns a JSON object with HTTP response overrides

Returns: {body: string}
    CSSDocument.prototype.getResponseData = function getResponseData(enabled) {
        // Serve up the in-memory text, including any unsaved changes
        return {
            body: this.doc.getText()
        };
    };

getSourceFromBrowser

Get the browser version of the source

Returns: jQuery.promise
Promise resolved with the text content of this CSS document
    CSSDocument.prototype.getSourceFromBrowser = function getSourceFromBrowser() {
        function getOnlyValue(obj) {
            var key;
            for (key in obj) {
                if (_.has(obj, key)) {
                    return obj[key];
                }
            }
            return null;
        }

        var deferred = new $.Deferred(),
            styleSheetHeader = this._getStyleSheetHeader(),
            styleSheet = getOnlyValue(styleSheetHeader);

        if (styleSheet) {
            Inspector.CSS.getStyleSheetText(styleSheet.styleSheetId).then(function (res) {
                deferred.resolve(res.text);
            }, deferred.reject);
        } else {
            deferred.reject();
        }

        return deferred.promise();
    };

isLiveEditingEnabled

Returns true if document edits appear live in the connected browser

Returns: boolean
    CSSDocument.prototype.isLiveEditingEnabled = function () {
        return true;
    };

onActiveEditorChange

Triggered when the active editor changes

    CSSDocument.prototype.onActiveEditorChange = function (event, newActive, oldActive) {
        this.detachFromEditor();

        if (newActive && newActive.document === this.doc) {
            this.attachToEditor(newActive);
        }
    };

onChange

Triggered whenever the Document is edited

    CSSDocument.prototype.onChange = function onChange(event, editor, change) {
        this._updateBrowser();
    };

onCursorActivity

Triggered on cursor activity of the editor

    CSSDocument.prototype.onCursorActivity = function onCursorActivity(event, editor) {
        this.updateHighlight();
    };

onDeleted

Triggered if the Document's file is deleted

    CSSDocument.prototype.onDeleted = function onDeleted(event, editor, change) {
        // clear the CSS
        CSSAgent.clearCSSForDocument(this.doc);

        // shut down, since our Document is now dead
        this.close();
        this.trigger("deleted", this);
    };

onHighlight

Triggered by the HighlightAgent to highlight a node in the editor

    CSSDocument.prototype.onHighlight = function onHighlight(event, node) {
        // clear an existing highlight
        var i;
        for (i in this._highlight) {
            this._highlight[i].clear();
        }
        this._highlight = [];
        if (!node || !node.location) {
            return;
        }

        // WebInspector Command: CSS.getMatchedStylesForNode
        Inspector.CSS.getMatchedStylesForNode(node.nodeId, function onGetMatchesStyles(res) {
            // res = {matchedCSSRules, pseudoElements, inherited}
            var codeMirror = this.editor._codeMirror,
                styleSheetIds = this._getStyleSheetHeader();

            var i, rule, from, to;
            for (i in res.matchedCSSRules) {
                rule = res.matchedCSSRules[i];
                if (rule.ruleId && styleSheetIds[rule.ruleId.styleSheetId]) {
                    from = codeMirror.posFromIndex(rule.selectorRange.start);
                    to = codeMirror.posFromIndex(rule.style.range.end);
                    this._highlight.push(codeMirror.markText(from, to, { className: "highlight" }));
                }
            }
        }.bind(this));
    };

    // Export the class
    module.exports = CSSDocument;
});

setInstrumentationEnabled

Enable instrumented CSS

{boolean} enabled
    CSSDocument.prototype.setInstrumentationEnabled = function setInstrumentationEnabled(enabled) {
        // no-op
        // "Instrumentation" is always enabled for CSS, we make no modifications
    };