/
githubmirror
/
brackets
Обзор
Документация
Войти
/
githubmirror
/
brackets
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/LiveDevelopment/MultiBrowserImpl/documents/LiveCSSDocument.js
202 строки
8 KB
Marcel Gerber
Live Dev MultiBrowser: Convert url()s so they reference the correct file
23 авг 2016, 02:41
23 авг 2016, 02:41
d974228
Код
Авторство
О чём код?
/* * Copyright (c) 2012 - 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. * */ /*jslint regexp: true */ /** * LiveCSSDocument manages a single CSS source document * * # EDITING * * Editing the document will cause the style sheet to be reloaded in the browser, * which immediately updates the appearance of the rendered document. * * # HIGHLIGHTING * * DOM nodes corresponding to the rule at the current cursor position are highlighted. * * # EVENTS * * LiveCSSDocument dispatches these events: * deleted - When the file for the underlying Document has been deleted. The * 2nd argument to the listener will be this LiveCSSDocument. */ define(function LiveCSSDocumentModule(require, exports, module) { "use strict"; var _ = require("thirdparty/lodash"), CSSUtils = require("language/CSSUtils"), EventDispatcher = require("utils/EventDispatcher"), LiveDocument = require("LiveDevelopment/MultiBrowserImpl/documents/LiveDocument"), PathUtils = require("thirdparty/path-utils/path-utils"); /** * @constructor * @see LiveDocument * @param {LiveDevProtocol} protocol The protocol to use for communicating with the browser. * @param {function(string): string} urlResolver A function that, given a path on disk, should return * the URL that Live Development serves that path at. * @param {Document} doc The Brackets document that this live document is connected to. * @param {?Editor} editor If specified, a particular editor that this live document is managing. * If not specified initially, the LiveDocument will connect to the editor for the given document * when it next becomes the active editor. */ var LiveCSSDocument = function LiveCSSDocument(protocol, urlResolver, doc, editor, roots) { LiveDocument.apply(this, arguments); // 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.LiveCSSDocument", this.onChange); this.doc.on("deleted.LiveCSSDocument", this.onDeleted); if (editor) { this._attachToEditor(editor); } }; LiveCSSDocument.prototype = Object.create(LiveDocument.prototype); LiveCSSDocument.prototype.constructor = LiveCSSDocument; LiveCSSDocument.prototype.parentClass = LiveDocument.prototype; EventDispatcher.makeEventDispatcher(LiveCSSDocument.prototype); /** * @override * Closes the live document, terminating its connection to the browser. */ LiveCSSDocument.prototype.close = function () { this.doc.off(".LiveCSSDocument"); this.doc.releaseRef(); this.parentClass.close.call(this); }; /** * When the user edits the file, update the stylesheet in the browser and redraw highlights. */ LiveCSSDocument.prototype._updateBrowser = function () { var i, docUrl = this.doc.url; // Determines whether an url() line contains a relative or absolute URL, and makes // the URL absolute to the CSS file if it is relative function makeUrlsRelativeToCss(match, quotationMark, url) { if (PathUtils.isRelativeUrl(url)) { var absUrl = PathUtils.makeUrlAbsolute(url, docUrl); return "url(" + quotationMark + absUrl + quotationMark + ")"; } return match; } for (i = 0; i < this.roots.length; i++) { if (docUrl !== this.roots[i].toString()) { // if it's not directly included through <link>, // reload the original doc this.trigger("updateDoc", this.roots[i]); } else { var docText = this.doc.getText(); // Replace all occurrences of url() where the URL is relative to the CSS file with // an absolute URL so it is relative to the CSS file, not the HTML file (see #11936) docText = docText.replace(/\burl\(\s*(["']?)([^)\n]+)\1\s*\)/ig, makeUrlsRelativeToCss); this.protocol.setStylesheetText(docUrl, docText); } } this.redrawHighlights(); }; /** * @override * Update the highlights in the browser based on the cursor position. */ LiveCSSDocument.prototype.updateHighlight = function () { if (this.isHighlightEnabled() && 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) { this.highlightRule(selectors.join(",")); } else { this.hideHighlight(); } } }; /** * @override * Returns true if document edits appear live in the connected browser. * @return {boolean} */ LiveCSSDocument.prototype.isLiveEditingEnabled = function () { return true; }; /** Event Handlers *******************************************************/ /** * @private * Handles edits to the document. Updates the stylesheet in the browser. * @param {$.Event} event * @param {Editor} editor * @param {Object} change */ LiveCSSDocument.prototype.onChange = function (event, editor, change) { this._updateBrowser(); }; /** * @private * Handles when the associated CSS document is deleted on disk. Removes the * stylesheet from the browser and shuts down the live document. * @param {$.Event} event */ LiveCSSDocument.prototype.onDeleted = function (event) { // TODO Need to add protocol API to remove the stylesheet from the document. //CSSAgent.clearCSSForDocument(this.doc); // shut down, since our Document is now dead this.close(); this.trigger("deleted", [this]); }; // Only used for unit testing. LiveCSSDocument.prototype.getSourceFromBrowser = function () { var deferred = new $.Deferred(); this.protocol.getStylesheetText(this.doc.url) .then(function (res) { deferred.resolve(res.text); }, deferred.reject); return deferred.promise(); }; // Export the class module.exports = LiveCSSDocument; });