Skip to content

Commit fe94d19

Browse files
committed
Merge remote-tracking branch 'origin/master' into irichter/code-inspection-improvements
* origin/master: (187 commits) improve comments update comments Fix a comment typo and just log the unhandled exception instead of trying to reject the promise, which probably won't work anyway. Enable Quick Docs for LESS Return a promise from ProjectManager.getAllFiles that is resiliant to misbehaving done handlers Updated by ALF automation. Revert LiveDev timeout changes Use Brackets shell for copying files to reduce the number of external watcher notifications and increase timeouts Don't refresh the file tree on change events for directories outside of the project root, but when we do refresh the file tree, also clear the change queue (using a new PromiseQueue.removeAll method) and use a debounced refreshFileTree call fix check for added and removed files in fs change event handler always hide dirty dot if there is no doc Fix selection update after fs change event. Remove unnecessary updates when no added or removed files are present. backout change for dismissing list Right aligning numbers column. Removed most inline css. Adding LOCALE_KO Initial commit. Fixed some dutch spelling/translation errors. Bump up timeouts to account for additional Project Manager synchronization Made canvas height 300 to stop weird rounding. ... Conflicts: src/language/CodeInspection.js
2 parents 12d33b9 + f36995c commit fe94d19

107 files changed

Lines changed: 7800 additions & 1678 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Gruntfile.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,29 @@ module.exports = function (grunt) {
6464
'LiveDevelopment/launch.html'
6565
]
6666
},
67+
/* node domains are not minified and must be copied to dist */
68+
{
69+
expand: true,
70+
dest: 'dist/',
71+
cwd: 'src/',
72+
src: [
73+
'extensibility/node/**',
74+
'!extensibility/node/spec/**',
75+
'filesystem/impls/appshell/node/**',
76+
'!filesystem/impls/appshell/node/spec/**'
77+
]
78+
},
6779
/* extensions and CodeMirror modes */
6880
{
6981
expand: true,
7082
dest: 'dist/',
7183
cwd: 'src/',
7284
src: [
73-
'extensibility/**/*',
7485
'!extensions/default/*/unittest-files/**/*',
7586
'!extensions/default/*/unittests.js',
7687
'extensions/default/*/**/*',
88+
'extensions/dev/*',
89+
'extensions/samples/**/*',
7790
'thirdparty/CodeMirror2/addon/{,*/}*',
7891
'thirdparty/CodeMirror2/keymap/{,*/}*',
7992
'thirdparty/CodeMirror2/lib/{,*/}*',

README.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,9 @@ How to install and run Brackets
2424
-------------------------------
2525

2626

27-
#### Brackets isn't ready for general use yet.
28-
29-
Some of the features you would expect in a code editor are missing, and some existing features might be
30-
incomplete or not as useful as you'd want. That said, what's there is reasonably stable—the
31-
Brackets team uses Brackets to develop Brackets full time. So feel free to give it a spin and let us know
32-
what's missing!
27+
#### Brackets is getting close to 1.0
3328

29+
Together with your contributions, we're getting close to our first release condidate. What's there is reasonably stable, and the Brackets team even uses Brackets to develop Brackets full time. So feel free to give it a spin and let us know what's missing! Being built on JavaScript, it's easy to make your own changes, and we give priority to integrating your pull requests back into Brackets!
3430

3531
#### Download
3632

samples/el/Getting Started/index.html

Lines changed: 187 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
html {
2+
background-color: #eeeeee;
3+
background-image: linear-gradient(bottom, rgb(238,238,238) 18%, rgb(153,153,153) 59%, rgb(238,238,238) 80%);
4+
background-image: -o-linear-gradient(bottom, rgb(238,238,238) 18%, rgb(153,153,153) 59%, rgb(238,238,238) 80%);
5+
background-image: -moz-linear-gradient(bottom, rgb(238,238,238) 18%, rgb(153,153,153) 59%, rgb(238,238,238) 80%);
6+
background-image: -webkit-linear-gradient(bottom, rgb(238,238,238) 18%, rgb(153,153,153) 59%, rgb(238,238,238) 80%);
7+
background-image: -ms-linear-gradient(bottom, rgb(238,238,238) 18%, rgb(153,153,153) 59%, rgb(238,238,238) 80%);
8+
}
9+
10+
body {
11+
margin: 0 auto;
12+
padding: 2em;
13+
max-width: 800px;
14+
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
15+
font-size: 14px;
16+
line-height: 1.5em;
17+
color: #333333;
18+
background-color: #ffffff;
19+
-webkit-box-shadow: 0 0 12px rgba(0, 0, 0, 0.4);
20+
-moz-box-shadow: 0 0 12px rgba(0, 0, 0, 0.4);
21+
box-shadow: 0 0 12px rgba(0, 0, 0, 0.4);
22+
}
23+
24+
h1, h2, h3, h4, h5, h6 {
25+
line-height: 1.3em;
26+
}
27+
28+
samp
29+
{
30+
/* hide <samp> from the browser so we can show cool features in Edge Code */
31+
display: none;
32+
}
33+
34+
img
35+
{
36+
background: dimgray;
37+
border: 1px solid black;
38+
border-radius: 2px;
39+
padding: 15px 10px 10px;
40+
margin: 10px 0;
41+
max-width: 95%;
42+
}
308 KB
Loading

src/command/Menus.js

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ define(function (require, exports, module) {
3737
StringUtils = require("utils/StringUtils"),
3838
CommandManager = require("command/CommandManager"),
3939
PopUpManager = require("widgets/PopUpManager"),
40-
ViewUtils = require("utils/ViewUtils"),
41-
CollectionUtils = require("utils/CollectionUtils");
40+
ViewUtils = require("utils/ViewUtils");
4241

4342
/**
4443
* Brackets Application Menu Constants
@@ -497,7 +496,7 @@ define(function (require, exports, module) {
497496
return;
498497
}
499498
} else {
500-
brackets.app.removeMenuItem(menuItemID, function (err) {
499+
brackets.app.removeMenuItem(menuItem.dividerId, function (err) {
501500
if (err) {
502501
console.error("removeMenuDivider() -- divider not found: %s (error: %s)", menuItemID, err);
503502
}
@@ -643,7 +642,9 @@ define(function (require, exports, module) {
643642
}
644643

645644
// Initialize MenuItem state
646-
if (!menuItem.isDivider) {
645+
if (menuItem.isDivider) {
646+
menuItem.dividerId = commandID;
647+
} else {
647648
if (keyBindings) {
648649
// Add key bindings. The MenuItem listens to the Command object to update MenuItem DOM with shortcuts.
649650
if (!Array.isArray(keyBindings)) {
@@ -947,7 +948,7 @@ define(function (require, exports, module) {
947948
// Remove all of the menu items in the menu
948949
menu = getMenu(id);
949950

950-
CollectionUtils.forEach(menuItemMap, function (value, key) {
951+
_.forEach(menuItemMap, function (value, key) {
951952
if (key.substring(0, id.length) === id) {
952953
if (value.isDivider) {
953954
menu.removeMenuDivider(key);
@@ -1050,18 +1051,24 @@ define(function (require, exports, module) {
10501051
closeAll();
10511052

10521053
// adjust positioning so menu is not clipped off bottom or right
1053-
var bottomOverhang = posTop + 25 + $menuWindow.height() - $window.height();
1054-
if (bottomOverhang > 0) {
1055-
posTop = Math.max(0, posTop - bottomOverhang);
1054+
var elementRect = {
1055+
top: posTop,
1056+
left: posLeft,
1057+
height: $menuWindow.height() + 25,
1058+
width: $menuWindow.width()
1059+
},
1060+
clip = ViewUtils.getElementClipSize($window, elementRect);
1061+
1062+
if (clip.bottom > 0) {
1063+
posTop = Math.max(0, posTop - clip.bottom);
10561064
}
10571065
posTop -= 30; // shift top for hidden parent element
10581066
posLeft += 5;
10591067

1060-
var rightOverhang = posLeft + $menuWindow.width() - $window.width();
1061-
if (rightOverhang > 0) {
1062-
posLeft = Math.max(0, posLeft - rightOverhang);
1068+
if (clip.right > 0) {
1069+
posLeft = Math.max(0, posLeft - clip.right);
10631070
}
1064-
1071+
10651072
// open the context menu at final location
10661073
$menuAnchor.addClass("open")
10671074
.css({"left": posLeft, "top": posTop});

src/document/DocumentCommandHandlers.js

Lines changed: 80 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,20 @@ define(function (require, exports, module) {
8080

8181
function updateTitle() {
8282
var currentDoc = DocumentManager.getCurrentDocument(),
83+
currentlyViewedPath = EditorManager.getCurrentlyViewedPath(),
8384
windowTitle = brackets.config.app_title;
8485

8586
if (!brackets.nativeMenus) {
86-
if (currentDoc) {
87+
if (currentlyViewedPath) {
8788
_$title.text(_currentTitlePath);
88-
_$title.attr("title", currentDoc.file.fullPath);
89-
// dirty dot is always in DOM so layout doesn't change, and visibility is toggled
90-
_$dirtydot.css("visibility", (currentDoc.isDirty) ? "visible" : "hidden");
89+
_$title.attr("title", currentlyViewedPath);
90+
if (currentDoc) {
91+
// dirty dot is always in DOM so layout doesn't change, and visibility is toggled
92+
_$dirtydot.css("visibility", (currentDoc.isDirty) ? "visible" : "hidden");
93+
} else {
94+
// hide dirty dot if there is no document
95+
_$dirtydot.css("visibility", "hidden");
96+
}
9197
} else {
9298
_$title.text("");
9399
_$title.attr("title", "");
@@ -111,9 +117,15 @@ define(function (require, exports, module) {
111117
}
112118

113119
// build shell/browser window title, e.g. "• file.html — Brackets"
114-
if (currentDoc) {
120+
if (currentlyViewedPath) {
115121
windowTitle = StringUtils.format(WINDOW_TITLE_STRING, _currentTitlePath, windowTitle);
122+
}
123+
124+
if (currentDoc) {
116125
windowTitle = (currentDoc.isDirty) ? "• " + windowTitle : windowTitle;
126+
} else {
127+
// hide dirty dot if there is no document
128+
_$dirtydot.css("visibility", "hidden");
117129
}
118130

119131
// update shell/browser window title
@@ -150,7 +162,12 @@ define(function (require, exports, module) {
150162
if (newDocument) {
151163
_currentTitlePath = _shortTitleForDocument(newDocument);
152164
} else {
153-
_currentTitlePath = null;
165+
var currentlyViewedFilePath = EditorManager.getCurrentlyViewedPath();
166+
if (currentlyViewedFilePath) {
167+
_currentTitlePath = ProjectManager.makeProjectRelativeIfPossible(currentlyViewedFilePath);
168+
} else {
169+
_currentTitlePath = null;
170+
}
154171
}
155172

156173
// Update title text & "dirty dot" display
@@ -522,13 +539,16 @@ define(function (require, exports, module) {
522539
);
523540
}
524541

542+
543+
525544
/**
526545
* Saves a document to its existing path. Does NOT support untitled documents.
527546
* @param {!Document} docToSave
547+
* @param {boolean=} force Ignore CONTENTS_MODIFIED errors from the FileSystem
528548
* @return {$.Promise} a promise that is resolved with the File of docToSave (to mirror
529549
* the API of _doSaveAs()). Rejected in case of IO error (after error dialog dismissed).
530550
*/
531-
function doSave(docToSave) {
551+
function doSave(docToSave, force) {
532552
var result = new $.Deferred(),
533553
file = docToSave.file;
534554

@@ -538,18 +558,61 @@ define(function (require, exports, module) {
538558
result.reject(error);
539559
});
540560
}
561+
562+
function handleContentsModified() {
563+
Dialogs.showModalDialog(
564+
DefaultDialogs.DIALOG_ID_ERROR,
565+
Strings.EXT_MODIFIED_TITLE,
566+
StringUtils.format(
567+
Strings.EXT_MODIFIED_WARNING,
568+
StringUtils.breakableUrl(docToSave.file.fullPath)
569+
),
570+
[
571+
{
572+
className : Dialogs.DIALOG_BTN_CLASS_LEFT,
573+
id : Dialogs.DIALOG_BTN_SAVE_AS,
574+
text : Strings.SAVE_AS
575+
},
576+
{
577+
className : Dialogs.DIALOG_BTN_CLASS_NORMAL,
578+
id : Dialogs.DIALOG_BTN_CANCEL,
579+
text : Strings.CANCEL
580+
},
581+
{
582+
className : Dialogs.DIALOG_BTN_CLASS_PRIMARY,
583+
id : Dialogs.DIALOG_BTN_OK,
584+
text : Strings.SAVE_AND_OVERWRITE
585+
}
586+
]
587+
)
588+
.done(function (id) {
589+
if (id === Dialogs.DIALOG_BTN_CANCEL) {
590+
result.reject();
591+
} else if (id === Dialogs.DIALOG_BTN_OK) {
592+
// Re-do the save, ignoring any CONTENTS_MODIFIED errors
593+
doSave(docToSave, true).then(result.resolve, result.reject);
594+
} else if (id === Dialogs.DIALOG_BTN_SAVE_AS) {
595+
// Let the user choose a different path at which to write the file
596+
exports.handleFileSaveAs({doc: docToSave}).then(result.resolve, result.reject);
597+
}
598+
});
599+
}
541600

542601
if (docToSave.isDirty) {
543602
var writeError = false;
544603

545604
// We don't want normalized line endings, so it's important to pass true to getText()
546-
FileUtils.writeText(file, docToSave.getText(true))
605+
FileUtils.writeText(file, docToSave.getText(true), force)
547606
.done(function () {
548607
docToSave.notifySaved();
549608
result.resolve(file);
550609
})
551610
.fail(function (err) {
552-
handleError(err);
611+
if (err === FileSystemError.CONTENTS_MODIFIED) {
612+
handleContentsModified();
613+
} else {
614+
handleError(err);
615+
}
553616
});
554617
} else {
555618
result.resolve(file);
@@ -651,7 +714,12 @@ define(function (require, exports, module) {
651714

652715
// First, write document's current text to new file
653716
newFile = FileSystem.getFileForPath(path);
654-
FileUtils.writeText(newFile, doc.getText()).done(function () {
717+
718+
// Save as warns you when you're about to overwrite a file, so we
719+
// explictly allow "blind" writes to the filesystem in this case,
720+
// ignoring warnings about the contents being modified outside of
721+
// the editor.
722+
FileUtils.writeText(newFile, doc.getText(), true).done(function () {
655723
// Add new file to project tree
656724
ProjectManager.refreshFileTree().done(function () {
657725
// If there were unsaved changes before Save As, they don't stay with the old
@@ -1352,7 +1420,8 @@ define(function (require, exports, module) {
13521420

13531421
// Listen for changes that require updating the editor titlebar
13541422
$(DocumentManager).on("dirtyFlagChange", handleDirtyChange);
1355-
$(DocumentManager).on("currentDocumentChange fileNameChange", updateDocumentTitle);
1423+
$(DocumentManager).on("fileNameChange", updateDocumentTitle);
1424+
$(EditorManager).on("currentlyViewedFileChange", updateDocumentTitle);
13561425

13571426
// Reset the untitled document counter before changing projects
13581427
$(ProjectManager).on("beforeProjectClose", function () { _nextUntitledIndexToUse = 1; });

src/document/InMemoryFile.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ define(function (require, exports, module) {
5151
InMemoryFile.prototype.constructor = InMemoryFile;
5252
InMemoryFile.prototype.parentClass = File.prototype;
5353

54-
5554
// Stub out invalid calls inherited from File
5655

5756
/**

src/editor/CSSInlineEditor.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -248,20 +248,24 @@ define(function (require, exports, module) {
248248
.appendTo($("body"));
249249

250250
var toggleOffset = $newRuleButton.offset(),
251-
$window = $(window),
252251
posLeft = toggleOffset.left,
253252
posTop = toggleOffset.top + $newRuleButton.outerHeight(),
254-
bottomOverhang = posTop + $dropdown.height() - $window.height(),
255-
rightOverhang = posLeft + $dropdown.width() - $window.width();
253+
elementRect = {
254+
top: posTop,
255+
left: posLeft,
256+
height: $dropdown.height(),
257+
width: $dropdown.width()
258+
},
259+
clip = ViewUtils.getElementClipSize($(window), elementRect);
256260

257-
if (bottomOverhang > 0) {
261+
if (clip.bottom > 0) {
258262
// Bottom is clipped, so move entire menu above button
259263
posTop = Math.max(0, toggleOffset.top - $dropdown.height() - 4);
260264
}
261265

262-
if (rightOverhang > 0) {
266+
if (clip.right > 0) {
263267
// Right is clipped, so adjust left to fit menu in editor
264-
posLeft = Math.max(0, posLeft - rightOverhang);
268+
posLeft = Math.max(0, posLeft - clip.right);
265269
}
266270

267271
$dropdown.css({

src/editor/Editor.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -986,10 +986,14 @@ define(function (require, exports, module) {
986986
return;
987987
}
988988

989+
// We set clearWhenEmpty: false so that if there's a blank line at the beginning or end of
990+
// the document, and that's the only hidden line, we can still actually hide it. Doing so
991+
// requires us to create a 0-length marked span, which would ordinarily be cleaned up by CM
992+
// if clearWithEmpty is true. See https://groups.google.com/forum/#!topic/codemirror/RB8VNF8ow2w
989993
var value = this._codeMirror.markText(
990994
{line: from, ch: 0},
991995
{line: to - 1, ch: this._codeMirror.getLine(to - 1).length},
992-
{collapsed: true, inclusiveLeft: true, inclusiveRight: true}
996+
{collapsed: true, inclusiveLeft: true, inclusiveRight: true, clearWhenEmpty: false}
993997
);
994998

995999
return value;

0 commit comments

Comments
 (0)