diff --git a/src/document/ChangedDocumentTracker.js b/src/document/ChangedDocumentTracker.js
index b7e95bbc2..4b339ae0a 100644
--- a/src/document/ChangedDocumentTracker.js
+++ b/src/document/ChangedDocumentTracker.js
@@ -40,6 +40,7 @@ define(function (require, exports, module) {
* changed when the Brackets window loses and regains focus. Does not
* read timestamps of files on disk. Clients may optionally track file
* timestamps on disk independently.
+ * @constructor
*/
function ChangedDocumentTracker() {
var self = this;
diff --git a/src/editor/Editor.js b/src/editor/Editor.js
index 8274338b5..2682195b7 100644
--- a/src/editor/Editor.js
+++ b/src/editor/Editor.js
@@ -381,6 +381,12 @@ define(function (require, exports, module) {
var nonWS = lineStr.search(/\S/);
if (nonWS === -1 || nonWS >= cursor.ch) {
+ if (nonWS === -1) {
+ // if the line is all whitespace, move the cursor to the end of the line
+ // before indenting so that embedded whitespace such as indents are not
+ // orphaned to the right of the electric char being inserted
+ this.setCursorPos(cursor.line, this.document.getLine(cursor.line).length);
+ }
// Need to do the auto-indent on a timeout to ensure
// the keypress is handled before auto-indenting.
// This is the same timeout value used by the
diff --git a/src/extensibility/ExtensionManager.js b/src/extensibility/ExtensionManager.js
index 430030861..15a45e393 100644
--- a/src/extensibility/ExtensionManager.js
+++ b/src/extensibility/ExtensionManager.js
@@ -373,11 +373,12 @@ define(function (require, exports, module) {
* Updates an installed extension with the given package file.
* @param {string} id of the extension
* @param {string} packagePath path to the package file
+ * @param {boolean=} keepFile Flag to keep extension package file, default=false
* @return {$.Promise} A promise that's resolved when the extension is updated or
* rejected with an error if there's a problem with the update.
*/
- function update(id, packagePath) {
- return Package.installUpdate(packagePath, id);
+ function update(id, packagePath, keepFile) {
+ return Package.installUpdate(packagePath, id, keepFile);
}
/**
@@ -386,8 +387,11 @@ define(function (require, exports, module) {
*/
function cleanupUpdates() {
Object.keys(_idsToUpdate).forEach(function (id) {
- var filename = _idsToUpdate[id].localPath;
- if (filename) {
+ var installResult = _idsToUpdate[id],
+ keepFile = installResult.keepFile,
+ filename = installResult.localPath;
+
+ if (filename && !keepFile) {
FileSystem.getFileForPath(filename).unlink();
}
});
@@ -461,7 +465,7 @@ define(function (require, exports, module) {
if (!installationResult) {
return;
}
- if (installationResult.localPath) {
+ if (installationResult.localPath && !installationResult.keepFile) {
FileSystem.getFileForPath(installationResult.localPath).unlink();
}
delete _idsToUpdate[id];
@@ -513,7 +517,7 @@ define(function (require, exports, module) {
Object.keys(_idsToUpdate),
function (id) {
var installationResult = _idsToUpdate[id];
- return update(installationResult.name, installationResult.localPath);
+ return update(installationResult.name, installationResult.localPath, installationResult.keepFile);
}
);
}
@@ -571,6 +575,31 @@ define(function (require, exports, module) {
}, []);
}
+ /**
+ * Toggles between truncated and full length extension descriptions
+ * @param {string} id The id of the extension clicked
+ * @param {JQueryElement} $element The DOM element of the extension clicked
+ * @param {boolean} showFull true if full length description should be shown, false for shorten version.
+ */
+ function toggleDescription(id, $element, showFull) {
+ var description, linkTitle,
+ entry = extensions[id];
+
+ // Toggle between appropriate descriptions and link title,
+ // depending on if extension is installed or not
+ if (showFull) {
+ description = entry.installInfo ? entry.installInfo.metadata.description : entry.registryInfo.metadata.description;
+ linkTitle = Strings.VIEW_TRUNCATED_DESCRIPTION;
+ } else {
+ description = entry.installInfo ? entry.installInfo.metadata.shortdescription : entry.registryInfo.metadata.shortdescription;
+ linkTitle = Strings.VIEW_COMPLETE_DESCRIPTION;
+ }
+
+ $element.attr("data-toggle-desc", showFull ? "trunc-desc" : "expand-desc")
+ .attr("title", linkTitle)
+ .prev(".ext-full-description").html(description);
+ }
+
// Listen to extension load and loadFailed events
$(ExtensionLoader)
.on("load", _handleExtensionLoad)
@@ -596,7 +625,7 @@ define(function (require, exports, module) {
exports.updateExtensions = updateExtensions;
exports.getAvailableUpdates = getAvailableUpdates;
exports.cleanAvailableUpdates = cleanAvailableUpdates;
-
+ exports.toggleDescription = toggleDescription;
exports.ENABLED = ENABLED;
exports.START_FAILED = START_FAILED;
diff --git a/src/extensibility/ExtensionManagerDialog.js b/src/extensibility/ExtensionManagerDialog.js
index f50c7203b..392863ef3 100644
--- a/src/extensibility/ExtensionManagerDialog.js
+++ b/src/extensibility/ExtensionManagerDialog.js
@@ -27,8 +27,11 @@
define(function (require, exports, module) {
"use strict";
- var Dialogs = require("widgets/Dialogs"),
+ var _ = require("thirdparty/lodash"),
+ Dialogs = require("widgets/Dialogs"),
DefaultDialogs = require("widgets/DefaultDialogs"),
+ FileSystem = require("filesystem/FileSystem"),
+ FileUtils = require("file/FileUtils"),
Package = require("extensibility/Package"),
Strings = require("strings"),
StringUtils = require("utils/StringUtils"),
@@ -48,6 +51,11 @@ define(function (require, exports, module) {
var _activeTabIndex;
+ function _stopEvent(event) {
+ event.stopPropagation();
+ event.preventDefault();
+ }
+
/**
* @private
* Triggers changes requested by the dialog UI.
@@ -156,6 +164,98 @@ define(function (require, exports, module) {
});
}
+
+ /**
+ * @private
+ * Install extensions from the local file system using the install dialog.
+ * @return {$.Promise}
+ */
+ function _installUsingDragAndDrop() {
+ var installZips = [],
+ updateZips = [],
+ deferred = new $.Deferred(),
+ validatePromise;
+
+ brackets.app.getDroppedFiles(function (err, paths) {
+ if (err) {
+ // Only possible error is invalid params, silently ignore
+ console.error(err);
+ deferred.resolve();
+ return;
+ }
+
+ // Parse zip files and separate new installs vs. updates
+ validatePromise = Async.doInParallel_aggregateErrors(paths, function (path) {
+ var result = new $.Deferred();
+
+ FileSystem.resolve(path, function (err, file) {
+ var extension = FileUtils.getFileExtension(path),
+ isZip = file.isFile && (extension === "zip"),
+ errStr;
+
+ if (err) {
+ errStr = FileUtils.getFileErrorString(err);
+ } else if (!isZip) {
+ errStr = Strings.INVALID_ZIP_FILE;
+ }
+
+ if (errStr) {
+ result.reject(errStr);
+ return;
+ }
+
+ // Call validate() so that we open the local zip file and parse the
+ // package.json. We need the name to detect if this zip will be a
+ // new install or an update.
+ Package.validate(path, { requirePackageJSON: true }).done(function (info) {
+ if (info.errors.length) {
+ result.reject(Package.formatError(info.errors));
+ return;
+ }
+
+ var extensionName = info.metadata.name,
+ extensionInfo = ExtensionManager.extensions[extensionName],
+ isUpdate = extensionInfo && !!extensionInfo.installInfo;
+
+ if (isUpdate) {
+ updateZips.push(file);
+ } else {
+ installZips.push(file);
+ }
+
+ result.resolve();
+ }).fail(function (err) {
+ result.reject(Package.formatError(err));
+ });
+ });
+
+ return result.promise();
+ });
+
+ validatePromise.done(function () {
+ var installPromise = Async.doSequentially(installZips, function (file) {
+ return InstallExtensionDialog.installUsingDialog(file);
+ });
+
+ var updatePromise = installPromise.then(function () {
+ return Async.doSequentially(updateZips, function (file) {
+ return InstallExtensionDialog.updateUsingDialog(file).done(function (result) {
+ ExtensionManager.updateFromDownload(result);
+ });
+ });
+ });
+
+ // InstallExtensionDialog displays it's own errors, always
+ // resolve the outer promise
+ updatePromise.always(deferred.resolve);
+ }).fail(function (errorArray) {
+ deferred.reject(errorArray);
+ });
+ });
+
+ return deferred.promise();
+ }
+
/**
* @private
* Show a dialog that allows the user to browse and manage extensions.
@@ -296,9 +396,7 @@ define(function (require, exports, module) {
// Open dialog to Installed tab if extension updates are available
if ($("#toolbar-extension-manager").hasClass('updatesAvailable')) {
$dlg.find(".nav-tabs a.installed").tab("show");
- }
- // Otherwise show the first tab
- else {
+ } else { // Otherwise show the first tab
$dlg.find(".nav-tabs a:first").tab("show");
}
});
@@ -309,6 +407,86 @@ define(function (require, exports, module) {
InstallExtensionDialog.showDialog().done(ExtensionManager.updateFromDownload);
});
+ // Handle the drag/drop zone
+ var $dropzone = $("#install-drop-zone"),
+ $dropmask = $("#install-drop-zone-mask");
+
+ $dropzone
+ .on("dragover", function (event) {
+ _stopEvent(event);
+
+ if (!event.originalEvent.dataTransfer.files) {
+ return;
+ }
+
+ var items = event.originalEvent.dataTransfer.items,
+ isValidDrop = false;
+
+ isValidDrop = _.every(items, function (item) {
+ if (item.kind === "file") {
+ var entry = item.webkitGetAsEntry(),
+ extension = FileUtils.getFileExtension(entry.fullPath);
+
+ return entry.isFile && extension === "zip";
+ }
+
+ return false;
+ });
+
+ if (isValidDrop) {
+ // Set an absolute width to stabilize the button size
+ $dropzone.width($dropzone.width());
+
+ // Show drop styling and message
+ $dropzone.removeClass("drag");
+ $dropzone.addClass("drop");
+ } else {
+ event.originalEvent.dataTransfer.dropEffect = "none";
+ }
+ })
+ .on("drop", _stopEvent);
+
+ $dropmask
+ .on("dragover", function (event) {
+ _stopEvent(event);
+ event.originalEvent.dataTransfer.dropEffect = "copy";
+ })
+ .on("dragleave", function () {
+ $dropzone.removeClass("drop");
+ $dropzone.addClass("drag");
+ })
+ .on("drop", function (event) {
+ _stopEvent(event);
+
+ if (event.originalEvent.dataTransfer.files) {
+ // Attempt install
+ _installUsingDragAndDrop().fail(function (errorArray) {
+ var message = Strings.INSTALL_EXTENSION_DROP_ERROR;
+
+ message += "
";
+ errorArray.forEach(function (info) {
+ message += "- ";
+ message += StringUtils.breakableUrl(info.item);
+ message += ": " + info.error + "
";
+ });
+ message += "
";
+
+ Dialogs.showModalDialog(
+ DefaultDialogs.DIALOG_ID_ERROR,
+ Strings.EXTENSION_MANAGER_TITLE,
+ message
+ );
+ }).always(function () {
+ $dropzone.removeClass("validating");
+ $dropzone.addClass("drag");
+ });
+
+ // While installing, show validating message
+ $dropzone.removeClass("drop");
+ $dropzone.addClass("validating");
+ }
+ });
+
return new $.Deferred().resolve(dialog).promise();
}
diff --git a/src/extensibility/ExtensionManagerView.js b/src/extensibility/ExtensionManagerView.js
index 95b785db7..e92b17db1 100644
--- a/src/extensibility/ExtensionManagerView.js
+++ b/src/extensibility/ExtensionManagerView.js
@@ -35,7 +35,7 @@ define(function (require, exports, module) {
InstallExtensionDialog = require("extensibility/InstallExtensionDialog"),
LocalizationUtils = require("utils/LocalizationUtils"),
itemTemplate = require("text!htmlContent/extension-manager-view-item.html");
-
+
/**
* Creates a view enabling the user to install and manage extensions. Must be initialized
* with initialize(). When the view is closed, dispose() must be called.
@@ -110,7 +110,7 @@ define(function (require, exports, module) {
* The individual views for each item, keyed by the extension ID.
*/
ExtensionManagerView.prototype._itemViews = null;
-
+
/**
* @private
* Attaches our event handlers. We wait to do this until we've fully fetched the extension list.
@@ -154,6 +154,10 @@ define(function (require, exports, module) {
ExtensionManager.markForRemoval($target.attr("data-extension-id"), true);
} else if ($target.hasClass("undo-update")) {
ExtensionManager.removeUpdate($target.attr("data-extension-id"));
+ } else if ($target.attr("data-toggle-desc") === "expand-desc") {
+ ExtensionManager.toggleDescription($target.attr("data-extension-id"), $target, true);
+ } else if ($target.attr("data-toggle-desc") === "trunc-desc") {
+ ExtensionManager.toggleDescription($target.attr("data-extension-id"), $target, false);
}
})
.on("click", "button.install", function (e) {
@@ -206,7 +210,11 @@ define(function (require, exports, module) {
// (or registry is offline). These flags *should* always be ignored in that scenario, but just in case...
context.isCompatible = context.isCompatibleLatest = true;
}
-
+
+ if (info.metadata.description !== undefined) {
+ info.metadata.shortdescription = StringUtils.truncate(info.metadata.description, 200);
+ }
+
context.isMarkedForRemoval = ExtensionManager.isMarkedForRemoval(info.metadata.name);
context.isMarkedForUpdate = ExtensionManager.isMarkedForUpdate(info.metadata.name);
diff --git a/src/extensibility/InstallExtensionDialog.js b/src/extensibility/InstallExtensionDialog.js
index 7b111ba61..c86cde632 100644
--- a/src/extensibility/InstallExtensionDialog.js
+++ b/src/extensibility/InstallExtensionDialog.js
@@ -29,6 +29,7 @@ define(function (require, exports, module) {
"use strict";
var Dialogs = require("widgets/Dialogs"),
+ File = require("filesystem/File"),
StringUtils = require("utils/StringUtils"),
Strings = require("strings"),
Commands = require("command/Commands"),
@@ -285,7 +286,7 @@ define(function (require, exports, module) {
} else if (this._state === STATE_ALREADY_INSTALLED) {
// If we were prompting the user about overwriting a previous installation,
// and the user cancels, we can delete the downloaded file.
- if (this._installResult && this._installResult.localPath) {
+ if (this._installResult && this._installResult.localPath && !this._installResult.keepFile) {
var filename = this._installResult.localPath;
FileSystem.getFileForPath(filename).unlink();
}
@@ -404,13 +405,34 @@ define(function (require, exports, module) {
/** Mediates between this module and the Package extension-installation utils. Mockable for unit-testing. */
- function InstallerFacade() { }
+ function InstallerFacade(isLocalFile) {
+ this._isLocalFile = isLocalFile;
+ }
+
InstallerFacade.prototype.install = function (url) {
if (this.pendingInstall) {
console.error("Extension installation already pending");
return new $.Deferred().reject("DOWNLOAD_ID_IN_USE").promise();
}
- this.pendingInstall = Package.installFromURL(url);
+
+ if (this._isLocalFile) {
+ var deferred = new $.Deferred();
+
+ this.pendingInstall = {
+ promise: deferred.promise(),
+ cancel: function () {
+ // Can't cancel local zip installs
+ }
+ };
+
+ Package.installFromPath(url).then(function (installationResult) {
+ // Flag to keep zip files for local file installation
+ installationResult.keepFile = true;
+ deferred.resolve(installationResult);
+ }, deferred.reject);
+ } else {
+ this.pendingInstall = Package.installFromURL(url);
+ }
// Store now since we'll null pendingInstall immediately if the promise was resolved synchronously
var promise = this.pendingInstall.promise;
@@ -440,14 +462,16 @@ define(function (require, exports, module) {
/**
* @private
* Show the installation dialog and automatically begin installing the given URL.
- * @param {string=} urlToInstall If specified, immediately starts installing the given file as if the user had
+ * @param {(string|File)=} urlOrFileToInstall If specified, immediately starts installing the given file as if the user had
* specified it.
* @return {$.Promise} A promise object that will be resolved when the selected extension
* has finished installing, or rejected if the dialog is cancelled.
*/
- function installUsingDialog(urlToInstall, _isUpdate) {
- var dlg = new InstallExtensionDialog(new InstallerFacade(), _isUpdate);
- return dlg.show(urlToInstall);
+ function installUsingDialog(urlOrFileToInstall, _isUpdate) {
+ var isLocalFile = (urlOrFileToInstall instanceof File),
+ dlg = new InstallExtensionDialog(new InstallerFacade(isLocalFile), _isUpdate);
+
+ return dlg.show(urlOrFileToInstall.fullPath || urlOrFileToInstall);
}
/**
diff --git a/src/extensibility/Package.js b/src/extensibility/Package.js
index dd26bfa47..e5d95cf2e 100644
--- a/src/extensibility/Package.js
+++ b/src/extensibility/Package.js
@@ -273,6 +273,51 @@ define(function (require, exports, module) {
});
}
+ /**
+ * On success, resolves with an extension metadata object; at that point, the extension has already
+ * started running in Brackets. On failure (including validation errors), rejects with an error object.
+ *
+ * An error object consists of either a string error code OR an array where the first entry is the error
+ * code and the remaining entries are further info. The error code string is one of either
+ * ExtensionsDomain.Errors or Package.Errors. Use formatError() to convert an error object to a friendly,
+ * localized error message.
+ *
+ * @param {string} path Absolute path to the package zip file
+ * @param {?string} filenameHint Hint for the extension folder's name (used in favor of
+ * path's filename if present, and if no package metadata present).
+ * @return {$.Promise} A promise that is rejected if there are errors during
+ * install or the extension is disabled.
+ */
+ function installFromPath(path, filenameHint) {
+ var d = new $.Deferred();
+
+ install(path, filenameHint)
+ .done(function (result) {
+ var installationStatus = result.installationStatus;
+ if (installationStatus === InstallationStatuses.ALREADY_INSTALLED ||
+ installationStatus === InstallationStatuses.NEEDS_UPDATE ||
+ installationStatus === InstallationStatuses.SAME_VERSION ||
+ installationStatus === InstallationStatuses.OLDER_VERSION) {
+ d.resolve(result);
+ } else {
+ if (result.errors && result.errors.length > 0) {
+ // Validation errors - for now, only return the first one
+ d.reject(result.errors[0]);
+ } else if (result.disabledReason) {
+ // Extension valid but left disabled (wrong API version, extension name collision, etc.)
+ d.reject(result.disabledReason);
+ } else {
+ // Success! Extension is now running in Brackets
+ d.resolve(result);
+ }
+ }
+ })
+ .fail(function (err) {
+ d.reject(err);
+ });
+
+ return d.promise();
+ }
/**
* On success, resolves with an extension metadata object; at that point, the extension has already
@@ -303,34 +348,19 @@ define(function (require, exports, module) {
.done(function (downloadResult) {
state = STATE_INSTALLING;
- install(downloadResult.localPath, downloadResult.filenameHint)
+ installFromPath(downloadResult.localPath, downloadResult.filenameHint)
.done(function (result) {
var installationStatus = result.installationStatus;
- if (installationStatus === InstallationStatuses.ALREADY_INSTALLED ||
- installationStatus === InstallationStatuses.NEEDS_UPDATE ||
- installationStatus === InstallationStatuses.SAME_VERSION ||
- installationStatus === InstallationStatuses.OLDER_VERSION) {
- // We don't delete the file in this case, because it will be needed
- // if the user is going to install the update.
- state = STATE_SUCCEEDED;
- result.localPath = downloadResult.localPath;
- d.resolve(result);
- } else {
+
+ state = STATE_SUCCEEDED;
+ result.localPath = downloadResult.localPath;
+
+ if (installationStatus === InstallationStatuses.INSTALLED) {
+ // Delete temp file
FileSystem.getFileForPath(downloadResult.localPath).unlink();
- if (result.errors && result.errors.length > 0) {
- // Validation errors - for now, only return the first one
- state = STATE_FAILED;
- d.reject(result.errors[0]);
- } else if (result.disabledReason) {
- // Extension valid but left disabled (wrong API version, extension name collision, etc.)
- state = STATE_FAILED;
- d.reject(result.disabledReason);
- } else {
- // Success! Extension is now running in Brackets
- state = STATE_SUCCEEDED;
- d.resolve(result);
- }
}
+
+ d.resolve(result);
})
.fail(function (err) {
// File IO errors, internal error in install()/validate(), or extension startup crashed
@@ -359,7 +389,9 @@ define(function (require, exports, module) {
}
/**
- * Converts an error object as returned by install() or installFromURL() into a flattened, localized string.
+ * Converts an error object as returned by install(), installFromPath() or
+ * installFromURL() into a flattened, localized string.
+ *
* @param {string|Array.} error
* @return {string}
*/
@@ -406,10 +438,11 @@ define(function (require, exports, module) {
* @param {string} path to package file
* @param {?string} nameHint Hint for the extension folder's name (used in favor of
* path's filename if present, and if no package metadata present).
+ * @param {boolean=} keepFile Flag to keep extension update, default=false
* @return {$.Promise} A promise that is resolved when the extension is successfully
* installed or rejected if there is a problem.
*/
- function installUpdate(path, nameHint) {
+ function installUpdate(path, nameHint, keepFile) {
var d = new $.Deferred();
install(path, nameHint, true)
.done(function (result) {
@@ -423,7 +456,9 @@ define(function (require, exports, module) {
d.reject(error);
})
.always(function () {
- FileSystem.getFileForPath(path).unlink();
+ if (!keepFile) {
+ FileSystem.getFileForPath(path).unlink();
+ }
});
return d.promise();
}
@@ -465,6 +500,7 @@ define(function (require, exports, module) {
exports._getNodeConnectionDeferred = _getNodeConnectionDeferred;
exports.installFromURL = installFromURL;
+ exports.installFromPath = installFromPath;
exports.validate = validate;
exports.install = install;
exports.remove = remove;
diff --git a/src/extensions/default/ThorDarkTheme/main.less b/src/extensions/default/ThorDarkTheme/main.less
index fe1d5b493..071d22ec4 100644
--- a/src/extensions/default/ThorDarkTheme/main.less
+++ b/src/extensions/default/ThorDarkTheme/main.less
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved.
+// Copyright (c) 2014 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"),
@@ -23,16 +23,16 @@
// Brackets-specific default font and color definitions
-@import url("brackets_colors.less");
+//@import url("brackets_colors.less");
// Default theme -- all UI styling comes from variables in a theme
// Themes can rely on variables defined above
-@import url("brackets_theme_default.less");
+//@import url("brackets_theme_default.less");
// Include Codemirror styling overrides so that we can overrides proper values
// for the theme. If you need to customize the tree, you also include jsTree.less
// and even brackets_scrollbars.less
-@import url("brackets_codemirror_override.less");
+//@import url("brackets_codemirror_override.less");
/*
@@ -48,147 +48,115 @@
* in this file.
*/
-/* Overall Colors */
+/* Define some variables used in multiple places */
@background: #1d1f21;
-@current-line: #000;
@foreground: #c5c8c6;
-@comment: #767676;
-@orange: #d89333;
-@blue: #6c9ef8;
-@purple: #b77fdb;
-@green: #85a300;
-@red: #dc322f;
-@aqua: #8abeb7;
-@violet: #6c71c4;
-@yellow: #f0c674;
-@pink: #d85896;
-
-/*
- * Background colors are ordered from least "intense" to most "intense"
- * So, if the background is light, then @background-color-3 should be
- * lightest, -2 should be darker, and -1 should be darker still.
- *
- * The opposite is true for a dark background -- background-color-3 should be
- * the darkest, -2 should be lighter, and -1 should be lighter still.
- */
-@background-color-1: lighten(@background, @bc-color-step-size*2);
-@background-color-2: lighten(@background, @bc-color-step-size);
-@background-color-3: @background;
-
-/*
- * @content-color-stronger should be should be further away from the
- * background color than @content-color (i.e. more contrasty).
- *
- * @content-color-weaker should be closer to the background color
- * than @content-color (i.e. less contrasty).
- */
-@content-color: @foreground;
-@content-color-stronger: lighten(@foreground, @bc-color-step-size);
-@content-color-weaker: darken(@foreground, @bc-color-step-size);
+@bc-color-step-size: 10%;
/* Code Styling */
-/* code accent colors */
-@accent-keyword: @blue;
-@accent-atom: @orange;
-@accent-number: @green;
-@accent-def: @purple;
-@accent-variable: @foreground;
-@accent-variable-2: @foreground;
-@accent-variable-3: @foreground;
-@accent-property: @purple;
-@accent-operator: @foreground;
-@accent-comment: @comment;
-@accent-string: @orange;
-@accent-string-2: @orange;
-@accent-meta: @foreground;
-@accent-error: @red;
-@accent-qualifier: @blue;
-@accent-builtin: @blue;
-@accent-bracket: @foreground;
-@accent-tag: @blue;
-@accent-attribute: @green;
-@accent-header: @pink;
-@accent-quote: @blue;
-@accent-hr: @orange;
-@accent-link: @purple;
-@accent-rangeinfo: @violet;
-@accent-minus: @red;
-@accent-plus: @green;
+/* Custom scrollbar colors */
+.platform-win & {
+ .CodeMirror-gutter-filler {
+ background-color: rgb(15, 15, 15);
+ }
+ // Note: when changing padding/margins, may need to adjust metrics in ScrollTrackMarkers.js
-/* inline editor colors */
-@inline-background-color-1: lighten(@background, @bc-color-step-size);
-@inline-background-color-2: lighten(@background, @bc-color-step-size*2);
-@inline-background-color-3: rgba(0,0,0,0);
+ ::-webkit-scrollbar {
+ background-color: rgb(15, 15, 15);
+ }
-@inline-color-1: darken(@foreground, @bc-color-step-size*2);
-@inline-color-2: darken(@foreground, @bc-color-step-size);
-@inline-color-3: @background;
+ ::-webkit-scrollbar-thumb {
+ box-shadow: 0 0 0 12px rgb(49, 49, 49) inset;
+ }
+ ::-webkit-scrollbar-thumb:hover,
+ ::-webkit-scrollbar-thumb:focus {
+ box-shadow: 0 0 0 12px rgb(89, 89, 89) inset;
+ }
+ ::-webkit-scrollbar-thumb:active {
+ box-shadow: 0 0 0 12px rgb(169, 169, 169) inset;
+ }
+}
-/* Selection colors */
-@selection-color-focused: #0050a0;
-@selection-color-unfocused: #333f48;
+.platform-linux & {
+ ::-webkit-scrollbar-thumb {
+ box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.24) inset;
+ }
-@activeline-bgcolor: #2f2f2f;
-@activeline-number: #fff;
-@activeline-number-bgcolor: #000;
-@matching-bracket: #2e5c00;
+ ::-webkit-scrollbar-thumb:window-inactive {
+ box-shadow: 0 0 0 5px rgba(255, 255, 255, 0.12) inset;
+ }
+}
-/* Status Bar Colors */
-@status-bar-background-color: #1C1C1E;
-@status-bar-border: rgba(255, 255, 255, 0.08);
-@status-bar-text-color: #a1a1a1;
-@status-bar-quiet-text-color: #666;
-/* custom scrollbar colors */
-@win-scrollbar-track: rgb(15, 15, 15);
-@win-scrollbar-thumb: rgb(49, 49, 49);
-@win-scrollbar-thumb-hover: rgb(89, 89, 89);
-@win-scrollbar-thumb-active: rgb(169, 169, 169);
+.CodeMirror, .CodeMirror-scroll {
+ background-color: @background;
+ color: @foreground;
+}
-@linux-scrollbar-thumb: rgba(255, 255, 255, 0.24);
-@linux-scrollbar-thumb-inactive: rgba(255, 255, 255, 0.12);
+.CodeMirror-focused .CodeMirror-activeline-background {
+ background: #2f2f2f;
+}
+.show-line-padding .CodeMirror-focused .CodeMirror-activeline-background {
+ box-shadow: inset 15px 0 0 0 #000;
+}
+.CodeMirror-focused .CodeMirror-activeline {
+ .CodeMirror-gutter-elt {
+ background: #000;
+ color: #fff;
+ }
+ .inline-widget .CodeMirror-gutter-elt {
+ color: #767676;
+ }
+}
+
+.cm-keyword, .cm-qualifier, .cm-builtin, .cm-tag, .cm-quote {color: #6c9ef8;}
+.cm-atom, .cm-string, .cm-string-2, .cm-hr {color: #d89333;}
+.cm-number, .cm-attribute, .cm-plus {color: #85a300;}
+.cm-def, .cm-property {color: #b77fdb;}
+.cm-variable, .cm-variable-2, .cm-variable-3, .cm-operator, .cm-meta, .cm-bracket {color: @foreground;}
+.cm-comment {color: #767676;}
+.cm-error, .cm-minus {color: #dc322f;}
+.cm-header {color: #d85896;}
+.cm-link {color: #b77fdb; text-decoration: none;}
+.cm-rangeinfo {color: #6c71c4;}
/* Extra CSS */
-.code-cursor() {
- // to make a block cursor, use something like this:
- // background-color: fadeout(@blue, 50%);
- // border: none !important;
-
- // to make an I-cursor, use something like this:
- border-left: 1px solid @content-color !important;
+.CodeMirror-cursor {
+ border-left: 1px solid #c5c8c6 !important;
}
-.CodeMirror .CodeMirror-gutters {
- // gutter border:
- // border-right: 1px solid rgba(255, 255, 255, 0.03);
+.CodeMirror-gutters {
+ background-color: @background;
+ border-right: none;
}
-.CodeMirror-focused .CodeMirror-activeline .CodeMirror-gutter-elt {
- color: @comment;
+.CodeMirror-focused .CodeMirror-activeline .CodeMirror-gutter-elt, .CodeMirror-linenumber {
+ color: #767676;
}
-#status-bar {
- background: @status-bar-background-color;
- border-top: 1px solid @status-bar-border;
- color:@status-bar-text-color;
+.CodeMirror .CodeMirror-selected {
+ background: #333f48;
+}
+.CodeMirror-focused .CodeMirror-selected {
+ background: #0050a0;
}
-#status-info {
- color: @status-bar-text-color;
+.CodeMirror-matchingbracket, .CodeMirror-matchingtag {
+ /* Ensure visibility against gray inline editor background */
+ background-color: #2e5c00;
+ color: @foreground !important;
}
-#status-file {
- color: @status-bar-quiet-text-color;
+/* Inline editor styling */
+
+.related-container .selection:before {
+ border-top: 9px solid black;
+ border-bottom: 9px solid black;
}
-#status-indicators {
- background: @status-bar-background-color;
- color: @status-bar-text-color;
-
- > div {
- border-left: 1px solid @status-bar-border;
- }
-}
+.inline-widget .CodeMirror, .inline-widget .CodeMirror-gutters {
+ background: transparent;
+}
\ No newline at end of file
diff --git a/src/extensions/default/ThorLightTheme/main.less b/src/extensions/default/ThorLightTheme/main.less
index b05bbeb21..a1691b226 100644
--- a/src/extensions/default/ThorLightTheme/main.less
+++ b/src/extensions/default/ThorLightTheme/main.less
@@ -18,27 +18,4 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
-// Brackets-specific default font and color definitions
-@import url("brackets_colors.less");
-
-// Default theme -- all UI styling comes from variables in a theme
-// Themes can rely on variables defined above
-@import url("brackets_theme_default.less");
-
-// Include Codemirror styling overrides so that we can overrides proper values
-// for the theme. If you need to customize the tree, you also include jsTree.less
-// and even brackets_scrollbars.less
-@import url("brackets_codemirror_override.less");
-
-/*
- * Brackets Default Theme
- *
- * Defines all the variables that one can configure in a theme. This should
- * contain all variables / mixins for UI styling that we want to be able to
- * change in a theme.
- *
- * Throughout the rest of the LESS files we should _only_ use color
- * variable names that are on the LHS of the list below. So, if we
- * need a new color for some UI element, we should add a variable
- * in this file.
- */
+// This is the default theme and doesn't need to do anything!
diff --git a/src/htmlContent/extension-manager-dialog.html b/src/htmlContent/extension-manager-dialog.html
index 7e828bc32..805328d1c 100644
--- a/src/htmlContent/extension-manager-dialog.html
+++ b/src/htmlContent/extension-manager-dialog.html
@@ -16,7 +16,12 @@
diff --git a/src/htmlContent/extension-manager-view-item.html b/src/htmlContent/extension-manager-view-item.html
index bd0fe9b8f..c966f681c 100644
--- a/src/htmlContent/extension-manager-view-item.html
+++ b/src/htmlContent/extension-manager-view-item.html
@@ -26,21 +26,25 @@
{{/isCompatibleLatest}}
{{/isCompatible}}
{{/showInstallButton}}
- {{metadata.description}}
- {{^metadata.description}}
- {{Strings.EXTENSION_NO_DESCRIPTION}}
- {{/metadata.description}}
+
+ {{#metadata.shortdescription}}
+ {{metadata.shortdescription}}
+ {{/metadata.shortdescription}}
+ {{^metadata.shortdescription}}
+ {{#metadata.description}}
+ {{metadata.description}}
+ {{/metadata.description}}
+ {{^metadata.description}}
+ {{Strings.EXTENSION_NO_DESCRIPTION}}
+ {{/metadata.description}}
+ {{/metadata.shortdescription}}
+
+ {{#metadata.shortdescription}}
+ ...
+ {{/metadata.shortdescription}}
{{#metadata.homepage}}
{{Strings.EXTENSION_MORE_INFO}}
{{/metadata.homepage}}
- {{#metadata.keywords.length}}
-
- {{Strings.EXTENSION_KEYWORDS}}:
- {{#metadata.keywords}}
- {{.}}
- {{/metadata.keywords}}
-
- {{/metadata.keywords.length}}
{{#translated}}
{{extensionTranslated}}
diff --git a/src/nls/hr/strings.js b/src/nls/hr/strings.js
index b2820b43b..85f495b86 100644
--- a/src/nls/hr/strings.js
+++ b/src/nls/hr/strings.js
@@ -282,18 +282,6 @@ define({
"CMD_SPLIT_SEL_INTO_LINES" : "Razdvoji odabrano u redove",
"CMD_ADD_CUR_TO_NEXT_LINE" : "Dodaj kursor u sljedeći red",
"CMD_ADD_CUR_TO_PREV_LINE" : "Dodaj kursor u prošli red",
- "FIND_MENU" : "Nađi",
- "CMD_FIND" : "Nađi",
- "CMD_FIND_FIELD_PLACEHOLDER" : "Nađi\u2026",
- "CMD_FIND_IN_FILES" : "Nađi u datotekama",
- "CMD_FIND_IN_SELECTED" : "Nađi u odabranoj Datoteci/Mapi",
- "CMD_FIND_IN_SUBTREE" : "Nađi u\u2026",
- "CMD_FIND_NEXT" : "Nađi sljedeće",
- "CMD_FIND_PREVIOUS" : "Nađi prethodno",
- "CMD_FIND_ALL_AND_SELECT" : "Nađi sve i odaberi",
- "CMD_ADD_NEXT_MATCH" : "Dodaj sljedeće slaganje u odabir",
- "CMD_SKIP_CURRENT_MATCH" : "Preskoči i dodaj sljedeće slaganje",
- "CMD_REPLACE" : "Zamijeni",
"CMD_INDENT" : "Pomakni udesno",
"CMD_UNINDENT" : "Pomakni ulijevo",
"CMD_DUPLICATE" : "Udvostruči",
@@ -307,6 +295,23 @@ define({
"CMD_TOGGLE_CLOSE_BRACKETS" : "Automatski zatvori zagrade",
"CMD_SHOW_CODE_HINTS" : "Prikaži naznake (hintove) kôda",
+ // Search menu commands
+ "FIND_MENU" : "Nađi",
+ "CMD_FIND" : "Nađi",
+ "CMD_FIND_FIELD_PLACEHOLDER" : "Nađi\u2026",
+ "CMD_FIND_IN_FILES" : "Nađi u datotekama",
+ "CMD_FIND_IN_SELECTED" : "Nađi u odabranoj Datoteci/Mapi",
+ "CMD_FIND_IN_SUBTREE" : "Nađi u\u2026",
+ "CMD_FIND_NEXT" : "Nađi sljedeće",
+ "CMD_FIND_PREVIOUS" : "Nađi prethodno",
+ "CMD_FIND_ALL_AND_SELECT" : "Nađi sve i odaberi",
+ "CMD_ADD_NEXT_MATCH" : "Dodaj sljedeće slaganje u odabir",
+ "CMD_SKIP_CURRENT_MATCH" : "Preskoči i dodaj sljedeće slaganje",
+ "CMD_REPLACE" : "Zamijeni",
+ "CMD_REPLACE_IN_FILES" : "Zamijeni u datotekama",
+ "CMD_REPLACE_IN_SELECTED" : "Zamijeni u odabranoj datoteci/mapi",
+ "CMD_REPLACE_IN_SUBTREE" : "Zamijeni u\u2026",
+
// View menu commands
"VIEW_MENU" : "Prikaz",
"CMD_HIDE_SIDEBAR" : "Sakrij bočnu traku",
diff --git a/src/nls/nl/strings.js b/src/nls/nl/strings.js
index 9bc174bc6..5c771de10 100644
--- a/src/nls/nl/strings.js
+++ b/src/nls/nl/strings.js
@@ -124,14 +124,14 @@ define({
"BUTTON_NEXT" : "\u25B6",
"BUTTON_PREV" : "\u25C0",
- "BUTTON_NEXT_HINT" : "Volgende Overeenkomst",
- "BUTTON_PREV_HINT" : "Vorige Overeenkomst",
+ "BUTTON_NEXT_HINT" : "Volgende overeenkomst",
+ "BUTTON_PREV_HINT" : "Vorige overeenkomst",
- "OPEN_FILE" : "Open Bestand",
- "SAVE_FILE_AS" : "Bewaar Bestand",
+ "OPEN_FILE" : "Bestand openen",
+ "SAVE_FILE_AS" : "Bestand opslaan",
"CHOOSE_FOLDER" : "Kies een map",
- "RELEASE_NOTES" : "Release Notes",
+ "RELEASE_NOTES" : "Release notes",
"NO_UPDATE_TITLE" : "Je bent up to date!",
"NO_UPDATE_MESSAGE" : "Je werkt met de laatste versie van {APP_NAME}.",
@@ -202,97 +202,97 @@ define({
// File menu commands
"FILE_MENU" : "Bestand",
"CMD_FILE_NEW_UNTITLED" : "Nieuw",
- "CMD_FILE_NEW" : "Nieuw Bestand",
- "CMD_FILE_NEW_FOLDER" : "Nieuwe Map",
- "CMD_FILE_OPEN" : "Open\u2026",
- "CMD_ADD_TO_WORKING_SET" : "Voeg Toe Aan Werkset",
+ "CMD_FILE_NEW" : "Nieuw bestand",
+ "CMD_FILE_NEW_FOLDER" : "Map openen",
+ "CMD_FILE_OPEN" : "Bestand openen\u2026",
+ "CMD_ADD_TO_WORKING_SET" : "Voeg toe aan werkset",
"CMD_OPEN_FOLDER" : "Open Map\u2026",
"CMD_FILE_CLOSE" : "Sluit",
- "CMD_FILE_CLOSE_ALL" : "Sluit alles",
- "CMD_FILE_SAVE" : "Bewaar",
- "CMD_FILE_SAVE_ALL" : "Bewaar Alles",
- "CMD_FILE_SAVE_AS" : "Bewaar Als\u2026",
- "CMD_LIVE_FILE_PREVIEW" : "Live Voorbeeld",
- "CMD_PROJECT_SETTINGS" : "Project Instellingen\u2026",
- "CMD_FILE_RENAME" : "Hernoem",
+ "CMD_FILE_CLOSE_ALL" : "Alles sluiten",
+ "CMD_FILE_SAVE" : "Opslaan",
+ "CMD_FILE_SAVE_ALL" : "Alles opslaan",
+ "CMD_FILE_SAVE_AS" : "Opslaan als\u2026",
+ "CMD_LIVE_FILE_PREVIEW" : "Live voorbeeld",
+ "CMD_PROJECT_SETTINGS" : "Project instellingen\u2026",
+ "CMD_FILE_RENAME" : "Bestand hernoemen",
"CMD_FILE_DELETE" : "Verwijder",
- "CMD_INSTALL_EXTENSION" : "Installeer Uitbreiding\u2026",
+ "CMD_INSTALL_EXTENSION" : "Installeer uitbreiding\u2026",
"CMD_EXTENSION_MANAGER" : "Uitbreidingbeheer\u2026",
- "CMD_FILE_REFRESH" : "Ververs Bestandsboom",
- "CMD_QUIT" : "Stop",
+ "CMD_FILE_REFRESH" : "Ververs bestandsboom",
+ "CMD_QUIT" : "Stoppen",
// Used in native File menu on Windows
- "CMD_EXIT" : "Exit",
+ "CMD_EXIT" : "Afsluiten",
// Edit menu commands
- "EDIT_MENU" : "Wijzig",
+ "EDIT_MENU" : "Bewerken",
"CMD_UNDO" : "Herstel",
"CMD_REDO" : "Opnieuw",
- "CMD_CUT" : "Knip",
- "CMD_COPY" : "Kopieer",
- "CMD_PASTE" : "Plak",
- "CMD_SELECT_ALL" : "Selecteer Alles",
- "CMD_SELECT_LINE" : "Selecteer Regel",
+ "CMD_CUT" : "Knippen",
+ "CMD_COPY" : "kopierën",
+ "CMD_PASTE" : "Plakken",
+ "CMD_SELECT_ALL" : "Alles selecteren",
+ "CMD_SELECT_LINE" : "Regel selecteren",
"CMD_FIND" : "Zoek",
- "CMD_FIND_IN_FILES" : "Zoek in Mappen",
+ "CMD_FIND_IN_FILES" : "Zoek in mappen",
"CMD_FIND_IN_SUBTREE" : "Zoek in\u2026",
- "CMD_FIND_NEXT" : "Zoek Volgende",
- "CMD_FIND_PREVIOUS" : "Zoek Vorige",
+ "CMD_FIND_NEXT" : "Zoek volgende",
+ "CMD_FIND_PREVIOUS" : "Zoek vorige",
"CMD_REPLACE" : "Vervang",
"CMD_INDENT" : "Inspringen",
- "CMD_UNINDENT" : "Insprong Verwijderen",
+ "CMD_UNINDENT" : "Inspringen verwijderen",
"CMD_DUPLICATE" : "Dupliceer",
"CMD_DELETE_LINES" : "Verwijder Regel",
- "CMD_COMMENT" : "Zet Regel Commentaar Aan/Uit",
- "CMD_BLOCK_COMMENT" : "Zet Blok Commentaar Aan/Uit",
- "CMD_LINE_UP" : "Verplaats Regel naar Boven",
- "CMD_LINE_DOWN" : "Verplaats Regel naar Beneden",
- "CMD_OPEN_LINE_ABOVE" : "Open Regel Boven",
- "CMD_OPEN_LINE_BELOW" : "Open Regel Beneden",
- "CMD_TOGGLE_CLOSE_BRACKETS" : "Automatisch Accolades Sluiten",
- "CMD_SHOW_CODE_HINTS" : "Toon Code Hints",
+ "CMD_COMMENT" : "Zet regel commentaar aan/uit",
+ "CMD_BLOCK_COMMENT" : "Zet blok commentaar aan/uit",
+ "CMD_LINE_UP" : "Verplaats regel naar boven",
+ "CMD_LINE_DOWN" : "Verplaats regel naar beneden",
+ "CMD_OPEN_LINE_ABOVE" : "Open regel boven",
+ "CMD_OPEN_LINE_BELOW" : "Open regel beneden",
+ "CMD_TOGGLE_CLOSE_BRACKETS" : "Automatisch accolades sluiten",
+ "CMD_SHOW_CODE_HINTS" : "Toon code hints",
// View menu commands
- "VIEW_MENU" : "Weergave",
- "CMD_HIDE_SIDEBAR" : "Verberg Zijbalk",
- "CMD_SHOW_SIDEBAR" : "Toon Zijbalk",
- "CMD_INCREASE_FONT_SIZE" : "Vergroot Lettertype",
- "CMD_DECREASE_FONT_SIZE" : "Verklein Lettertype",
- "CMD_RESTORE_FONT_SIZE" : "Herstel Lettertype",
- "CMD_SCROLL_LINE_UP" : "Scroll Regel naar Boven",
- "CMD_SCROLL_LINE_DOWN" : "Scroll Regel naar Beneden",
+ "VIEW_MENU" : "Beeld",
+ "CMD_HIDE_SIDEBAR" : "Verberg zijbalk",
+ "CMD_SHOW_SIDEBAR" : "Toon zijbalk",
+ "CMD_INCREASE_FONT_SIZE" : "Vergroot lettertype",
+ "CMD_DECREASE_FONT_SIZE" : "Verklein lettertype",
+ "CMD_RESTORE_FONT_SIZE" : "Herstel lettertype",
+ "CMD_SCROLL_LINE_UP" : "Scroll regel naar Boven",
+ "CMD_SCROLL_LINE_DOWN" : "Scroll regel naar Beneden",
"CMD_TOGGLE_LINE_NUMBERS" : "Regelnummers",
- "CMD_TOGGLE_ACTIVE_LINE" : "Markeer Actieve Regel",
- "CMD_TOGGLE_WORD_WRAP" : "Word Wrap",
- "CMD_LIVE_HIGHLIGHT" : "Live Voorbeeld Markeren",
- "CMD_VIEW_TOGGLE_INSPECTION" : "Lint Bestanden bij Opslaan",
- "CMD_SORT_WORKINGSET_BY_ADDED" : "Sorteer op Toegevoegd",
- "CMD_SORT_WORKINGSET_BY_NAME" : "Sorteer op Naam",
- "CMD_SORT_WORKINGSET_BY_TYPE" : "Sorteer op Type",
- "CMD_SORT_WORKINGSET_AUTO" : "Automatisch Sorteren",
+ "CMD_TOGGLE_ACTIVE_LINE" : "Markeer actieve regel",
+ "CMD_TOGGLE_WORD_WRAP" : "Word wrap",
+ "CMD_LIVE_HIGHLIGHT" : "Live voorbeeld markeren",
+ "CMD_VIEW_TOGGLE_INSPECTION" : "Lint bestanden bij opslaan",
+ "CMD_SORT_WORKINGSET_BY_ADDED" : "Sorteren op toegevoegd",
+ "CMD_SORT_WORKINGSET_BY_NAME" : "Sorteren op naam",
+ "CMD_SORT_WORKINGSET_BY_TYPE" : "Sorteren op type",
+ "CMD_SORT_WORKINGSET_AUTO" : "Automatisch sorteren",
// Navigate menu Commands
"NAVIGATE_MENU" : "Navigeer",
- "CMD_QUICK_OPEN" : "Open Snel",
- "CMD_GOTO_LINE" : "Ga naar Regel",
- "CMD_GOTO_DEFINITION" : "Definitie Snel Zoeken",
- "CMD_GOTO_FIRST_PROBLEM" : "Ga naar de eerstvolgende Fout/Waarschuwing",
- "CMD_TOGGLE_QUICK_EDIT" : "Wijzig snel",
- "CMD_TOGGLE_QUICK_DOCS" : "Snel naar Documentatie",
- "CMD_QUICK_EDIT_PREV_MATCH" : "Vorige Overeenkomst",
- "CMD_QUICK_EDIT_NEXT_MATCH" : "Volgende Overeenkomst",
- "CMD_NEXT_DOC" : "Volgend Document",
- "CMD_PREV_DOC" : "Vorig Document",
- "CMD_SHOW_IN_TREE" : "Toon in Bestandsboom",
- "CMD_SHOW_IN_OS" : "Toon in Besturingssysteem",
+ "CMD_QUICK_OPEN" : "Snel openen",
+ "CMD_GOTO_LINE" : "Ga naar regel",
+ "CMD_GOTO_DEFINITION" : "Definitie snel zoeken",
+ "CMD_GOTO_FIRST_PROBLEM" : "Ga naar de eerstvolgende fout/waarschuwing",
+ "CMD_TOGGLE_QUICK_EDIT" : "Snel wijzigen",
+ "CMD_TOGGLE_QUICK_DOCS" : "Snel naar documentatie",
+ "CMD_QUICK_EDIT_PREV_MATCH" : "Vorige overeenkomst",
+ "CMD_QUICK_EDIT_NEXT_MATCH" : "Volgende overeenkomst",
+ "CMD_NEXT_DOC" : "Volgend document",
+ "CMD_PREV_DOC" : "Vorig document",
+ "CMD_SHOW_IN_TREE" : "Toon in bestandsboom",
+ "CMD_SHOW_IN_OS" : "Toon in besturingssysteem",
// Help menu commands
"HELP_MENU" : "Help",
- "CMD_CHECK_FOR_UPDATE" : "Controleer op Updates",
+ "CMD_CHECK_FOR_UPDATE" : "Controleer op updates",
"CMD_HOW_TO_USE_BRACKETS" : "Hoe gebruik je {APP_NAME}",
- "CMD_FORUM" : "{APP_NAME} Forum",
+ "CMD_FORUM" : "{APP_NAME} forum",
"CMD_RELEASE_NOTES" : "Release Notes",
"CMD_REPORT_AN_ISSUE" : "Rapporteer een probleem",
- "CMD_SHOW_EXTENSIONS_FOLDER" : "Toon de Map met Uitbreidingen",
+ "CMD_SHOW_EXTENSIONS_FOLDER" : "Toon de map met Uitbreidingen",
"CMD_TWITTER" : "{TWITTER_NAME} op Twitter",
"CMD_ABOUT" : "Over {APP_TITLE}",
@@ -302,53 +302,53 @@ define({
"OK" : "OK",
"DONT_SAVE" : "Niet opslaan",
"SAVE" : "Opslaan",
- "CANCEL" : "Annuleer",
- "DELETE" : "Verwijder",
- "RELOAD_FROM_DISK" : "Laad opnieuw van Schijf",
- "KEEP_CHANGES_IN_EDITOR" : "Behoud veranderingen in Editor",
- "CLOSE_DONT_SAVE" : "Sluit (Bewaar Niet)",
+ "CANCEL" : "Annuleren",
+ "DELETE" : "Verwijderen",
+ "RELOAD_FROM_DISK" : "Opnieuw laden van schijf",
+ "KEEP_CHANGES_IN_EDITOR" : "Behoud veranderingen in editor",
+ "CLOSE_DONT_SAVE" : "Sluit (niet bewaren)",
"RELAUNCH_CHROME" : "Herstart Chrome",
"ABOUT" : "Over",
- "CLOSE" : "Sluit",
+ "CLOSE" : "Sluiten",
"ABOUT_TEXT_LINE1" : "sprint {VERSION_MINOR} {BUILD_TYPE} {VERSION}",
"ABOUT_TEXT_LINE3" : "Kennisgevingen, voorwaarden en bepalingen met betrekking tot software van derden bevinden zich op {ADOBE_THIRD_PARTY} en op de pagina's, hierin door verwijzing opgenomen.",
"ABOUT_TEXT_LINE4" : "Documentatie en broncode op https://github.com/adobe/brackets/",
"ABOUT_TEXT_LINE5" : "Gemaakt met \u2764 en JavaScript door:",
"ABOUT_TEXT_LINE6" : "Veel mensen (maar we hebben problemen met het laden van die data op dit moment).",
- "ABOUT_TEXT_WEB_PLATFORM_DOCS" : "Web Platform Docs en het Web Platform grafisch logo zijn gelicentieerd onder een Creative Commons Attribution licentie, CC-BY 3.0 Unported.",
- "UPDATE_NOTIFICATION_TOOLTIP" : "Er is een nieuwe build van {APP_NAME} beschikbaar! Klik hier voor details.",
- "UPDATE_AVAILABLE_TITLE" : "Update Beschikbaar",
- "UPDATE_MESSAGE" : "Hey, er is een nieuwe build van {APP_NAME} beschikbaar. Hier zijn een aantal van de nieuwe functies:",
+ "ABOUT_TEXT_WEB_PLATFORM_DOCS" : "Web Platform Docs en het Web Platform logo zijn gelicentieerd onder een Creative Commons Attribution licentie, CC-BY 3.0 Unported.",
+ "UPDATE_NOTIFICATION_TOOLTIP" : "Er is een nieuwe versie van {APP_NAME} beschikbaar! Klik hier voor details.",
+ "UPDATE_AVAILABLE_TITLE" : "Update beschikbaar",
+ "UPDATE_MESSAGE" : "Hey, er is een nieuwe versie van {APP_NAME} beschikbaar. Hier zijn een aantal van de nieuwe functies:",
"GET_IT_NOW" : "Haal het nu!",
- "PROJECT_SETTINGS_TITLE" : "Project Instellingen voor: {0}",
- "PROJECT_SETTING_BASE_URL" : "Live Voorbeeld Start URL",
- "PROJECT_SETTING_BASE_URL_HINT" : "Om een locale server te gebruiken, voor een url in zoals http://localhost:8000/",
+ "PROJECT_SETTINGS_TITLE" : "Project instellingen voor: {0}",
+ "PROJECT_SETTING_BASE_URL" : "Live voorbeeld begin URL",
+ "PROJECT_SETTING_BASE_URL_HINT" : "Om als locale server te gebruiken, voer een url in als http://localhost:8000/",
"BASEURL_ERROR_INVALID_PROTOCOL" : "Het {0} protocol wordt niet ondersteund door Live Voorbeeld—gebruik http: of https: .",
"BASEURL_ERROR_SEARCH_DISALLOWED" : "De start URL kan geen zoekparameters bevatten zoals \"{0}\".",
"BASEURL_ERROR_HASH_DISALLOWED" : "De start URL kan geen hashes bevatten zoals \"{0}\".",
"BASEURL_ERROR_INVALID_CHAR" : "Speciale karakters zoals '{0}' moeten %-geëncodeerd zijn.",
- "BASEURL_ERROR_UNKNOWN_ERROR" : "Onbekende fout bij het parsen van de Start URL",
+ "BASEURL_ERROR_UNKNOWN_ERROR" : "Onbekende fout bij het parsen van de begin URL",
// Extension Management strings
- "INSTALL" : "Installeer",
+ "INSTALL" : "Installeren",
"UPDATE" : "Update",
"REMOVE" : "Verwijder",
"OVERWRITE" : "Overschrijf",
- "CANT_REMOVE_DEV" : "Uitbreidings in de \"dev\" map moeten manueel verwijderd worden.",
+ "CANT_REMOVE_DEV" : "Uitbreidingen in de \"dev\" map moeten met de hand verwijderd worden.",
"CANT_UPDATE" : "De update is niet compatibel met deze versie van {APP_NAME}.",
- "INSTALL_EXTENSION_TITLE" : "Installeer Uitbreiding",
- "UPDATE_EXTENSION_TITLE" : "Update Uitbreiding",
+ "INSTALL_EXTENSION_TITLE" : "Installeer uitbreiding",
+ "UPDATE_EXTENSION_TITLE" : "Update uitbreiding",
"INSTALL_EXTENSION_LABEL" : "Uitbreiding URL",
"INSTALL_EXTENSION_HINT" : "URL van het zip bestand of de GitHup repo van de uitbreiding",
"INSTALLING_FROM" : "Bezig met installeren van uitbreiding van {0}\u2026",
"INSTALL_SUCCEEDED" : "Installatie succesvol!",
- "INSTALL_FAILED" : "Installatie gefaald.",
+ "INSTALL_FAILED" : "Installatie mislukt.",
"CANCELING_INSTALL" : "Bezig met annuleren\u2026",
"CANCELING_HUNG" : "Het annuleren van de installatie duurt lang. Een intern probleem kan zijn opgetreden.",
"INSTALL_CANCELED" : "Installatie geannuleerd.",
// These must match the error codes in ExtensionsDomain.Errors.* :
"INVALID_ZIP_FILE" : "De gedownloade inhoud is geen geldig zip bestand.",
- "INVALID_PACKAGE_JSON" : "Het package.json bestand is niet geldig (fout was: {0}).",
+ "INVALID_PACKAGE_JSON" : "Het package.json bestand is niet geldig (Fout: {0}).",
"MISSING_PACKAGE_NAME" : "Het package.json specifieert geen pakket naam.",
"BAD_PACKAGE_NAME" : "{0} is een ongeldige pakket naam.",
"MISSING_PACKAGE_VERSION" : "Het package.json bestand specifieert geen geldige pakket versie.",
@@ -362,15 +362,15 @@ define({
"EXTENSION_OLDER_VERSION" : "Dit pakket is versie {0} dewelke ouder is dan de op dit moment geïnstalleerde ({1}). Overschrijf de bestaande installatie?",
"DOWNLOAD_ID_IN_USE" : "Interne fout: download ID is reeds in gebruik.",
"NO_SERVER_RESPONSE" : "Kan niet verbinden met de server.",
- "BAD_HTTP_STATUS" : "Bestand niet gevonden op server (HTTP {0}).",
- "CANNOT_WRITE_TEMP" : "Onmogelijk om download op te slaan naar tijdelijk bestand.",
+ "BAD_HTTP_STATUS" : "Bestand niet worden gevonden op server (HTTP {0}).",
+ "CANNOT_WRITE_TEMP" : "Onmogelijk om het gedownloade bestand op te slaan naar een tijdelijk bestand.",
"ERROR_LOADING" : "De uitbreiding ondervond een probleem bij het opstarten.",
- "MALFORMED_URL" : "De URL is ongeldig. Controleer of ze correct werd ingevoerd.",
+ "MALFORMED_URL" : "De URL is ongeldig. Controleer of deze correct is ingevoerd.",
"UNSUPPORTED_PROTOCOL" : "De URL moet een http of https URL zijn.",
"UNKNOWN_ERROR" : "Onbekende interne fout.",
// For NOT_FOUND_ERR, see generic strings above
"EXTENSION_MANAGER_TITLE" : "Uitbreidingbeheer",
- "EXTENSION_MANAGER_ERROR_LOAD" : "Onmogelijk om toegang te verkrijgen tot het uitbreidingen register. Probeer later opnieuw.",
+ "EXTENSION_MANAGER_ERROR_LOAD" : "Er is momenteel geen toegang verkrijgbaar tot het uitbreidingen register. Probeer later opnieuw.",
"INSTALL_FROM_URL" : "Installeer van URL\u2026",
"EXTENSION_AUTHOR" : "Auteur",
"EXTENSION_DATE" : "Datum",
@@ -384,22 +384,22 @@ define({
"EXTENSION_UPDATE_INSTALLED" : "Deze uitbreiding is gedownload en zal geïnstalleerd worden wanneer je {APP_NAME} stopt.",
"EXTENSION_SEARCH_PLACEHOLDER" : "Zoek",
"EXTENSION_MORE_INFO_LINK" : "Meer",
- "BROWSE_EXTENSIONS" : "Blader door Uitbreidingen",
- "EXTENSION_MANAGER_REMOVE" : "Verwijder Uitbreiding",
+ "BROWSE_EXTENSIONS" : "Blader door uitbreidingen",
+ "EXTENSION_MANAGER_REMOVE" : "Verwijder uitbreiding",
"EXTENSION_MANAGER_REMOVE_ERROR" : "Onmogelijk om een of meerdere uitbreidingen te verwijderen: {0}. {APP_NAME} zal nog steeds stoppen.",
- "EXTENSION_MANAGER_UPDATE" : "Update Uitbreiding",
+ "EXTENSION_MANAGER_UPDATE" : "Update uitbreiding",
"EXTENSION_MANAGER_UPDATE_ERROR" : "Onmogelijk om een of meerdere uitbreidingen te updaten: {0}. {APP_NAME} zal nog steeds stoppen.",
"MARKED_FOR_REMOVAL" : "Aangeduid voor verwijdering",
"UNDO_REMOVE" : "Herstel",
"MARKED_FOR_UPDATE" : "Aangeduid voor update",
"UNDO_UPDATE" : "Herstel",
"CHANGE_AND_QUIT_TITLE" : "Wijzig Uitbreidingen",
- "CHANGE_AND_QUIT_MESSAGE" : "Om de aangeduidde uitbreiding te updaten of te verwijderen, moet je {APP_NAME} stoppen en herstarten. Je zal gevraagd worden alle onbewaarde wijzigingen op te slaan.",
- "REMOVE_AND_QUIT" : "Verwijder Uitbreidingen en stop",
- "CHANGE_AND_QUIT" : "Wijzig Uitbreidingen en Stop",
- "UPDATE_AND_QUIT" : "Update Uitbreidingen en Stop",
- "EXTENSION_NOT_INSTALLED" : "Kon de uitbreiding {0} niet verwijderen omdat ze niet was geïnstalleerd",
- "NO_EXTENSIONS" : "Nog geen uitbreidingen geïnstalleerd.
Klik op de Beschikbaar tab hierboven om te starten.",
+ "CHANGE_AND_QUIT_MESSAGE" : "Om de aangeduidde uitbreiding te updaten of te verwijderen, moet je {APP_NAME} stoppen en herstarten. Er zal gevraagd worden alle onbewaarde wijzigingen op te slaan.",
+ "REMOVE_AND_QUIT" : "Verwijder uitbreidingen en afsluiten",
+ "CHANGE_AND_QUIT" : "Wijzig Uitbreidingen en afsluiten",
+ "UPDATE_AND_QUIT" : "Update Uitbreidingen en afsluiten",
+ "EXTENSION_NOT_INSTALLED" : "Kon de uitbreiding {0} niet verwijderen omdat deze niet is geïnstalleerd",
+ "NO_EXTENSIONS" : "Geen uitbreidingen geïnstalleerd.
Klik op de Beschikbaar tab hierboven om te starten.",
"NO_EXTENSION_MATCHES" : "Geen uitbreidingen komen overeen met je zoekopdracht.",
"REGISTRY_SANITY_CHECK_WARNING" : "Wees voorzichtig bij het installeren van uitbreidingen van een onbekende bron.",
"EXTENSIONS_INSTALLED_TITLE" : "Geïnstalleerd",
@@ -415,45 +415,46 @@ define({
// extensions/default/DebugCommands
"DEBUG_MENU" : "Debug",
- "CMD_SHOW_DEV_TOOLS" : "Toon Developer Tools",
- "CMD_REFRESH_WINDOW" : "Herlaad {APP_NAME}",
- "CMD_NEW_BRACKETS_WINDOW" : "Nieuw {APP_NAME} Venster",
- "CMD_SWITCH_LANGUAGE" : "Wijzig Taal",
- "CMD_RUN_UNIT_TESTS" : "Start Testen",
+ "CMD_SHOW_DEV_TOOLS" : "Tools weergeven voor ontwikkelaars",
+ "CMD_REFRESH_WINDOW" : "Opnieuw laden {APP_NAME}",
+ "CMD_NEW_BRACKETS_WINDOW" : "Nieuw {APP_NAME} venster",
+ "CMD_SWITCH_LANGUAGE" : "Wijzig taal",
+ "CMD_RUN_UNIT_TESTS" : "Start testen",
"CMD_SHOW_PERF_DATA" : "Toon Performantie Data",
"CMD_ENABLE_NODE_DEBUGGER" : "Schakel Node Debugger in",
"CMD_LOG_NODE_STATE" : "Log Node Status naar Console",
"CMD_RESTART_NODE" : "Herstart Node",
- "LANGUAGE_TITLE" : "Wijzig Taal",
+ "LANGUAGE_TITLE" : "Wijzig taal",
"LANGUAGE_MESSAGE" : "Taal:",
- "LANGUAGE_SUBMIT" : "Herlaad {APP_NAME}",
- "LANGUAGE_CANCEL" : "Annuleer",
- "LANGUAGE_SYSTEM_DEFAULT" : "Systeem Standaard",
+ "LANGUAGE_SUBMIT" : "{APP_NAME} opnieuw laden",
+ "LANGUAGE_CANCEL" : "Annuleren",
+ "LANGUAGE_SYSTEM_DEFAULT" : "Systeem voorkeuren",
// extensions/default/InlineColorEditor
- "COLOR_EDITOR_CURRENT_COLOR_SWATCH_TIP" : "Huidige Kleur",
- "COLOR_EDITOR_ORIGINAL_COLOR_SWATCH_TIP" : "Originele Kleur",
- "COLOR_EDITOR_RGBA_BUTTON_TIP" : "RGBa Formaat",
- "COLOR_EDITOR_HEX_BUTTON_TIP" : "Hex Formaat",
- "COLOR_EDITOR_HSLA_BUTTON_TIP" : "HSLa Formaat",
+ "COLOR_EDITOR_CURRENT_COLOR_SWATCH_TIP" : "Huidige kleur",
+ "COLOR_EDITOR_ORIGINAL_COLOR_SWATCH_TIP" : "Originele kleur",
+ "COLOR_EDITOR_RGBA_BUTTON_TIP" : "RGBa formaat",
+ "COLOR_EDITOR_HEX_BUTTON_TIP" : "Hex formaat",
+ "COLOR_EDITOR_HSLA_BUTTON_TIP" : "HSLa formaat",
"COLOR_EDITOR_USED_COLOR_TIP_SINGULAR" : "{0} ({1} keer gebruikt)",
- "COLOR_EDITOR_USED_COLOR_TIP_PLURAL" : "{0} ({1} keren gebruikt)",
+ "COLOR_EDITOR_USED_COLOR_TIP_PLURAL" : "{0} ({1} keer gebruikt)",
// extensions/default/JavaScriptCodeHints
- "CMD_JUMPTO_DEFINITION" : "Ga naar Definitie",
- "CMD_SHOW_PARAMETER_HINT" : "Toon Parameter Hint",
+ "CMD_JUMPTO_DEFINITION" : "Ga naar definitie",
+ "CMD_SHOW_PARAMETER_HINT" : "Toon parameter Hint",
"NO_ARGUMENTS" : "",
// extensions/default/JSLint
"JSLINT_NAME" : "JSLint",
// extensions/default/QuickView
- "CMD_ENABLE_QUICK_VIEW" : "Snel bekijken bij Muis Over",
+ "CMD_ENABLE_QUICK_VIEW" : "Snel bekijken bij muis over",
// extensions/default/RecentProjects
- "CMD_TOGGLE_RECENT_PROJECTS" : "Recente Projecten",
+ "CMD_TOGGLE_RECENT_PROJECTS" : "Recente projecten",
// extensions/default/WebPlatformDocs
"DOCS_MORE_LINK" : "Lees meer"
});
+/* Last translated for 752856d58d2e9dde14e1af6be615bb7080727b7a */
diff --git a/src/nls/root/strings.js b/src/nls/root/strings.js
index 9e4a11045..d4048948d 100644
--- a/src/nls/root/strings.js
+++ b/src/nls/root/strings.js
@@ -40,15 +40,17 @@ define({
"UNSUPPORTED_ENCODING_ERR" : "{APP_NAME} currently only supports UTF-8 encoded text files.",
"FILE_EXISTS_ERR" : "The file or directory already exists.",
"FILE" : "file",
+ "FILE_TITLE" : "File",
"DIRECTORY" : "directory",
+ "DIRECTORY_TITLE" : "Directory",
"DIRECTORY_NAMES_LEDE" : "Directory names",
"FILENAMES_LEDE" : "Filenames",
- "FILENAME" : "filename",
- "DIRECTORY_NAME" : "directory name",
+ "FILENAME" : "Filename",
+ "DIRECTORY_NAME" : "Directory Name",
// Project error strings
- "ERROR_LOADING_PROJECT" : "Error loading project",
+ "ERROR_LOADING_PROJECT" : "Error Loading Project",
"OPEN_DIALOG_ERROR" : "An error occurred when showing the open file dialog. (error {0})",
"REQUEST_NATIVE_FILE_SYSTEM_ERROR" : "An error occurred when trying to load the directory {0}. (error {1})",
"READ_DIRECTORY_ENTRIES_ERROR" : "An error occurred when reading the contents of the directory {0}. (error {1})",
@@ -61,10 +63,10 @@ define({
"ERROR_RELOADING_FILE" : "An error occurred when trying to reload the file {0}. {1}",
"ERROR_SAVING_FILE_TITLE" : "Error Saving File",
"ERROR_SAVING_FILE" : "An error occurred when trying to save the file {0}. {1}",
- "ERROR_RENAMING_FILE_TITLE" : "Error Renaming File",
- "ERROR_RENAMING_FILE" : "An error occurred when trying to rename the file {0}. {1}",
- "ERROR_DELETING_FILE_TITLE" : "Error Deleting File",
- "ERROR_DELETING_FILE" : "An error occurred when trying to delete the file {0}. {1}",
+ "ERROR_RENAMING_FILE_TITLE" : "Error Renaming {0}",
+ "ERROR_RENAMING_FILE" : "An error occurred when trying to rename the {2} {0}. {1}",
+ "ERROR_DELETING_FILE_TITLE" : "Error Deleting {0}",
+ "ERROR_DELETING_FILE" : "An error occurred when trying to delete the {2} {0}. {1}",
"INVALID_FILENAME_TITLE" : "Invalid {0}",
"INVALID_FILENAME_MESSAGE" : "{0} cannot use any system reserved words, end with dots (.) or use any of the following characters: {1}
",
"ENTRY_WITH_SAME_NAME_EXISTS" : "A file or directory with the name {0} already exists.",
@@ -183,7 +185,7 @@ define({
"REPLACE_IN_FILES_ERRORS_TITLE" : "Replace Errors",
"REPLACE_IN_FILES_ERRORS" : "The following files weren't modified because they changed after the search or couldn't be written.",
- "ERROR_FETCHING_UPDATE_INFO_TITLE" : "Error getting update info",
+ "ERROR_FETCHING_UPDATE_INFO_TITLE" : "Error Getting Update Info",
"ERROR_FETCHING_UPDATE_INFO_MSG" : "There was a problem getting the latest update information from the server. Please make sure you are connected to the internet and try again.",
// File exclusion filters
@@ -446,6 +448,8 @@ define({
"CANCELING_INSTALL" : "Canceling\u2026",
"CANCELING_HUNG" : "Canceling the install is taking a long time. An internal error may have occurred.",
"INSTALL_CANCELED" : "Installation canceled.",
+ "VIEW_COMPLETE_DESCRIPTION" : "View complete description",
+ "VIEW_TRUNCATED_DESCRIPTION" : "View truncated description",
// These must match the error codes in ExtensionsDomain.Errors.* :
"INVALID_ZIP_FILE" : "The downloaded content is not a valid zip file.",
"INVALID_PACKAGE_JSON" : "The package.json file is not valid (error was: {0}).",
@@ -471,7 +475,11 @@ define({
// For NOT_FOUND_ERR, see generic strings above
"EXTENSION_MANAGER_TITLE" : "Extension Manager",
"EXTENSION_MANAGER_ERROR_LOAD" : "Unable to access the extension registry. Please try again later.",
+ "INSTALL_EXTENSION_DRAG" : "Drag .zip in here or",
+ "INSTALL_EXTENSION_DROP" : "Drop .zip to install",
+ "INSTALL_EXTENSION_DROP_ERROR" : "Install/Update aborted due to the following errors:",
"INSTALL_FROM_URL" : "Install from URL\u2026",
+ "INSTALL_EXTENSION_VALIDATING" : "Validating\u2026",
"EXTENSION_AUTHOR" : "Author",
"EXTENSION_DATE" : "Date",
"EXTENSION_INCOMPATIBLE_NEWER" : "This extension requires a newer version of {APP_NAME}.",
diff --git a/src/project/ProjectManager.js b/src/project/ProjectManager.js
index 91e30de34..320cb8242 100644
--- a/src/project/ProjectManager.js
+++ b/src/project/ProjectManager.js
@@ -115,6 +115,22 @@ define(function (require, exports, module) {
*/
var SETTINGS_FILENAME = "." + PreferencesManager.SETTINGS_FILENAME;
+ /**
+ * @const
+ * @private
+ * Error context to show the correct error message
+ * @type {int}
+ */
+ var ERR_TYPE_CREATE = 1,
+ ERR_TYPE_CREATE_EXISTS = 2,
+ ERR_TYPE_RENAME = 3,
+ ERR_TYPE_DELETE = 4,
+ ERR_TYPE_LOADING_PROJECT = 5,
+ ERR_TYPE_LOADING_PROJECT_NATIVE = 6,
+ ERR_TYPE_MAX_FILES = 7,
+ ERR_TYPE_OPEN_DIALOG = 8,
+ ERR_TYPE_INVALID_FILENAME = 9;
+
/**
* @private
* Reference to the tree control container div. Initialized by
@@ -764,6 +780,62 @@ define(function (require, exports, module) {
return Async.withTimeout(result.promise(), 1000);
}
+ function _showErrorDialog(errType, isFolder, error, path) {
+ var titleType = isFolder ? Strings.DIRECTORY_TITLE : Strings.FILE_TITLE,
+ entryType = isFolder ? Strings.DIRECTORY : Strings.FILE,
+ title,
+ message;
+ path = StringUtils.breakableUrl(path);
+
+ switch (errType) {
+ case ERR_TYPE_CREATE:
+ title = StringUtils.format(Strings.ERROR_CREATING_FILE_TITLE, titleType);
+ message = StringUtils.format(Strings.ERROR_CREATING_FILE, entryType, path, error);
+ break;
+ case ERR_TYPE_CREATE_EXISTS:
+ title = StringUtils.format(Strings.INVALID_FILENAME_TITLE, titleType);
+ message = StringUtils.format(Strings.ENTRY_WITH_SAME_NAME_EXISTS, path);
+ break;
+ case ERR_TYPE_RENAME:
+ title = StringUtils.format(Strings.ERROR_RENAMING_FILE_TITLE, titleType);
+ message = StringUtils.format(Strings.ERROR_RENAMING_FILE, path, error, entryType);
+ break;
+ case ERR_TYPE_DELETE:
+ title = StringUtils.format(Strings.ERROR_DELETING_FILE_TITLE, titleType);
+ message = StringUtils.format(Strings.ERROR_DELETING_FILE, path, error, entryType);
+ break;
+ case ERR_TYPE_LOADING_PROJECT:
+ title = Strings.ERROR_LOADING_PROJECT;
+ message = StringUtils.format(Strings.READ_DIRECTORY_ENTRIES_ERROR, path, error);
+ break;
+ case ERR_TYPE_LOADING_PROJECT_NATIVE:
+ title = Strings.ERROR_LOADING_PROJECT;
+ message = StringUtils.format(Strings.REQUEST_NATIVE_FILE_SYSTEM_ERROR, path, error);
+ break;
+ case ERR_TYPE_MAX_FILES:
+ title = Strings.ERROR_MAX_FILES_TITLE;
+ message = Strings.ERROR_MAX_FILES;
+ break;
+ case ERR_TYPE_OPEN_DIALOG:
+ title = Strings.ERROR_LOADING_PROJECT;
+ message = StringUtils.format(Strings.OPEN_DIALOG_ERROR, error);
+ break;
+ case ERR_TYPE_INVALID_FILENAME:
+ title = StringUtils.format(Strings.INVALID_FILENAME_TITLE, isFolder ? Strings.DIRECTORY_NAME : Strings.FILENAME);
+ message = StringUtils.format(Strings.INVALID_FILENAME_MESSAGE, isFolder ? Strings.DIRECTORY_NAMES_LEDE : Strings.FILENAMES_LEDE, error);
+ break;
+ }
+
+ if (title && message) {
+ return Dialogs.showModalDialog(
+ DefaultDialogs.DIALOG_ID_ERROR,
+ title,
+ message
+ );
+ }
+ return null;
+ }
+
/**
* @private
* See shouldShow
@@ -945,15 +1017,7 @@ define(function (require, exports, module) {
// Fetch dirEntry's contents
dirEntry.getContents(function (err, contents, stats, statsErrs) {
if (err) {
- Dialogs.showModalDialog(
- DefaultDialogs.DIALOG_ID_ERROR,
- Strings.ERROR_LOADING_PROJECT,
- StringUtils.format(
- Strings.READ_DIRECTORY_ENTRIES_ERROR,
- StringUtils.breakableUrl(dirEntry.fullPath),
- err
- )
- );
+ _showErrorDialog(ERR_TYPE_LOADING_PROJECT, null, err, dirEntry.fullPath);
// Reject the render promise so we can move on.
deferred.reject();
} else {
@@ -1049,25 +1113,13 @@ define(function (require, exports, module) {
return updateWelcomeProjectPath(PreferencesManager.getViewState("projectPath"));
}
- /**
- * Error dialog when max files in index is hit
- * @return {Dialog}
- */
- function _showMaxFilesDialog() {
- return Dialogs.showModalDialog(
- DefaultDialogs.DIALOG_ID_ERROR,
- Strings.ERROR_MAX_FILES_TITLE,
- Strings.ERROR_MAX_FILES
- );
- }
-
function _watchProjectRoot(rootPath) {
FileSystem.on("change", _fileSystemChange);
FileSystem.on("rename", _fileSystemRename);
FileSystem.watch(FileSystem.getDirectoryForPath(rootPath), _shouldShowName, function (err) {
if (err === FileSystemError.TOO_MANY_ENTRIES) {
- _showMaxFilesDialog();
+ _showErrorDialog(ERR_TYPE_MAX_FILES);
} else if (err) {
console.error("Error watching project root: ", rootPath, err);
}
@@ -1200,7 +1252,6 @@ define(function (require, exports, module) {
if (exists) {
var projectRootChanged = (!_projectRoot || !rootEntry) ||
_projectRoot.fullPath !== rootEntry.fullPath;
- var i;
// Success!
var perfTimerName = PerfUtils.markStart("Load Project: " + rootPath);
@@ -1246,31 +1297,24 @@ define(function (require, exports, module) {
PerfUtils.addMeasurement(perfTimerName);
});
} else {
- Dialogs.showModalDialog(
- DefaultDialogs.DIALOG_ID_ERROR,
- Strings.ERROR_LOADING_PROJECT,
- StringUtils.format(
- Strings.REQUEST_NATIVE_FILE_SYSTEM_ERROR,
- StringUtils.breakableUrl(rootPath),
- err || FileSystemError.NOT_FOUND
- )
- ).done(function () {
- // Reset _projectRoot to null so that the following _loadProject call won't
- // run the 'beforeProjectClose' event a second time on the original project,
- // which is now partially torn down (see #6574).
- _projectRoot = null;
-
- // The project folder stored in preference doesn't exist, so load the default
- // project directory.
- // TODO (issue #267): When Brackets supports having no project directory
- // defined this code will need to change
- _loadProject(_getWelcomeProjectPath()).always(function () {
- // Make sure not to reject the original deferred until the fallback
- // project is loaded, so we don't violate expectations that there is always
- // a current project before continuing after _loadProject().
- result.reject();
+ _showErrorDialog(ERR_TYPE_LOADING_PROJECT_NATIVE, null, rootPath, err || FileSystemError.NOT_FOUND)
+ .done(function () {
+ // Reset _projectRoot to null so that the following _loadProject call won't
+ // run the 'beforeProjectClose' event a second time on the original project,
+ // which is now partially torn down (see #6574).
+ _projectRoot = null;
+
+ // The project folder stored in preference doesn't exist, so load the default
+ // project directory.
+ // TODO (issue #267): When Brackets supports having no project directory
+ // defined this code will need to change
+ _loadProject(_getWelcomeProjectPath()).always(function () {
+ // Make sure not to reject the original deferred until the fallback
+ // project is loaded, so we don't violate expectations that there is always
+ // a current project before continuing after _loadProject().
+ result.reject();
+ });
});
- });
}
});
}
@@ -1522,11 +1566,7 @@ define(function (require, exports, module) {
result.reject();
}
} else {
- Dialogs.showModalDialog(
- DefaultDialogs.DIALOG_ID_ERROR,
- Strings.ERROR_LOADING_PROJECT,
- StringUtils.format(Strings.OPEN_DIALOG_ERROR, err)
- );
+ _showErrorDialog(ERR_TYPE_OPEN_DIALOG, null, err);
result.reject();
}
});
@@ -1565,11 +1605,7 @@ define(function (require, exports, module) {
// See http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
if ((filename.search(new RegExp("[" + _invalidChars + "]+")) !== -1) ||
filename.match(_illegalFilenamesRegEx)) {
- Dialogs.showModalDialog(
- DefaultDialogs.DIALOG_ID_ERROR,
- StringUtils.format(Strings.INVALID_FILENAME_TITLE, isFolder ? Strings.DIRECTORY_NAME : Strings.FILENAME),
- StringUtils.format(Strings.INVALID_FILENAME_MESSAGE, isFolder ? Strings.DIRECTORY_NAMES_LEDE : Strings.FILENAMES_LEDE, _invalidChars)
- );
+ _showErrorDialog(ERR_TYPE_INVALID_FILENAME, isFolder, _invalidChars);
return false;
}
return true;
@@ -1694,27 +1730,15 @@ define(function (require, exports, module) {
_createNode($baseDirNode, null, _entryToJSON(entry), true, true);
};
- var errorCallback = function (error, entry) {
- var titleType = isFolder ? Strings.DIRECTORY_NAME : Strings.FILENAME,
- entryType = isFolder ? Strings.DIRECTORY : Strings.FILE;
+ var errorCallback = function (error) {
if (error === FileSystemError.ALREADY_EXISTS) {
- Dialogs.showModalDialog(
- DefaultDialogs.DIALOG_ID_ERROR,
- StringUtils.format(Strings.INVALID_FILENAME_TITLE, titleType),
- StringUtils.format(Strings.ENTRY_WITH_SAME_NAME_EXISTS,
- StringUtils.breakableUrl(data.rslt.name))
- );
+ _showErrorDialog(ERR_TYPE_CREATE_EXISTS, isFolder, null, data.rslt.name);
} else {
var errString = error === FileSystemError.NOT_WRITABLE ?
Strings.NO_MODIFICATION_ALLOWED_ERR :
StringUtils.format(Strings.GENERIC_ERROR, error);
- Dialogs.showModalDialog(
- DefaultDialogs.DIALOG_ID_ERROR,
- StringUtils.format(Strings.ERROR_CREATING_FILE_TITLE, entryType),
- StringUtils.format(Strings.ERROR_CREATING_FILE, entryType,
- StringUtils.breakableUrl(data.rslt.name), errString)
- );
+ _showErrorDialog(ERR_TYPE_CREATE, isFolder, errString, data.rslt.name);
}
errorCleanup();
@@ -1722,10 +1746,10 @@ define(function (require, exports, module) {
var newItemPath = baseDirEntry.fullPath + data.rslt.name;
- FileSystem.resolve(newItemPath, function (err, item) {
+ FileSystem.resolve(newItemPath, function (err) {
if (!err) {
// Item already exists, fail with error
- errorCallback(FileSystemError.ALREADY_EXISTS, item);
+ errorCallback(FileSystemError.ALREADY_EXISTS);
} else {
if (isFolder) {
var directory = FileSystem.getDirectoryForPath(newItemPath);
@@ -1820,17 +1844,11 @@ define(function (require, exports, module) {
result.resolve();
} else {
// Show an error alert
- Dialogs.showModalDialog(
- DefaultDialogs.DIALOG_ID_ERROR,
- Strings.ERROR_RENAMING_FILE_TITLE,
- StringUtils.format(
- Strings.ERROR_RENAMING_FILE,
- StringUtils.breakableUrl(newName),
- err === FileSystemError.ALREADY_EXISTS ?
+ var errString = err === FileSystemError.ALREADY_EXISTS ?
Strings.FILE_EXISTS_ERR :
- FileUtils.getFileErrorString(err)
- )
- );
+ FileUtils.getFileErrorString(err);
+
+ _showErrorDialog(ERR_TYPE_RENAME, isFolder, errString, newName);
result.reject(err);
}
});
@@ -2005,16 +2023,7 @@ define(function (require, exports, module) {
_deleteTreeNode(entry);
result.resolve();
} else {
- // Show an error alert
- Dialogs.showModalDialog(
- Dialogs.DIALOG_ID_ERROR,
- Strings.ERROR_DELETING_FILE_TITLE,
- StringUtils.format(
- Strings.ERROR_DELETING_FILE,
- _.escape(entry.fullPath),
- FileUtils.getFileErrorString(err)
- )
- );
+ _showErrorDialog(ERR_TYPE_DELETE, entry.isDirectory, FileUtils.getFileErrorString(err), entry.fullPath);
result.reject(err);
}
diff --git a/src/styles/brackets.less b/src/styles/brackets.less
index 57ed4c35d..71597e0aa 100644
--- a/src/styles/brackets.less
+++ b/src/styles/brackets.less
@@ -1652,6 +1652,65 @@ label input {
font-size: 1.01em;
}
+/* Extension Manager */
+#install-drop-zone {
+ background-color: transparent;
+ box-shadow: initial;
+ font-weight: normal;
+ border-style: dashed;
+ position: relative;
+}
+
+#install-drop-zone-mask {
+ position: absolute;
+ top: -1px;
+ left: -1px;
+
+ padding: 1px;
+ width: 100%;
+ height: 100%;
+ display: none;
+
+ cursor: copy;
+}
+
+#install-drop-zone.drop #install-drop-zone-mask {
+ display: block;
+}
+
+#install-drop-zone.drop {
+ background: @tc-call-to-action;
+ box-shadow: initial;
+ font-weight: normal;
+ border: 1px solid @tc-call-to-action;
+ color: @tc-call-to-action-text;
+ text-shadow: none;
+}
+
+.install-drag-message {
+ display: none;
+}
+
+.install-drop-message {
+ display: none;
+}
+
+.install-validating-message {
+ display: none;
+}
+
+#install-drop-zone.drag .install-drag-message {
+ display: inline;
+}
+
+#install-drop-zone.drop .install-drop-message {
+ display: inline;
+}
+
+#install-drop-zone.validating .install-validating-message {
+ display: inline;
+}
+
.theme-settings td {
padding: 2px;
}
diff --git a/src/styles/brackets_patterns_override.less b/src/styles/brackets_patterns_override.less
index 64eaf4955..5775faa17 100644
--- a/src/styles/brackets_patterns_override.less
+++ b/src/styles/brackets_patterns_override.less
@@ -972,9 +972,6 @@ a[href^="http"] {
.user-select(text);
cursor: text;
}
- .ext-keywords {
- color: @tc-input-placeholder-text;
- }
.ext-translated {
color: @tc-input-placeholder-text;
}
diff --git a/src/utils/StringUtils.js b/src/utils/StringUtils.js
index 3770f47ff..4b59316c6 100644
--- a/src/utils/StringUtils.js
+++ b/src/utils/StringUtils.js
@@ -198,6 +198,27 @@ define(function (require, exports, module) {
return returnVal;
}
+ /**
+ * Truncate strings to specified length.
+ * @param {string} str Text to be truncated.
+ * @param {number} len Length to which text should be limited.
+ * @return {string} Returns truncated text only if it was changed.
+ */
+ function truncate(str, len) {
+ // Truncate the description if it is too long
+ if (str.length > len) {
+ str = str.substr(0, len);
+
+ // To prevent awkward addition of ellipsis, try to truncate
+ // at the end of the last whole word
+ var lastSpaceChar = str.lastIndexOf(" ");
+ if (lastSpaceChar < len && lastSpaceChar > -1) {
+ str = str.substr(0, lastSpaceChar);
+ }
+ return str;
+ }
+ }
+
// Define public API
exports.format = format;
exports.htmlEscape = htmlEscape;
@@ -209,4 +230,5 @@ define(function (require, exports, module) {
exports.breakableUrl = breakableUrl;
exports.endsWith = endsWith;
exports.prettyPrintBytes = prettyPrintBytes;
+ exports.truncate = truncate;
});
diff --git a/test/spec/ExtensionManager-test.js b/test/spec/ExtensionManager-test.js
index 13aef10d7..207f81d4f 100644
--- a/test/spec/ExtensionManager-test.js
+++ b/test/spec/ExtensionManager-test.js
@@ -690,7 +690,7 @@ define(function (require, exports, module) {
});
runs(function () {
expect(file.unlink).not.toHaveBeenCalled();
- expect(Package.installUpdate).toHaveBeenCalledWith(filename, id);
+ expect(Package.installUpdate).toHaveBeenCalledWith(filename, id, undefined);
});
});
@@ -770,8 +770,7 @@ define(function (require, exports, module) {
// Simple fields
[item.metadata.version,
- item.metadata.author && item.metadata.author.name,
- item.metadata.description]
+ item.metadata.author && item.metadata.author.name]
.forEach(function (value) {
if (value) {
expect(view).toHaveText(value);
@@ -782,7 +781,7 @@ define(function (require, exports, module) {
}
// Array-valued fields
- [item.metadata.keywords, item.metadata.categories].forEach(function (arr) {
+ [item.metadata.categories].forEach(function (arr) {
if (arr) {
arr.forEach(function (value) {
expect(view).toHaveText(value);
@@ -793,6 +792,33 @@ define(function (require, exports, module) {
});
});
+ it("should display original description", function () {
+ setupViewWithMockData(ExtensionManagerViewModel.RegistryViewModel);
+ runs(function () {
+ _.forEach(mockRegistry, function (item) {
+ if (item.metadata.description) {
+ if (StringUtils.truncate(item.metadata.description, 200) === undefined) {
+ expect(view).toHaveText(item.metadata.description);
+ }
+ }
+ });
+ });
+ });
+
+ it("should display shortened description", function () {
+ setupViewWithMockData(ExtensionManagerViewModel.RegistryViewModel);
+ runs(function () {
+ _.forEach(mockRegistry, function (item) {
+ if (item.metadata.description) {
+ var shortDescription = StringUtils.truncate(item.metadata.description, 200);
+ if (shortDescription !== undefined) {
+ expect(view).toHaveText(shortDescription);
+ }
+ }
+ });
+ });
+ });
+
it("should display owner even for installed items", function () {
ExtensionManager._setExtensions(JSON.parse(mockExtensionList));
setupViewWithMockData(ExtensionManagerViewModel.InstalledViewModel);
@@ -1499,7 +1525,7 @@ define(function (require, exports, module) {
});
waitsFor(function () { return didReload; }, "mock reload");
runs(function () {
- expect(Package.installUpdate).toHaveBeenCalledWith(filename, id);
+ expect(Package.installUpdate).toHaveBeenCalledWith(filename, id, undefined);
expect(didClose).toBe(true);
expect(didReload).toBe(true);
});