This commit is contained in:
Chema 2012-09-07 20:28:26 +02:00
Родитель f09e70f397 c49ef244c6
Коммит 54a8bdeb64
44 изменённых файлов: 1050 добавлений и 346 удалений

Просмотреть файл

@ -53,18 +53,18 @@ If you want to pull the repo directly via git, see
[How to Use Brackets](http://github.com/adobe/brackets/wiki/How-to-Use-Brackets)
for instructions on how to get everything.
By default, Brackets shows its own source code (MIND BLOWN). You can choose
a different folder to edit from *File > Open Folder*.
By default, Brackets opens a folder containing some simple "Getting Started" content.
You can choose a different folder to edit from *File > Open Folder*. (Might we
suggest editing the Brackets source code and submitting some pull requests?)
Most of Brackets should be pretty self-explanatory, but for information on how
to use its unique features, like Quick Edit and Live Development, please read
[How to Use Brackets](http://github.com/adobe/brackets/wiki/How-to-Use-Brackets).
The [extensions wiki page](https://github.com/adobe/brackets/wiki/Brackets-Extensions) has a list of extensions that have been contributed.
The [extensions wiki page](https://github.com/adobe/brackets/wiki/Brackets-Extensions)
has a list of extensions that have been contributed.
Also, see the [release notes](http://github.com/adobe/brackets/wiki/Release-Notes)
for a list of new features and known issues in each build.
I found a bug/missing feature!
------------------------------
@ -77,9 +77,9 @@ When filing a new bug, please remember to include:
* platform/OS version
* repro steps, actual and expected results
* link to test files (you can create a gist on [gist.github.com](https://gist.github.com/)
if that's convenient)
if that's convenient)
More details how to file an issue can be found [here](https://github.com/adobe/brackets/wiki/How-to-Report-an-Issue).
More details on how to file an issue can be found [here](https://github.com/adobe/brackets/wiki/How-to-Report-an-Issue).
For feature requests, go ahead and file them in the issue tracker; they'll be converted
to user stories on the [public Brackets backlog*](http://bit.ly/BracketsBacklog).

Просмотреть файл

@ -85,9 +85,9 @@
l'aperçu en direct (Live Preview) est activé dans un document HTML, tous les documents CSS liés
à ce document peuvent être édité en temps réel.
Désormais, placez le curseur sur le tag <!-- <img> --> ci-dessous et appuyez sur les touches
Désormais, placez le curseur sur le tag <!-- <img> --> ci-dessus et appuyez sur les touches
<kbd>Cmd/Ctrl + E</kbd> pour ouvrir les règles CSS appliquées. Essayez de modifier l'épaisseur de la
bordure d'1px en 10px, ou modifier la couleur de fond en "hotpink" (rose) plutôt que "dimgray"(gris).
bordure d'1px en 10px, ou modifier la couleur de fond en "hotpink" (rose) plutôt que "dimgray" (gris).
Si vous avez placé Edge Code et votre navigateur côte à côte, vous devriez voir vos modifications
être prises en compte en temps réel dans le navigateur. Pas mal, non?
</samp>

Просмотреть файл

@ -77,11 +77,11 @@
<samp>
If you have Google Chrome installed, you can try this out yourself. Click on the lightning bolt
icon in the top right or hit <kbd>Cmd/Ctrl + Alt + P</kbd>. When Live File Preview is enabled on
icon in the top right or hit <kbd>Cmd/Ctrl + Alt + P</kbd>. When Live Preview is enabled on
an HTML document, all linked CSS documents can be edited in real-time. The icon will change from
grey to gold when Brackets establishes a connection to your browser.
gray to gold when Brackets establishes a connection to your browser.
Now, place your cursor on the <!-- <img> --> tag below and use <kbd>Cmd/Ctrl + E</kbd> to open up the
Now, place your cursor on the <!-- <img> --> tag above and use <kbd>Cmd/Ctrl + E</kbd> to open up the
defined CSS rules. Try changing the size of the border from 1px to 10px or change the background
color from "dimgray" to "hotpink". If you have Brackets and your browser running side-by-side, you
will see your changes instantly reflected in your browser. Cool, right?

Просмотреть файл

@ -272,7 +272,7 @@ define(function Inspector(require, exports, module) {
var i, page;
for (i in response) {
page = response[i];
if (page.webSocketDebuggerUrl && page.url.search(url) === 0) {
if (page.webSocketDebuggerUrl && page.url.indexOf(url) === 0) {
connect(page.webSocketDebuggerUrl);
deferred.resolve();
return;

Просмотреть файл

@ -104,7 +104,6 @@ define(function LiveDevelopment(require, exports, module) {
// store the names (matching property names in the 'agent' object) of agents that we've loaded
var _loadedAgentNames = [];
var _htmlDocumentPath; // the path of the html file open for live development
var _liveDocument; // the document open for live editing.
var _relatedDocuments; // CSS and JS documents that are used by the live HTML document
@ -377,7 +376,7 @@ define(function LiveDevelopment(require, exports, module) {
_setStatus(STATUS_ERROR);
Dialogs.showModalDialog(
Dialogs.DIALOG_ID_LIVE_DEVELOPMENT,
Strings.LIVE_DEVELOPMENT_ERROR_TITLE,
Strings.LIVE_DEVELOPMENT_RELAUNCH_TITLE,
Strings.LIVE_DEVELOPMENT_ERROR_MESSAGE
).done(function (id) {
if (id === Dialogs.DIALOG_BTN_OK) {
@ -472,14 +471,11 @@ define(function LiveDevelopment(require, exports, module) {
_openDocument(doc, editor);
} else {
/* FUTURE: support live connections for docments other than html */
if (doc.extension && doc.extension.indexOf("htm") === 0 && doc.file.fullPath !== _htmlDocumentPath) {
if (exports.config.experimental || (doc.extension && doc.extension.indexOf('htm') === 0)) {
close();
window.setTimeout(open);
_htmlDocumentPath = doc.file.fullPath;
}
}
} else if (exports.config.autoconnect) {
window.setTimeout(open);
}
}

Просмотреть файл

@ -38,14 +38,20 @@
define(function main(require, exports, module) {
"use strict";
var DocumentManager = require("document/DocumentManager"),
Commands = require("command/Commands"),
AppInit = require("utils/AppInit"),
LiveDevelopment = require("LiveDevelopment/LiveDevelopment"),
Inspector = require("LiveDevelopment/Inspector/Inspector"),
CommandManager = require("command/CommandManager"),
Strings = require("strings");
var DocumentManager = require("document/DocumentManager"),
Commands = require("command/Commands"),
AppInit = require("utils/AppInit"),
LiveDevelopment = require("LiveDevelopment/LiveDevelopment"),
Inspector = require("LiveDevelopment/Inspector/Inspector"),
CommandManager = require("command/CommandManager"),
PreferencesManager = require("preferences/PreferencesManager"),
Dialogs = require("widgets/Dialogs"),
UrlParams = require("utils/UrlParams").UrlParams,
Strings = require("strings");
var PREFERENCES_KEY = "com.adobe.brackets.live-development";
var prefs;
var params = new UrlParams();
var config = {
experimental: false, // enable experimental features
debug: true, // enable debug output and helpers
@ -114,7 +120,18 @@ define(function main(require, exports, module) {
LiveDevelopment.close();
// TODO Ty: when checkmark support lands, remove checkmark
} else {
LiveDevelopment.open();
if (!params.get("skipLiveDevelopmentInfo") && !prefs.getValue("afterFirstLaunch")) {
prefs.setValue("afterFirstLaunch", "true");
Dialogs.showModalDialog(
Dialogs.DIALOG_ID_INFO,
Strings.LIVE_DEVELOPMENT_INFO_TITLE,
Strings.LIVE_DEVELOPMENT_INFO_MESSAGE
).done(function (id) {
LiveDevelopment.open();
});
} else {
LiveDevelopment.open();
}
// TODO Ty: when checkmark support lands, add checkmark
}
}
@ -167,6 +184,9 @@ define(function main(require, exports, module) {
/** Initialize LiveDevelopment */
function init() {
prefs = PreferencesManager.getPreferenceStorage(PREFERENCES_KEY);
params.parse();
Inspector.init(config);
LiveDevelopment.init(config);
_loadStyles();
@ -181,6 +201,11 @@ define(function main(require, exports, module) {
AppInit.appReady(function () {
if (DocumentManager.getCurrentDocument()) {
_handleGoLiveCommand();
} else {
$(DocumentManager).on("currentDocumentChange", _handleGoLiveCommand);
window.setTimeout(function () {
$(DocumentManager).off("currentDocumentChange", _handleGoLiveCommand);
}, 200);
}
});
}

Просмотреть файл

@ -103,8 +103,9 @@ define(function (require, exports, module) {
//Load modules that self-register and just need to get included in the main project
require("document/ChangedDocumentTracker");
require("editor/EditorCommandHandlers");
require("debug/DebugCommandHandlers");
require("view/ViewCommandHandlers");
require("debug/DebugCommandHandlers");
require("help/HelpCommandHandlers");
require("search/FindInFiles");
require("search/FindReplace");
require("utils/ExtensionUtils");
@ -186,23 +187,6 @@ define(function (require, exports, module) {
// that self-register" above for some). A few commands need an extra kick here though:
DocumentCommandHandlers.init($("#main-toolbar"));
// About dialog
CommandManager.register(Strings.CMD_ABOUT, Commands.HELP_ABOUT, function () {
// If we've successfully determined a "build number" via .git metadata, add it to dialog
var bracketsSHA = BuildInfoUtils.getBracketsSHA(),
bracketsAppSHA = BuildInfoUtils.getBracketsAppSHA(),
versionLabel = "";
if (bracketsSHA) {
versionLabel += " (" + bracketsSHA.substr(0, 7) + ")";
}
if (bracketsAppSHA) {
versionLabel += " (shell " + bracketsAppSHA.substr(0, 7) + ")";
}
$("#about-build-number").text(versionLabel);
Dialogs.showModalDialog(Dialogs.DIALOG_ID_ABOUT);
});
}
function _initWindowListeners() {
@ -224,8 +208,8 @@ define(function (require, exports, module) {
if (brackets.inBrowser) {
Dialogs.showModalDialog(
Dialogs.DIALOG_ID_ERROR,
Strings.ERROR_BRACKETS_IN_BROWSER_TITLE,
Strings.ERROR_BRACKETS_IN_BROWSER
Strings.ERROR_IN_BROWSER_TITLE,
Strings.ERROR_IN_BROWSER
);
}
@ -289,7 +273,13 @@ define(function (require, exports, module) {
}
// Localize MainViewHTML and inject into <BODY> tag
$('body').html(Mustache.render(MainViewHTML, Strings));
var templateVars = $.extend({ ABOUT_ICON: brackets.config.about_icon }, Strings);
$("body").html(Mustache.render(MainViewHTML, templateVars));
// Update title
$("title").text(Strings.APP_NAME);
// Dispatch htmlReady callbacks
AppInit._dispatchReady(AppInit.HTML_READY);
$(window.document).ready(_onReady);

Просмотреть файл

@ -1,3 +0,0 @@
{
"buildNumber": 100
}

Просмотреть файл

@ -88,12 +88,12 @@ define(function (require, exports, module) {
exports.DEBUG_RUN_UNIT_TESTS = "debug.runUnitTests";
exports.DEBUG_SHOW_PERF_DATA = "debug.showPerfData";
exports.DEBUG_NEW_BRACKETS_WINDOW = "debug.newBracketsWindow";
exports.DEBUG_SHOW_EXT_FOLDER = "debug.showExtensionsFolder";
exports.DEBUG_SWITCH_LANGUAGE = "debug.switchLanguage";
exports.CHECK_FOR_UPDATE = "app.checkForUpdate";
// Command that does nothing. Can be used for place holder menuItems
// Help
exports.HELP_SHOW_EXT_FOLDER = "help.showExtensionsFolder";
exports.HELP_CHECK_FOR_UPDATE = "help.checkForUpdate";
exports.HELP_FORUM = "help.forum";
exports.HELP_ABOUT = "help.about";
// File shell callbacks

Просмотреть файл

@ -29,7 +29,8 @@ define(function (require, exports, module) {
"use strict";
// Load dependent modules
var Commands = require("command/Commands"),
var Global = require("utils/Global"),
Commands = require("command/Commands"),
KeyBindingManager = require("command/KeyBindingManager"),
EditorManager = require("editor/EditorManager"),
Strings = require("strings"),
@ -42,11 +43,12 @@ define(function (require, exports, module) {
* @enum {string}
*/
var AppMenuBar = {
FILE_MENU: "file-menu",
EDIT_MENU: "edit-menu",
VIEW_MENU : "view-menu",
NAVIGATE_MENU: "navigate-menu",
DEBUG_MENU: "debug-menu"
FILE_MENU : "file-menu",
EDIT_MENU : "edit-menu",
VIEW_MENU : "view-menu",
NAVIGATE_MENU : "navigate-menu",
DEBUG_MENU : "debug-menu",
HELP_MENU : "help-menu"
};
/**
@ -920,20 +922,34 @@ define(function (require, exports, module) {
/*
* Debug menu
*/
menu = addMenu(Strings.DEBUG_MENU, AppMenuBar.DEBUG_MENU);
menu.addMenuItem(Commands.DEBUG_SHOW_DEVELOPER_TOOLS, [{key: "F12", platform: "win"},
{key: "Cmd-Opt-I", platform: "mac"}]);
menu.addMenuItem(Commands.DEBUG_REFRESH_WINDOW, [{key: "F5", platform: "win"},
{key: "Cmd-R", platform: "mac"}]);
menu.addMenuItem(Commands.DEBUG_NEW_BRACKETS_WINDOW);
menu.addMenuItem(Commands.DEBUG_SHOW_EXT_FOLDER);
if (brackets.config.show_debug_menu) {
menu = addMenu(Strings.DEBUG_MENU, AppMenuBar.DEBUG_MENU);
menu.addMenuItem(Commands.DEBUG_SHOW_DEVELOPER_TOOLS, [{key: "F12", platform: "win"},
{key: "Cmd-Opt-I", platform: "mac"}]);
menu.addMenuItem(Commands.DEBUG_REFRESH_WINDOW, [{key: "F5", platform: "win"},
{key: "Cmd-R", platform: "mac"}]);
menu.addMenuItem(Commands.DEBUG_NEW_BRACKETS_WINDOW);
menu.addMenuDivider();
menu.addMenuItem(Commands.DEBUG_SWITCH_LANGUAGE);
menu.addMenuDivider();
menu.addMenuItem(Commands.DEBUG_RUN_UNIT_TESTS);
menu.addMenuItem(Commands.DEBUG_SHOW_PERF_DATA);
}
/*
* Help menu
*/
menu = addMenu(Strings.HELP_MENU, AppMenuBar.HELP_MENU);
menu.addMenuItem(Commands.HELP_SHOW_EXT_FOLDER);
menu.addMenuItem(Commands.HELP_CHECK_FOR_UPDATE);
if (brackets.config.forum_url) {
menu.addMenuDivider();
menu.addMenuItem(Commands.HELP_FORUM);
}
menu.addMenuDivider();
menu.addMenuItem(Commands.DEBUG_SWITCH_LANGUAGE);
menu.addMenuDivider();
menu.addMenuItem(Commands.DEBUG_RUN_UNIT_TESTS);
menu.addMenuItem(Commands.DEBUG_SHOW_PERF_DATA);
menu.addMenuDivider();
menu.addMenuItem(Commands.CHECK_FOR_UPDATE);
menu.addMenuItem(Commands.HELP_ABOUT);
/*

Просмотреть файл

@ -31,24 +31,16 @@ define(function (require, exports, module) {
var Commands = require("command/Commands"),
CommandManager = require("command/CommandManager"),
Editor = require("editor/Editor").Editor,
FileUtils = require("file/FileUtils"),
Strings = require("strings"),
PerfUtils = require("utils/PerfUtils"),
NativeApp = require("utils/NativeApp"),
NativeFileSystem = require("file/NativeFileSystem").NativeFileSystem,
FileUtils = require("file/FileUtils"),
UpdateNotification = require("utils/UpdateNotification");
NativeFileSystem = require("file/NativeFileSystem").NativeFileSystem;
function handleShowDeveloperTools(commandData) {
brackets.app.showDeveloperTools();
}
function _handleUseTabChars() {
var useTabs = !Editor.getUseTabChar();
Editor.setUseTabChar(useTabs);
CommandManager.get(Commands.TOGGLE_USE_TAB_CHARS).setChecked(useTabs);
}
// Implements the 'Run Tests' menu to bring up the Jasmine unit test window
var _testWindow = null;
function _handleRunUnitTests() {
@ -245,19 +237,6 @@ define(function (require, exports, module) {
});
}
function _handleShowExtensionsFolder() {
brackets.app.showExtensionsFolder(
FileUtils.convertToNativePath(window.location.href),
function (err) {
// Ignore errors
}
);
}
function _handleCheckForUpdates() {
UpdateNotification.checkForUpdate(true);
}
function _enableRunTestsMenuItem() {
// Check for the SpecRunner.html file
var fileEntry = new NativeFileSystem.FileEntry(
@ -283,7 +262,6 @@ define(function (require, exports, module) {
CommandManager.register(Strings.CMD_SHOW_DEV_TOOLS, Commands.DEBUG_SHOW_DEVELOPER_TOOLS, handleShowDeveloperTools)
.setEnabled(!!brackets.app.showDeveloperTools);
CommandManager.register(Strings.CMD_NEW_BRACKETS_WINDOW, Commands.DEBUG_NEW_BRACKETS_WINDOW, _handleNewBracketsWindow);
CommandManager.register(Strings.CMD_SHOW_EXTENSIONS_FOLDER, Commands.DEBUG_SHOW_EXT_FOLDER, _handleShowExtensionsFolder);
// Start with the "Run Tests" item disabled. It will be enabled later if the test file can be found.
CommandManager.register(Strings.CMD_RUN_UNIT_TESTS, Commands.DEBUG_RUN_UNIT_TESTS, _handleRunUnitTests)
@ -292,10 +270,5 @@ define(function (require, exports, module) {
CommandManager.register(Strings.CMD_SHOW_PERF_DATA, Commands.DEBUG_SHOW_PERF_DATA, _handleShowPerfData);
CommandManager.register(Strings.CMD_SWITCH_LANGUAGE, Commands.DEBUG_SWITCH_LANGUAGE, _handleSwitchLanguage);
CommandManager.register(Strings.CMD_USE_TAB_CHARS, Commands.TOGGLE_USE_TAB_CHARS, _handleUseTabChars)
.setChecked(Editor.getUseTabChar());
CommandManager.register(Strings.CMD_CHECK_FOR_UPDATE, Commands.CHECK_FOR_UPDATE, _handleCheckForUpdates);
_enableRunTestsMenuItem();
});

Просмотреть файл

@ -409,15 +409,22 @@ define(function (require, exports, module) {
// Switch editor to next document (or blank it out)
if (nextFile) {
CommandManager.execute(Commands.FILE_OPEN, { fullPath: nextFile.fullPath });
CommandManager.execute(Commands.FILE_OPEN, { fullPath: nextFile.fullPath })
.done(function () {
// (Now we're guaranteed that the current document is not the one we're closing)
console.assert(!(_currentDocument && _currentDocument.file.fullPath === file.fullPath));
})
.fail(function () {
// File chosen to be switched to could not be opened, and the original file
// is still in editor. Close it again so code will try to open the next file,
// or empty the editor if there are no other files.
closeFullEditor(file);
});
} else {
_clearCurrentDocument();
}
}
// (Now we're guaranteed that the current document is not the one we're closing)
console.assert(!(_currentDocument && _currentDocument.file.fullPath === file.fullPath));
// Remove closed doc from working set, if it was in there
// This happens regardless of whether the document being closed was the current one or not
removeFromWorkingSet(file);

Просмотреть файл

@ -271,9 +271,11 @@ define(function (require, exports, module) {
.css({"left": hintPos.left, "top": hintPos.top});
this.opened = true;
PopUpManager.addPopUp(this.$hintMenu, function () {
self.close();
});
PopUpManager.addPopUp(this.$hintMenu,
function () {
self.close();
},
true);
}
};

Просмотреть файл

@ -61,17 +61,20 @@
define(function (require, exports, module) {
"use strict";
var EditorManager = require("editor/EditorManager"),
CodeHintManager = require("editor/CodeHintManager"),
Commands = require("command/Commands"),
CommandManager = require("command/CommandManager"),
Menus = require("command/Menus"),
PerfUtils = require("utils/PerfUtils"),
Strings = require("strings"),
TextRange = require("document/TextRange").TextRange,
ViewUtils = require("utils/ViewUtils");
var EditorManager = require("editor/EditorManager"),
CodeHintManager = require("editor/CodeHintManager"),
Commands = require("command/Commands"),
CommandManager = require("command/CommandManager"),
Menus = require("command/Menus"),
PerfUtils = require("utils/PerfUtils"),
PreferencesManager = require("preferences/PreferencesManager"),
Strings = require("strings"),
TextRange = require("document/TextRange").TextRange,
ViewUtils = require("utils/ViewUtils");
var PREFERENCES_CLIENT_ID = "com.adobe.brackets.Editor",
defaultPrefs = { useTabChar: false };
/**
* @private
* Handle Tab key press.
@ -225,6 +228,8 @@ define(function (require, exports, module) {
}
}
/** Editor preferences */
var _prefs = PreferencesManager.getPreferenceStorage(PREFERENCES_CLIENT_ID, defaultPrefs);
/**
* List of all current (non-destroy()ed) Editor instances. Needed when changing global preferences
@ -234,7 +239,7 @@ define(function (require, exports, module) {
var _instances = [];
/** @type {boolean} Global setting: When inserting new text, use tab characters? (instead of spaces) */
var _useTabChar = false;
var _useTabChar = _prefs.getValue("useTabChar");
@ -1046,6 +1051,9 @@ define(function (require, exports, module) {
_instances.forEach(function (editor) {
editor._codeMirror.setOption("indentWithTabs", _useTabChar);
});
// Remember the setting across launches
_prefs.setValue("useTabChar", Boolean(_useTabChar));
};
/** @type {boolean} Gets whether all Editors use tab characters (vs. spaces) when inserting new text */

Просмотреть файл

@ -35,7 +35,8 @@ define(function (require, exports, module) {
var Commands = require("command/Commands"),
Strings = require("strings"),
CommandManager = require("command/CommandManager"),
EditorManager = require("editor/EditorManager");
EditorManager = require("editor/EditorManager"),
Editor = require("editor/Editor").Editor;
/**
@ -262,12 +263,23 @@ define(function (require, exports, module) {
editor._codeMirror.execCommand("indentLess");
}
/**
* Toggles tabs/spaces preferences
*/
function toggleUseTabChars() {
var useTabs = !Editor.getUseTabChar();
Editor.setUseTabChar(useTabs);
CommandManager.get(Commands.TOGGLE_USE_TAB_CHARS).setChecked(useTabs);
}
// Register commands
CommandManager.register(Strings.CMD_INDENT, Commands.EDIT_INDENT, indentText);
CommandManager.register(Strings.CMD_UNINDENT, Commands.EDIT_UNINDENT, unidentText);
CommandManager.register(Strings.CMD_COMMENT, Commands.EDIT_LINE_COMMENT, lineComment);
CommandManager.register(Strings.CMD_DUPLICATE, Commands.EDIT_DUPLICATE, duplicateText);
CommandManager.register(Strings.CMD_LINE_UP, Commands.EDIT_LINE_UP, moveLineUp);
CommandManager.register(Strings.CMD_LINE_DOWN, Commands.EDIT_LINE_DOWN, moveLineDown);
CommandManager.register(Strings.CMD_INDENT, Commands.EDIT_INDENT, indentText);
CommandManager.register(Strings.CMD_UNINDENT, Commands.EDIT_UNINDENT, unidentText);
CommandManager.register(Strings.CMD_COMMENT, Commands.EDIT_LINE_COMMENT, lineComment);
CommandManager.register(Strings.CMD_DUPLICATE, Commands.EDIT_DUPLICATE, duplicateText);
CommandManager.register(Strings.CMD_LINE_UP, Commands.EDIT_LINE_UP, moveLineUp);
CommandManager.register(Strings.CMD_LINE_DOWN, Commands.EDIT_LINE_DOWN, moveLineDown);
CommandManager.register(Strings.CMD_USE_TAB_CHARS, Commands.TOGGLE_USE_TAB_CHARS, toggleUseTabChars)
.setChecked(Editor.getUseTabChar());
});

Просмотреть файл

@ -230,6 +230,12 @@ define(function (require, exports, module) {
query.queryStr = tagInfo.attr.value.slice(0, tagInfo.position.offset);
query.attrName = tagInfo.attr.name;
}
} else if (tokenType === HTMLUtils.ATTR_VALUE) {
// We get negative offset for a quoted attribute value with some leading whitespaces
// as in <a rel= "rtl" where the cursor is just to the right of the "=".
// So just set the queryStr to an empty string.
query.queryStr = "";
query.attrName = tagInfo.attr.name;
}
// TODO: get existing attributes for the current tag and add them to query.usedAttr

Просмотреть файл

@ -23,7 +23,7 @@
/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global define, describe, it, expect, beforeEach, afterEach, waitsFor, runs, $, brackets, waitsForDone */
/*global define, describe, it, xit, expect, beforeEach, afterEach, waitsFor, runs, $, brackets, waitsForDone */
define(function (require, exports, module) {
"use strict";
@ -38,9 +38,11 @@ define(function (require, exports, module) {
var defaultContent = "<!doctype html>\n" +
"<html>\n" +
"<style type=\"text/css\">\n" +
"</style>\n" +
"<body>\n" +
" <h1 id='foo'>Heading</h1>\n" + // tag without whitespace
" <h3 id = 'bar' >Subheading</h3>\n" + // tag with whitespace
" <h3 id = 'bar' >Subheading</h3>\n" + // tag with whitespace
" <p></p>\n" + // tag without attributes
" <h5 id='aaa' class='bbb'></h5>\n" + // tag with two attributes
" <div \n" + // incomplete tag
@ -122,118 +124,140 @@ define(function (require, exports, module) {
});
it("should hint for < just before existing tag", function () { // (bug #1260)
testDocument.replaceRange("<", { line: 3, ch: 2 }); // insert text: "<h1" -> "<<h1"
testDocument.replaceRange("<", { line: 5, ch: 2 }); // insert text: "<h1" -> "<<h1"
testEditor.setCursorPos({ line: 3, ch: 3 }); // cursor between the two <s
testEditor.setCursorPos({ line: 5, ch: 3 }); // cursor between the two <s
var hintList = expectHints(HTMLCodeHints.tagHintProvider);
verifyTagHints(hintList);
expect(hintList.indexOf("div")).not.toBe(-1); // additional sanity check
});
it("should filter hints by prefix", function () { // (bug #1260)
testDocument.replaceRange(" <s\n", { line: 6, ch: 0 }); // insert new line "<s", after line "<p></p>"
testDocument.replaceRange(" <s\n", { line: 8, ch: 0 }); // insert new line "<s", after line "<p></p>"
testEditor.setCursorPos({ line: 6, ch: 4 }); // cursor at end of line
testEditor.setCursorPos({ line: 8, ch: 4 }); // cursor at end of line
var hintList = expectHints(HTMLCodeHints.tagHintProvider);
verifyTagHints(hintList, "samp");
expect(hintList.indexOf("div")).toBe(-1);
expect(hintList.indexOf("span")).not.toBe(-1);
});
it("should list hints between '<' and some trailing spaces", function () { // (bug #1515)
// Replace line 9 with a complete div tag and insert a blank line and the closing div tag.
testDocument.replaceRange("<div>\n \n</div>", { line: 9, ch: 2 });
expect(testDocument.getLine(10)).toBe(" ");
// Insert a < on line 10
testDocument.replaceRange("<", { line: 10, ch: 0 });
testEditor.setCursorPos({ line: 10, ch: 1 }); // cursor between < and some trailing whitespaces
var hintList = expectHints(HTMLCodeHints.tagHintProvider);
verifyTagHints(hintList);
// Replace '< ' on line 10 with '<\t'
testDocument.replaceRange("<\t", { line: 10, ch: 0 }, { line: 10, ch: 2 });
testEditor.setCursorPos({ line: 10, ch: 1 }); // cursor between < and some trailing whitespaces
hintList = expectHints(HTMLCodeHints.tagHintProvider);
verifyTagHints(hintList);
});
});
describe("Attribute hint provider", function () {
describe("Attribute name hint provider", function () {
it("should list hints at start of existing attribute", function () {
testEditor.setCursorPos({ line: 3, ch: 6 });
testEditor.setCursorPos({ line: 5, ch: 6 });
var hintList = expectHints(HTMLCodeHints.attrHintProvider);
verifyAttrHints(hintList); // expect no filtering (bug #1311)
});
it("should list hints within existing attribute", function () {
testEditor.setCursorPos({ line: 3, ch: 7 });
testEditor.setCursorPos({ line: 5, ch: 7 });
var hintList = expectHints(HTMLCodeHints.attrHintProvider);
verifyAttrHints(hintList, "id"); // filtered on "i"
});
it("should list hints at end of existing attribute", function () {
testEditor.setCursorPos({ line: 3, ch: 8 });
testEditor.setCursorPos({ line: 5, ch: 8 });
var hintList = expectHints(HTMLCodeHints.attrHintProvider);
verifyAttrHints(hintList, "id"); // filtered on "id"
});
it("should list hints at end of existing attribute with whitespace", function () {
testEditor.setCursorPos({ line: 4, ch: 8 }); // cursor between end of attr ("d") and space
testEditor.setCursorPos({ line: 6, ch: 8 }); // cursor between end of attr ("d") and space
var hintList = expectHints(HTMLCodeHints.attrHintProvider);
verifyAttrHints(hintList, "id"); // filtered on "id"
});
it("should list hints to right of attribute value and a space", function () {
testEditor.setCursorPos({ line: 4, ch: 17 }); // cursor between space (after attr value) and >
testEditor.setCursorPos({ line: 6, ch: 18 }); // cursor between space (after attr value) and >
var hintList = expectHints(HTMLCodeHints.attrHintProvider);
verifyAttrHints(hintList); // expect no filtering
});
it("should NOT list hints to right of '=' sign", function () {
testEditor.setCursorPos({ line: 3, ch: 9 });
it("should list hints to right of '=' sign", function () {
testEditor.setCursorPos({ line: 5, ch: 9 });
expectHints(HTMLCodeHints.attrHintProvider);
});
// TODO: Uncomment this after fixing issue #1521
xit("should NOT list hints to left of '=' sign with whitespace", function () {
testEditor.setCursorPos({ line: 6, ch: 9 }); // cursor between two spaces before =
expectNoHints(HTMLCodeHints.attrHintProvider);
testEditor.setCursorPos({ line: 6, ch: 10 }); // cursor between space and =
expectNoHints(HTMLCodeHints.attrHintProvider);
});
it("should NOT list hints to left of '=' sign with whitespace", function () {
testEditor.setCursorPos({ line: 4, ch: 9 }); // cursor between space and =
expectNoHints(HTMLCodeHints.attrHintProvider);
});
it("should NOT list hints to right of '=' sign with whitespace", function () {
testEditor.setCursorPos({ line: 4, ch: 10 }); // cursor between = and space
expectNoHints(HTMLCodeHints.attrHintProvider);
testEditor.setCursorPos({ line: 4, ch: 11 }); // cursor between space and '
expectNoHints(HTMLCodeHints.attrHintProvider);
it("should list hints to right of '=' sign with whitespace", function () {
testEditor.setCursorPos({ line: 6, ch: 11 }); // cursor between = and space
expectHints(HTMLCodeHints.attrHintProvider);
testEditor.setCursorPos({ line: 6, ch: 12 }); // cursor between space and '
expectHints(HTMLCodeHints.attrHintProvider);
});
it("should NOT list hints to right of attribute value with no separating space", function () {
testEditor.setCursorPos({ line: 3, ch: 14 }); // cursor between ' and >
testEditor.setCursorPos({ line: 5, ch: 14 }); // cursor between ' and >
expectNoHints(HTMLCodeHints.attrHintProvider);
});
it("should NOT list hints within tag name", function () {
testEditor.setCursorPos({ line: 3, ch: 3 }); // cursor between < and start of tag name ("h")
testEditor.setCursorPos({ line: 5, ch: 3 }); // cursor between < and start of tag name ("h")
expectNoHints(HTMLCodeHints.attrHintProvider);
testEditor.setCursorPos({ line: 3, ch: 4 }); // cursor in middle of tag name
testEditor.setCursorPos({ line: 5, ch: 4 }); // cursor in middle of tag name
expectNoHints(HTMLCodeHints.attrHintProvider);
// two cases for end of tag name:
testEditor.setCursorPos({ line: 3, ch: 5 }); // cursor between end of tag name ("1") and space
testEditor.setCursorPos({ line: 5, ch: 5 }); // cursor between end of tag name ("1") and space
expectNoHints(HTMLCodeHints.attrHintProvider);
testEditor.setCursorPos({ line: 5, ch: 4 }); // cursor between end of tag name ("p") and >
testEditor.setCursorPos({ line: 7, ch: 4 }); // cursor between end of tag name ("p") and >
expectNoHints(HTMLCodeHints.attrHintProvider);
});
it("should list hints to right of tag name and a space", function () { // (bug #1310)
testDocument.replaceRange(" ", { line: 5, ch: 4 }); // insert a space: "<p>" -> "<p >"
testDocument.replaceRange(" ", { line: 7, ch: 4 }); // insert a space: "<p>" -> "<p >"
testEditor.setCursorPos({ line: 5, ch: 5 }); // cursor between space and >
testEditor.setCursorPos({ line: 7, ch: 5 }); // cursor between space and >
var hintList = expectHints(HTMLCodeHints.attrHintProvider);
verifyAttrHints(hintList); // expect no filtering
});
it("should list hints between tag name and attribute name (space on both sides of cursor)", function () {
testDocument.replaceRange(" ", { line: 3, ch: 5 }); // insert a space: "<h1 id" -> "<h1 id"
testDocument.replaceRange(" ", { line: 5, ch: 5 }); // insert a space: "<h1 id" -> "<h1 id"
testEditor.setCursorPos({ line: 3, ch: 6 }); // cursor between two spaces, which are between end of tag name ("p") and start of attribute name
testEditor.setCursorPos({ line: 5, ch: 6 }); // cursor between two spaces, which are between end of tag name ("p") and start of attribute name
var hintList = expectHints(HTMLCodeHints.attrHintProvider);
verifyAttrHints(hintList); // expect no filtering
});
it("should list hints between prev attribute value and next attribute name (space on both sides of cursor)", function () {
testDocument.replaceRange(" ", { line: 6, ch: 14 }); // insert a space: "'aaa' class" -> "'aaa' class"
testDocument.replaceRange(" ", { line: 8, ch: 14 }); // insert a space: "'aaa' class" -> "'aaa' class"
testEditor.setCursorPos({ line: 6, ch: 15 }); // cursor between two spaces, which are between end of attribute value ("p") and start of attribute name
testEditor.setCursorPos({ line: 8, ch: 15 }); // cursor between two spaces, which are between end of attribute value ("p") and start of attribute name
var hintList = expectHints(HTMLCodeHints.attrHintProvider);
verifyAttrHints(hintList); // expect no filtering
});
it("should NOT list hints to left of tag", function () {
testEditor.setCursorPos({ line: 2, ch: 0 }); // tag starting at column zero
testEditor.setCursorPos({ line: 4, ch: 0 }); // tag starting at column zero
expectNoHints(HTMLCodeHints.attrHintProvider);
testEditor.setCursorPos({ line: 3, ch: 2 }); // tag with whitespace indent after it
testEditor.setCursorPos({ line: 5, ch: 2 }); // tag with whitespace indent after it
expectNoHints(HTMLCodeHints.attrHintProvider);
});
it("should NOT list hints within text content or whitespace", function () {
testEditor.setCursorPos({ line: 3, ch: 0 }); // whitespace
testEditor.setCursorPos({ line: 5, ch: 0 }); // whitespace
expectNoHints(HTMLCodeHints.attrHintProvider);
testEditor.setCursorPos({ line: 3, ch: 18 }); // plain text content
testEditor.setCursorPos({ line: 5, ch: 18 }); // plain text content
expectNoHints(HTMLCodeHints.attrHintProvider);
});
@ -243,42 +267,161 @@ define(function (require, exports, module) {
});
it("should NOT list hints within closing tag", function () {
testEditor.setCursorPos({ line: 3, ch: 23 }); // cursor between < and /
testEditor.setCursorPos({ line: 5, ch: 23 }); // cursor between < and /
expectNoHints(HTMLCodeHints.attrHintProvider);
testEditor.setCursorPos({ line: 3, ch: 24 }); // cursor between / and start of tag name ("h")
testEditor.setCursorPos({ line: 5, ch: 24 }); // cursor between / and start of tag name ("h")
expectNoHints(HTMLCodeHints.attrHintProvider);
testEditor.setCursorPos({ line: 3, ch: 25 }); // cursor in middle of tag name
testEditor.setCursorPos({ line: 5, ch: 25 }); // cursor in middle of tag name
expectNoHints(HTMLCodeHints.attrHintProvider);
testEditor.setCursorPos({ line: 3, ch: 26 }); // cursor between end of tag name ("1") and > (bug #1335)
testEditor.setCursorPos({ line: 5, ch: 26 }); // cursor between end of tag name ("1") and > (bug #1335)
expectNoHints(HTMLCodeHints.attrHintProvider);
});
it("should NOT list hints between begin 'div' and end 'div' tag", function () { // (bug #1510)
// replace line 9 with a complete div tag and insert a blank line and the closing div tag.
testDocument.replaceRange("<div>\n \n </div>", { line: 9, ch: 2 });
testEditor.setCursorPos({ line: 10, ch: 2 }); // cursor between whitespaces on the newly inserted blank line
expectNoHints(HTMLCodeHints.attrHintProvider);
testEditor.setCursorPos({ line: 9, ch: 7 }); // cursor to the right of <div>
expectNoHints(HTMLCodeHints.attrHintProvider);
testEditor.setCursorPos({ line: 11, ch: 2 }); // cursor to the left of </div>
expectNoHints(HTMLCodeHints.attrHintProvider);
});
it("should NOT list hints between an empty tag and 'body' end tag", function () { // (bug #1519)
// replace line 9 with an input tag and insert two extra blank lines with some whitespaces.
testDocument.replaceRange("<input type='button' />\n \n ", { line: 9, ch: 2 }, { line: 9, ch: 7 });
// Set cursor between whitespaces on one of the newly inserted blank lines.
testEditor.setCursorPos({ line: 11, ch: 2 });
expectNoHints(HTMLCodeHints.attrHintProvider);
});
it("should NOT list hints between the 'body' begin tag and 'h1' begin tag", function () { // (bug #1519)
// Insert two blank lines with some whitespaces before line 5.
testDocument.replaceRange("\n \n ", { line: 5, ch: 0 });
// Set cursor between whitespaces on one of the newly inserted blank lines.
testEditor.setCursorPos({ line: 7, ch: 2 });
expectNoHints(HTMLCodeHints.attrHintProvider);
});
it("should NOT list hints between the 'h1' end tag and 'h3' begin tag", function () { // (bug #1519)
// Insert two blank lines with some whitespaces before line 5.
testDocument.replaceRange("\n \n ", { line: 6, ch: 0 });
// Set cursor between whitespaces on one of the newly inserted blank lines.
testEditor.setCursorPos({ line: 8, ch: 2 });
expectNoHints(HTMLCodeHints.attrHintProvider);
});
it("should NOT list hints after an HTML comment", function () { // (bug #1440)
// replace line 9 with an HTML comment and some spaces
testDocument.replaceRange("<!-- some comments --> ", { line: 9, ch: 2 });
testEditor.setCursorPos({ line: 9, ch: 25 }); // cursor between whitespaces at the end of line 9
expectNoHints(HTMLCodeHints.attrHintProvider);
});
it("should list hints on incomplete tag, after tag name", function () {
testEditor.setCursorPos({ line: 7, ch: 7 });
testEditor.setCursorPos({ line: 9, ch: 7 });
var hintList = expectHints(HTMLCodeHints.attrHintProvider);
verifyAttrHints(hintList); // expect no filtering
});
it("should NOT list hints on incomplete tag, at end of tag name", function () {
testEditor.setCursorPos({ line: 7, ch: 5 }); // end of tag name
testEditor.setCursorPos({ line: 9, ch: 5 }); // end of tag name
expectNoHints(HTMLCodeHints.attrHintProvider);
testEditor.setCursorPos({ line: 7, ch: 6 }); // within tag name
testEditor.setCursorPos({ line: 9, ch: 6 }); // within tag name
expectNoHints(HTMLCodeHints.attrHintProvider);
});
it("should NOT list hints to left of incomplete tag", function () {
testEditor.setCursorPos({ line: 7, ch: 2 });
testEditor.setCursorPos({ line: 9, ch: 2 });
expectNoHints(HTMLCodeHints.attrHintProvider);
});
it("should list hints on incomplete attribute", function () {
testDocument.replaceRange("i", { line: 7, ch: 7 }); // insert start of attribute: "<div " -> "<div i"
testDocument.replaceRange("i", { line: 9, ch: 7 }); // insert start of attribute: "<div " -> "<div i"
testEditor.setCursorPos({ line: 7, ch: 8 });
testEditor.setCursorPos({ line: 9, ch: 8 });
var hintList = expectHints(HTMLCodeHints.attrHintProvider);
verifyAttrHints(hintList, "id"); // filtered on "i"
});
});
describe("Attribute value hint provider", function () {
it("should list attribute value hints for a single quote after the equal sign", function () {
testDocument.replaceRange(" dir='", { line: 7, ch: 4 }); // insert dir=' between <p and >
testEditor.setCursorPos({ line: 7, ch: 10 }); // set cursor right after dir='
var hintList = expectHints(HTMLCodeHints.attrHintProvider);
expect(hintList.indexOf("ltr")).not.toBe(-1); // additional sanity check
});
it("should list attribute value hints within an existing attribute value", function () {
testDocument.replaceRange(" dir=\"ltr\"", { line: 7, ch: 4 }); // insert dir="ltr" between <p and >
testEditor.setCursorPos({ line: 7, ch: 11 }); // set cursor right after dir="l
var hintList = expectHints(HTMLCodeHints.attrHintProvider);
expect(hintList.indexOf("ltr")).not.toBe(-1); // additional sanity check
});
it("should list attribute value hints within an unquoted attribute value", function () {
testDocument.replaceRange(" dir=ltr", { line: 7, ch: 4 }); // insert dir=ltr between <p and >
testEditor.setCursorPos({ line: 7, ch: 10 }); // set cursor right after dir=l
var hintList = expectHints(HTMLCodeHints.attrHintProvider);
expect(hintList.indexOf("ltr")).not.toBe(-1); // additional sanity check
});
it("should list sorted boolean attribute value hints", function () {
testDocument.replaceRange(" spellcheck=\"", { line: 7, ch: 4 }); // insert spellcheck=" between <p and >
testEditor.setCursorPos({ line: 7, ch: 17 }); // set cursor right after spellcheck="
var hintList = expectHints(HTMLCodeHints.attrHintProvider);
expect(hintList.indexOf("false")).toBe(0);
expect(hintList.indexOf("true")).toBe(1);
expect(hintList.length).toBe(2);
});
it("should NOT list attribute value hints to the right of a closing double quote", function () {
testDocument.replaceRange(" dir=\"ltr\"", { line: 7, ch: 4 }); // insert dir="ltr" between <p and >
testEditor.setCursorPos({ line: 7, ch: 14 }); // set cursor right after dir="ltr"
expectNoHints(HTMLCodeHints.attrHintProvider);
});
it("should NOT list attribute value hints to the right of a closing single quote", function () {
testDocument.replaceRange(" dir='ltr'", { line: 6, ch: 5 }); // insert dir='ltr' between <h3 and id
testEditor.setCursorPos({ line: 4, ch: 15 }); // set cursor right after dir='ltr'
expectNoHints(HTMLCodeHints.attrHintProvider);
});
it("should list attribute value hints for type attribute of style tag", function () {
// set cursor to the right of type attribute but before the closing quote
testEditor.setCursorPos({ line: 2, ch: 21 });
var hintList = expectHints(HTMLCodeHints.attrHintProvider);
expect(hintList.indexOf("text/css")).not.toBe(-1);
});
it("should NOT list any attribute value for type attribute of embed tag", function () {
// set cursor to the right of type attribute but before the closing quote
testEditor.setCursorPos({ line: 9, ch: 3 });
// Replace div on line 9 with embed type=' ("<div " --> "<embed type='")
testDocument.replaceRange("embed type='", { line: 9, ch: 3 }, { line: 9, ch: 7 });
testEditor.setCursorPos({ line: 9, ch: 15 });
var hintList = expectHints(HTMLCodeHints.attrHintProvider);
expect(hintList.length).toBe(0);
});
it("should NOT list any attribute value for an unknown attribute name", function () {
testDocument.replaceRange("foo='", { line: 9, ch: 7 }); // insert foo=' after <div tag
testEditor.setCursorPos({ line: 9, ch: 12 });
var hintList = expectHints(HTMLCodeHints.attrHintProvider);
expect(hintList.length).toBe(0);
});
});
@ -287,9 +430,9 @@ define(function (require, exports, module) {
describe("Valueless attributes", function () {
it("should list hints after valueless attribute", function () { // (bug #1313)
testDocument.replaceRange(" <input checked >\n", { line: 7, ch: 0 }); // insert new line
testDocument.replaceRange(" <input checked >\n", { line: 9, ch: 0 }); // insert new line
testEditor.setCursorPos({ line: 7, ch: 17 }); // cursor between space and >
testEditor.setCursorPos({ line: 9, ch: 17 }); // cursor between space and >
var hintList = expectHints(HTMLCodeHints.attrHintProvider);
// Expect no filtering - however, we offer some attributes (including first in the list) that
@ -300,9 +443,9 @@ define(function (require, exports, module) {
});
it("should list hints after attribute that follows a valueless attribute", function () { // (bug #1313)
testDocument.replaceRange(" <input checked accept='' >\n", { line: 7, ch: 0 }); // insert new line
testDocument.replaceRange(" <input checked accept='' >\n", { line: 9, ch: 0 }); // insert new line
testEditor.setCursorPos({ line: 7, ch: 27 }); // cursor between space and >
testEditor.setCursorPos({ line: 9, ch: 27 }); // cursor between space and >
var hintList = expectHints(HTMLCodeHints.attrHintProvider);
verifyAttrHints(hintList, "accept"); // expect no filtering (see note above)
@ -327,58 +470,170 @@ define(function (require, exports, module) {
}
it("should insert =\"\" after attribute", function () {
testEditor.setCursorPos({ line: 4, ch: 17 }); // cursor between space and >
testEditor.setCursorPos({ line: 6, ch: 18 }); // cursor between space and >
selectHint(HTMLCodeHints.attrHintProvider, "class");
expect(testDocument.getLine(4)).toBe(" <h3 id = 'bar' class=\"\">Subheading</h3>");
expectCursorAt({ line: 4, ch: 24 }); // cursor between the two "s
expect(testDocument.getLine(6)).toBe(" <h3 id = 'bar' class=\"\">Subheading</h3>");
expectCursorAt({ line: 6, ch: 25 }); // cursor between the two "s
});
it("should pop up attribute value hints after attribute name has been inserted", function () {
testEditor.setCursorPos({ line: 4, ch: 17 }); // cursor between space and >
testEditor.setCursorPos({ line: 6, ch: 18 }); // cursor between space and >
selectHint(HTMLCodeHints.attrHintProvider, "dir");
expect(testDocument.getLine(4)).toBe(" <h3 id = 'bar' dir=\"\">Subheading</h3>");
expect(testDocument.getLine(6)).toBe(" <h3 id = 'bar' dir=\"\">Subheading</h3>");
expect(CodeHintManager._getCodeHintList()).toBeTruthy();
expect(CodeHintManager._getCodeHintList().isOpen()).toBe(true);
});
it("should NOT insert =\"\" after valueless attribute", function () {
testDocument.replaceRange(" <input \n", { line: 7, ch: 0 }); // insert new line
testDocument.replaceRange(" <input \n", { line: 9, ch: 0 }); // insert new line
testEditor.setCursorPos({ line: 7, ch: 9 }); // cursor after trailing space
testEditor.setCursorPos({ line: 9, ch: 9 }); // cursor after trailing space
selectHint(HTMLCodeHints.attrHintProvider, "checked");
expect(testDocument.getLine(7)).toBe(" <input checked");
expectCursorAt({ line: 7, ch: 16 }); // cursor at end of attr name
expect(testDocument.getLine(9)).toBe(" <input checked");
expectCursorAt({ line: 9, ch: 16 }); // cursor at end of attr name
});
it("should overwrite attribute but not change value, cursor at start", function () { // (bug #1312)
testEditor.setCursorPos({ line: 3, ch: 6 }); // cursor between space and start of existing attribute name ("id")
testEditor.setCursorPos({ line: 5, ch: 6 }); // cursor between space and start of existing attribute name ("id")
selectHint(HTMLCodeHints.attrHintProvider, "class");
expect(testDocument.getLine(3)).toBe(" <h1 class='foo'>Heading</h1>");
expectCursorAt({ line: 3, ch: 11 }); // cursor at end of attr name
expect(testDocument.getLine(5)).toBe(" <h1 class='foo'>Heading</h1>");
expectCursorAt({ line: 5, ch: 11 }); // cursor at end of attr name
});
it("should change nothing when cursor at end", function () { // (bug #1314)
testEditor.setCursorPos({ line: 3, ch: 8 }); // cursor between end of existing attribute name ("id") and =
testEditor.setCursorPos({ line: 5, ch: 8 }); // cursor between end of existing attribute name ("id") and =
selectHint(HTMLCodeHints.attrHintProvider, "id");
expect(testDocument.getLine(3)).toBe(" <h1 id='foo'>Heading</h1>");
expectCursorAt({ line: 3, ch: 8 }); // cursor stays at end of attr name
expect(testDocument.getLine(5)).toBe(" <h1 id='foo'>Heading</h1>");
expectCursorAt({ line: 5, ch: 8 }); // cursor stays at end of attr name
});
it("should overwrite attribute with valueless attribute, but still not change value", function () {
testDocument.replaceRange(" <input id='foo'>\n", { line: 7, ch: 0 }); // insert new line
testDocument.replaceRange(" <input id='foo'>\n", { line: 9, ch: 0 }); // insert new line
testEditor.setCursorPos({ line: 7, ch: 9 }); // cursor after trailing space
testEditor.setCursorPos({ line: 9, ch: 9 }); // cursor after trailing space
selectHint(HTMLCodeHints.attrHintProvider, "checked");
expect(testDocument.getLine(7)).toBe(" <input checked='foo'>");
expectCursorAt({ line: 7, ch: 16 }); // cursor between end of attr name and =
expect(testDocument.getLine(9)).toBe(" <input checked='foo'>");
expectCursorAt({ line: 9, ch: 16 }); // cursor between end of attr name and =
});
it("should overwrite valueless attribute with normal attribute, adding value", function () {
testDocument.replaceRange(" <input checked>\n", { line: 7, ch: 0 }); // insert new line
testDocument.replaceRange(" <input checked>\n", { line: 9, ch: 0 }); // insert new line
testEditor.setCursorPos({ line: 7, ch: 9 }); // cursor after trailing space
testEditor.setCursorPos({ line: 9, ch: 9 }); // cursor after trailing space
selectHint(HTMLCodeHints.attrHintProvider, "class");
expect(testDocument.getLine(7)).toBe(" <input class=\"\">");
expectCursorAt({ line: 7, ch: 16 }); // cursor between the two "s
expect(testDocument.getLine(9)).toBe(" <input class=\"\">");
expectCursorAt({ line: 9, ch: 16 }); // cursor between the two "s
});
it("should insert the selected attribute value with the closing (single) quote", function () {
testDocument.replaceRange("dir='", { line: 9, ch: 7 }); // insert dir=' after <div tag
testEditor.setCursorPos({ line: 9, ch: 12 });
selectHint(HTMLCodeHints.attrHintProvider, "rtl");
expect(testDocument.getLine(9)).toBe(" <div dir='rtl'");
expectCursorAt({ line: 9, ch: 16 }); // cursor after the closing quote
});
it("should insert the selected attribute value with the closing (double) quote", function () {
testDocument.replaceRange("dir=\"", { line: 9, ch: 7 }); // insert dir=" after <div tag
testEditor.setCursorPos({ line: 9, ch: 12 });
selectHint(HTMLCodeHints.attrHintProvider, "rtl");
expect(testDocument.getLine(9)).toBe(" <div dir=\"rtl\"");
expectCursorAt({ line: 9, ch: 16 }); // cursor after the closing quote
});
it("should insert the selected attribute value inside the existing quotes", function () {
testDocument.replaceRange("dir=\"\"", { line: 9, ch: 7 }); // insert dir="" after <div tag
testEditor.setCursorPos({ line: 9, ch: 12 });
selectHint(HTMLCodeHints.attrHintProvider, "rtl");
expect(testDocument.getLine(9)).toBe(" <div dir=\"rtl\"");
expectCursorAt({ line: 9, ch: 16 }); // cursor after the closing quote
});
it("should insert the selected attribute value WITHOUT begin or end quote", function () {
testDocument.replaceRange("dir=", { line: 9, ch: 7 }); // insert dir= after <div tag
testEditor.setCursorPos({ line: 9, ch: 11 });
selectHint(HTMLCodeHints.attrHintProvider, "rtl");
expect(testDocument.getLine(9)).toBe(" <div dir=rtl");
expectCursorAt({ line: 9, ch: 14 }); // cursor after the closing quote
});
it("should replace the partially typed attribute value with the selected attribute value", function () {
testDocument.replaceRange("dir=\"lt", { line: 9, ch: 7 }); // insert dir="lt after <div tag
testEditor.setCursorPos({ line: 9, ch: 14 });
selectHint(HTMLCodeHints.attrHintProvider, "ltr");
expect(testDocument.getLine(9)).toBe(" <div dir=\"ltr\"");
expectCursorAt({ line: 9, ch: 16 }); // cursor after the closing quote
});
it("should replace the partially typed attribute value with the selected attribute value", function () {
testDocument.replaceRange("dir=lt", { line: 9, ch: 7 }); // insert dir="lt after <div tag
testEditor.setCursorPos({ line: 9, ch: 13 });
selectHint(HTMLCodeHints.attrHintProvider, "ltr");
expect(testDocument.getLine(9)).toBe(" <div dir=ltr");
expectCursorAt({ line: 9, ch: 14 }); // cursor after the closing quote
});
it("should replace an existing attribute value with the selected attribute value", function () {
// Intentionally change the type of style attribute to an invalid value by replacing
// "css" with "javascript".
testDocument.replaceRange("javascript", { line: 2, ch: 18 }, { line: 2, ch: 21 });
testEditor.setCursorPos({ line: 2, ch: 18 });
selectHint(HTMLCodeHints.attrHintProvider, "text/css");
expect(testDocument.getLine(2)).toBe("<style type=\"text/css\">");
expectCursorAt({ line: 2, ch: 22 }); // cursor after the closing quote
});
it("should replace a quoted attribute value and keep the preceding space and quotes", function () {
// Insert an unquoted attribute between <div and id on line 5.
testDocument.replaceRange("dir= \"ltr\" ", { line: 5, ch: 6 });
testEditor.setCursorPos({ line: 5, ch: 10 }); // Set the cursor between = and the space
// Select "rtl" to replace "ltr"
selectHint(HTMLCodeHints.attrHintProvider, "rtl");
expect(testDocument.getLine(5)).toBe(" <h1 dir= \"rtl\" id='foo'>Heading</h1>");
expectCursorAt({ line: 5, ch: 16 }); // cursor after the closing quote
testEditor.setCursorPos({ line: 5, ch: 11 }); // Set the cursor between the space and the begin quote
// Select "ltr" to replace "rtl"
selectHint(HTMLCodeHints.attrHintProvider, "ltr");
expect(testDocument.getLine(5)).toBe(" <h1 dir= \"ltr\" id='foo'>Heading</h1>");
expectCursorAt({ line: 5, ch: 16 }); // cursor after the closing quote
});
it("should replace the unquoted attribute value with the selected attribute value", function () {
// Insert an unquoted attribute between <div and id on line 5.
testDocument.replaceRange("dir=ltr ", { line: 5, ch: 6 });
testEditor.setCursorPos({ line: 5, ch: 10 });
// Select "rtl" to replace "ltr"
selectHint(HTMLCodeHints.attrHintProvider, "rtl");
expect(testDocument.getLine(5)).toBe(" <h1 dir=rtl id='foo'>Heading</h1>");
expectCursorAt({ line: 5, ch: 13 }); // cursor after the inserted value
});
it("should replace an unquoted attribute value when the cursor is inside that value", function () {
// Insert an unquoted attribute between <div and id on line 5.
// intentionally have an invalid attribute lttr here
testDocument.replaceRange("dir= lttr ", { line: 5, ch: 6 });
testEditor.setCursorPos({ line: 5, ch: 12 }); // Set cursor after l in the invalid attribute value
selectHint(HTMLCodeHints.attrHintProvider, "ltr");
expect(testDocument.getLine(5)).toBe(" <h1 dir= ltr id='foo'>Heading</h1>");
expectCursorAt({ line: 5, ch: 14 }); // cursor after the inserted value
});
it("should insert an unquoted attribute value before an existing unquoted attribute value with preceding space character", function () {
// Insert an unquoted attribute between <div and id on line 5.
testDocument.replaceRange("dir= ltr ", { line: 5, ch: 6 });
testEditor.setCursorPos({ line: 5, ch: 10 }); // Set cursor between = and the space
selectHint(HTMLCodeHints.attrHintProvider, "rtl");
expect(testDocument.getLine(5)).toBe(" <h1 dir=rtl ltr id='foo'>Heading</h1>");
expectCursorAt({ line: 5, ch: 13 }); // cursor after the inserted value
});
it("should insert an unquoted attribute value before an existing id attribute", function () {
// Insert an unquoted attribute between <div and id on line 5.
testDocument.replaceRange("dir= ", { line: 5, ch: 6 });
testEditor.setCursorPos({ line: 5, ch: 10 }); // Set cursor between = and the space
selectHint(HTMLCodeHints.attrHintProvider, "rtl");
expect(testDocument.getLine(5)).toBe(" <h1 dir=rtl id='foo'>Heading</h1>");
expectCursorAt({ line: 5, ch: 13 }); // cursor after the inserted value
});
});

Просмотреть файл

@ -302,6 +302,9 @@ define(function (require, exports, module) {
var extensionRequire,
JavaScriptQuickEdit,
i,
perfMeasurements;
runs(function () {
perfMeasurements = [
{
measure: PerfUtils.JAVASCRIPT_INLINE_CREATE,
@ -335,6 +338,7 @@ define(function (require, exports, module) {
]
}
];
});
runs(function () {
extensionRequire = testWindow.brackets.getModule("utils/ExtensionLoader").getRequireContextForExtension("JavaScriptQuickEdit");

Просмотреть файл

@ -37,7 +37,9 @@ define(function (require, exports, module) {
ExtensionUtils = brackets.getModule("utils/ExtensionUtils"),
AppInit = brackets.getModule("utils/AppInit"),
Strings = brackets.getModule("strings"),
SidebarView = brackets.getModule("project/SidebarView");
SidebarView = brackets.getModule("project/SidebarView"),
Menus = brackets.getModule("command/Menus"),
PopUpManager = brackets.getModule("widgets/PopUpManager");
var $dropdownToggle;
var MAX_PROJECTS = 20;
@ -97,6 +99,8 @@ define(function (require, exports, module) {
return;
}
Menus.closeAll();
// TODO: Can't just use Bootstrap 1.4 dropdowns for this since they're hard-coded to
// assume that the dropdown is inside a top-level menubar created using <li>s.
// Have to do this stopProp to avoid the html click handler from firing when this returns.
@ -106,12 +110,18 @@ define(function (require, exports, module) {
recentProjects = prefs.getValue("recentProjects") || [],
$dropdown = $("<ul id='project-dropdown' class='dropdown-menu'></ul>"),
toggleOffset = $dropdownToggle.offset();
function closeDropdown() {
// Since we passed "true" for autoRemove to addPopUp(), this will
// automatically remove the dropdown from the DOM.
PopUpManager.removePopUp($dropdown);
}
function cleanupDropdown() {
$("html").off("click", closeDropdown);
$("#project-files-container").off("scroll", closeDropdown);
$(SidebarView).off("hide", closeDropdown);
$dropdown.remove();
$("#main-toolbar .nav").off("click", closeDropdown);
}
var currentProject = ProjectManager.getProjectRoot().fullPath,
@ -150,6 +160,7 @@ define(function (require, exports, module) {
top: toggleOffset.top + $dropdownToggle.outerHeight()
})
.appendTo($("body"));
PopUpManager.addPopUp($dropdown, cleanupDropdown, true);
// TODO: should use capture, otherwise clicking on the menus doesn't close it. More fallout
// from the fact that we can't use the Boostrap (1.4) dropdowns.
@ -165,6 +176,10 @@ define(function (require, exports, module) {
// Hide the menu if the sidebar is hidden.
// TODO: Is there some more general way we could handle this for dropdowns?
$(SidebarView).on("hide", closeDropdown);
// Hacky: if we detect a click in the menubar, close ourselves.
// TODO: again, we should have centralized popup management.
$("#main-toolbar .nav").on("click", closeDropdown);
}
// Initialize extension

Просмотреть файл

@ -0,0 +1,82 @@
/*
* Copyright (c) 2012 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 vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global define, $, brackets, window */
define(function (require, exports, module) {
"use strict";
var Global = require("utils/Global"),
BuildInfoUtils = require("utils/BuildInfoUtils"),
Commands = require("command/Commands"),
CommandManager = require("command/CommandManager"),
Dialogs = require("widgets/Dialogs"),
Strings = require("strings"),
UpdateNotification = require("utils/UpdateNotification"),
FileUtils = require("file/FileUtils"),
NativeApp = require("utils/NativeApp");
function _handleShowExtensionsFolder() {
brackets.app.showExtensionsFolder(
FileUtils.convertToNativePath(window.location.href),
function (err) {
// Ignore errors
}
);
}
function _handleCheckForUpdates() {
UpdateNotification.checkForUpdate(true);
}
function _handleAboutDialog() {
// If we've successfully determined a "build number" via .git metadata, add it to dialog
var bracketsSHA = BuildInfoUtils.getBracketsSHA(),
bracketsAppSHA = BuildInfoUtils.getBracketsAppSHA(),
versionLabel = "";
if (bracketsSHA) {
versionLabel += " (" + bracketsSHA.substr(0, 7) + ")";
}
if (bracketsAppSHA) {
versionLabel += " (shell " + bracketsAppSHA.substr(0, 7) + ")";
}
$("#about-build-number").text(versionLabel);
Dialogs.showModalDialog(Dialogs.DIALOG_ID_ABOUT);
}
function _handleForum() {
if (!brackets.config.forum_url) {
return;
}
NativeApp.openURLInDefaultBrowser(brackets.config.forum_url);
}
CommandManager.register(Strings.CMD_SHOW_EXTENSIONS_FOLDER, Commands.HELP_SHOW_EXT_FOLDER, _handleShowExtensionsFolder);
CommandManager.register(Strings.CMD_CHECK_FOR_UPDATE, Commands.HELP_CHECK_FOR_UPDATE, _handleCheckForUpdates);
CommandManager.register(Strings.CMD_FORUM, Commands.HELP_FORUM, _handleForum);
CommandManager.register(Strings.CMD_ABOUT, Commands.HELP_ABOUT, _handleAboutDialog);
});

Просмотреть файл

@ -91,7 +91,6 @@
<div id="editor-holder">
<div id="not-editor">
<div id="not-editor-content">[&nbsp;&nbsp;]</div>
</div>
</div>
@ -180,7 +179,7 @@
<h1 class="dialog-title">{{ABOUT}}</h1>
</div>
<div class="modal-body">
<img class="about-icon" src="styles/images/brackets_icon.svg">
<img class="about-icon" src="{{ABOUT_ICON}}">
<div class="about-text">
<h2>{{APP_NAME}}</h2>
<p class="dialog-message">{{ABOUT_TEXT_LINE1}} <span id="about-build-number"><!-- populated programmatically --></span></p>

Просмотреть файл

@ -25,7 +25,7 @@
<html>
<head>
<meta charset="utf-8">
<title>Brackets</title>
<title></title>
<!-- CSS/LESS -->

Просмотреть файл

@ -73,8 +73,8 @@ define(function (require, exports, module) {
var selectorStartChar = -1, selectorStartLine = -1;
var selectorGroupStartLine = -1, selectorGroupStartChar = -1;
var declListStartLine = -1, declListStartChar = -1;
var escapePattern = /\\[^\\]+/g;
var validationPattern = /\\([a-fA-F0-9]{6}|[a-fA-F0-9]{4}(\s|\\|$)|[a-fA-F0-9]{2}(\s|\\|$)|.)/;
var escapePattern = new RegExp("\\\\[^\\\\]+", "g");
var validationPattern = new RegExp("\\\\([a-f0-9]{6}|[a-f0-9]{4}(\\s|\\\\|$)|[a-f0-9]{2}(\\s|\\\\|$)|.)", "i");
// implement _firstToken()/_nextToken() methods to
// provide a single stream of tokens
@ -186,18 +186,23 @@ define(function (require, exports, module) {
}
}
// Is faster regexp.test() than a replace with no hits?
//if(/\\/.test(currentSelector))
//{
// Unicode character replacement as defined in http://www.w3.org/TR/CSS21/syndata.html#characters
if (/\\/.test(currentSelector)) {
// Double replace in case of pattern overlapping (regex improvement?)
currentSelector = currentSelector.replace(escapePattern,function(escapedToken){
return escapedToken.replace(validationPattern,function(unicodeChar){
currentSelector = currentSelector.replace(escapePattern, function (escapedToken) {
return escapedToken.replace(validationPattern, function (unicodeChar) {
unicodeChar = unicodeChar.substr(1);
if (unicodeChar.length==1) return unicodeChar;
else return parseInt(unicodeChar,16)<0x10FFFF?String.fromCharCode(parseInt(unicodeChar,16)):"<22>";
if (unicodeChar.length === 1) {
return unicodeChar;
} else {
if (parseInt(unicodeChar, 16) < 0x10FFFF) {
return String.fromCharCode(parseInt(unicodeChar, 16));
} else { return String.fromCharCode(0xFFFD); }
}
});
});
//}
}
currentSelector = currentSelector.trim();
if (currentSelector !== "") {
selectors.push({selector: currentSelector,

Просмотреть файл

@ -163,8 +163,8 @@ define(function (require, exports, module) {
if (foundEqualSign) {
var spaceIndex = attrValue.indexOf(" ");
attrValue = attrValue.substring(0, (spaceIndex > offset) ? spaceIndex : offset);
} else if (offset > 0) {
//The att value it getting edit in progress. There is possible extra
} else if (offset > 0 && (startChar === "'" || startChar === '"')) {
//The att value is getting edit in progress. There is possible extra
//stuff in this token state since the quote isn't closed, so we assume
//the stuff from the quote to the current pos is definitely in the attribute
//value.
@ -316,11 +316,12 @@ define(function (require, exports, module) {
* A tagInfo object with some context about the current tag hint.
*/
function getTagInfo(editor, constPos) {
//we're going to changing pos a lot, but we don't want to mess up
//the pos the caller passed in so we use extend to make a safe copy of it.
//This is what pass by value in c++ would do.
// We're going to be changing pos a lot, but we don't want to mess up
// the pos the caller passed in so we use extend to make a safe copy of it.
// This is what pass by value in c++ would do.
var pos = $.extend({}, constPos),
ctx = _getInitialContext(editor._codeMirror, pos),
tempCtx = null,
offset = _offsetInToken(ctx),
tagInfo,
tokenType;
@ -347,23 +348,31 @@ define(function (require, exports, module) {
ctx.token = testToken;
if (ctx.token.className === "tag") {
// check to see if the cursor is just before a "<" but not in any tag.
// Check to see if the cursor is just before a "<" but not in any tag.
if (ctx.token.string.charAt(0) === "<") {
return createTagInfo();
}
} else if (ctx.token.className === "attribute") {
// check to see if the user is going to add a new attr before an existing one
// Check to see if the user is going to add a new attr before an existing one
return _getTagInfoStartingFromAttrName(ctx, false);
} else if (ctx.token.className === "string") {
// we're either before a "=" or an attribute value.
} else if (ctx.token.string === "=") {
// We're between a whitespace and "=", so return an empty tag info.
return createTagInfo();
}
ctx.pos = testPos;
// Get the new offset from test token and subtract one for testPos adjustment
offset = _offsetInToken(ctx) - 1;
} else {
// We get here if ">" or white spaces after testPos.
// Check if there is an equal sign after testPos by creating a new ctx
// with the original pos. We can't use the current ctx since we need to
// use it to scan backwards if we don't find an equal sign here.
// Comment out this block to fix issue #1510.
// if (testToken.string.length > 0 && testToken.string.charAt(0) !== ">") {
// tempCtx = _getInitialContext(editor._codeMirror, pos);
// if (_moveSkippingWhitespace(_moveNextToken, tempCtx) && tempCtx.token.string === "=") {
// // Return an empty tag info since we're between an atribute name and the equal sign.
// return createTagInfo();
// }
// }
// next, see what's before pos
if (!_movePrevToken(ctx)) {
return createTagInfo();
@ -371,24 +380,32 @@ define(function (require, exports, module) {
if (ctx.token.className === "comment") {
return createTagInfo();
} else if (ctx.token.className !== "tag") {
//if wasn't the tag name, assume it was an attr value
} else if (ctx.token.className !== "tag" && ctx.token.string !== "=") {
// If it wasn't the tag name, assume it was an attr value
// Also we don't handle the "=" here.
tagInfo = _getTagInfoStartingFromAttrValue(ctx);
//if it wasn't an attr value, assume it was an empty attr (ie. attr with no value)
// Check to see if this is the closing of a tag (either the start or end)
if (ctx.token.className === "tag" &&
(ctx.token.string === ">" || ctx.token.string === "/>" ||
(ctx.token.string.charAt(0) === "<" && ctx.token.string.charAt(1) === "/"))) {
return createTagInfo();
}
// If it wasn't an attr value, assume it was an empty attr (ie. attr with no value)
if (!tagInfo.tagName) {
tagInfo = _getTagInfoStartingFromAttrName(ctx, true);
}
//We don't want to give context for the previous attr
//and we want it to look like the user is going to add a new attr
// We don't want to give context for the previous attr
// and we want it to look like the user is going to add a new attr
if (tagInfo.tagName) {
return createTagInfo(ATTR_NAME, 0, tagInfo.tagName);
}
return createTagInfo();
}
//we know the tag was here, so they user is adding an attr name
// We know the tag was here, so the user is adding an attr name
tokenType = ATTR_NAME;
offset = 0;
}
@ -396,12 +413,12 @@ define(function (require, exports, module) {
if (ctx.token.className === "tag") {
// Check if the user just typed a white space after "<" that made an existing tag invalid.
if (ctx.token.string.indexOf("< ") === 0) {
if (ctx.token.string.match(/^<\s+/) && offset !== 1) {
return createTagInfo();
}
//check to see if this is the closing of a tag (either the start or end)
if (ctx.token.string === ">" ||
// Check to see if this is the closing of a tag (either the start or end)
if (ctx.token.string === ">" || ctx.token.string === "/>" ||
(ctx.token.string.charAt(0) === "<" && ctx.token.string.charAt(1) === "/")) {
return createTagInfo();
}
@ -411,19 +428,39 @@ define(function (require, exports, module) {
offset--; //need to take off 1 for the leading "<"
}
//we're actually in the tag, just return that as we have no relevant
//info about what attr is selected
// We're actually in the tag, just return that as we have no relevant
// info about what attr is selected
return createTagInfo(tokenType, offset, _extractTagName(ctx));
}
if (ctx.token.string === "=") {
// To discourage unquoted attribute value usage we intentionally return an invalid tag info here.
// This will also spare us from handling the conversion between quoted and unquoted attribute values.
return createTagInfo();
// We could be between the attr and the value
// Step back and check
if (!_moveSkippingWhitespace(_movePrevToken, ctx) || ctx.token.className !== "attribute") {
return createTagInfo();
}
// The "=" is added, time to hint for values
tokenType = ATTR_VALUE;
offset = 0;
}
if (ctx.token.className === "attribute") {
tagInfo = _getTagInfoStartingFromAttrName(ctx, false);
// If we're in attr value, then we may need to calculate the correct offset
// from the beginning of the attribute value. If the cursor position is to
// the left of attr value, then the offset is negative.
// e.g. if the cursor is just to the right of the "=" in <a rel= "rtl", then
// the offset will be -2.
if (tagInfo.attr.quoteChar) {
offset = constPos.ch - ctx.pos.ch;
} else if (tokenType === ATTR_VALUE && (constPos.ch + 1) < ctx.pos.ch) {
// The cursor may be right before an unquoted attribute or another attribute name.
// Since we can't distinguish between them, we will empty the value so that the
// caller can just insert a new attribute value.
tagInfo.attr.value = "";
}
} else {
// if we're not at a tag, "=", or attribute name, assume we're in the value
tagInfo = _getTagInfoStartingFromAttrValue(ctx);

Просмотреть файл

@ -23,7 +23,7 @@
/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global define, $, JSLINT, PathUtils */
/*global define, $, brackets, JSLINT, PathUtils */
/**
* Allows JSLint to run on the current document and report results in a UI panel.
@ -37,13 +37,14 @@ define(function (require, exports, module) {
require("thirdparty/jslint/jslint");
// Load dependent modules
var Commands = require("command/Commands"),
var Global = require("utils/Global"),
Commands = require("command/Commands"),
CommandManager = require("command/CommandManager"),
DocumentManager = require("document/DocumentManager"),
EditorManager = require("editor/EditorManager"),
PreferencesManager = require("preferences/PreferencesManager"),
PerfUtils = require("utils/PerfUtils"),
Strings = require("strings"),
EditorManager = require("editor/EditorManager");
Strings = require("strings");
/**
* @private
@ -204,7 +205,7 @@ define(function (require, exports, module) {
CommandManager.register(Strings.CMD_JSLINT, Commands.TOGGLE_JSLINT, _handleToggleJSLint);
// Init PreferenceStorage
_prefs = PreferencesManager.getPreferenceStorage(module.id, { enabled: true });
_prefs = PreferencesManager.getPreferenceStorage(module.id, { enabled: !!brackets.config.enable_jslint });
_setEnabled(_prefs.getValue("enabled"));
// Define public API

Просмотреть файл

@ -1,6 +1,6 @@
/*
* Copyright (c) 2012 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
@ -56,8 +56,8 @@ define({
"ERROR_CREATING_FILE": "Une erreur sest produite lors de la tentative de création du fichier <span class='dialog-filename'>{0}</span>. {1}",
// Application error strings
"ERROR_BRACKETS_IN_BROWSER_TITLE": "Malheureusement, Brackets ne sexécute pas encore dans les navigateurs.",
"ERROR_BRACKETS_IN_BROWSER": "Brackets est défini en HTML, mais il sexécute actuellement en tant quapplication de bureau, vous pouvez donc lutiliser afin de modifier des fichiers locaux. Utilisez linterpréteur de commandes dapplication situé dans le référentiel <b>github.com/adobe/brackets-app</b> afin dexécuter Brackets.",
"ERROR_IN_BROWSER_TITLE": "Malheureusement, {APP_NAME} nest pas encore compatible avec les navigateurs.",
"ERROR_IN_BROWSER": "{APP_NAME} est défini en HTML, mais il sexécute actuellement en tant quapplication de bureau, vous pouvez donc lutiliser afin de modifier des fichiers locaux. Utilisez linterpréteur de commandes dapplication situé dans le référentiel <b>github.com/adobe/brackets-shell</b> afin dexécuter {APP_NAME}.",
// FileIndexManager error string
"ERROR_MAX_FILES_TITLE": "Erreur lors de lindexation des fichiers",
@ -84,8 +84,8 @@ define({
"SAVE_CLOSE_MESSAGE": "Souhaitez-vous enregistrer les modifications apportées au document <span class='dialog-filename'>{0}</span> ?",
"SAVE_CLOSE_MULTI_MESSAGE": "Souhaitez-vous enregistrer les modifications apportées aux fichiers suivants ?",
"EXT_MODIFIED_TITLE": "Modifications externes",
"EXT_MODIFIED_MESSAGE": "Le fichier <span class='dialog-filename'>{0}</span> a été modifié sur le disque mais présente également des modifications non enregistrées dans Brackets.<br /><br />Quelle version souhaitez-vous conserver ?",
"EXT_DELETED_MESSAGE": "Le fichier <span class='dialog-filename'>{0}</span> a été supprimé sur le disque mais présente des modifications non enregistrées dans Brackets.<br /><br />Souhaitez-vous conserver vos modifications ?",
"EXT_MODIFIED_MESSAGE": "Le fichier <span class='dialog-filename'>{0}</span> a été modifié sur le disque mais présente également des modifications non enregistrées dans {APP_NAME}.<br /><br />Quelle version souhaitez-vous conserver ?",
"EXT_DELETED_MESSAGE": "Le fichier <span class='dialog-filename'>{0}</span> a été supprimé sur le disque mais présente des modifications non enregistrées dans {APP_NAME}.<br /><br />Souhaitez-vous conserver vos modifications ?",
// Find, Replace, Find in Files
"SEARCH_REGEXP_INFO": "Utiliser la syntaxe /re/ pour la recherche regexp",
@ -95,18 +95,28 @@ define({
"BUTTON_STOP": "Arrêter",
"OPEN_FILE": "Ouvrir le fichier",
"CHOOSE_FOLDER": "Choisir un dossier",
"RELEASE_NOTES": "[B/] !é=Release Notes=!",
"NO_UPDATE_TITLE": "[B+] !é=You're up to date!=!",
"NO_UPDATE_MESSAGE": "[B9] !é=You are running the latest version of Brackets.=!",
"RELEASE_NOTES": "Notes de mise à jour",
"NO_UPDATE_TITLE": "Votre logiciel est à jour.",
"NO_UPDATE_MESSAGE": "Vous utilisez la dernière version de {APP_NAME}.",
"FIND_IN_FILES_TITLE": "- {0} {1} sur {2} {3}",
"FIND_IN_FILES_FILE": "fichier",
"FIND_IN_FILES_FILES": "fichiers",
"FIND_IN_FILES_MATCH": "résultat",
"FIND_IN_FILES_MATCHES": "résultats",
"FIND_IN_FILES_MAX": " (affichage des {0} premiers résultats)",
"FIND_IN_FILES_FILE_PATH": "Fichier : <b>{0}</b>",
"FIND_IN_FILES_LINE": "Ligne :&nbsp;{0}",
"ERROR_FETCHING_UPDATE_INFO_TITLE": "[CF] !é=Error getting update info=!",
"ERROR_FETCHING_UPDATE_INFO_MSG": "[CE] !é=There was a problem getting the latest update information from the server. Please make sure you are connected to the internet and try again.=!",
"ERROR_FETCHING_UPDATE_INFO_TITLE": "Erreur de récupération des informations de mise à jour",
"ERROR_FETCHING_UPDATE_INFO_MSG": "Un problème est survenu lors de la récupération des dernières informations de mise à jour sur le serveur. Vérifiez que vous êtes connecté à Internet et réessayez.",
// Switch language
"LANGUAGE_TITLE": "Changer de langue",
"LANGUAGE_MESSAGE": "Sélectionnez la langue souhaitée dans la liste ci-dessous :",
"LANGUAGE_SUBMIT": "Recharger Brackets",
"LANGUAGE_SUBMIT": "Recharger {APP_NAME}",
"LANGUAGE_CANCEL": "Annuler",
/**
@ -168,19 +178,21 @@ define({
// Debug menu commands
"DEBUG_MENU": "Déboguer",
"CMD_REFRESH_WINDOW": "Recharger Brackets",
"CMD_REFRESH_WINDOW": "Recharger {APP_NAME}",
"CMD_SHOW_DEV_TOOLS": "Afficher les outils de développement",
"CMD_RUN_UNIT_TESTS": "Exécuter des tests",
"CMD_JSLINT": "Activer JSLint",
"CMD_SHOW_PERF_DATA": "Afficher les données de performances",
"CMD_NEW_BRACKETS_WINDOW": "Nouvelle fenêtre Brackets",
"CMD_SHOW_EXTENSIONS_FOLDER": "[CD] !é=Show Extensions Folder=!",
"CMD_NEW_BRACKETS_WINDOW": "Nouvelle fenêtre {APP_NAME}",
"CMD_SHOW_EXTENSIONS_FOLDER": "Afficher le dossier dextensions",
"CMD_USE_TAB_CHARS": "Utiliser les caractères de tabulation",
"CMD_SWITCH_LANGUAGE": "Changer de langue",
"CMD_CHECK_FOR_UPDATE": "[B7] !é=Check for Updates=!",
"CMD_CHECK_FOR_UPDATE": "Rechercher les mises à jour",
// Help menu commands
"HELP_MENU": "Aide",
"CMD_ABOUT": "A propos",
"CMD_FORUM": "Forum {APP_NAME}",
// Special commands invoked by the native shell
"CMD_CLOSE_WINDOW": "Fermer la fenêtre",
@ -199,13 +211,13 @@ define({
"CLOSE_DONT_SAVE": "Fermer (sans enregistrer)",
"RELAUNCH_CHROME": "Relancer Chrome",
"ABOUT": "A propos",
"APP_NAME": "[CG] !é=Brackets=!",
"APP_NAME": "Brackets",
"CLOSE": "Fermer",
"ABOUT_TEXT_LINE1": "version expérimentale sprint 13 ",
"ABOUT_TEXT_LINE3": "[E] !é=Notices, terms and conditions pertaining to third party software are located at <span class=\"non-clickble-link\">http://www.adobe.com/go/thirdparty/</span> and incorporated by reference herein.=!",
"ABOUT_TEXT_LINE4": "[F] !é=Documentation and source at <span class=\"non-clickble-link\">https://github.com/adobe/brackets/</span>=!",
"UPDATE_NOTIFICATION_TOOLTIP": "[CC] !é=There's a new build of Brackets available! Click here for details.=!",
"UPDATE_AVAILABLE_TITLE": "[CA] !é=Update Available=!",
"UPDATE_MESSAGE": "[CB] !é=Hey, there's a new build of Brackets available. Here are some of the new features:=!",
"GET_IT_NOW": "[B8] !é=Get it now!=!"
"ABOUT_TEXT_LINE1": "version expérimentale sprint 14 ",
"ABOUT_TEXT_LINE3": "Les mentions légales et conditions générales relatives aux logiciels tiers sont disponibles (en anglais) à ladresse <span class=\"non-clickble-link\">http://www.adobe.com/go/thirdparty_fr/</span> et sont incluses dans le présent document à titre de référence.",
"ABOUT_TEXT_LINE4": "La documentation et le code source sont disponibles à ladresse <span class=\"non-clickble-link\">https://github.com/adobe/brackets/</span>",
"UPDATE_NOTIFICATION_TOOLTIP": "Une nouvelle version de {APP_NAME} est disponible. Cliquez ici pour plus de détails.",
"UPDATE_AVAILABLE_TITLE": "Mise à jour disponible",
"UPDATE_MESSAGE": "Une nouvelle version de {APP_NAME} est disponible. Voici quelques-unes des nouvelles fonctionnalités proposées :",
"GET_IT_NOW": "Obtenir maintenant !"
});

Просмотреть файл

@ -56,8 +56,8 @@ define({
"ERROR_CREATING_FILE" : "An error occurred when trying to create the file <span class='dialog-filename'>{0}</span>. {1}",
// Application error strings
"ERROR_BRACKETS_IN_BROWSER_TITLE" : "Oops! Brackets doesn't run in browsers yet.",
"ERROR_BRACKETS_IN_BROWSER" : "Brackets is built in HTML, but right now it runs as a desktop app so you can use it to edit local files. Please use the application shell in the <b>github.com/adobe/brackets-app</b> repo to run Brackets.",
"ERROR_IN_BROWSER_TITLE" : "Oops! {APP_NAME} doesn't run in browsers yet.",
"ERROR_IN_BROWSER" : "{APP_NAME} is built in HTML, but right now it runs as a desktop app so you can use it to edit local files. Please use the application shell in the <b>github.com/adobe/brackets-shell</b> repo to run {APP_NAME}.",
// FileIndexManager error string
"ERROR_MAX_FILES_TITLE" : "Error Indexing Files",
@ -71,21 +71,24 @@ define({
"ERROR_CANT_FIND_CHROME" : "The Google Chrome browser could not be found. Please make sure it is installed.",
"ERROR_LAUNCHING_BROWSER" : "An error occurred when launching the browser. (error {0})",
"LIVE_DEVELOPMENT_ERROR_TITLE" : "Live Development Error",
"LIVE_DEVELOPMENT_ERROR_MESSAGE" : "A live development connection to Chrome could not be established. For live development to work, Chrome needs to be started with remote debugging enabled.<br /><br />Would you like to relaunch Chrome and enable remote debugging?",
"LIVE_DEVELOPMENT_ERROR_TITLE" : "Live Preview Error",
"LIVE_DEVELOPMENT_RELAUNCH_TITLE" : "Connecting to Browser",
"LIVE_DEVELOPMENT_ERROR_MESSAGE" : "In order for Live Preview to connect, Chrome needs to be relaunched with remote debugging enabled.<br /><br />Would you like to relaunch Chrome and enable remote debugging?",
"LIVE_DEV_NEED_HTML_MESSAGE" : "Open an HTML file in order to launch live preview.",
"LIVE_DEVELOPMENT_INFO_TITLE" : "Welcome to Live Preview!",
"LIVE_DEVELOPMENT_INFO_MESSAGE" : "Live Preview connects {APP_NAME} to your browser. It launches a preview of your HTML file in the browser, then updates the preview instantly as you edit your code.<br /><br />In this early version of {APP_NAME}, Live Preview only works for edits to <strong>CSS files</strong> and only with <strong>Google Chrome</strong>. We'll be implementing it for HTML and JavaScript soon!<br /><br />(You'll only see this message once.)",
"LIVE_DEV_STATUS_TIP_NOT_CONNECTED" : "Live File Preview",
"LIVE_DEV_STATUS_TIP_PROGRESS1" : "Live File Preview: Connecting...",
"LIVE_DEV_STATUS_TIP_PROGRESS2" : "Live File Preview: Initializing...",
"LIVE_DEV_STATUS_TIP_CONNECTED" : "Disconnect Live File Preview",
"LIVE_DEV_STATUS_TIP_NOT_CONNECTED" : "Live Preview",
"LIVE_DEV_STATUS_TIP_PROGRESS1" : "Live Preview: Connecting...",
"LIVE_DEV_STATUS_TIP_PROGRESS2" : "Live Preview: Initializing...",
"LIVE_DEV_STATUS_TIP_CONNECTED" : "Disconnect Live Preview",
"SAVE_CLOSE_TITLE" : "Save Changes",
"SAVE_CLOSE_MESSAGE" : "Do you want to save the changes you made in the document <span class='dialog-filename'>{0}</span>?",
"SAVE_CLOSE_MULTI_MESSAGE" : "Do you want to save your changes to the following files?",
"EXT_MODIFIED_TITLE" : "External Changes",
"EXT_MODIFIED_MESSAGE" : "<span class='dialog-filename'>{0}</span> has been modified on disk, but also has unsaved changes in Brackets.<br /><br />Which version do you want to keep?",
"EXT_DELETED_MESSAGE" : "<span class='dialog-filename'>{0}</span> has been deleted on disk, but has unsaved changes in Brackets.<br /><br />Do you want to keep your changes?",
"EXT_MODIFIED_MESSAGE" : "<span class='dialog-filename'>{0}</span> has been modified on disk, but also has unsaved changes in {APP_NAME}.<br /><br />Which version do you want to keep?",
"EXT_DELETED_MESSAGE" : "<span class='dialog-filename'>{0}</span> has been deleted on disk, but has unsaved changes in {APP_NAME}.<br /><br />Do you want to keep your changes?",
// Find, Replace, Find in Files
"SEARCH_REGEXP_INFO" : "Use /re/ syntax for regexp search",
@ -99,7 +102,7 @@ define({
"RELEASE_NOTES" : "Release Notes",
"NO_UPDATE_TITLE" : "You're up to date!",
"NO_UPDATE_MESSAGE" : "You are running the latest version of Brackets.",
"NO_UPDATE_MESSAGE" : "You are running the latest version of {APP_NAME}.",
"FIND_IN_FILES_TITLE" : "- {0} {1} in {2} {3}",
"FIND_IN_FILES_FILE" : "file",
@ -116,7 +119,7 @@ define({
// Switch language
"LANGUAGE_TITLE" : "Switch Language",
"LANGUAGE_MESSAGE" : "Please select the desired language from the list below:",
"LANGUAGE_SUBMIT" : "Reload Brackets",
"LANGUAGE_SUBMIT" : "Reload {APP_NAME}",
"LANGUAGE_CANCEL" : "Cancel",
/**
@ -139,7 +142,7 @@ define({
"CMD_FILE_CLOSE_ALL" : "Close All",
"CMD_FILE_SAVE" : "Save",
"CMD_FILE_SAVE_ALL" : "Save All",
"CMD_LIVE_FILE_PREVIEW" : "Live File Preview",
"CMD_LIVE_FILE_PREVIEW" : "Live Preview",
"CMD_QUIT" : "Quit",
// Edit menu commands
@ -178,19 +181,21 @@ define({
// Debug menu commands
"DEBUG_MENU" : "Debug",
"CMD_REFRESH_WINDOW" : "Reload Brackets",
"CMD_REFRESH_WINDOW" : "Reload {APP_NAME}",
"CMD_SHOW_DEV_TOOLS" : "Show Developer Tools",
"CMD_RUN_UNIT_TESTS" : "Run Tests",
"CMD_JSLINT" : "Enable JSLint",
"CMD_SHOW_PERF_DATA" : "Show Performance Data",
"CMD_NEW_BRACKETS_WINDOW" : "New Brackets Window",
"CMD_NEW_BRACKETS_WINDOW" : "New {APP_NAME} Window",
"CMD_SHOW_EXTENSIONS_FOLDER" : "Show Extensions Folder",
"CMD_USE_TAB_CHARS" : "Use Tab Characters",
"CMD_SWITCH_LANGUAGE" : "Switch Language",
"CMD_CHECK_FOR_UPDATE" : "Check for Updates",
// Help menu commands
"HELP_MENU" : "Help",
"CMD_ABOUT" : "About",
"CMD_FORUM" : "{APP_NAME} Forum",
// Special commands invoked by the native shell
"CMD_CLOSE_WINDOW" : "Close Window",
@ -211,11 +216,11 @@ define({
"ABOUT" : "About",
"APP_NAME" : "Brackets",
"CLOSE" : "Close",
"ABOUT_TEXT_LINE1" : "sprint 13 experimental build ",
"ABOUT_TEXT_LINE1" : "sprint 14 experimental build ",
"ABOUT_TEXT_LINE3" : "Notices, terms and conditions pertaining to third party software are located at <span class=\"non-clickble-link\">http://www.adobe.com/go/thirdparty/</span> and incorporated by reference herein.",
"ABOUT_TEXT_LINE4" : "Documentation and source at <span class=\"non-clickble-link\">https://github.com/adobe/brackets/</span>",
"UPDATE_NOTIFICATION_TOOLTIP" : "There's a new build of Brackets available! Click here for details.",
"UPDATE_NOTIFICATION_TOOLTIP" : "There's a new build of {APP_NAME} available! Click here for details.",
"UPDATE_AVAILABLE_TITLE" : "Update Available",
"UPDATE_MESSAGE" : "Hey, there's a new build of Brackets available. Here are some of the new features:",
"UPDATE_MESSAGE" : "Hey, there's a new build of {APP_NAME} available. Here are some of the new features:",
"GET_IT_NOW" : "Get it now!"
});

21
src/package.json Normal file
Просмотреть файл

@ -0,0 +1,21 @@
{
"name" : "Brackets",
"version" : "0.14.0-0",
"homepage" : "http://brackets.io",
"issues" :
{
"url" : "http://github.com/adobe/brackets/issues"
},
"repository" :
{
"type" : "git",
"url" : "https://github.com/adobe/brackets.git"
},
"config" :
{
"about_icon" : "styles/images/brackets_icon.svg",
"show_debug_menu" : true,
"enable_jslint" : true,
"forum_url" : "https://groups.google.com/forum/?fromgroups#!forum/brackets-dev"
}
}

Просмотреть файл

@ -319,6 +319,11 @@ define(function (require, exports, module) {
var result = new $.Deferred(),
suppressToggleOpen = false;
// For #1542, make sure the tree is scrolled to the top before refreshing.
// If we try to do this later (e.g. after the tree has been refreshed), it
// doesn't seem to work properly.
$projectTreeContainer.scrollTop(0);
// Instantiate tree widget
// (jsTree is smart enough to replace the old tree if there's already one there)
$projectTreeContainer.hide();

Просмотреть файл

@ -22,7 +22,7 @@
*/
/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global define, $, window */
/*global define, $, window, setTimeout */
/*
* Displays an auto suggest pop-up list of files to allow the user to quickly navigate to a file and lines
@ -267,7 +267,6 @@ define(function (require, exports, module) {
/**
* KeyUp is for cases that handle AFTER a character has been committed to $searchField
*
*/
QuickNavigateDialog.prototype._handleKeyUp = function (e) {
var query = this.$searchField.val();
@ -351,13 +350,27 @@ define(function (require, exports, module) {
// Ty TODO: disabled for now while file switching is disabled in _handleItemFocus
//JSLintUtils.setEnabled(true);
// Make sure Smart Autocomplete knows its popup is getting closed (in cases where there's no
// editor to give focus to below, it won't notice otherwise).
this.$searchField.trigger("lostFocus");
EditorManager.focusEditor();
this.dialog.remove();
// Closing the dialog is a little tricky (see #1384): some Smart Autocomplete code may run later (e.g.
// (because it's a later handler of the event that just triggered _close()), and that code expects to
// find metadata that it stuffed onto the DOM node earlier. But $.remove() strips that metadata.
// So, to hide the dialog immediately it's only safe to remove using raw DOM APIs:
this.dialog[0].parentNode.removeChild(this.dialog[0]);
var self = this;
setTimeout(function () {
// Now that it's safe, call the real jQuery API to clear the metadata & prevent a memory leak
self.dialog.remove();
}, 0);
$(".smart_autocomplete_container").remove();
$(window.document).off("mousedown", this.handleDocumentClick);
$(window.document).off("mousedown", this.handleDocumentMouseDown);
};
function filterFileList(query) {
@ -485,10 +498,11 @@ define(function (require, exports, module) {
}
/**
* Close the dialog when the user clicks outside of it. Note, auto smart complete has a "lostFocus" event that is
* supposed to capture this event, but it also gets triggered on keyUp which doesn't work for quick find.
* Close the dialog when the user clicks outside of it. Smart-autocomplete listens for this and automatically closes its popup,
* but we want to close the whole search "dialog." (And we can't just piggyback on the popup closing event, since there are cases
* where the popup closes that we want the dialog to remain open (e.g. deleting search term via backspace).
*/
QuickNavigateDialog.prototype.handleDocumentClick = function (e) {
QuickNavigateDialog.prototype.handleDocumentMouseDown = function (e) {
if ($(this.dialog).find(e.target).length === 0 && $(".smart_autocomplete_container").find(e.target).length === 0) {
this._close();
}
@ -505,8 +519,8 @@ define(function (require, exports, module) {
}
dialogOpen = true;
this.handleDocumentClick = this.handleDocumentClick.bind(this);
$(window.document).on("mousedown", this.handleDocumentClick);
this.handleDocumentMouseDown = this.handleDocumentMouseDown.bind(this);
$(window.document).on("mousedown", this.handleDocumentMouseDown);
// Ty TODO: disabled for now while file switching is disabled in _handleItemFocus

Просмотреть файл

@ -22,7 +22,7 @@
*/
/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global define */
/*global define, brackets */
/**
* This file provides the interface to user visible strings in Brackets. Code that needs
@ -32,7 +32,18 @@
*/
define(function (require, exports, module) {
"use strict";
var strings = require("i18n!nls/strings"),
Global = require("utils/Global"),
StringUtils = require("utils/StringUtils");
strings.APP_NAME = brackets.metadata.name || strings.APP_NAME;
// Convert {APP_NAME}
Object.keys(strings).forEach(function (key) {
strings[key] = strings[key].replace(/\{APP_NAME\}/g, strings.APP_NAME);
});
module.exports = require("i18n!nls/strings");
module.exports = strings;
});

Просмотреть файл

@ -105,16 +105,7 @@ a, img {
.vbox;
.box-pack(center);
.box-align(center);
background-color: @background-color-2;
#not-editor-content {
color: @background-color-1;
font-size: 350px;
line-height: normal;
margin-top: -0.25em;
text-shadow: 0 1px @bc-black;
opacity: 0.30;
}
background: @background-color-2 url('images/no_content_bg.svg') no-repeat center 45%;
}
}

Просмотреть файл

@ -422,7 +422,7 @@
h2 {
font-weight: normal;
font-size: 25px;
margin-bottom: -8px;
margin-bottom: -4px;
margin-top: 3px;
}
.dialog-message {

Просмотреть файл

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="116px" height="55px" viewBox="0 0 116 55" enable-background="new 0 0 116 55" xml:space="preserve">
<g opacity="0.5">
<g>
<path fill="#FFFFFF" d="M45,1H9c-4.951,0-9,4.05-9,9v36c0,4.95,4.049,9,9,9h36c4.949,0,9-4.05,9-9V10C54,5.05,49.949,1,45,1z
M47.25,43.75c0,2.475-2.025,4.5-4.5,4.5h-31.5c-2.475,0-4.5-2.025-4.5-4.5v-31.5c0-2.476,2.025-4.5,4.5-4.5h31.5
c2.475,0,4.5,2.024,4.5,4.5V43.75z"/>
<g>
<g>
<g>
<path fill="#FFFFFF" d="M25.312,15.344v5.906h-5.906v13.5h5.906v5.906H13.5V15.344H25.312z"/>
</g>
<g>
<path fill="#FFFFFF" d="M40.5,15.344v25.312H28.688V34.75h5.906v-13.5h-5.906v-5.906H40.5z"/>
</g>
</g>
</g>
</g>
</g>
<g>
<g>
<path fill="#D9D9D9" d="M45,0H9C4.049,0,0,4.05,0,9v36c0,4.95,4.049,9,9,9h36c4.949,0,9-4.05,9-9V9C54,4.05,49.949,0,45,0z
M47.25,42.75c0,2.475-2.025,4.5-4.5,4.5h-31.5c-2.475,0-4.5-2.025-4.5-4.5v-31.5c0-2.476,2.025-4.5,4.5-4.5h31.5
c2.475,0,4.5,2.024,4.5,4.5V42.75z"/>
<g>
<g>
<g>
<path fill="#D9D9D9" d="M25.312,14.344v5.906h-5.906v13.5h5.906v5.906H13.5V14.344H25.312z"/>
</g>
<g>
<path fill="#D9D9D9" d="M40.5,14.344v25.312H28.688V33.75h5.906v-13.5h-5.906v-5.906H40.5z"/>
</g>
</g>
</g>
</g>
</g>
<g opacity="0.5">
<g>
<path fill="#FFFFFF" d="M71.768,3.734c1.596,0,2.897,0.546,3.947,1.428l-1.47,2.478c-0.672-0.462-1.428-0.798-2.352-0.798
c-1.974,0-3.233,1.554-3.233,4.031c0,2.688,1.176,4.115,3.527,4.115c0.882,0,1.638-0.504,2.226-0.966l1.554,2.436
c-1.092,1.092-2.646,1.638-4.115,1.638c-3.905,0-6.887-2.436-6.887-7.223C64.965,6.38,67.988,3.734,71.768,3.734z"/>
<path fill="#FFFFFF" d="M76.725,10.873c0-4.493,2.688-7.139,6.467-7.139s6.467,2.667,6.467,7.139c0,4.493-2.688,7.223-6.467,7.223
S76.725,15.366,76.725,10.873z M85.963,10.873c0-2.478-1.134-4.031-2.771-4.031s-2.771,1.554-2.771,4.031s1.134,4.115,2.771,4.115
S85.963,13.351,85.963,10.873z"/>
<path fill="#FFFFFF" d="M92.265,3.986h4.241c4.157,0,7.013,2.058,7.013,6.887s-2.855,6.971-6.803,6.971h-4.451V3.986z
M96.296,14.946c1.974,0,3.527-0.882,3.527-4.073s-1.554-3.989-3.527-3.989h-0.42v8.062H96.296z"/>
<path fill="#FFFFFF" d="M106.124,3.986h8.986V7.01h-5.375v2.226h4.619v3.023h-4.619v2.562h5.585v3.023h-9.196V3.986z"/>
<path fill="#FFFFFF" d="M68.156,25.01h-3.653v-3.023h10.918v3.023h-3.653v10.834h-3.611V25.01z"/>
<path fill="#FFFFFF" d="M77.564,21.986h3.611v5.165h4.367v-5.165h3.611v13.857h-3.611v-5.543h-4.367v5.543h-3.611V21.986z"/>
<path fill="#FFFFFF" d="M92.349,21.986h8.986v3.023H95.96v2.226h4.619v3.023H95.96v2.562h5.585v3.023h-9.196V21.986z"/>
<path fill="#FFFFFF" d="M64.167,39.986h3.695l0.756,6.173l0.462,4.283h0.084l0.756-4.283l1.302-6.173h3.023l1.302,6.173
l0.756,4.283h0.084l0.462-4.283l0.756-6.173h3.443L78.78,53.844h-4.577l-1.134-5.627l-0.42-2.981h-0.084l-0.42,2.981l-1.092,5.627
h-4.493L64.167,39.986z"/>
<path fill="#FFFFFF" d="M82.856,39.986h8.986v3.023h-5.375v2.226h4.619v3.023h-4.619v2.562h5.585v3.023h-9.196V39.986z"/>
<path fill="#FFFFFF" d="M94.784,39.986h5.039c2.855,0,5.165,0.882,5.165,3.569c0,1.176-0.63,2.394-2.058,2.897v0.084
c1.806,0.462,2.688,1.554,2.688,3.275c0,2.813-2.436,4.031-5.375,4.031h-5.459V39.986z M99.571,45.487
c1.344,0,1.89-0.588,1.89-1.428s-0.546-1.302-1.89-1.302h-1.176v2.729H99.571z M99.991,51.072c1.428,0,2.1-0.588,2.1-1.596
s-0.672-1.47-2.1-1.47h-1.596v3.065H99.991z"/>
</g>
</g>
<g>
<g>
<path fill="#D9D9D9" d="M71.768,2.734c1.596,0,2.897,0.546,3.947,1.428l-1.47,2.478c-0.672-0.462-1.428-0.798-2.352-0.798
c-1.974,0-3.233,1.554-3.233,4.031c0,2.688,1.176,4.115,3.527,4.115c0.882,0,1.638-0.504,2.226-0.966l1.554,2.436
c-1.092,1.092-2.646,1.638-4.115,1.638c-3.905,0-6.887-2.436-6.887-7.223C64.965,5.38,67.988,2.734,71.768,2.734z"/>
<path fill="#D9D9D9" d="M76.725,9.873c0-4.493,2.688-7.139,6.467-7.139s6.467,2.667,6.467,7.139c0,4.493-2.688,7.223-6.467,7.223
S76.725,14.366,76.725,9.873z M85.963,9.873c0-2.478-1.134-4.031-2.771-4.031S80.42,7.396,80.42,9.873s1.134,4.115,2.771,4.115
S85.963,12.351,85.963,9.873z"/>
<path fill="#D9D9D9" d="M92.265,2.986h4.241c4.157,0,7.013,2.058,7.013,6.887s-2.855,6.971-6.803,6.971h-4.451V2.986z
M96.296,13.946c1.974,0,3.527-0.882,3.527-4.073s-1.554-3.989-3.527-3.989h-0.42v8.062H96.296z"/>
<path fill="#D9D9D9" d="M106.124,2.986h8.986V6.01h-5.375v2.226h4.619v3.023h-4.619v2.562h5.585v3.023h-9.196V2.986z"/>
<path fill="#D9D9D9" d="M68.156,24.01h-3.653v-3.023h10.918v3.023h-3.653v10.834h-3.611V24.01z"/>
<path fill="#D9D9D9" d="M77.564,20.986h3.611v5.165h4.367v-5.165h3.611v13.857h-3.611v-5.543h-4.367v5.543h-3.611V20.986z"/>
<path fill="#D9D9D9" d="M92.349,20.986h8.986v3.023H95.96v2.226h4.619v3.023H95.96v2.562h5.585v3.023h-9.196V20.986z"/>
<path fill="#D9D9D9" d="M64.167,38.986h3.695l0.756,6.173l0.462,4.283h0.084l0.756-4.283l1.302-6.173h3.023l1.302,6.173
l0.756,4.283h0.084l0.462-4.283l0.756-6.173h3.443L78.78,52.844h-4.577l-1.134-5.627l-0.42-2.981h-0.084l-0.42,2.981l-1.092,5.627
h-4.493L64.167,38.986z"/>
<path fill="#D9D9D9" d="M82.856,38.986h8.986v3.023h-5.375v2.226h4.619v3.023h-4.619v2.562h5.585v3.023h-9.196V38.986z"/>
<path fill="#D9D9D9" d="M94.784,38.986h5.039c2.855,0,5.165,0.882,5.165,3.569c0,1.176-0.63,2.394-2.058,2.897v0.084
c1.806,0.462,2.688,1.554,2.688,3.275c0,2.813-2.436,4.031-5.375,4.031h-5.459V38.986z M99.571,44.487
c1.344,0,1.89-0.588,1.89-1.428s-0.546-1.302-1.89-1.302h-1.176v2.729H99.571z M99.991,50.072c1.428,0,2.1-0.588,2.1-1.596
s-0.672-1.47-2.1-1.47h-1.596v3.065H99.991z"/>
</g>
</g>
</svg>

После

Ширина:  |  Высота:  |  Размер: 5.8 KiB

Просмотреть файл

@ -34,6 +34,8 @@
define(function (require, exports, module) {
"use strict";
var packageJSON = require("text!package.json");
// Define core brackets namespace if it isn't already defined
//
// We can't simply do 'brackets = {}' to define it in the global namespace because
@ -47,6 +49,14 @@ define(function (require, exports, module) {
if (!global.brackets) {
global.brackets = {};
}
// Parse src/config.json
try {
global.brackets.metadata = JSON.parse(packageJSON);
global.brackets.config = global.brackets.metadata.config;
} catch (err) {
console.log(err);
}
// Uncomment the following line to force all low level file i/o routines to complete
// asynchronously. This should only be done for testing/debugging.

Просмотреть файл

@ -35,11 +35,10 @@ define(function (require, exports, module) {
NativeApp = require("utils/NativeApp"),
PreferencesManager = require("preferences/PreferencesManager"),
Strings = require("strings"),
StringUtils = require("utils/StringUtils"),
BuildNumberJSON = require("text!buildNumber.json");
StringUtils = require("utils/StringUtils");
// Current build number.
var _buildNumber = JSON.parse(BuildNumberJSON).buildNumber;
// Extract current build number from package.json version field 0.0.0-0
var _buildNumber = /-([0-9]+)/.exec(brackets.metadata.version)[1];
// PreferenceStorage
var _prefs = PreferencesManager.getPreferenceStorage(module.id, {lastNotifiedBuildNumber: 0});
@ -331,11 +330,13 @@ define(function (require, exports, module) {
})
.fail(function () {
// Error fetching the update data. If this is a forced check, alert the user
Dialogs.showModalDialog(
Dialogs.DIALOG_ID_ERROR,
Strings.ERROR_FETCHING_UPDATE_INFO_TITLE,
Strings.ERROR_FETCHING_UPDATE_INFO_MSG
);
if (force) {
Dialogs.showModalDialog(
Dialogs.DIALOG_ID_ERROR,
Strings.ERROR_FETCHING_UPDATE_INFO_TITLE,
Strings.ERROR_FETCHING_UPDATE_INFO_MSG
);
}
result.reject();
});

Просмотреть файл

@ -44,6 +44,7 @@ define(function (require, exports, module) {
// TODO: (issue #258) In future, we should templatize the HTML for the dialogs rather than having
// it live directly in the HTML.
var DIALOG_ID_ERROR = "error-dialog",
DIALOG_ID_INFO = "error-dialog", // uses the same template for now--could be different in future
DIALOG_ID_SAVE_CLOSE = "save-close-dialog",
DIALOG_ID_EXT_CHANGED = "ext-changed-dialog",
DIALOG_ID_EXT_DELETED = "ext-deleted-dialog",
@ -218,6 +219,7 @@ define(function (require, exports, module) {
exports.DIALOG_BTN_DOWNLOAD = DIALOG_BTN_DOWNLOAD;
exports.DIALOG_ID_ERROR = DIALOG_ID_ERROR;
exports.DIALOG_ID_INFO = DIALOG_ID_INFO;
exports.DIALOG_ID_SAVE_CLOSE = DIALOG_ID_SAVE_CLOSE;
exports.DIALOG_ID_EXT_CHANGED = DIALOG_ID_EXT_CHANGED;
exports.DIALOG_ID_EXT_DELETED = DIALOG_ID_EXT_DELETED;

Просмотреть файл

@ -40,22 +40,17 @@ define(function (require, exports, module) {
*
* @param {!jQuery} $popUp jQuery object for the DOM element pop-up
* @param {function} removeHandler Pop-up specific remove (e.g. display:none or DOM removal)
* @param {?Boolean} autoAddRemove - Specify true to indicate the PopUpManager should
* add/remove the popup from the DOM when the popup is open/closed. Specify false
* when the popup is either always persistant in the DOM or the add/remove is handled
* external to the PopupManager
* @param {?Boolean} autoRemove - Specify true to indicate the PopUpManager should
* remove the popup from the _popUps array when the popup is closed. Specify false
* when the popup is always persistant in the _popUps array.
*
*/
function addPopUp($popUp, removeHandler, autoAddRemove) {
autoAddRemove = autoAddRemove || false;
function addPopUp($popUp, removeHandler, autoRemove) {
autoRemove = autoRemove || false;
_popUps.push($popUp[0]);
$popUp.data("PopUpManager-autoAddRemove", autoAddRemove);
$popUp.data("PopUpManager-autoRemove", autoRemove);
$popUp.data("PopUpManager-removeHandler", removeHandler);
if (autoAddRemove) {
$(window.document.body).append($popUp);
}
}
/**
@ -65,18 +60,23 @@ define(function (require, exports, module) {
* @param {!jQuery} $popUp
*/
function removePopUp($popUp) {
var index = _popUps.indexOf($popUp[0]);
if (index >= 0) {
var autoAddRemove = $popUp.data("PopUpManager-autoAddRemove"),
removeHandler = $popUp.data("PopUpManager-removeHandler");
if (removeHandler && $popUp.find(":visible").length > 0) {
// check visible first to help protect against recursive calls
// via removeHandler
if ($popUp.find(":visible").length > 0) {
var removeHandler = $popUp.data("PopUpManager-removeHandler");
if (removeHandler) {
removeHandler();
}
if (autoAddRemove) {
}
// check index after removeHandler is done processing to protect
// against recursive calls
var index = _popUps.indexOf($popUp[0]);
if (index >= 0) {
var autoRemove = $popUp.data("PopUpManager-autoRemove");
if (autoRemove) {
$popUp.remove();
_popUps = _popUps.slice(index);
_popUps.splice(index, 1);
}
}
}

Просмотреть файл

@ -163,7 +163,7 @@ define(function (require, exports, module) {
[ '</body>', '</html>']);
var tag = HTMLUtils.getTagInfo(myEditor, pos);
expect(tag).toEqual(HTMLUtils.createTagInfo(HTMLUtils.ATTR_VALUE, 0, "p", "class", "foo", true, '"', true));
expect(tag).toEqual(HTMLUtils.createTagInfo(HTMLUtils.ATTR_VALUE, -1, "p", "class", "foo", true, '"', true));
});
it("should find the tagname as it's typed", function () {

Просмотреть файл

@ -142,6 +142,9 @@ define(function (require, exports, module) {
// disable loading of sample project
params.put("skipSampleProjectLoad", true);
// disable initial dialog for live development
params.put("skipLiveDevelopmentInfo", true);
_testWindow = window.open(getBracketsSourceRoot() + "/index.html?" + params.toString(), "_blank", optionsStr);
_testWindow.executeCommand = function executeCommand(cmd, args) {

Просмотреть файл

@ -0,0 +1,18 @@
@ECHO OFF
REM - Check for parameter
IF %1.==. GOTO Error
REM - Remove 'dev' directory
ECHO Removing %1\dev
rmdir %1\dev
GOTO Exit
:Error
ECHO Usage: restore_installed_build.bat application_path
ECHO Restore Brackets to use the installed HTML/CSS/JS files.
ECHO Parameters: application_path - path that contains the Brackets application
ECHO Example: restore_installed_build.bat "c:\Program Files (x86)\Brackets Sprint 14"
:Exit

Просмотреть файл

@ -0,0 +1,21 @@
#!/bin/sh
# Make sure the appname was passed in and is valid
if [[ ${1} == "" ]]; then
echo "Usage: restore_installed_build.sh <application>"
echo "Restore Brackets to use the installed HTML/CSS/JS files."
echo ""
echo "Parameters: application - full path to the Brackets application"
echo "Example: ./restore_installed_build.sh \"/Applications/Brackets Sprint 14.app\""
exit;
fi
if [ ! -d ${1} ]; then
echo "$1 not found."
exit;
fi
if [ -d "${1}/Contents/dev" ]; then
rm "${1}/Contents/dev"
echo "$1 has been restored to the installed configuration."
fi

Просмотреть файл

@ -0,0 +1,35 @@
@ECHO OFF
REM - Use full path of this batch file to determine root directory
set root_path=%~f0
set root_path=%root_path:~0,-27%
REM - Check for OS. This script works in Vista or later.
ver | findstr /i "5\.1\." > nul
IF %ERRORLEVEL% EQU 0 GOTO XPNotSupported
REM - Check for parameter
IF %1.==. GOTO Error
REM - Remove existing 'dev' directory (if present)
rmdir %1\dev
REM - Make symlink
mklink /d %1\dev %root_path%
GOTO Exit
:Error
ECHO Usage: setup_for_hacking.bat application_path
ECHO Setup Brackets to use the HTML/CSS/JS files pulled from GitHub.
ECHO Parameters: application_path - path that contains the Brackets application
ECHO Example: setup_for_hacking.bat "c:\Program Files (x86)\Brackets Sprint 14"
GOTO Exit
:XPNotSupported
ECHO Sorry, this script doesn't run in Windows XP.
ECHO To enable hacking, make a shortcut to
ECHO %root_path%, name it
ECHO "dev", and put it next to your Brackets.exe file
:Exit

37
tools/setup_for_hacking.sh Executable file
Просмотреть файл

@ -0,0 +1,37 @@
#!/bin/sh
# Make sure the appname was passed in and is valid
if [[ ${1} == "" ]]; then
echo "Usage: setup_for_hacking.sh <application>"
echo "Setup Brackets to use the HTML/CSS/JS files pulled from GitHub."
echo ""
echo "Parameters: application - full path to the Brackets application"
echo "Example: ./setup_for_hacking.sh \"/Applications/Brackets Sprint 14.app\""
exit;
fi
if [ ! -d ${1} ]; then
echo "$1 not found."
exit;
fi
# Get the full path of this script
if [[ ${0} == /* ]]; then
full_path="$0"
else
full_path="${PWD}/${0#./}"
fi;
# Remove /tools/setup_for_hacking.sh to get the root directory
root_dir=${full_path%/*/*}
# Remove existing "dev" symlink, if present
if [ -d "${1}/Contents/dev" ]; then
rm "${1}/Contents/dev"
fi
# Make new symlink
ln -s "$root_dir" "${1}/Contents/dev"
echo "Brackets will now use the files in $root_dir"
echo "Run the restore_installed_build.sh script to revert back to the installed source files"