Skip to content
This repository has been archived by the owner on Sep 6, 2021. It is now read-only.

Combine jdiel's "language switching" pull request with tvoliter's templatization of index.html using mustache #1358

Merged
merged 20 commits into from
Aug 14, 2012
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@
[submodule "src/thirdparty/smart-auto-complete"]
path = src/thirdparty/smart-auto-complete
url = https://github.com/laktek/jQuery-Smart-Auto-Complete.git
[submodule "src/thirdparty/mustache"]
path = src/thirdparty/mustache
url = https://github.com/janl/mustache.js.git
21 changes: 18 additions & 3 deletions src/brackets.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,15 @@


/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global require, define, brackets: true, $, PathUtils, window, navigator */
/*global require, define, brackets: true, $, PathUtils, window, navigator, Mustache */

require.config({
paths: {
"text" : "thirdparty/text"
}
"text" : "thirdparty/text",
"i18n" : "thirdparty/i18n"
},
// store the locale in localStorage until CEF sets the correct navigator.language
locale: window.localStorage.getItem("locale")
});

/**
Expand All @@ -40,6 +43,10 @@ require.config({
*
* Unlike other modules, this one can be accessed without an explicit require() because it exposes
* a global object, window.brackets.
*
* Events:
* htmlContentLoadComplete - sent when the HTML DOM is fully loaded. Modules should not touch
* or modify DOM elements before this event is sent.
*/
define(function (require, exports, module) {
"use strict";
Expand Down Expand Up @@ -74,6 +81,7 @@ define(function (require, exports, module) {
QuickOpen = require("search/QuickOpen"),
Menus = require("command/Menus"),
FileUtils = require("file/FileUtils"),
MainViewHTML = require("text!htmlContent/main-view.html"),
Strings = require("strings"),
Dialogs = require("widgets/Dialogs"),
ExtensionLoader = require("utils/ExtensionLoader"),
Expand Down Expand Up @@ -333,6 +341,13 @@ define(function (require, exports, module) {

// Main Brackets initialization
_initGlobalBrackets();

// Localize MainViewHTML and inject into <BODY> tag
$('body').html(Mustache.render(MainViewHTML, Strings));
// modules that depend on the HTML DOM should listen to
// the htmlContentLoadComplete event.
$(brackets).trigger("htmlContentLoadComplete");

$(window.document).ready(_onReady);

});
1 change: 1 addition & 0 deletions src/command/Commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ 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_SWITCH_LANGUAGE = "debug.switchLanguage";

// Command that does nothing. Can be used for place holder menuItems

Expand Down
2 changes: 2 additions & 0 deletions src/command/Menus.js
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,8 @@ define(function (require, exports, module) {
{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);

Expand Down
92 changes: 91 additions & 1 deletion src/debug/DebugCommandHandlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ define(function (require, exports, module) {
Editor = require("editor/Editor").Editor,
Strings = require("strings"),
PerfUtils = require("utils/PerfUtils"),
NativeApp = require("utils/NativeApp");
NativeApp = require("utils/NativeApp"),
NativeFileSystem = require("file/NativeFileSystem").NativeFileSystem,
FileUtils = require("file/FileUtils");

function handleShowDeveloperTools(commandData) {
brackets.app.showDeveloperTools();
Expand Down Expand Up @@ -130,6 +132,93 @@ define(function (require, exports, module) {
function _handleNewBracketsWindow() {
window.open(window.location.href);
}

function _handleSwitchLanguage() {
var stringsPath = FileUtils.getNativeBracketsDirectoryPath() + "/nls";
NativeFileSystem.requestNativeFileSystem(stringsPath, function (dirEntry) {
dirEntry.createReader().readEntries(function (entries) {

var $activeLanguage;
var $submit;
function setLanguage(event) {
if ($activeLanguage) {
$activeLanguage.css("font-weight", "normal");
}
$activeLanguage = $(event.currentTarget);
$activeLanguage.css("font-weight", "bold");
$submit.attr("disabled", false);
}

var $modal = $("<div class='modal hide' />");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll file a general issue to move blocks such as this one into a template.


var $header = $("<div class='modal-header' />")
.append("<a href='#' class='close'>&times;</a>")
.append("<h1 class='dialog-title'>" + Strings.LANGUAGE_TITLE + "</h1>")
.appendTo($modal);

var $body = $("<div class='modal-body' style='max-height: 500px; overflow: auto;' />")
.appendTo($modal);

var $p = $("<p class='dialog-message'>")
.text(Strings.LANGUAGE_MESSAGE)
.appendTo($body);

var $ul = $("<ul>")
.on("click", "li", setLanguage)
.appendTo($p);

// add english
var $li = $("<li>")
.text("en-EN")
.data("locale", "en-EN")
.appendTo($ul);

// inspect all children of dirEntry
entries.forEach(function (entry) {
if (entry.isDirectory && entry.name.match(/^[a-z]{2}-[A-Z]{2}$/)) {
var language = entry.name;
var $li = $("<li>")
.text(entry.name)
.data("locale", language)
.appendTo($ul);
}
});

var $footer = $("<div class='modal-footer' />")
.appendTo($modal);

var $cancel = $("<button class='dialog-button btn left'>")
.on("click", function () {
$modal.modal('hide');
})
.text(Strings.LANGUAGE_CANCEL)
.appendTo($footer);

$submit = $("<button class='dialog-button btn primary'>")
.text(Strings.LANGUAGE_SUBMIT)
.on("click", function () {
if (!$activeLanguage) {
return;
}
var locale = $activeLanguage.data("locale");
window.localStorage.setItem("locale", locale);
CommandManager.execute(Commands.DEBUG_REFRESH_WINDOW);
})
.attr("disabled", "disabled")
.appendTo($footer);

$modal
.appendTo(window.document.body)
.modal({
backdrop: "static",
show: true
})
.on("hidden", function () {
$(this).remove();
});
});
});
}

/* Register all the command handlers */

Expand All @@ -139,6 +228,7 @@ define(function (require, exports, module) {
CommandManager.register(Strings.CMD_NEW_BRACKETS_WINDOW, Commands.DEBUG_NEW_BRACKETS_WINDOW, _handleNewBracketsWindow);
CommandManager.register(Strings.CMD_RUN_UNIT_TESTS, Commands.DEBUG_RUN_UNIT_TESTS, _handleRunUnitTests);
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());
Expand Down
199 changes: 199 additions & 0 deletions src/htmlContent/main-view.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
<!--
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.
-->


<!--
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs copyright header

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm getting a jslint error for this html template fragment. I'm not sure what the solution is though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed this too. I think JSLint expects it to be a fully formed html structure since it sees the .html suffix. Since this is really an html fragment it doesn’t have or tags.

I don’t know if the JSLint options you can put in comments work in HTML comments.

This is the HTML for the body tag of index.html. It is loaded dynamically by the
htmlContentLoad module and localized using a combination of mustache.js and i18n.js.

LOCALIZATION NOTE:
All display text for this file must use templating so the text can be localized.

English text goes in src/nls/strings.js. All other translations go in the strings.js file for
the specific local in the nls folder. If a translation is missing for a specific key English
is used as a fallback

Strings should be referenced using the double brackets syntax.
Example: {{keyname}}. Note, all strings are HTML escaped unless the form
{{&keyname}} is used.

-->

<!-- Main UI -->
<div class="main-view">
<div id="sidebar-resizer"></div>
<div id="sidebar" class="sidebar quiet-scrollbars">
<!-- Left-hand 'Project panel' -->
<div id="projects" class="panel">
<div id="project-header"></div>
<div id="file-section">
<div id="open-files-container">
<!-- This will contain a dynamically generated <ul> at runtime -->
<ul>
</ul>
</div>

<div id="project-files-header" class="project-file-header-area">
<span id="project-title" class="title"></span>
</div>
<div id="project-files-container">
<!-- This will contain a dynamically generated <ul> hierarchy at runtime -->
</div>
</div>
</div>
</div>

<!-- Right-hand content: toolbar, editor, bottom panels -->
<div class="content">
<!-- Toolbar containing menus, filename, and icons -->
<div id="main-toolbar" class="toolbar">
<!-- Menu bar -->
<ul class="nav" data-dropdown="dropdown">
</ul>

<!-- Toolbar -->
<div class="buttons">
<span class="experimental-label">{{EXPERIMENTAL_BUILD}}</span>

<a href="#" id="toolbar-go-live"></a> <!-- tooltip for this is set in JS -->

<span id="gold-star" title="No JSLint errors - good job!">
&#9733;
</span>
</div>

<!-- Filename label -->
<div class="title-wrapper">
<span class="title"></span>&nbsp;<span class='dirty-dot' style="visibility:hidden;">•</span>
</div>
</div>

<div id="editor-holder">
<div id="not-editor">
<div id="not-editor-content">[&nbsp;&nbsp;]</div>
</div>
</div>

<div id="jslint-results" class="bottom-panel">
<div class="toolbar simple-toolbar-layout">
<div class="title">{{JSLINT_ERRORS}}</div>
</div>
<div class="table-container"></div>
</div>
<div id="search-results" class="bottom-panel">
<div class="toolbar simple-toolbar-layout">
<div class="title">{{SEARCH_RESULTS}}</div>
<div class="title" id="search-result-summary"></div>
<a href="#" class="close">&times;</a>
</div>
<div class="table-container"></div>
</div>
</div>
</div>

<!-- Modal Windows -->
<div class="error-dialog template modal hide">
<div class="modal-header">
<a href="#" class="close">&times;</a>
<h1 class="dialog-title">Error</h1>
</div>
<div class="modal-body">
<p class="dialog-message">Message goes here</p>
</div>
<div class="modal-footer">
<a href="#" class="dialog-button btn primary" data-button-id="ok">{{OK}}</a>
</div>
</div>
<div class="save-close-dialog template modal hide">
<div class="modal-header">
<a href="#" class="close">&times;</a>
<h1 class="dialog-title">{{SAVE_CHANGES}}</h1>
</div>
<div class="modal-body">
<p class="dialog-message">Message goes here</p>
</div>
<div class="modal-footer">
<a href="#" class="dialog-button btn left" data-button-id="dontsave">{{DONT_SAVE}}</a>
<a href="#" class="dialog-button btn primary" data-button-id="ok">{{SAVE}}</a>
<a href="#" class="dialog-button btn" data-button-id="cancel">{{CANCEL}}</a>
</div>
</div>
<div class="ext-changed-dialog template modal hide">
<div class="modal-header">
<h1 class="dialog-title">Title goes here</h1>
</div>
<div class="modal-body">
<p class="dialog-message">Message goes here</p>
</div>
<div class="modal-footer">
<a href="#" class="dialog-button btn left" data-button-id="dontsave">{{RELOAD_FROM_DISK}}</a>
<a href="#" class="dialog-button btn primary" data-button-id="cancel">{{KEEP_CHANGES_IN_EDITOR}}</a>
</div>
</div>
<div class="ext-deleted-dialog template modal hide">
<div class="modal-header">
<h1 class="dialog-title">Title goes here</h1>
</div>
<div class="modal-body">
<p class="dialog-message">Message goes here</p>
</div>
<div class="modal-footer">
<a href="#" class="dialog-button btn left" data-button-id="dontsave">{{CLOSE_DONT_SAVE}}}</a>
<a href="#" class="dialog-button btn primary" data-button-id="cancel">{{KEEP_CHANGES_IN_EDITOR}}</a>
</div>
</div>
<div class="live-development-error-dialog template modal hide">
<div class="modal-header">
<h1 class="dialog-title">Title goes here</h1>
</div>
<div class="modal-body">
<p class="dialog-message">Message goes here</p>
</div>
<div class="modal-footer">
<a href="#" class="dialog-button btn left" data-button-id="cancel">{{CANCEL}}}</a>
<a href="#" class="dialog-button btn primary" data-button-id="ok">{{RELAUNCH_CHROME}}</a>
</div>
</div>
<div class="about-dialog template modal hide">
<div class="modal-header">
<h1 class="dialog-title">{{ABOUT}}</h1>
</div>
<div class="modal-body">
<img class="about-icon" src="styles/images/brackets_icon.svg">
<div class="about-text">
<h2>{{BRACKETS}}</h2>
<p class="dialog-message">{{ABOUT_TEXT_LINE1}} <span id="about-build-number"><!-- populated programmatically --></span></p>
<p class="dialog-message">{{ABOUT_TEXT_LINE2}}</p>
<p class="dialog-message">{{ABOUT_TEXT_LINE3}}<span class="non-clickble-link">http://www.adobe.com/go/thirdparty/</span>{{ABOUT_TEXT_LINE4}}</p>
<p class="dialog-message">{{ABOUT_TEXT_LINE5}}<span class="non-clickble-link">https://github.com/adobe/brackets/</span></p>
</div>
</div>
<div class="modal-footer">
<a href="#" class="dialog-button btn primary" data-button-id="ok">{{CLOSE}}</a>
</div>
</div>
<div id="context-menu-bar">
<ul data-dropdown="dropdown"></ul>
</div>
<div id="codehint-menu-bar">
<ul data-dropdown="dropdown"></ul>
</div>
Loading