diff --git a/README.md b/README.md index 802ca6e73a9..28a3412145a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Welcome to Brackets! [![Build Status](https://travis-ci.org/adobe/brackets.svg?branch=master)](https://travis-ci.org/adobe/brackets) ------------------- -This is an early version of Brackets, a code editor for HTML, CSS +Brackets is a modern open-source code editor for HTML, CSS and JavaScript that's *built* in HTML, CSS and JavaScript. What makes Brackets different from other web code editors? @@ -15,19 +15,17 @@ back and forth between your real source code and the browser view. * **Do it yourself.** Because Brackets is open source, and built with HTML, CSS and JavaScript, you can [help build](https://github.com/adobe/brackets/blob/master/CONTRIBUTING.md) the best code editor for the web. +Brackets is at 1.0 and we're not stopping there. We have many feature ideas on our +[trello board](http://bit.ly/BracketsTrelloBoard) that we're anxious to add and other +innovative web development workflows that we're planning to build into Brackets. +So take Brackets out for a spin and let us know how we can make it your favorite editor. + You can see some [screenshots of Brackets](https://github.com/adobe/brackets/wiki/Brackets-Screenshots) on the wiki, [intro videos](http://www.youtube.com/user/CodeBrackets) on YouTube, and news on the [Brackets blog](http://blog.brackets.io/). - How to install and run Brackets ------------------------------- - - -#### Brackets is getting close to 1.0 - -Together with your contributions, we're getting close to our first release candidate. 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! - #### Download Installers for the latest stable build for Mac, Windows and Linux (Debian/Ubuntu) can be [downloaded here](http://brackets.io/). diff --git a/package.json b/package.json index 78e3b7c32c8..7275be0ee2b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "Brackets", - "version": "0.45.0-0", - "apiVersion": "0.45.0", + "version": "1.1.0-0", + "apiVersion": "1.1.0", "homepage": "http://brackets.io", "issues": { "url": "http://github.com/adobe/brackets/issues" @@ -17,7 +17,7 @@ "jasmine-node": "1.11.0", "grunt-jasmine-node": "0.1.0", "grunt-cli": "0.1.9", - "phantomjs": "1.9.0-1", + "phantomjs": "1.9.11", "grunt-lib-phantomjs": "0.3.0", "grunt-contrib-jshint": "0.6.0", "grunt-contrib-watch": "0.4.3", @@ -35,6 +35,7 @@ "grunt-usemin": "0.1.11", "load-grunt-tasks": "0.2.0", "q": "0.9.2", + "semver": "^4.1.0", "jshint": "2.1.4", "xmldoc": "^0.1.2" }, diff --git a/samples/da/Kom godt i gang/screenshots/quick-edit.png b/samples/da/Kom godt i gang/screenshots/quick-edit.png index b72a6bf496f..911d70c8266 100644 Binary files a/samples/da/Kom godt i gang/screenshots/quick-edit.png and b/samples/da/Kom godt i gang/screenshots/quick-edit.png differ diff --git a/samples/de/Erste Schritte/index.html b/samples/de/Erste Schritte/index.html index 67d533ed38d..f80c7e2fc15 100644 --- a/samples/de/Erste Schritte/index.html +++ b/samples/de/Erste Schritte/index.html @@ -18,10 +18,9 @@

Dies ist Ihre Anleitung!

-->

- Willkommen zu einer frühen Vorschau von Brackets, einem neuen Open-Source-Editor für die - nächste Generation des Webs. Wir sind große Fans von Standards und wollen bessere Tools für - JavaScript, HTML und CSS sowie verwandte offene Web-Technologien bauen. Dies ist erst - der Anfang von dem, was wir noch vorhaben. + Willkommen zu Brackets, einem modernen, quelloffenen Code-Editor, der Webdesign versteht. Es ist ein + einfacher, aber dennoch leistungsfähiger Editor, der Ihnen immer die richtigen Tools einblendet, sodass + Sie die genau richtige Menge an Hilfestellung haben, wann immer Sie diese brauchen.

Brackets ist eine andere Art Editor. - Ein entscheidender Unterschied ist, dass dieser Editor in JavaScript, HTML und CSS geschrieben ist. - Das heißt, dass die meisten von euch Brackets-Nutzern die nötigen Fähigkeiten haben, Brackets selbst - zu verändern und erweitern. - Tatsächlich benutzen wir Brackets täglich, um Brackets zu verbessern. - Es hat außerdem einige einzigartige Funktionen wie Schnelles Bearbeiten, die Live-Vorschau und andere, - die sie wahrscheinlich nicht in anderen Editoren finden werden. - Lesen Sie weiter, um zu erfahren, wie sie diese Funktionen nutzen können. + Brackets hat ein paar einzigartige Features wie Schnelles Bearbeiten, Live-Vorschau und zahlreiche + weitere, die Sie in anderen Editoren vergeblich suchen werden. Zudem ist Brackets in JavaScript, HTML + und CSS geschrieben. Das heißt, dass die meisten Brackets-Nutzer dazu in der Lage sind, den Editor + selbst zu verändern und erweitern. Tatsächlich nutzen wir Brackets täglich, um Brackets zu verbessern. + Lesen Sie weiter, um mehr über die Nutzung der Hauptfeatures zu erfahren. +

+ + - -

Wir probieren ein paar neue Dinge aus

+

Projekte in Brackets

+

+ Um Ihren eigenen Code in Brackets zu bearbeiten, können Sie einfach den Ordner öffnen, der Ihre + Dateien enthält. + Brackets sieht den geöffneten Ordner als "Projekt"; Features wie Code-Vervollständigung, Live-Vorschau + und Schnelles Bearbeiten nutzen nur Dateien im aktuell geöffneten Ordner. +

+ + + Sobald Sie bereit sind, dieses Beispielprojekt zu verlassen und Ihren eigenen Code zu editieren, können + Sie die Drop-Down-Liste auf der linken Seite nutzen, um einen Ordner auszuwählen. Die Drop-Down-Liste + heißt zurzeit "Erste Schritte" - das ist der Ordner, der die aktuell geöffnete Datei enthält. Klicken + Sie darauf und wählen Sie daraufhin "Ordner öffnen…", um Ihren eigenen Ordner zu öffnen. + Sie können auf diese Weise auch später wieder zu zuvor geöffneten Ordnern, wie diesem Beispielprojekt, + zurückkehren. + -Tag oben und drücken Sie Cmd/Strg + E. Sie sollten einen Editor zum Schnellen Bearbeiten von CSS erscheinen sehen, der die geltenden CSS-Regeln anzeigt. Das Schnelle Bearbeiten funktioniert genauso in Klassen- und - ID-Attributen. + ID-Attributen. Sie können es zudem in LESS- und SCSS-Dateien nutzen. Sie können auf die selbe Weise neue Regeln erstellen. Klicken Sie in einen der -Tags weiter oben und drücken Sie Cmd/Strg + E. Es gibt noch keine Regeln dafür, aber Sie können den @@ -72,6 +89,8 @@

Schnelles Bearbeiten von CSS und JavaScript

Sie können die selbe Tastenkombination nutzen, um andere Dinge auf die selbe Weise zu bearbeiten - wie JavaScript-Funktionen, Farben und Animations-Timing-Funktionen - und wir fügen ständig mehr hinzu. +

+

Im Augenblick können solche Editoren allerdings nicht verschachtelt werden. Sie können das Schnelle Bearbeiten also nur nutzen, während der Cursor sich im Haupteditor befindet.

@@ -145,7 +164,7 @@

Schnelle Farbansicht

Sie benötigen etwas anderes? Probieren Sie es mit einer Erweiterung!

Zusätzlich zu all dem, was in Brackets eingebaut ist, hat unsere große und wachsende Community der - Erweiterungs-Entwickler über hundert Erweiterungen erstellt, die nützliche Funktionen bringen. Wenn + Erweiterungs-Entwickler hunderte Erweiterungen erstellt, die nützliche Funktionen bringen. Wenn Sie etwas brauchen, was es nicht in Brackets gibt, ist es sehr wahrscheinlich, dass bereits jemand eine Erweiterung dafür geschrieben hat. Um die Liste der verfügbaren Erweiterungen zu durchstöbern oder zu durchsuchen nutzen Sie Datei > Erweiterungs-Verwaltung und klicken auf @@ -153,23 +172,6 @@

Sie benötigen etwas anderes? Probieren Sie es mit einer Erweiterung!

auf den "Installieren"-Button daneben.

-

Projekte in Brackets

-

- Um Ihren eigenen Code in Brackets zu bearbeiten, können Sie einfach den Ordner öffnen, der Ihre - Dateien enthält. - Brackets sieht den geöffneten Ordner als "Projekt"; Features wie Code-Vervollständigung, Live-Vorschau - und Schnelles Bearbeiten nutzen nur Dateien im aktuell geöffneten Ordner. -

- - - Sobald Sie bereit sind, dieses Beispielprojekt zu verlassen und Ihren eigenen Code zu editieren, können - Sie die Drop-Down-Liste auf der linken Seite nutzen, um einen Ordner auszuwählen. Die Drop-Down-Liste - heißt zurzeit "Erste Schritte" - das ist der Ordner, der die aktuell geöffnete Datei enthält. Klicken - Sie darauf und wählen Sie daraufhin "Ordner öffnen…", um Ihren eigenen Ordner zu öffnen. - Sie können auf diese Weise auch später wieder zu zuvor geöffneten Ordnern, wie diesem Beispielprojekt, - zurückkehren. - - @@ -188,7 +190,7 @@

Machen Sie mit

  • Brackets Wiki
  • Brackets Developer-Mailingliste
  • @brackets auf Twitter
  • -
  • Mit Brackets-Entwicklern per IRC in #brackets auf Freenode chatten
  • +
  • Mit Brackets-Entwicklern via IRC in #brackets auf Freenode chatten
  • diff --git a/samples/es/Primeros Pasos/index.html b/samples/es/Primeros Pasos/index.html index 2225bfd8bf6..416e6365155 100644 --- a/samples/es/Primeros Pasos/index.html +++ b/samples/es/Primeros Pasos/index.html @@ -18,10 +18,9 @@

    ¡Ésta es tu guía!

    -->

    - Bienvenido a una versión preliminar de Brackets, un nuevo editor de código abierto para la nueva - generación de Internet. Somos unos apasionados de los estándares y queremos construir mejores - herramientas para JavaScript, HTML, CSS y el resto de tecnologías web. Éste es nuestro humilde - comienzo. + Bienvenido a Brackets, un nuevo editor de código abierto que entiende el diseño web. Es un editor de + código liviano y potente al mismo tiempo que incluye herramientas visuales dentro del mismo para + que puedas obtener la ayuda que necesites cuando la necesites.

    Brackets es un editor diferente. - La gran diferencia es que está escrito en JavaScript, HTML y CSS. Esto significa que la mayoría de quienes - usan Brackets tiene las habilidades necesarias para modificar y extender el editor. De hecho, nosotros - lo usamos todos los días para desarrollar Brackets. También tiene algunas características únicas como - Edición Rápida, Desarrollo en Vivo y más que no encontrarás en otros editores. - Sigue leyendo para saber más sobre cómo sacar provecho de estas características + Brackets tiene varias características únicas como la Edición rápida y la Vista previa dinámica y muchas + más que no vas a encontrar en otros editores. Además, Brackets está escrito en JavaScript, HTML y CSS. + Esto significa que la mayoría de quienes usan Brackets tienen las habilidades necesarias para modificar y + extender el editor. De hecho, nosotros usamos Brackets todos los días para desarrollar Brackets. Para + saber más sobre cómo utilizar estas características únicas, continua leyendo.

    + + +

    Proyectos en Brackets

    +

    + Para poder editar tu propio código en Brackets, puedes simplemente abrir la carpeta que contiene los + archivos. Brackets considera a la carpeta abierta como el "proyecto"; características como las Sugerencias + de código, la Vista previa dinámica y la Edición rápida solo utilizan los archivos contenidos dentro de + la carpeta actualmente abierta. +

    + + + Una vez que estés listo para salir del proyecto de ejemplo y editar tu propio código, puedes usar el menú + despegable en la barra de la izquierda para cambiar de carpeta. En estos momentos, el menú despegable dice + "Primeros Pasos" - la cual es la carpeta que contiene el archivo que estás viendo en estos momentos. Haz + clic en el menú despegable y selecciona "Abrir carpeta…" para abrir tu carpeta. + También puedes usar el menú despegable para abrir las carpetas que abriste recientemente, incluyendo este + proyecto de ejemplo. + +

    Estamos intentando algunas cosas nuevas

    y oprime Cmd/Ctrl + E. - Deberías ver aparecer un editor rápido de CSS más arriba, mostrando la regla CSS que le afecta. La edición rápida - funciona también en atributos de de tipo clase e id. + ¿Quieres verlo funcionando? Coloca tu cursor sobre la etiqueta y oprime + Cmd/Ctrl + E. Deberías ver aparecer un editor rápido de CSS más arriba, mostrando la regla de + CSS que le afecta. La edición rápida funciona también en atributos de de tipo clase e id. También puedes + utilizarlo en tus archivos LESS o SCSS. - Puedes crear nuevas reglas de la misma manera. Haz click en una de las etiquetas de más arriba y - oprime Cmd/Ctrl + E. Todavía no hay reglas para ese elemento, pero puedes hacer click en el + Puedes crear nuevas reglas de la misma manera. Haz clic en una de las etiquetas de más arriba + y oprime Cmd/Ctrl + E. Todavía no hay reglas para ese elemento, pero puedes hacer clic en el botón Nueva Regla para añadir una nueva regla a las etiquetas . @@ -65,9 +87,12 @@

    Edición rápida de CSS y JavaScript

    - También puedes usar el mismo atajo para editar otras cosas--como funciones en JavaScript, colores y funciones de - temporización de animaciones--y estamos añadiendo más y más continuamente. Por ahora, no se pueden anidar editores - en línea, por lo que sólo puedes usar la característica de Edición Rápida cuando el cursor está en un editor "completo". + También puedes usar el mismo atajo para editar otras cosas--como funciones en JavaScript, colores y + funciones de temporización de animaciones--y estamos añadiendo más y más continuamente. +

    +

    + Por ahora, no se pueden anidar editores en línea, por lo que sólo puedes usar la característica de + Edición Rápida cuando el cursor está en un editor "completo".

    que se encuentra un poco más arriba. Observa cómo aparece el resaltado azul alrededor de la imagen en Chrome. Luego, utiliza Cmd/Ctrl + E - para abrir las reglas de CSS existentes. Intenta cambiar el tamaño del borde de 10 a 20 píxeles o el color - del fondo de "transparent" a "hotpink". Si Brackets y tu navegador están funcionando en paralelo, verás los - cambios reflejados de manera instantánea en tu navegador. Genial, ¿verdad? + para abrir las reglas de CSS existentes. Intenta cambiar el tamaño del borde de 10px a 20px o el color + del fondo de "transparent" a "hotpink". Si Brackets y tu navegador están funcionando en paralelo, verás + los cambios reflejados de manera instantánea en tu navegador. Genial, ¿verdad?

    - Actualmente, Brackets sólo soporta Desarrollo en Vivo para HTML y CSS. Aún así, en la versión actual, los cambios - en ficheros JavaScript son detectados y recargados automáticamente en el navegador cuando guardas. En - estos momentos estamos trabajando en añadir soporte para Desarrollo en Vivo para JavaScript. Además, las - actualizaciones automáticas sólo son posibles en Google Chrome, pero esperamos poder trasladar próximamente - esta funcionalidad a todos los grandes navegadores. + Actualmente, Brackets sólo soporta Vista previa dinámica para HTML y CSS. Aún así, en la versión actual, + los cambios en archivos JavaScript son recargados automáticamente en el navegador cuando guardas. En estos + momentos estamos trabajando en el soporte de Vista previa dinámica para JavaScript. Las actualizaciones + automáticas sólo son posibles en Google Chrome, pero esperamos poder trasladar esta funcionalidad a todos + los grandes navegadores.

    Vista Rápida

    - Para aquellos que todavía no han memorizado las equivalencias de color entre Hex y RGB, Brackets permite ver - exactamente qué color se está utilizando rápida y fácilmente. Tanto en CSS como en HTML, simplemente mueve el - cursor sobre cualquier valor de color o gradiente y Brackets mostrará una previsualización del mismo de manera - automática. Lo mismo sirve para imágenes: simplemente pasa el cursor sobre la dirección de una imagen en Brackets, - y éste mostrará una vista en miniatura de la misma. + Para aquellos que todavía no han memorizado las equivalencias de color entre Hex y RGB, Brackets permite + ver exactamente qué color se está utilizando rápida y fácilmente. Tanto en CSS como en HTML, simplemente + mueve el cursor sobre cualquier valor de color o gradiente y Brackets mostrará una previsualización del + mismo de manera automática. Lo mismo sirve para imágenes: simplemente pasa el cursor sobre la dirección + de una imagen en Brackets, y éste mostrará una vista en miniatura de la misma.

    - Para probar la previsualización tú mismo, coloca el cursor en la etiqueta al principio de este - documento y oprime Cmd/Ctrl + E para abrir un editor CSS. Ahora, simplemente mueve el ratón sobre - cualquiera de los colores dentro del CSS. También puedes verlo funcionando en gradientes abriendo un editor - de CSS en la etiqueta pasando el cursor por cualquiera de los valores para las imágenes de fondo. - Para probar la vista previa de imágenes, coloca el cursor sobre la imagen con la captura de pantalla incluida - antes en este documento. + Para probar la previsualización tú mismo, coloca el cursor en la etiqueta al principio de + este documento y oprime Cmd/Ctrl + E para abrir un editor CSS. Ahora, simplemente mueve el + cursor sobre cualquiera de los colores dentro del CSS. También puedes verlo funcionando en gradientes + abriendo un editor de CSS en la etiqueta y pasando el cursor por cualquiera de los valores + para las imágenes de fondo. Para probar la vista previa de imágenes, coloca el cursor sobre la imagen + incluida antes en éste documento.

    ¿Necesitas algo más? ¡Prueba una extensión!

    - Además de todas las bondades naturales de Brackets, nuestra amplia y creciente comunidad de - desarrolladores de extensiones ha creado más de un centenar de extensiones que añaden útiles - funcionalidades. Si hay algo que necesitas que Brackets no soporte, es bastante probable que - alguien haya construido una extensión para ello. Para navegar o buscar en la lista de extensiones - disponibles, selecciona Archivo > Gestionar extensiones... y haz click en la - pestaña "Disponibles". Cuando encuentres una que quieras, simplemente presiona el botón "Instalar" - a su derecha. -

    - -

    Proyectos en Brackets

    -

    - Para poder editar tu propio código en Brackets, puedes simplemente abrir la carpeta que contiene los archivos. - Brackets considera a la carpeta abierta como el "proyecto"; características como las Sugerencias de Código, - la Vista Previa y la Edición Rápida solo usan los archivos dentro de la carpeta abierta actualmente. + Además de todas las bondades naturales de Brackets, nuestra amplia y creciente comunidad de desarrolladores + de extensiones ha creado cientos de extensiones que añaden útiles funcionalidades. Si hay algo que + necesitas que Brackets no soporte, es bastante probable que alguien haya construido una extensión para + ello. Para navegar o buscar en la lista de extensiones disponibles, selecciona Archivo > + Gestionar extensiones... y haz clic en la pestaña "Disponibles". Cuando encuentres una que + quieras, simplemente presiona el botón "Instalar" a su derecha.

    - - Una vez que estés listo para salir del proyecto de ejemplo y editar tu propio código, puedes usar el menú - despegable en la barra de la izquierda para cambiar carpetas. En estos momentos, el menú despegable dice - "Primeros Pasos" - la cual es la carpeta que contiene el archivo que estás viendo en estos momentos. Haz - click en el menú despegable y selecciona "Abrir carpeta…" para abrir tu carpeta. - También puedes usar el menú despegable para abrir las carpetas que abriste recientemente, incluyendo este - proyecto de ejemplo. - - diff --git a/samples/fi/Aloitus/index.html b/samples/fi/Aloitus/index.html index 31b0a1aaa8f..c5c60a17797 100644 --- a/samples/fi/Aloitus/index.html +++ b/samples/fi/Aloitus/index.html @@ -18,56 +18,78 @@

    Tämä on oppaasi!

    -->

    - Tervetuloa Bracketsin varhaiseen esiversioon, uuteen avoimen lähdekoodin editoriin seuraavalle web-sukupolvelle. - Olemme suuria standardien faneja ja haluamme rakentaa paremmat työkalut JavaScriptille, HTML:lle ja CSS:lle sekä - niihin liittyville, avoimille web-tekniikoille. Tämä on vaatimaton alkumme. + Tervetuloa käyttämään Bracketsia, nykyaikaista, avoimen lähdekoodin koodieditoria, joka ymmärtää + web-suunnittelun. Se on kevyt mutta silti tehokas: koodieditori, joka sulauttaa visuaaliset työkalut suoraan + editoriin, niin että saat oikean määrän apua silloin, kun haluat sitä.

    Brackets on erityyppinen editori. - Yksi huomattava ero on se, että tämä editori on kirjoitettu JavaScriptillä, HTML:llä ja CSS:llä. Se tarkoittaa, että - useilla teistä Bracketsin käyttäjistä on tarvittavat taidot editorin muokkaamiseen ja laajentamiseen. Itse asiassa - käytämme Bracketsia joka päivä sen itsensä kehittämiseen. Bracketsissa on joitakin ainutlaatuisia ominaisuuksia, - kuten pikamuokkaus, reaaliaikainen esikatselu ja muita, joita et voi löytää muista editoreista. Oppiaksesi lisää, - kuinka käyttää näitä ominaisuuksia, jatka lukemista. + Bracketsissa on joitakin ainutlaatuisia ominaisuuksia, kuten pikamuokkaus, reaaliaikainen esikatselu ja + muita, joita et voi löytää muista editoreista. Lisäksi Brackets on kirjoitettu JavaSciptillä, HTML:llä ja + CSS:llä. Se tarkoittaa, että useimmilla Bracketsin käyttäjistä on riittävät taidot muokata ja laajentaa + editoria. Itse asiassa käytämme Bracketsia joka päivä sen itsensä kehitykseen. Oppiaksesi lisää siitä, + kuinka käyttää avainominaisuuksia, jatka lukemista.

    + -

    Kokeilemme muutamia uusia asioita

    +

    Projektit Bracketsissa

    +

    + Muokataksesi omaa koodiasi Bracketsia käyttäen voit vain avata tiedostosi sisältävän kansion. Brackets pitää + nykyistä avointa kansiota ”projektina”; ominaisuudet, kuten koodivihjeet, esikatselu ja pikamuokkaus, + käyttävät vain parhaillaan avoinna olevan kansion tiedostoja. +

    + + + Heti kun olet valmis luopumaan tästä näyteprojektista ja muokkaamaan omaa koodiasi, voit käyttää vasemman + sivupalkin pudotusvalikkoa kansioiden vaihtamiseen. Juuri nyt pudotusvalikossa lukee ”Aloitus”. Tämä on + kansio, joka sisältää tiedoston, jota tarkastelet juuri nyt. Avaa oma kansiosi napsauttamalla + pudotusvalikkoa ja valitsemalla ”Avaa kansio…”. + Voit käyttää pudotusvalikkoa myös myöhemmin vaihtaaksesi takaisin kansioihin, jotka olet avannut aiemmin, + sisältäen tämän näyteprojektin. +

    Pikamuokkaus CSS:lle ja JavaScriptille

    Ei lisää dokumenttien välillä vaihtamista tai asiayhteyden hukkaamista. Muokatessasi HTML:ää käytä - Cmd/Ctrl + E -näppäinyhdistelmää avataksesi upotetun pikaeditorin, joka näyttää kaiken tiedostoon - liittyvän CSS:n. Muokkaa CSS:ääsi, paina ESC-näppäintä ja olet takaisin editoimassa HTML:ää, tai jätä - CSS-säännöt auki ja ne tulevat osaksi HTML-editoriasi. Jos painat ESC-näppäintä pikaeditorin ulkopuolella, - ne kaikki sulkeutuvat. + näppäinyhdistelmää Cmd/Ctrl + E avataksesi upotetun pikaeditorin, joka näyttää kaiken tiedostoon + liittyvän CSS:n. Muokkaa CSS:ääsi, paina ESC-näppäintä ja olet taas muokkaamassa HTML:ää, tai + yksinkertaisesti jätä CSS-säännöt auki, ja niistä tulee osa HTML-editoriasi. Jos painat + ESC-näppäintä pikaeditorin ulkopuolella, ne kaikki sulkeutuvat. Pikaeditori löytää myös LESS- ja + SCSS-tiedostoissa määritellyt säännöt, sisältäen sisäkkäiset sellaiset.

    - Haluatko nähdä sen toiminnassa? Aseta osoitin alla olevan -tagin päälle ja paina - Cmd/Ctrl + E. Sinun pitäisi nähdä CSS-pikaeditorin ilmestyvän alapuolelle näyttäen CSS-säännön, joka - kuuluu sille. Pikamuokkaus toimii niin class- kuin id-attribuuttien kanssa. + Haluatko nähdä sen toiminnassa? Aseta kohdistin alla olevaan -tägiin ja paina + Cmd/Ctrl + E. Sinun pitäisi nähdä, kun CSS-pikaeditori ilmestyy alapuolelle näyttäen CSS-säännön, + joka pätee siihen. Pikamuokkaus toimii toki myös class- ja id-attribuuttien kanssa. Voit käyttää sitä myös + LESS- ja SCSS-tiedostojesi kanssa. - Voit luoda uusia sääntöjä samalla tavalla. Napsauta jotakin alaosan -tageista ja paina - Cmd/Ctrl + E. Sille ei ole sääntöjä juuri nyt, mutta voit napsauttaa Uusi sääntö -painiketta lisätäksesi - uuden säännön -tageille. + Voit luoda uusia sääntöjä samalla tavalla. Napsauta yhtä alaosan -tägeistä ja paina + Cmd/Ctrl + E. Sille ei ole sääntöjä juuri nyt, mutta voit napsauttaa Uusi sääntö -painiketta + lisätäksesi uuden säännön -tägeille. - Kuvankaappaus näyttää CSS:n pikamuokkauksen + Kuvankaappaus, jossa näkyy CSS:n pikamuokkaus

    - Voit käyttää samaa näppäinyhdistelmää muokataksesi myös muita asioita, kuten funktioita JavaScriptissä, värejä ja - animaatioiden ajoitusfunktioita, ja lisäämme koko ajan yhä enemmän ominaisuuksia. Toistaiseksi sisäeditorit eivät voi - olla sisäkkäin, joten voit käyttää pikamuokkausta vain, kun osoitin on täyskokoisessa editorissa. + Voit käyttää samaa näppäinyhdistelmää muokataksesi myös muita asioita - kuten JavaScriptin funktioita, + värejä ja animaatioiden ajoitusfunktioita - ja me lisäämme koko ajan yhä enemmän ominaisuuksia. +

    +

    + Toistaiseksi sisäeditorit eivät voi olla sisäkkäin, joten voit käyttää pikamuokkausta vain silloin, kun + kohdistin on täyskokoisessa editorissa.

    Esikatsele HTML:n ja CSS:n muutoksia reaaliaikaisesti selaimessa

    - Tiedäthän sen ”tallenna/päivitä-tanssin”, jota olemme tehneet vuosia? Se, jossa tehdään muutoksia editorissa, - tallennetaan, vaihdetaan selaimeen ja sitten päivitetään tuloksen näkemiseksi viimein? Bracketsissa sinun ei - tarvitse harrastaa tätä tanssia. + Tiedäthän sen ”tallenna ja päivitä -tanssin”, jota olemme harrastaneet vuosia? Se, jossa tehdään muutoksia + editorissa, painetaan tallenna, vaihdetaan selaimeen ja sitten päivitetään, jotta tulos tulee viimein + näkyville? Bracketsissa sinun ei tarvitse harrastaa tätä tanssia.

    - Brackets avaa reaaliaikaisen yhteyden paikalliseen selaimeesi ja vie HTML:n CSS:n päivitykset samalla kun - kirjoitat! Saatat jo olla tehnyt jotain tämän kaltaista selainpohjaisilla työkaluilla, mutta Bracketsin kanssa ei - tarvitse kopioida ja liittää lopullista koodia takaisin editoriin. Koodisi suoritetaan selaimessasi, mutta se - sijaitsee editorissasi! + Brackets avaa reaaliaikaisen yhteyden paikalliseen selaimeesi ja vie HTML:n CSS:n päivitykset + samalla kun kirjoitat! Saatat olla jo tehnyt jotakin tämän kaltaista selainpohjaisilla työkaluilla, mutta + Bracketsin kanssa ei tarvitse kopioida ja liittää lopullista koodia takaisin editoriin. Koodisi suoritetaan + selaimessasi, mutta se sijaitsee editorissasi!

    Korosta HTML-elementtejä ja CSS-sääntöjä reaaliaikaisesti

    - Brackets tekee helpoksi nähdä, kuinka muutoksesi HTML:ssä ja CSS:ssä vaikuttavat sivuun. Kun osoittimesi on - CSS-säännön päällä, Brackets korostaa kaikki sääntöön liittyvät elementit selaimessa. Samoin muokatessa - HTML-tiedostoa, Brackets korostaa vastaavat HTML-elementit selaimessa. + Brackets tekee helpoksi nähdä, kuinka muutoksesi HTML:ssä ja CSS:ssä vaikuttavat sivuun. Kun kohdistin on + CSS-säännöllä, Brackets korostaa kaikki siihen liittyvät elementit selaimessa. Samalla tavoin muokattaessa + HTML-tiedostoa Brackets korostaa vastaavat HTML-elementit selaimessa.

    - Jos sinulla on Google Chrome asennettuna, voit kokeilla tätä itse. Napsauta salama-kuvaketta Brackets-ikkunan - oikeassa yläkulmassa tai paina Cmd/Ctrl + Alt + P. Kun esikatselu on käytössä HTML-dokumentissa, kaikkia - linkitettyjä CSS-dokumentteja voidaan muokata reaaliajassa. Kuvake muuttuu harmaasta kultaiseksi, kun Brackets - muodostaa yhteyden selaimeesi. + Jos sinulla on Google Chrome asennettuna, voit kokeilla tätä itse. Napsauta Brackets-ikkunan oikeassa + yläkulmassa sijaitsevaa salamakuvaketta tai paina Cmd/Ctrl + Alt + P. Kun esikatselu on käytössä + HTML-dokumentissa, kaikkia linkitettyjä CSS-dokumentteja voi muokata reaaliajassa. Kuvake muuttuu harmaasta + kultaiseksi, kun Brackets muodostaa yhteyden selaimeesi. - Aseta osoittimesi nyt yläpuolella olevan -tagin päälle. Huomaa sininen korostus, joka ilmestyy kuvan + Aseta kohdistin nyt yläpuolella olevaan -tägiin. Huomaa sininen korostus, joka ilmestyy kuvan ympärille Chromessa. Käytä seuraavaksi Cmd/Ctrl + E -näppäinyhdistelmää avataksesi määritellyt - CSS-säännöt. Yritä muuttaa reunaviivan kokoa arvosta 10px arvoon 20px tai vaihtaa taustaväriä arvosta ”transparent” - arvoon ”hotpink”. Jos Brackets ja selaimesi ovat näytöllä vierekkäin, näet muutosten heijastuvan välittömästi - selaimeesi. Siistiä, eikö? + CSS-säännöt. Yritä muuttaa reunaviivan kokoa arvosta 10px arvoon 20px tai vaihtaa taustaväriä arvosta + ”transparent” arvoon ”hotpink”. Jos Brackets ja selain ovat näytölläsi vierekkäin, näet muutosten + heijastuvan välittömästi selaimeesi. Siistiä, eikö?

    - Tällä hetkellä Brackets tukee esikatselua vain HTML:lle ja CSS:lle. Kuitenkin jo nykyisessä versiossa muutokset - JavaScript-tiedostoihin päivitetään automaattisesti tallentaessasi tiedoston. Työskentelemme tällä hetkellä - esikatselun tuomiseksi JavaScriptille. Esikatselu on myös mahdollista vain Google Chromella, mutta toivomme - pystyvämme tuomaan tämän toiminnon kaikille merkittäville selaimille tulevaisuudessa. + Nykyisellään Brackets tukee esikatselua vain HTML:lle ja CSS:lle. Kuitenkin jo nykyisessä versiossa + muutokset JavaScript-tiedostoihin päivitetään automaattisesti tallentaessasi tiedoston. Työskentelemme + parhaillaan esikatselun tuomiseksi JavaScriptille. Esikatselu on myös mahdollista vain Google Chromella, + mutta toivomme pystyvämme tuomaan tämän toiminnon kaikille pääselaimille tulevaisuudessa.

    Pikanäkymä

    - Niille meistä, joilla ei ole vielä muistissa värien vastineita HEX- tai RGB-arvoille, Brackets tekee nopeaksi ja - helpoksi nähdä täsmälleen, mitä väriä ollaan käyttämässä. Sekä CSS:ssä että HTML:ssä osoita yksinkertaisesti mitä - tahansa väriarvoa tai liukuväriä ja Brackets näyttää esikatselun tästä (liuku)väristä automaattisesti. Sama pätee - kuviin: yksinkertaisesti osoita kuvalinkkiä Brackets-editorissa ja se näyttää pikkukuvaesikatselun tästä kuvasta. + Niille meistä, jotka eivät vielä osaa ulkoa värien vastineita HEX- tai RGB-arvoille, Brackets tekee nopeaksi + ja helpoksi nähdä täsmälleen, mitä väriä on käyttämässä. Kerta kaikkiaan osoita mitä tahansa väriarvoa tai + liukuväriä joko CSS:ssä tai HTML:ssä, ja Brackets näyttää esikatselun tästä väristä tai liukuväristä + automaattisesti. Sama tulee kuviin: osoita yksinkertaisesti kuvalinkkiä Brackets-editorissa ja se näyttää + pienen esikatselukuvan tästä kuvasta.

    - Kokeillaksesi pikanäkymää itse aseta osoittimesi tämän dokumentin yläosassa olevan -tagin päälle ja - paina Cmd/Ctrl + E avataksesi CSS-pikaeditorin. Nyt yksinkertaisesti osoita mitä tahansa väriarvoista - CSS:n yhteydessä. Voit myös nähdä sen toiminnassa liukuvärin kohdalla avaamalla CSS-pikaeditorin - -tagille ja osoittamalla mitä tahansa taustakuvan arvoista. Kokeillaksesi kuvan esikatselua aseta osoittimesi tässä - dokumentissa aiemmin esiintyneen kuvankaappauskuvan päälle. + Kokeile pikanäkymää itse asettamalla kohdistimesi tämän dokumentin yläosassa sijaitsevaan + -tägiin ja painalla Cmd/Ctrl + E avataksesi CSS-pikaeditorin. Nyt yksinkertaisesti osoita mitä + tahansa CSS:n väriarvoista. Voit myös nähdä sen toiminnassa liukuväreissä avaamalla CSS-pikaeditorin + -tägille ja osoittamalla mitä tahansa taustakuva-arvoista. Kokeile kuvan esikatselua + asettamalla osoittimesi tässä dokumentissa aiemmin esiintyneen kuvankaappauskuvan päälle.

    Tarvitsetko jotakin muuta? Kokeile laajennusta!

    - Sen kaiken hyvän lisäksi, mitä Bracketsiin on rakennettu, suuri ja kasvava laajennuskehittäjien yhteisömme on tehnyt - yli sata laajennusta, jotka lisäävät hyödyllisiä toimintoja. Jos on jotakin, mitä tarvitset ja jota Brackets ei - tarjoa, enemmän kuin todennäköisesti joku on tehnyt laajennuksen siihen. Selataksesi tai hakeaksesi saatavilla - olevien laajennusten luetteloa valitse Tiedosto > Laajennusten hallinta ja napsauta ”Saatavilla”- - välilehteä. Kun löydät haluamasi laajennuksen, napsauta vain ”Asenna”-painiketta sen vierestä. -

    - -

    Projektit Bracketsissa

    -

    - Muokataksesi omaa koodiasi Bracketsia käyttäen voit vain avata tiedostosi sisältävän kansion. Brackets pitää nykyistä - avointa kansiota ”projektina”; Ominaisuudet, kuten koodivihjeet, esikatselu ja pikamuokkaus käyttävät vain tällä - hetkellä avoinna olevan kansion tiedostoja. + Sen kaiken hyvän lisäksi, jota Bracketsiin on rakennettu, on suuri ja kasvava laajennuskehittäjien + yhteisömme tehnyt satoja laajennuksia, jotka lisäävät hyödyllisiä toimintoja. Jos on jotakin, jota tarvitset + ja jota Brackets ei tarjoa, enemmän kuin todennäköisesti joku on tehnyt laajennuksen siihen. Selaa + saatavilla olevien laajennusten luetteloa tai hae siitä valitsemalla Tiedosto > Laajennusten + hallinta ja napsauttamalla ”Saatavilla”-välilehteä. Kun löydät haluamasi laajennuksen, napsauta + vain ”Asenna”-painiketta sen vierestä.

    - - Heti kun olet valmis luopumaan tästä näyteprojektista ja muokkaamaan omaa koodiasi, voit käyttää vasemman sivupalkin - pudotusvalikkoa kansioiden vaihtamiseen. Juuri nyt pudotusvalikossa lukee ”Aloitus”. Tämä on tiedoston, jota katsot - juuri nyt, sisältävä kansio. Napsauta pudotusvalikkoa ja valitse ”Avaa kansio…” avataksesi oman kansiosi. Voit - käyttää pudotusvalikkoa myös myöhemmin vaihtaaksesi takaisin kansioihin, jotka olet avannut aiemmin, sisältäen tämän - näyteprojektin. - -

    Lähde mukaan

    Brackets on avoimen lähdekoodin projekti. Web-kehittäjät ympäri maailmaa osallistuvat paremman koodieditorin - kehittämiseen. Paljon enemmän rakennetaan laajennuksia, jotka laajentavat Bracketsin kykyjä. Anna meidän tietää, + kehittämiseen. Vieläkin enemmän kehitetään laajennuksia, jotka laajentavat Bracketsin kykyjä. Kerro meille, mitä ajattelet. Jaa ideasi tai osallistu suoraan projektiin.

    diff --git a/samples/fr/Premiers pas/index.html b/samples/fr/Premiers pas/index.html index 287b2ff2a88..fac3d38fd36 100644 --- a/samples/fr/Premiers pas/index.html +++ b/samples/fr/Premiers pas/index.html @@ -18,7 +18,7 @@

    Suivez le guide !

    -->

    - Bienvenue dans cette version préliminaire de Brackets, le nouvel éditeur open source adapté au Web de demain. Nous attachons une grande importance aux normes et cherchons à créer des outils plus adaptés aux langages JavaScript, HTML et CSS ainsi qu’aux autres technologies du Web ouvert. Il s’agit là de notre modeste première contribution. + Bienvenue dans Brackets, un éditeur de code open source qui comprend et facilite la conception de sites web. Il s’agit d’un éditeur à la fois léger et puissant qui intègre des outils visuels directement dans son interface, de sorte que chaque opération peut devenir un véritable jeu d’enfant.

    Brackets se distingue des éditeurs traditionnels, - notamment par son écriture en JavaScript, HTML et CSS. - Autrement dit, la plupart des utilisateurs de Brackets disposent des capacités nécessaires pour modifier et étendre l’éditeur. - En fait, nous utilisons Brackets tous les jours pour son propre développement. Brackets propose aussi des fonctionnalités uniques, comme l’Edition rapide ou l’Aperçu en direct, que vous ne trouverez pas forcément dans d’autres éditeurs. - Pour en savoir plus sur l’utilisation de ces fonctionnalités, poursuivez votre lecture. + notamment par ses fonctionnalités uniques, comme l’Edition rapide ou l’Aperçu en direct, que vous ne trouverez pas forcément dans d’autres éditeurs. Cerise sur le gâteau, Brackets est écrit en JavaScript, en HTML et en CSS. Autrement dit, la grande majorité des utilisateurs de Brackets est capable de modifier et d’étendre l’éditeur. En fait, nous utilisons Brackets tous les jours pour son propre développement. Pour en savoir plus sur l’utilisation de ses fonctionnalités centrales, poursuivez votre lecture. +

    + + +

    Projets Brackets

    +

    + Pour éditer votre propre code à l’aide de l’application Brackets, il vous suffit d’ouvrir le dossier contenant vos fichiers. + Brackets traite le dossier ouvert en tant que « projet » ; ainsi, les fonctionnalités Indicateurs de code, Aperçu en direct ou encore Edition rapide s’appliquent uniquement aux fichiers du dossier ouvert. +

    -

    Nous testons actuellement quelques nouveautés.

    + + Si vous vous sentez prêt à franchir le cap et à éditer votre propre code, fermez cet exemple de projet et utilisez la liste déroulante de la barre latérale de gauche pour changer de dossier. Pour le moment, la liste déroulante s’intitule « Prise en main », ce qui correspond au dossier dans lequel se trouve le fichier fictif sur lequel vous vous exercez actuellement. Cliquez sur la liste déroulante et sélectionnez « Ouvrir un dossier… » pour accéder à votre propre dossier. + Par la suite, vous pourrez tout à fait revenir aux dossiers précédemment ouverts, y compris cet exemple de projet, grâce à cette même liste déroulante. + et tapez Cmd/Ctrl + E. Un éditeur rapide CSS apparaît en superposition, avec la règle CSS applicable. La fonction Edition rapide est également utilisable pour les attributs de classe et d’ID. + Une petite démonstration ? Placez le curseur de la souris sur la balise et tapez Cmd/Ctrl + E. Un éditeur rapide CSS apparaît en superposition, avec la règle CSS applicable. La fonction Edition rapide est également utilisable pour les attributs de classe et d’ID. Vous pouvez aussi vous en servir sur vos fichiers LESS et SCSS. - Vous pouvez créer de nouvelles règles en procédant de la même manière. Cliquez sur l’une des balises en haut du document et appuyez sur Cmd/Ctrl + E. Il n’existe aucune règle associée pour le moment, mais vous pouvez cliquer sur le bouton Nouvelle règle afin d’ajouter une règle pour . + Vous pouvez créer de nouvelles règles en procédant de la même manière. Cliquez sur l’une des balises en haut du document et appuyez sur Cmd/Ctrl + E</kbd>. Il n’existe aucune règle associée pour le moment, mais vous pouvez cliquer sur le bouton Nouvelle règle afin d’ajouter une règle pour . @@ -55,7 +65,9 @@

    Edition rapide des codes CSS et JavaScript

    - Vous pouvez utiliser le même raccourci pour éditer d’autres éléments, comme les fonctions dans JavaScript, les couleurs ou les fonctions de temporisation d’animation ; nous ajoutons sans cesse des nouveautés. + Vous pouvez utiliser le même raccourci pour éditer d’autres éléments, comme les fonctions dans JavaScript, les couleurs ou les fonctions de temporisation d’animation ; nous ajoutons sans cesse des nouveautés. +

    +

    Les éditeurs intégrés ne peuvent pas encore être imbriqués. Vous ne pouvez donc utiliser la fonction Edition rapide que lorsque le curseur se trouve dans un éditeur « plein écran ».

    @@ -80,7 +92,7 @@

    Mise en surbrillance en direct des éléments HTML et règles CSS

    Si vous avez installé Google Chrome, vous pouvez dès maintenant tester cette fonctionnalité. Cliquez sur l’icône représentant un éclair en haut à droite de la fenêtre Brackets ou utilisez la combinaison Cmd/Ctrl + Alt + P. Lorsque le module Aperçu en direct est activé sur un document HTML, tous les documents CSS associés peuvent être modifiés en temps réel. L’icône passe du gris au doré une fois que Brackets a établi la connexion à votre navigateur. - Placez maintenant le curseur de la souris sur la balise . Vous constatez qu’une surbrillance bleue apparaît tout autour de l’image dans Chrome. Utilisez ensuite la combinaison Cmd/Ctrl + E pour ouvrir les règles CSS définies. + Placez maintenant le curseur sur la balise . Vous constatez qu’une surbrillance bleue apparaît tout autour de l’image dans Chrome. Utilisez ensuite la combinaison Cmd/Ctrl + E pour ouvrir les règles CSS définies. Essayez de faire passer l’épaisseur de la bordure de 10 px à 20 px, ou de remplacer la couleur d’arrière-plan « transparent » par « hotpink ». Si Brackets et votre navigateur s’exécutent côte à côte, ce dernier affiche immédiatement les modifications. Plutôt sympathique, non ? @@ -99,19 +111,9 @@

    Affichage rapide

    Vous en voulez plus ? Jetez un œil du côté des extensions !

    - En plus de tous les atouts déjà intégrés à Brackets, notre communauté de développeurs, qui ne cesse de s’agrandir, a mis au point plus d’une centaine d’extensions qui offrent des fonctionnalités très pratiques. Si vous avez besoin d’une fonction qui ne se trouve pas dans Brackets, il est fort probable qu’un utilisateur ait créé l’extension qu’il vous faut. Pour parcourir la liste des extensions disponibles ou en rechercher une en particulier, cliquez sur Fichier > Extension Manager, puis ouvrez l’onglet « Disponible ». Lorsque vous trouvez l’extension qui vous convient, il vous suffit de cliquer sur le bouton Installer correspondant. -

    - -

    Projets Brackets

    -

    - Pour éditer votre propre code à l’aide de l’application Brackets, il vous suffit d’ouvrir le dossier contenant vos fichiers. Brackets traite le dossier ouvert en tant que « projet » ; ainsi, les fonctionnalités Indicateurs de code, Aperçu en direct ou encore Edition rapide s’appliquent uniquement aux fichiers du dossier ouvert. + En plus de tous les atouts déjà intégrés à Brackets, notre communauté de développeurs, qui ne cesse de s’agrandir, a mis au point des centaines d’extensions qui offrent des fonctionnalités très pratiques. Si vous avez besoin d’une fonction qui ne se trouve pas dans Brackets, il est fort probable qu’un utilisateur ait créé l’extension qu’il vous faut. Pour parcourir la liste des extensions disponibles ou en rechercher une en particulier, cliquez sur Fichier > Extension Manager, puis ouvrez l’onglet « Disponible ». Lorsque vous trouvez l’extension qui vous convient, il vous suffit de cliquer sur le bouton Installer correspondant.

    - - Si vous vous sentez prêt à franchir le cap et à éditer votre propre code, fermez cet exemple de projet et utilisez la liste déroulante de la barre latérale de gauche pour changer de dossier. Pour le moment, la liste déroulante s’intitule « Prise en main », ce qui correspond au dossier dans lequel se trouve le fichier fictif sur lequel vous vous exercez actuellement. Cliquez sur la liste déroulante et sélectionnez « Ouvrir un dossier… » pour accéder à votre propre dossier. - Par la suite, vous pourrez tout à fait revenir aux dossiers précédemment ouverts, y compris cet exemple de projet, grâce à cette même liste déroulante. - - @@ -127,8 +129,8 @@

    Participer

  • Registre des extensions Brackets
  • Wiki Brackets
  • Liste de diffusion des développeurs Brackets
  • -
  • @brackets sur Twitter
  • -
  • Discutez avec les développeurs de Brackets via IRC sur le canal #brackets du réseau Freenode.
  • +
  • @brackets on Twitter
  • +
  • Discutez avec les développeurs de Brackets via IRC sur #brackets on Freenode
  • diff --git a/samples/ja/Getting Started/index.html b/samples/ja/Getting Started/index.html index bfb99d8930c..a00dc9ee238 100644 --- a/samples/ja/Getting Started/index.html +++ b/samples/ja/Getting Started/index.html @@ -18,7 +18,7 @@

    まずはこのガイドからスタート

    -->

    - プレビュー版 Brackets に関心をお持ちいただきまして、誠にありがとうございます。Brackets は次世代の Web に向けて新開発されたオープンソースのエディターです。アドビでは標準規格を重視しており、JavaScript、HTML、CSS 用の優れたツールや、それに関連するオープンな Web テクノロジーの構築を目指しています。このプレビュー版 Brackets は、それに向けてのささやかな第一歩といえます。 + Web デザインを認識する最新のオープンソースエディター、Brackets をご利用いただき、ありがとうございます。軽量でありながらパワフルなコードエディターでのビジュアルツールとエディターとの融合により、必要なときに必要なだけのサポートを利用することができます。

    Brackets は、新しいタイプのエディターです。 - これまでのエディターと大きく異なる点は、JavaScript、HTML、CSS で記述されているということです。 - つまり、ほとんどの Brackets ユーザーは、習得済みのスキルを使って、このエディターそのものを変更したり拡張したりできるということになります。 - 実際、アドビ社内の開発チームも、毎日 Brackets を使用して Brackets の構築を進めています。また、Brackets にはクイック編集やライブプレビューなど、他のエディターにはないユニークな機能が備わっています。 - こうした機能の使用方法について、下記で詳しくご説明します。 + Brackets にはクイック編集やライブプレビューなど、他のエディターにはないユニークな機能が備わっています。Brackets は JavaScript、HTML および CSS で記述されています。つまり、ほとんどの Brackets ユーザーは、習得済みのスキルを使って、このエディターそのものを変更したり拡張したりできるということになります。実際、アドビ社内の開発チームも、毎日 Brackets を使用して Brackets の構築を進めています。主要機能の使用方法について、下記で詳しくご説明します。 +

    + + +

    Brackets のプロジェクト

    +

    + Brackets を使用して独自のコードを記述するには、自分のファイルを格納したフォルダーを開きます。 + 現時点で開いているフォルダーが Brackets によって「プロジェクト」として処理され、そのフォルダー内のファイルのみがコードヒント、ライブプレビュー、クイック編集などの機能で使用されます。 +

    -

    新しいアイデアを実装

    + + このサンプルプロジェクトを終了し、コードを編集する準備ができたら、左側のサイドバーのドロップダウンを使用してフォルダーを切り替えます。この時点で、ドロップダウンには「はじめに」が表示され、現在表示されているファイルが格納されたフォルダーが選択されています。ドロップダウンで「フォルダーを開く...」を選択して、使用するフォルダーを開きます。 + ドロップダウンを使用して、このサンプルプロジェクトが含まれるフォルダーなど、以前に開いたフォルダーに切り替えることもできます。 +

    CSS と JavaScript のクイック編集

    - いくつものドキュメントを行ったり来たりして、コードの文脈を見失うようなことはもうありません。HTML ファイルの編集中にショートカットの Command + E キーまたは Ctrl + E キーを使用すると、クイック編集用のインラインエディターが開き、関連する CSS がすべて表示されます。 - ここで CSS を調整して Esc キーを押せば、HTML の編集に戻ることができます。また、CSS ルールを開いたままにしておけば、HTML エディターの一部として使用できます。カーソルがクイック編集用インラインエディターの外にあるときに Esc キーを押すと、CSS ルールはすべて折りたたまれます。 + いくつものドキュメントを行ったり来たりして、コードの文脈を見失うようなことはもうありません。HTML ファイルの編集中にショートカットの Command+E キーまたは Ctrl+E キーを使用すると、クイック編集用のインラインエディターが開き、関連する CSS がすべて表示されます。 + ここで CSS を調整して Esc キーを押せば、HTML の編集に戻ることができます。また、CSS ルールを開いたままにしておけば、HTML エディターの一部として使用できます。カーソルがクイック編集用インラインエディターの外にあるときに Esc キーを押すと、CSS ルールはすべて折りたたまれます。また、クイック編集には、ネストされたルールなど、LESS および SCSS ファイルで定義されたルールも備わっています。

    - + - この機能を実際に使用するには、上部の タグにカーソルを合わせた状態で Command + E キーまたは Ctrl + E キーを押します。すると、上部に CSS クイック編集エディターが開き、適用する CSS ルールが表示されます。クイック編集は、クラスおよび id 属性にも使用できます。 + この機能を実際に使用するには、上部の タグにカーソルを合わせた状態で Command+E キーまたは Ctrl+E キーを押します。すると、上部に CSS クイック編集エディターが開き、適用する CSS ルールが表示されます。クイック編集は、クラスおよび id 属性にも使用できます。また、クイック編集は LESS および SCSS ファイルでも使用できます。 - 新規ルールも同じように作成できます。上部の タグのいずれかをクリックし、Command + E キーまたは Ctrl + E キーを押します。そのとき既存のルールがなければ、「新規ルール」ボタンをクリックして に新規ルールを追加できます。 + 新規ルールも同じように作成できます。上部の タグのいずれかをクリックし、Command+E キーまたは Ctrl+E キー</kbd>を押します。そのとき既存のルールがなければ、「新規ルール」ボタンをクリックして に新規ルールを追加できます。 @@ -56,6 +66,8 @@

    CSS と JavaScript のクイック編集

    同じショートカットを使用して、JavaScript の関数、カラー、アニメーションタイミング機能など、他のエレメントも編集できます。アドビでは、この機能を継続して強化していきます。 +

    +

    現時点ではインラインエディターをネストすることはできませんので、クイック編集を使用できるのは、カーソルが「フルサイズ」のエディター内にある場合に限られています。

    @@ -77,10 +89,10 @@

    HTML エレメントと CSS ルールのライブハイライト

    - お使いのコンピューターに Google Chrome がインストールされていれば、これを実際にお試しいただくことができます。Brackets ウィンドウの右上にある稲妻アイコンをクリックするか、Command + Alt + P キーまたは Ctrl + Alt + P キーを押します。HTML ドキュメントでライブプレビューが有効になっていれば、リンクされている CSS ドキュメントはすべてリアルタイムで編集可能です。 + お使いのコンピューターに Google Chrome がインストールされていれば、これを実際にお試しいただくことができます。Brackets ウィンドウの右上にある稲妻アイコンをクリックするか、Command+Alt+P キーまたは Ctrl+Alt+P キーを押します。HTML ドキュメントでライブプレビューが有効になっていれば、リンクされている CSS ドキュメントはすべてリアルタイムで編集可能です。 Brackets でローカルブラウザーとの接続が確立されると、アイコンがグレーから金色に変わります。 - この状態で、上部の タグにカーソルを合わせます。すると、Chrome 上で画像の周囲が青くハイライト表示されます。次に、Command + E キーまたは Ctrl + E キーを押して、定義済みの CSS ルールを開きます。 + この状態で、上部の タグにカーソルを合わせます。すると、Chrome 上で画像の周囲が青くハイライト表示されます。次に、Command+E キーまたは Ctrl+E キーを押して、定義済みの CSS ルールを開きます。 枠のサイズを 10 ピクセルから 20 ピクセルに変更するか、背景色を「透明」から「ホットピンク」に変更してみてください。Brackets とブラウザーが同時に動作していれば、この変更内容が瞬時にブラウザーの表示に反映されるのを確認できます。 @@ -94,30 +106,20 @@

    クイックビュー

    - クイックビューを実際に使ってみるには、このドキュメントの上部にある タグにカーソルを合わせます。その状態で Command + E キーまたは Ctrl + E キーを押すと、CSS クイック編集エディターが開きます。あとは、CSS 内でカラー値のどれかにカーソルを重ねるだけです。また、グラデーションに対してこの機能を使ってみるには、 タグで CSS クイック編集エディターを開き、背景画像の値にカーソルを重ねます。画像のプレビューを試す場合は、このドキュメントの前半に掲載されているスクリーンショット画像にカーソルを重ねてみてください。 + クイックビューを実際に使ってみるには、このドキュメントの上部にある タグにカーソルを合わせます。その状態で Command+E キーまたは Ctrl+E キーを押すと、CSS クイック編集エディターが開きます。あとは、CSS 内でカラー値のどれかにカーソルを重ねるだけです。また、グラデーションに対してこの機能を使ってみるには、 タグで CSS クイック編集エディターを開き、背景画像の値にカーソルを重ねます。画像のプレビューを試す場合は、このドキュメントの前半に掲載されているスクリーンショット画像にカーソルを重ねてみてください。

    拡張機能でさらに補強

    - Brackets に組み込まれた優れた機能に加え、拡大を続ける大規模なコミュニティで、デベロッパーらが 100 種類以上の便利な拡張機能を構築しています。Brackets にない機能を必要としたとき、ほぼ確実に構築済みの拡張機能が見つかります。使用可能な拡張機能の一覧を参照または検索するには、ファイル/Extension Manager を選択し、「入手可能」タブをクリックします。使用する拡張機能が見つかったら、その横の「インストール」ボタンをクリックします。 -

    - -

    Brackets のプロジェクト

    -

    - Brackets を使用して独自のコードを記述するには、自分のファイルを格納したフォルダーを開きます。現時点で開いているフォルダーが Brackets によって「プロジェクト」として処理され、そのフォルダー内のファイルのみがコードヒント、ライブプレビュー、クイック編集などの機能で使用されます。 + Brackets に組み込まれた優れた機能に加え、拡大を続ける大規模なコミュニティで、デベロッパーらが何百もの便利な拡張機能を構築しています。Brackets にない機能を必要としたとき、ほぼ確実に構築済みの拡張機能が見つかります。使用可能な拡張機能の一覧を参照または検索するには、ファイル/Extension Manager を選択し、「入手可能」タブをクリックします。使用する拡張機能が見つかったら、その横の「インストール」ボタンをクリックします。

    - - このサンプルプロジェクトを終了し、コードを編集する準備ができたら、左側のサイドバーのドロップダウンを使用してフォルダーを切り替えます。この時点で、ドロップダウンには「はじめに」が表示され、現在表示されているファイルが格納されたフォルダーが選択されています。ドロップダウンで「フォルダーを開く...」を選択して、使用するフォルダーを開きます。 - ドロップダウンを使用して、このサンプルプロジェクトが含まれるフォルダーなど、以前に開いたフォルダーに切り替えることもできます。 - -

    Brackets プロジェクトに参加

    - Brackets はオープンソースのプロジェクトです。世界中の Web デベロッパーが、優れたコードエディターの構築に貢献しています。さらに多くの人々が、Brackets の拡張機能の構築に携わっています。 + Brackets はオープンソースのプロジェクトです。世界中の Web 開発者が、優れたコードエディターの構築に貢献しています。さらに多くの人々が、Brackets の拡張機能の構築に携わっています。 ぜひ、このプロジェクトについてご意見・アイデアをお寄せください。プロジェクトへの直接的なご参加もお待ちしております。

    diff --git a/samples/root/Getting Started/index.html b/samples/root/Getting Started/index.html index b8bb45fc4ba..f77776d55cb 100644 --- a/samples/root/Getting Started/index.html +++ b/samples/root/Getting Started/index.html @@ -18,9 +18,9 @@

    This is your guide!

    -->

    - Welcome to an early preview of Brackets, a new open-source editor for the next generation of - the web. We're big fans of standards and want to build better tooling for JavaScript, HTML and CSS - and related open web technologies. This is our humble beginning. + Welcome to Brackets, a modern open-source code editor that understands web design. It's a lightweight, + yet powerful, code editor that blends visual tools into the editor so you get the right amount of help + when you want it.

    Brackets is a different type of editor. - One notable difference is that this editor is written in JavaScript, HTML and CSS. - This means that most of you using Brackets have the skills necessary to modify and extend the editor. - In fact, we use Brackets every day to build Brackets. It also has some unique features like Quick Edit, - Live Preview and others that you may not find in other editors. - To learn more about how to use those features, read on. + Brackets has some unique features like Quick Edit, Live Preview and others that you may not find in other + editors. And Brackets is written in JavaScript, HTML and CSS. That means that most of you using Brackets + have the skills necessary to modify and extend the editor. In fact, we use Brackets every day to build + Brackets. To learn more about how to use the key features, read on. +

    + -

    We're trying out a few new things

    +

    Projects in Brackets

    +

    + In order to edit your own code using Brackets, you can just open the folder containing your files. + Brackets treats the currently open folder as a "project"; features like Code Hints, Live Preview and + Quick Edit only use files within the currently open folder. +

    + + + Once you're ready to get out of this sample project and edit your own code, you can use the dropdown + in the left sidebar to switch folders. Right now, the dropdown says "Getting Started" - that's the + folder containing the file you're looking at right now. Click on the dropdown and choose "Open Folder…" + to open your own folder. + You can also use the dropdown later to switch back to folders you've opened previously, including this + sample project. + tag above and press Cmd/Ctrl + E. You should see a CSS quick editor appear above, showing the CSS rule that - applies to it. Quick Edit works in class and id attributes as well. + applies to it. Quick Edit works in class and id attributes as well. You can use it with your + LESS and SCSS files also. You can create new rules the same way. Click in one of the tags above and press Cmd/Ctrl + E. There are no rules for it right now, but you can click the New Rule @@ -137,29 +155,13 @@

    Quick View

    Need something else? Try an extension!

    In addition to all the goodness that's built into Brackets, our large and growing community of - extension developers has built over a hundred extensions that add useful functionality. If there's + extension developers has built hundreds of extensions that add useful functionality. If there's something you need that Brackets doesn't offer, more than likely someone has built an extension for it. To browse or search the list of available extensions, choose File > Extension Manager and click on the "Available" tab. When you find an extension you want, just click the "Install" button next to it.

    -

    Projects in Brackets

    -

    - In order to edit your own code using Brackets, you can just open the folder containing your files. - Brackets treats the currently open folder as a "project"; features like Code Hints, Live Preview and - Quick Edit only use files within the currently open folder. -

    - - - Once you're ready to get out of this sample project and edit your own code, you can use the dropdown - in the left sidebar to switch folders. Right now, the dropdown says "Getting Started" - that's the - folder containing the file you're looking at right now. Click on the dropdown and choose "Open Folder…" - to open your own folder. - You can also use the dropdown later to switch back to folders you've opened previously, including this - sample project. - - diff --git a/src/LiveDevelopment/Agents/CSSAgent.js b/src/LiveDevelopment/Agents/CSSAgent.js index e369eab3c89..eb5dd98a94a 100644 --- a/src/LiveDevelopment/Agents/CSSAgent.js +++ b/src/LiveDevelopment/Agents/CSSAgent.js @@ -91,19 +91,6 @@ define(function CSSAgent(require, exports, module) { return styles; } - /** - * Use styleSheetAdded and styleSheetRemoved events. - * Get a list of all loaded stylesheet files by URL. - * @deprecated - */ - function getStylesheetURLs() { - var styleSheetId, urls = []; - for (styleSheetId in _styleSheetDetails) { - urls[_styleSheetDetails[styleSheetId].canonicalizedURL] = true; - } - return _.keys(urls); - } - /** * Reload a CSS style sheet from a document * @param {Document} document @@ -242,7 +229,6 @@ define(function CSSAgent(require, exports, module) { // Export public functions exports.enable = enable; exports.styleForURL = styleForURL; - exports.getStylesheetURLs = getStylesheetURLs; exports.reloadCSSForDocument = reloadCSSForDocument; exports.clearCSSForDocument = clearCSSForDocument; exports.load = load; diff --git a/src/LiveDevelopment/Agents/GotoAgent.js b/src/LiveDevelopment/Agents/GotoAgent.js index e5eac3a1347..9107a86d279 100644 --- a/src/LiveDevelopment/Agents/GotoAgent.js +++ b/src/LiveDevelopment/Agents/GotoAgent.js @@ -33,14 +33,14 @@ define(function GotoAgent(require, exports, module) { require("utils/Global"); - var Inspector = require("LiveDevelopment/Inspector/Inspector"); - var DOMAgent = require("LiveDevelopment/Agents/DOMAgent"); - var ScriptAgent = require("LiveDevelopment/Agents/ScriptAgent"); - var RemoteAgent = require("LiveDevelopment/Agents/RemoteAgent"); - - var DocumentManager = require("document/DocumentManager"); - var EditorManager = require("editor/EditorManager"); - var MainViewManager = require("view/MainViewManager"); + var Inspector = require("LiveDevelopment/Inspector/Inspector"), + DOMAgent = require("LiveDevelopment/Agents/DOMAgent"), + ScriptAgent = require("LiveDevelopment/Agents/ScriptAgent"), + RemoteAgent = require("LiveDevelopment/Agents/RemoteAgent"), + EditorManager = require("editor/EditorManager"), + CommandManager = require("command/CommandManager"), + Commands = require("command/Commands"); + /** Return the URL without the query string * @param {string} URL @@ -168,9 +168,8 @@ define(function GotoAgent(require, exports, module) { var path = url.slice(brackets.platform === "win" ? 8 : 7); // URL-decode the path ('%20' => ' ') path = decodeURI(path); - var promise = DocumentManager.getDocumentForPath(path); + var promise = CommandManager.execute(Commands.FILE_OPEN, {fullPath: path}); promise.done(function onDone(doc) { - MainViewManager._edit(MainViewManager.ACTIVE_PANE, doc); if (location) { openLocation(location, noFlash); } diff --git a/src/LiveDevelopment/Documents/CSSDocument.js b/src/LiveDevelopment/Documents/CSSDocument.js index 13df847e5ed..86a1ca6095b 100644 --- a/src/LiveDevelopment/Documents/CSSDocument.js +++ b/src/LiveDevelopment/Documents/CSSDocument.js @@ -93,16 +93,6 @@ define(function CSSDocumentModule(require, exports, module) { return CSSAgent.styleForURL(this.doc.url); }; - /** - * CSSStyleSheetBody was removed in protocol 1.1. This method is unused in Brackets 36. - * Get the browser version of the StyleSheet object - * @deprecated - * @return {jQuery.promise} - */ - CSSDocument.prototype.getStyleSheetFromBrowser = function getStyleSheetFromBrowser() { - return new $.Deferred().reject().promise(); - }; - /** * Get the browser version of the source * @return {jQuery.promise} Promise resolved with the text content of this CSS document diff --git a/src/base-config/keyboard.json b/src/base-config/keyboard.json index 891d30e61d4..eed48add7cc 100644 --- a/src/base-config/keyboard.json +++ b/src/base-config/keyboard.json @@ -1,4 +1,4 @@ -{ +{ "file.newDoc": [ "Ctrl-N" ], @@ -161,7 +161,7 @@ "key": "Ctrl-Shift-H" }, { - "key": "Cmd-Alt-Shift-F", + "key": "Cmd-Opt-Shift-F", "platform": "mac" } ], @@ -207,7 +207,7 @@ "key": "Ctrl-H" }, { - "key": "Cmd-Alt-F", + "key": "Cmd-Opt-F", "platform": "mac" } ], @@ -223,17 +223,16 @@ "view.increaseFontSize": [ { "key": "Ctrl-=", - "displayKey": "Cmd-+" + "displayKey": "Ctrl-+" }, { - "key": "Ctrl-+", - "displayKey": "Cmd-+" + "key": "Ctrl-+" } ], "view.decreaseFontSize": [ { "key": "Ctrl--", - "displayKey": "Cmd-−" + "displayKey": "Ctrl-−" } ], "view.restoreFontSize": [ @@ -245,8 +244,8 @@ "displayKey": "Ctrl-\u2191" }, { - "key": "Ctrl-Alt-Up", - "displayKey": "Ctrl-Alt-\u2191", + "key": "Ctrl-Opt-Up", + "displayKey": "Ctrl-Opt-\u2191", "platform": "mac" } ], @@ -256,8 +255,8 @@ "displayKey": "Ctrl-\u2193" }, { - "key": "Ctrl-Alt-Down", - "displayKey": "Ctrl-Alt-\u2193", + "key": "Ctrl-Opt-Down", + "displayKey": "Ctrl-Opt-\u2193", "platform": "mac" } ], @@ -333,7 +332,7 @@ } ], "navigate.newRule": [ - "Cmd-Alt-N" + "Ctrl-Alt-N" ], "file.rename": [ "F2" diff --git a/src/brackets.js b/src/brackets.js index 094e3902f94..e0d5e728334 100644 --- a/src/brackets.js +++ b/src/brackets.js @@ -135,8 +135,6 @@ define(function (require, exports, module) { require("extensibility/ExtensionManagerDialog"); require("editor/ImageViewer"); - // Deprecated modules loaded just so extensions can still use them for now - require("utils/CollectionUtils"); // Compatibility shims for filesystem API migration require("project/FileIndexManager"); require("file/NativeFileSystem"); diff --git a/src/command/Commands.js b/src/command/Commands.js index 82035ea82a7..87d0466caec 100644 --- a/src/command/Commands.js +++ b/src/command/Commands.js @@ -1,16 +1,16 @@ /* * 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 @@ -18,7 +18,7 @@ * 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. - * + * */ @@ -56,6 +56,7 @@ define(function (require, exports, module) { exports.FILE_EXTENSION_MANAGER = "file.extensionManager"; // ExtensionManagerDialog.js _showDialog() exports.FILE_REFRESH = "file.refresh"; // ProjectManager.js refreshFileTree() exports.FILE_OPEN_PREFERENCES = "file.openPreferences"; // PreferencesManager.js _handleOpenPreferences() + exports.FILE_OPEN_KEYMAP = "file.openKeyMap"; // KeyBindingManager.js _openUserKeyMap() // File shell callbacks - string must MATCH string in native code (appshell/command_callbacks.h) exports.FILE_CLOSE_WINDOW = "file.close_window"; // DocumentCommandHandlers.js handleFileCloseWindow() @@ -175,16 +176,5 @@ define(function (require, exports, module) { DeprecationWarning.deprecateConstant(exports, "SORT_WORKINGSET_BY_NAME", "CMD_WORKINGSET_SORT_BY_NAME"); DeprecationWarning.deprecateConstant(exports, "SORT_WORKINGSET_BY_TYPE", "CMD_WORKINGSET_SORT_BY_TYPE"); DeprecationWarning.deprecateConstant(exports, "SORT_WORKINGSET_AUTO", "CMD_WORKING_SORT_TOGGLE_AUTO"); - - // DEPRECATED: Edit commands that were moved from the Edit Menu to the Find Menu - DeprecationWarning.deprecateConstant(exports, "EDIT_FIND", "CMD_FIND"); - DeprecationWarning.deprecateConstant(exports, "EDIT_FIND_IN_SELECTED", "CMD_FIND_IN_SELECTED"); - DeprecationWarning.deprecateConstant(exports, "EDIT_FIND_IN_SUBTREE", "CMD_FIND_IN_SUBTREE"); - DeprecationWarning.deprecateConstant(exports, "EDIT_FIND_NEXT", "CMD_FIND_NEXT"); - DeprecationWarning.deprecateConstant(exports, "EDIT_FIND_PREVIOUS", "CMD_FIND_PREVIOUS"); - DeprecationWarning.deprecateConstant(exports, "EDIT_FIND_ALL_AND_SELECT", "CMD_FIND_ALL_AND_SELECT"); - DeprecationWarning.deprecateConstant(exports, "EDIT_ADD_NEXT_MATCH", "CMD_ADD_NEXT_MATCH"); - DeprecationWarning.deprecateConstant(exports, "EDIT_SKIP_CURRENT_MATCH", "CMD_SKIP_CURRENT_MATCH"); - DeprecationWarning.deprecateConstant(exports, "EDIT_REPLACE", "CMD_REPLACE"); }); diff --git a/src/command/KeyBindingManager.js b/src/command/KeyBindingManager.js index d55a81e4d4c..caebbd39c4f 100644 --- a/src/command/KeyBindingManager.js +++ b/src/command/KeyBindingManager.js @@ -34,26 +34,81 @@ define(function (require, exports, module) { require("utils/Global"); - var AppInit = require("utils/AppInit"), - CommandManager = require("command/CommandManager"), - KeyEvent = require("utils/KeyEvent"), - Strings = require("strings"); + var AppInit = require("utils/AppInit"), + Commands = require("command/Commands"), + CommandManager = require("command/CommandManager"), + DefaultDialogs = require("widgets/DefaultDialogs"), + FileSystem = require("filesystem/FileSystem"), + FileSystemError = require("filesystem/FileSystemError"), + FileUtils = require("file/FileUtils"), + KeyEvent = require("utils/KeyEvent"), + Strings = require("strings"), + StringUtils = require("utils/StringUtils"), + UrlParams = require("utils/UrlParams").UrlParams, + _ = require("thirdparty/lodash"); - var KeyboardPrefs = JSON.parse(require("text!base-config/keyboard.json")); + var KeyboardPrefs = JSON.parse(require("text!base-config/keyboard.json")); + var KEYMAP_FILENAME = "keymap.json", + _userKeyMapFilePath = brackets.app.getApplicationSupportDirectory() + "/" + KEYMAP_FILENAME; + /** * @private * Maps normalized shortcut descriptor to key binding info. * @type {!Object.} */ - var _keyMap = {}; + var _keyMap = {}, // For the actual key bindings including user specified ones + // For the default factory key bindings, cloned from _keyMap after all extensions are loaded. + _defaultKeyMap = {}; + /** + * @typedef {{shortcut: !string, + * commandID: ?string}} UserKeyBinding + */ + + /** + * @private + * Maps shortcut descriptor to a command id. + * @type {UserKeyBinding} + */ + var _customKeyMap = {}, + _customKeyMapCache = {}; + /** * @private * Maps commandID to the list of shortcuts that are bound to it. * @type {!Object.>} */ - var _commandMap = {}; + var _commandMap = {}, + _allCommands = []; + + /** + * @private + * Maps key names to the corresponding unicode symols + * @type {{key: string, displayKey: string}} + */ + var _displayKeyMap = { "up": "\u2191", + "down": "\u2193", + "left": "\u2190", + "right": "\u2192", + "-": "\u2212" }; + + var _specialCommands = [Commands.EDIT_UNDO, Commands.EDIT_REDO, Commands.EDIT_SELECT_ALL, + Commands.EDIT_CUT, Commands.EDIT_COPY, Commands.EDIT_PASTE], + _reservedShortcuts = ["Ctrl-Z", "Ctrl-Y", "Ctrl-A", "Ctrl-X", "Ctrl-C", "Ctrl-V"], + _macReservedShortcuts = ["Cmd-,", "Cmd-H", "Cmd-Alt-H", "Cmd-M", "Cmd-Shift-Z", "Cmd-Q"], + _keyNames = ["Up", "Down", "Left", "Right", "Backspace", "Enter", "Space", "Tab"]; + + /** + * @private + * Flag to show key binding errors in the key map file. Default is true and + * it will be set to false when reloading without extensions. This flag is not + * used to suppress errors in loading or parsing the key map file. So if the key + * map file is corrupt, then the error dialog still shows up. + * + * @type {boolean} + */ + var _showErrors = true; /** * @private @@ -74,8 +129,12 @@ define(function (require, exports, module) { */ function _reset() { _keyMap = {}; + _defaultKeyMap = {}; + _customKeyMap = {}; + _customKeyMapCache = {}; _commandMap = {}; _globalKeydownHooks = []; + _userKeyMapFilePath = brackets.app.getApplicationSupportDirectory() + "/" + KEYMAP_FILENAME; } /** @@ -152,11 +211,19 @@ define(function (require, exports, module) { hasCtrl = true; } } else if (_compareModifierString("cmd", ele)) { - hasCtrl = true; + if (brackets.platform === "mac") { + hasCtrl = true; + } else { + error = true; + } } else if (_compareModifierString("alt", ele)) { hasAlt = true; } else if (_compareModifierString("opt", ele)) { - hasAlt = true; + if (brackets.platform === "mac") { + hasAlt = true; + } else { + error = true; + } } else if (_compareModifierString("shift", ele)) { hasShift = true; } else if (key.length > 0) { @@ -183,6 +250,21 @@ define(function (require, exports, module) { return null; } + // Ensure that the first letter of the key name is in upper case. + // i.e. 'a' => 'A' and 'up' => 'Up' + if (/^[a-z]/.test(key)) { + key = key.toLowerCase().replace(/(^[a-z])/, function (match, p1) { + return p1.toUpperCase(); + }); + } + + // No restriction on single character key yet, but other key names are restricted to either + // Function keys or those listed in _keyNames array. + if (key.length > 1 && !/F\d+/.test(key) && + _keyNames.indexOf(key) === -1) { + return null; + } + return _buildKeyDescriptor(hasMacCtrl, hasCtrl, hasAlt, hasShift, key); } @@ -268,6 +350,8 @@ define(function (require, exports, module) { key = "Tab"; } else if (key === " ") { key = "Space"; + } else if (key === "\b") { + key = "Backspace"; } else { key = _mapKeycodeToKey(event.keyCode, key); } @@ -374,6 +458,12 @@ define(function (require, exports, module) { targetPlatform = brackets.platform; } + + // Skip if the key binding is not for this platform. + if (explicitPlatform === "mac" && brackets.platform !== "mac") { + return null; + } + // if the request does not specify an explicit platform, and we're // currently on a mac, then replace Ctrl with Cmd. key = (keyBinding.key) || keyBinding; @@ -383,6 +473,7 @@ define(function (require, exports, module) { keyBinding.displayKey = keyBinding.displayKey.replace("Ctrl", "Cmd"); } } + normalized = normalizeKeyDescriptorString(key); // skip if the key binding is invalid @@ -504,11 +595,14 @@ define(function (require, exports, module) { } /** - * Returns a copy of the keymap + * Returns a copy of the current key map. If the optional 'defaults' parameter is true, + * then a copy of the default key map is returned. + * @param {boolean=} defaults true if the caller wants a copy of the default key map. + * Otherwise, the current active key map is returned. * @return {!Object.} */ - function getKeymap() { - return $.extend({}, _keyMap); + function getKeymap(defaults) { + return $.extend({}, defaults ? _defaultKeyMap : _keyMap); } /** @@ -568,7 +662,7 @@ define(function (require, exports, module) { * Returns record(s) for valid key binding(s) */ function addBinding(command, keyBindings, platform) { - var commandID = "", + var commandID = "", results; if (!command) { @@ -719,10 +813,443 @@ define(function (require, exports, module) { (brackets.platform !== "win"); }); + /** + * @private + * Displays an error dialog and also opens the user key map file for editing only if + * the error is not the loading file error. + * + * @param {?string} err Error type returned from JSON parser or open file operation + * @param {string=} message Error message to be displayed in the dialog + */ + function _showErrorsAndOpenKeyMap(err, message) { + // Asynchronously loading Dialogs module to avoid the circular dependency + require(["widgets/Dialogs"], function (Dialogs) { + var errorMessage = Strings.ERROR_KEYMAP_CORRUPT; + + if (err === FileSystemError.UNSUPPORTED_ENCODING) { + errorMessage = Strings.ERROR_LOADING_KEYMAP; + } else if (message) { + errorMessage = message; + } + + Dialogs.showModalDialog( + DefaultDialogs.DIALOG_ID_ERROR, + Strings.ERROR_KEYMAP_TITLE, + errorMessage + ) + .done(function () { + if (err !== FileSystemError.UNSUPPORTED_ENCODING) { + CommandManager.execute(Commands.FILE_OPEN_KEYMAP); + } + }); + }); + } + + /** + * @private + * + * Checks whether the given command ID is a special command that the user can't bind + * to another shortcut. + * @param {!string} commandID A string referring to a specific command + * @return {boolean} true if normalizedKey is a special command, false otherwise. + */ + function _isSpecialCommand(commandID) { + if (brackets.platform === "mac" && commandID === "file.quit") { + return true; + } + + return (_specialCommands.indexOf(commandID) > -1); + } + + /** + * @private + * + * Checks whether the given key combination is a shortcut of a special command + * or a Mac system command that the user can't reassign to another command. + * @param {!string} normalizedKey A key combination string used for a keyboard shortcut + * @return {boolean} true if normalizedKey is a restricted shortcut, false otherwise. + */ + function _isReservedShortcuts(normalizedKey) { + if (!normalizedKey) { + return false; + } + + if (_reservedShortcuts.indexOf(normalizedKey) > -1 || + _reservedShortcuts.indexOf(normalizedKey.replace("Cmd", "Ctrl")) > -1) { + return true; + } + + if (brackets.platform === "mac" && _macReservedShortcuts.indexOf(normalizedKey) > -1) { + return true; + } + + return false; + } + + /** + * @private + * + * Creates a bullet list item for any item in the given list. + * @param {Array.} list An array of strings to be converted into a + * message string with a bullet list. + * @return {string} the html text version of the list + */ + function _getBulletList(list) { + var message = "
      "; + list.forEach(function (info) { + message += "
    • " + info + "
    • "; + }); + message += "
    "; + return message; + } + + /** + * @private + * + * Gets the corresponding unicode symbol of an arrow key for display in the menu. + * @param {string} key The non-modifier key used in the shortcut. It does not need to be normalized. + * @return {string} An empty string if key is not one of those we want to show with the unicode symbol. + * Otherwise, the corresponding unicode symbol is returned. + */ + function _getDisplayKey(key) { + var displayKey = "", + match = key ? key.match(/(Up|Down|Left|Right|\-)$/i) : null; + if (match) { + displayKey = key.substr(0, match.index) + _displayKeyMap[match[0].toLowerCase()]; + } + return displayKey; + } + + /** + * @private + * + * Applies each user key binding to all the affected commands and updates _keyMap. + * Shows errors in a dialog and then opens the user key map file if any of the following + * is detected while applying the user key bindings. + * - A key binding is attempting to modify a special command. + * - A key binding is attempting to assign a shortcut of a special command to another one. + * - Multiple key bindings are specified for the same command ID. + * - The same key combination is listed for multiple key bindings. + * - A key binding has any invalid key syntax. + * - A key binding is referring to a non-existent command ID. + */ + function _applyUserKeyBindings() { + var remappedCommands = [], + remappedKeys = [], + restrictedCommands = [], + restrictedKeys = [], + invalidKeys = [], + invalidCommands = [], + multipleKeys = [], + duplicateBindings = [], + errorMessage = ""; + + _.forEach(_customKeyMap, function (commandID, key) { + var normalizedKey = normalizeKeyDescriptorString(key), + existingBindings = _commandMap[commandID] || []; + + // Skip this since we don't allow user to update key binding of a special + // command like cut, copy, paste, undo, redo and select all. + if (_isSpecialCommand(commandID)) { + restrictedCommands.push(commandID); + return; + } + + // Skip this since we don't allow user to update a shortcut used in + // a special command or any Mac system command. + if (_isReservedShortcuts(normalizedKey)) { + restrictedKeys.push(key); + return; + } + + // Skip this if the key is invalid. + if (!normalizedKey) { + invalidKeys.push(key); + return; + } + + if (_isKeyAssigned(normalizedKey)) { + if (remappedKeys.indexOf(normalizedKey) !== -1) { + // JSON parser already removed all the duplicates that have the exact + // same case or order in their keys. So we're only detecting duplicate + // bindings that have different orders or different cases used in the key. + duplicateBindings.push(key); + return; + } + // The same key binding already exists, so skip this. + if (_keyMap[normalizedKey].commandID === commandID) { + // Still need to add it to the remappedCommands so that + // we can detect any duplicate later on. + remappedCommands.push(commandID); + return; + } + removeBinding(normalizedKey); + } + + if (remappedKeys.indexOf(normalizedKey) === -1) { + remappedKeys.push(normalizedKey); + } + + // Remove another key binding if the new key binding is for a command + // that has a different key binding. e.g. "Ctrl-W": "edit.selectLine" + // requires us to remove "Ctrl-W" from "file.close" command, but we + // also need to remove "Ctrl-L" from "edit.selectLine". + if (existingBindings.length) { + existingBindings.forEach(function (binding) { + removeBinding(binding.key); + }); + } + + if (commandID) { + if (_allCommands.indexOf(commandID) !== -1) { + if (remappedCommands.indexOf(commandID) === -1) { + var keybinding = { key: normalizedKey }; + + keybinding.displayKey = _getDisplayKey(normalizedKey); + addBinding(commandID, keybinding.displayKey ? keybinding : normalizedKey, brackets.platform); + remappedCommands.push(commandID); + } else { + multipleKeys.push(commandID); + } + } else { + invalidCommands.push(commandID); + } + } + }); + + if (restrictedCommands.length) { + errorMessage = StringUtils.format(Strings.ERROR_RESTRICTED_COMMANDS, _getBulletList(restrictedCommands)); + } + + if (restrictedKeys.length) { + errorMessage += StringUtils.format(Strings.ERROR_RESTRICTED_SHORTCUTS, _getBulletList(restrictedKeys)); + } + + if (multipleKeys.length) { + errorMessage += StringUtils.format(Strings.ERROR_MULTIPLE_SHORTCUTS, _getBulletList(multipleKeys)); + } + + if (duplicateBindings.length) { + errorMessage += StringUtils.format(Strings.ERROR_DUPLICATE_SHORTCUTS, _getBulletList(duplicateBindings)); + } + + if (invalidKeys.length) { + errorMessage += StringUtils.format(Strings.ERROR_INVALID_SHORTCUTS, _getBulletList(invalidKeys)); + } + + if (invalidCommands.length) { + errorMessage += StringUtils.format(Strings.ERROR_NONEXISTENT_COMMANDS, _getBulletList(invalidCommands)); + } + + if (_showErrors && errorMessage) { + _showErrorsAndOpenKeyMap("", errorMessage); + } + } + + /** + * @private + * + * Restores the default key bindings for all the commands that are modified by each key binding + * specified in _customKeyMapCache (old version) but no longer specified in _customKeyMap (new version). + */ + function _undoPriorUserKeyBindings() { + _.forEach(_customKeyMapCache, function (commandID, key) { + var normalizedKey = normalizeKeyDescriptorString(key), + defaults = _.find(_.toArray(_defaultKeyMap), { "commandID": commandID }), + defaultCommand = _defaultKeyMap[normalizedKey]; + + // We didn't modified this before, so skip it. + if (_isSpecialCommand(commandID) || + _isReservedShortcuts(normalizedKey)) { + return; + } + + if (_isKeyAssigned(normalizedKey) && + _customKeyMap[key] !== commandID && _customKeyMap[normalizedKey] !== commandID) { + // Unassign the key from any command. e.g. "Cmd-W": "file.open" in _customKeyMapCache + // will require us to remove Cmd-W shortcut from file.open command. + removeBinding(normalizedKey); + + // Reassign the default key binding. e.g. "Cmd-W": "file.open" in _customKeyMapCache + // will require us to reassign Cmd-O shortcut to file.open command. + if (defaults) { + addBinding(commandID, defaults, brackets.platform); + } + + // Reassign the default key binding of the previously modified command. + // e.g. "Cmd-W": "file.open" in _customKeyMapCache will require us to reassign Cmd-W + // shortcut to file.close command. + if (defaultCommand && defaultCommand.key) { + addBinding(defaultCommand.commandID, defaultCommand.key, brackets.platform); + } + } + }); + } + + /** + * @private + * + * Gets the full file path to the user key map file. In testing environment + * a different file path is returned so that running integration tests won't + * pop up the error dialog showing the errors from the actual user key map file. + * + * @return {string} full file path to the user key map file. + */ + function _getUserKeyMapFilePath() { + if (window.isBracketsTestWindow) { + return brackets.app.getApplicationSupportDirectory() + "/_test_/" + KEYMAP_FILENAME; + } + return _userKeyMapFilePath; + } + + /** + * @private + * + * Reads in the user key map file and parses its content into JSON. + * Returns the user key bindings if JSON has "overrides". + * Otherwise, returns an empty object or an error if the file + * cannot be parsed or loaded. + * + * @return {$.Promise} a jQuery promise that will be resolved with the JSON + * object if the user key map file has "overrides" property or an empty JSON. + * If the key map file cannot be read or cannot be parsed by the JSON parser, + * then the promise is rejected with an error. + */ + function _readUserKeyMap() { + var file = FileSystem.getFileForPath(_getUserKeyMapFilePath()), + result = new $.Deferred(); + + file.exists(function (err, doesExist) { + if (doesExist) { + FileUtils.readAsText(file) + .done(function (text) { + var keyMap = {}; + try { + if (text) { + var json = JSON.parse(text); + // If no overrides, return an empty key map. + result.resolve((json && json.overrides) || keyMap); + } else { + // The file is empty, so return an empty key map. + result.resolve(keyMap); + } + } catch (err) { + // Cannot parse the text read from the key map file. + result.reject(err); + } + }) + .fail(function (err) { + // Key map file cannot be loaded. + result.reject(err); + }); + } else { + // Just resolve if no user key map file + result.resolve(); + } + }); + return result.promise(); + } + + /** + * @private + * + * Reads in the user key bindings and updates the key map with each user key + * binding by removing the existing one assigned to each key and adding + * new one for the specified command id. Shows errors and opens the user + * key map file if it cannot be parsed. + */ + function _loadUserKeyMap() { + _readUserKeyMap() + .then(function (keyMap) { + _customKeyMapCache = _.cloneDeep(_customKeyMap); + _customKeyMap = keyMap; + _undoPriorUserKeyBindings(); + _applyUserKeyBindings(); + }, function (err) { + _showErrorsAndOpenKeyMap(err); + }); + } + + /** + * @private + * + * Opens the existing key map file or creates a new one with default content + * if it does not exist. + */ + function _openUserKeyMap() { + var userKeyMapPath = _getUserKeyMapFilePath(), + file = FileSystem.getFileForPath(userKeyMapPath); + file.exists(function (err, doesExist) { + if (doesExist) { + CommandManager.execute(Commands.FILE_OPEN, { fullPath: userKeyMapPath }); + } else { + var defaultContent = "{\n \"documentation\": \"https://github.com/adobe/brackets/wiki/User-Key-Bindings\"," + + "\n \"overrides\": {" + + "\n \n }\n}\n"; + + FileUtils.writeText(file, defaultContent, true) + .done(function () { + CommandManager.execute(Commands.FILE_OPEN, { fullPath: userKeyMapPath }); + }); + } + }); + } + $(CommandManager).on("commandRegistered", _handleCommandRegistered); + CommandManager.register(Strings.CMD_OPEN_KEYMAP, Commands.FILE_OPEN_KEYMAP, _openUserKeyMap); + + // Asynchronously loading DocumentManager to avoid the circular dependency + require(["document/DocumentManager"], function (DocumentManager) { + $(DocumentManager).on("documentSaved", function checkKeyMapUpdates(e, doc) { + if (doc && doc.file.fullPath === _userKeyMapFilePath) { + _loadUserKeyMap(); + } + }); + }); + + /** + * @private + * + * Initializes _allCommands array and _defaultKeyMap so that we can use them for + * detecting non-existent commands and restoring the original key binding. + * + * @param {string} fullPath file path to the user key map file. + */ + function _initCommandAndKeyMaps() { + _allCommands = CommandManager.getAll(); + // Keep a copy of the default key bindings before loading user key bindings. + _defaultKeyMap = _.cloneDeep(_keyMap); + } + + /** + * @private + * + * Sets the full file path to the user key map file. Only used by unit tests + * to load a test file instead of the actual user key map file. + * + * @param {string} fullPath file path to the user key map file. + */ + function _setUserKeyMapFilePath(fullPath) { + _userKeyMapFilePath = fullPath; + } + + AppInit.extensionsLoaded(function () { + var params = new UrlParams(); + params.parse(); + if (params.get("reloadWithoutUserExts") === "true") { + _showErrors = false; + } + + _initCommandAndKeyMaps(); + _loadUserKeyMap(); + }); // unit test only exports._reset = _reset; + exports._setUserKeyMapFilePath = _setUserKeyMapFilePath; + exports._getDisplayKey = _getDisplayKey; + exports._loadUserKeyMap = _loadUserKeyMap; + exports._initCommandAndKeyMaps = _initCommandAndKeyMaps; // Define public API exports.getKeymap = getKeymap; diff --git a/src/command/Menus.js b/src/command/Menus.js index 7fdfd7097fd..019aada3db5 100644 --- a/src/command/Menus.js +++ b/src/command/Menus.js @@ -94,10 +94,6 @@ define(function (require, exports, module) { EDIT_CODE_HINTS_COMMANDS: {sectionMarker: Commands.SHOW_CODE_HINTS}, EDIT_TOGGLE_OPTIONS: {sectionMarker: Commands.TOGGLE_CLOSE_BRACKETS}, - // DEPRECATED: Old Edit menu sections redirected to existing Edit menu section - EDIT_FIND_COMMANDS: {sectionMarker: Commands.TOGGLE_CLOSE_BRACKETS}, - EDIT_REPLACE_COMMANDS: {sectionMarker: Commands.TOGGLE_CLOSE_BRACKETS}, - FIND_FIND_COMMANDS: {sectionMarker: Commands.CMD_FIND}, FIND_FIND_IN_COMMANDS: {sectionMarker: Commands.CMD_FIND_IN_FILES}, FIND_REPLACE_COMMANDS: {sectionMarker: Commands.CMD_REPLACE}, @@ -558,14 +554,6 @@ define(function (require, exports, module) { name, commandID; - if (relativeID === MenuSection.EDIT_FIND_COMMANDS) { - DeprecationWarning.deprecationWarning("Add " + command + " Command to the Find Menu instead of the Edit Menu.", true); - DeprecationWarning.deprecationWarning("Use MenuSection.FIND_FIND_COMMANDS instead of MenuSection.EDIT_FIND_COMMANDS.", true); - } else if (relativeID === MenuSection.EDIT_REPLACE_COMMANDS) { - DeprecationWarning.deprecationWarning("Add " + command + " Command to the Find Menu instead of the Edit Menu.", true); - DeprecationWarning.deprecationWarning("Use MenuSection.FIND_REPLACE_COMMANDS instead of MenuSection.EDIT_REPLACE_COMMANDS.", true); - } - if (!command) { console.error("addMenuItem(): missing required parameters: command"); return null; diff --git a/src/config.json b/src/config.json index 04f71689b8a..4a59a4887c2 100644 --- a/src/config.json +++ b/src/config.json @@ -22,8 +22,8 @@ "build_timestamp": "" }, "name": "Brackets", - "version": "0.45.0-0", - "apiVersion": "0.45.0", + "version": "1.1.0-0", + "apiVersion": "1.1.0", "homepage": "http://brackets.io", "issues": { "url": "http://github.com/adobe/brackets/issues" @@ -39,7 +39,7 @@ "jasmine-node": "1.11.0", "grunt-jasmine-node": "0.1.0", "grunt-cli": "0.1.9", - "phantomjs": "1.9.0-1", + "phantomjs": "1.9.11", "grunt-lib-phantomjs": "0.3.0", "grunt-contrib-jshint": "0.6.0", "grunt-contrib-watch": "0.4.3", @@ -57,6 +57,7 @@ "grunt-usemin": "0.1.11", "load-grunt-tasks": "0.2.0", "q": "0.9.2", + "semver": "^4.1.0", "jshint": "2.1.4", "xmldoc": "^0.1.2" }, diff --git a/src/document/DocumentCommandHandlers.js b/src/document/DocumentCommandHandlers.js index 0432e47359d..25f1fff634f 100644 --- a/src/document/DocumentCommandHandlers.js +++ b/src/document/DocumentCommandHandlers.js @@ -873,7 +873,7 @@ define(function (require, exports, module) { // explictly allow "blind" writes to the filesystem in this case, // ignoring warnings about the contents being modified outside of // the editor. - FileUtils.writeText(newFile, doc.getText(), true) + FileUtils.writeText(newFile, doc.getText(true), true) .done(function () { // If there were unsaved changes before Save As, they don't stay with the old // file anymore - so must revert the old doc to match disk content. diff --git a/src/document/DocumentManager.js b/src/document/DocumentManager.js index c5409022737..c95290196df 100644 --- a/src/document/DocumentManager.js +++ b/src/document/DocumentManager.js @@ -115,7 +115,7 @@ define(function (require, exports, module) { /** * Returns the existing open Document for the given file, or null if the file is not open ('open' * means referenced by the UI somewhere). If you will hang onto the Document, you must addRef() - * it; see {@link getDocumentForPath()} for details. + * it; see {@link #getDocumentForPath} for details. * @param {!string} fullPath * @return {?Document} */ @@ -586,6 +586,24 @@ define(function (require, exports, module) { $(exports).triggerHandler("dirtyFlagChange", doc); if (doc.isDirty) { MainViewManager.addToWorkingSet(MainViewManager.ACTIVE_PANE, doc.file); + + // We just dirtied a doc and added it to the active working set + // this may have come from an internal dirtying so if it was + // added to a working set that had no active document then + // open the document + // + // See: https://github.com/adobe/brackets/issues/9569 + // + // NOTE: Adding a file to the active working set may not actually add + // it to the active working set (e.g. the document was already + // opened to the inactive working set.) + // + // Check that it was actually added to the active working set + + if (!MainViewManager.getCurrentlyViewedFile() && + MainViewManager.findInWorkingSet(MainViewManager.ACTIVE_PANE, doc.file.fullPath) !== -1) { + CommandManager.execute(Commands.FILE_OPEN, {fullPath: doc.file.fullPath}); + } } }) .on("_documentSaved", function (event, doc) { diff --git a/src/editor/CSSInlineEditor.js b/src/editor/CSSInlineEditor.js index 18524091f20..6e568972a34 100644 --- a/src/editor/CSSInlineEditor.js +++ b/src/editor/CSSInlineEditor.js @@ -36,7 +36,9 @@ define(function (require, exports, module) { DocumentManager = require("document/DocumentManager"), EditorManager = require("editor/EditorManager"), Editor = require("editor/Editor").Editor, + LanguageManager = require("language/LanguageManager"), ProjectManager = require("project/ProjectManager"), + FileUtils = require("file/FileUtils"), HTMLUtils = require("language/HTMLUtils"), MultiRangeInlineEditor = require("editor/MultiRangeInlineEditor"), Strings = require("strings"), @@ -146,7 +148,7 @@ define(function (require, exports, module) { /** Item renderer for stylesheet-picker dropdown */ function _stylesheetListRenderer(item) { var html = "" + _.escape(item.name); - if (item.subDirStr.length) { + if (item.subDirStr) { html += " — " + _.escape(item.subDirStr) + ""; } html += ""; @@ -240,65 +242,52 @@ define(function (require, exports, module) { /** * @private - * Sort fileInfo objects by name then sub-directory + * Sort files with LESS/SCSS above CSS, and then within each grouping sort by path & filename + * (the same order we use for Find in Files) + * @param {!File} a, b + * @return {number} */ - function _sortFileInfos(a, b) { - var nameComparison = a.name.localeCompare(b.name); - if (nameComparison !== 0) { - return nameComparison; + function _fileComparator(a, b) { + var aIsCSS = LanguageManager.getLanguageForPath(a.fullPath).getId() === "css", + bIsCSS = LanguageManager.getLanguageForPath(b.fullPath).getId() === "css"; + if (aIsCSS && !bIsCSS) { + return 1; + } else if (!aIsCSS && bIsCSS) { + return -1; + } else { + return FileUtils.comparePaths(a.fullPath, b.fullPath); } - return a.subDirStr.localeCompare(b.subDirStr); } /** * @private * Prepare file list for display */ - function _prepFileList(fileInfos) { - var i, j, firstDupeIndex, - displayPaths = [], - dupeList = []; + function _prepFileList(files) { + // First, sort list (the same ordering we use for the results list) + files.sort(_fileComparator); - // Add subdir field to each entry - fileInfos.forEach(function (fileInfo) { - fileInfo.subDirStr = ""; - }); - - // Add directory path to files with the same name so they can be - // distinguished in list. Start with list sorted by name. - fileInfos.sort(_sortFileInfos); - - // For identical names, add a subdir - for (i = 1; i < fileInfos.length; i++) { - if (_sortFileInfos(fileInfos[i - 1], fileInfos[i]) === 0) { - // Duplicates found - firstDupeIndex = i - 1; - dupeList.push(fileInfos[i - 1]); - dupeList.push(fileInfos[i]); - - // Lookahead for more dupes - while (++i < fileInfos.length && - _sortFileInfos(dupeList[0], fileInfos[i]) === 0) { - dupeList.push(fileInfos[i]); - } - - // Get minimum subdir to make each unique - displayPaths = ViewUtils.getDirNamesForDuplicateFiles(dupeList); - - // Add a subdir to each dupe entry - for (j = 0; j < displayPaths.length; j++) { - fileInfos[firstDupeIndex + j].subDirStr = displayPaths[j]; - } - - // Release memory - dupeList = []; + // Find any files that share the same name (with different path) + var fileNames = {}; + files.forEach(function (file) { + if (!fileNames[file.name]) { + fileNames[file.name] = []; } - } + fileNames[file.name].push(file); + }); - // Sort by name again, so paths are sorted - fileInfos.sort(_sortFileInfos); + // For any duplicate filenames, set subDirStr to a path snippet the helps + // the user distinguish each file in the list. + _.forEach(fileNames, function (files) { + if (files.length > 1) { + var displayPaths = ViewUtils.getDirNamesForDuplicateFiles(files); + files.forEach(function (file, i) { + file.subDirStr = displayPaths[i]; + }); + } + }); - return fileInfos; + return files; } function _onHostEditorScroll() { @@ -309,7 +298,8 @@ define(function (require, exports, module) { .done(function (rules) { var inlineEditorDeferred = new $.Deferred(); cssInlineEditor = new MultiRangeInlineEditor.MultiRangeInlineEditor(CSSUtils.consolidateRules(rules), - _getNoRulesMsg, CSSUtils.getRangeSelectors); + _getNoRulesMsg, CSSUtils.getRangeSelectors, + _fileComparator); cssInlineEditor.load(hostEditor); cssInlineEditor.$htmlContent .on("focusin", _updateCommands) diff --git a/src/editor/Editor.js b/src/editor/Editor.js index c426ed7b450..9d7c98dea14 100644 --- a/src/editor/Editor.js +++ b/src/editor/Editor.js @@ -1248,7 +1248,7 @@ define(function (require, exports, module) { * @param {boolean} center true to center the viewport * @param {number} centerOptions Option value, or 0 for no options; one of the BOUNDARY_* constants above. * @param {?string} origin An optional string that describes what other selection or edit operations this - * should be merged with for the purposes of undo. See Document.replaceRange() for more details. + * should be merged with for the purposes of undo. See {@link Document#replaceRange} for more details. */ Editor.prototype.setSelection = function (start, end, center, centerOptions, origin) { this.setSelections([{start: start, end: end || start}], center, centerOptions, origin); @@ -1267,7 +1267,7 @@ define(function (require, exports, module) { * @param {boolean} center true to center the viewport around the primary selection. * @param {number} centerOptions Option value, or 0 for no options; one of the BOUNDARY_* constants above. * @param {?string} origin An optional string that describes what other selection or edit operations this - * should be merged with for the purposes of undo. See Document.replaceRange() for more details. + * should be merged with for the purposes of undo. See {@link Document#replaceRange} for more details. */ Editor.prototype.setSelections = function (selections, center, centerOptions, origin) { var primIndex = selections.length - 1, options; @@ -1793,7 +1793,7 @@ define(function (require, exports, module) { * Sets the height of an inline widget in this editor. * @param {!InlineWidget} inlineWidget The widget whose height should be set. * @param {!number} height The height of the widget. - * @param {boolean} ensureVisible Whether to scroll the entire widget into view. + * @param {boolean=} ensureVisible Whether to scroll the entire widget into view. Default false. */ Editor.prototype.setInlineWidgetHeight = function (inlineWidget, height, ensureVisible) { var self = this, @@ -2002,7 +2002,7 @@ define(function (require, exports, module) { * the start and end. * @return {?(Object|string)} Name of syntax-highlighting mode, or object containing a "name" property * naming the mode along with configuration options required by the mode. - * @see {@link LanguageManager#getLanguageForPath()} and {@link Language#getMode()}. + * @see {@link LanguageManager::#getLanguageForPath} and {@link LanguageManager::Language#getMode}. */ Editor.prototype.getModeForRange = function (start, end, knownMixed) { var outerMode = this._codeMirror.getMode(), @@ -2028,7 +2028,7 @@ define(function (require, exports, module) { * * @return {?(Object|string)} Name of syntax-highlighting mode, or object containing a "name" property * naming the mode along with configuration options required by the mode. - * @see {@link LanguageManager#getLanguageForPath()} and {@link Language#getMode()}. + * @see {@link LanguageManager::#getLanguageForPath} and {@link LanguageManager::Language#getMode}. */ Editor.prototype.getModeForSelection = function () { // Check for mixed mode info @@ -2081,7 +2081,8 @@ define(function (require, exports, module) { /** * Gets the syntax-highlighting mode for the document. * - * @return {Object|String} Object or Name of syntax-highlighting mode; see {@link LanguageManager#getLanguageForPath()} and {@link Language#getMode()}. + * @return {Object|String} Object or Name of syntax-highlighting mode + * @see {@link LanguageManager::#getLanguageForPath|LanguageManager.getLanguageForPath} and {@link LanguageManager::Language#getMode|Language.getMode}. */ Editor.prototype.getModeForDocument = function () { return this._codeMirror.getOption("mode"); diff --git a/src/editor/EditorManager.js b/src/editor/EditorManager.js index f1d575cd4a1..5667c0d6f00 100644 --- a/src/editor/EditorManager.js +++ b/src/editor/EditorManager.js @@ -81,7 +81,7 @@ define(function (require, exports, module) { /** * Registered inline-editor widget providers sorted descending by priority. - * @see {@link #registerInlineEditProvider()}. + * @see {@link #registerInlineEditProvider}. * @type {Array.<{priority:number, provider:function(...)}>} * @private */ @@ -89,7 +89,7 @@ define(function (require, exports, module) { /** * Registered inline documentation widget providers sorted descending by priority. - * @see {@link #registerInlineDocsProvider()}. + * @see {@link #registerInlineDocsProvider}. * @type {Array.<{priority:number, provider:function(...)}>} * @private */ @@ -97,7 +97,7 @@ define(function (require, exports, module) { /** * Registered jump-to-definition providers. - * @see {@link #registerJumpToDefProvider()}. + * @see {@link #registerJumpToDefProvider}. * @private * @type {Array.} */ @@ -598,7 +598,7 @@ define(function (require, exports, module) { /** * @deprecated Register a View Factory instead - * @see MainViewManager.registerViewFactory() + * @see MainViewFactory::#registerViewFactory */ function registerCustomViewer() { throw new Error("EditorManager.registerCustomViewer() has been removed."); @@ -685,7 +685,7 @@ define(function (require, exports, module) { * Returns the current active editor (full-sized OR inline editor). This editor may not * have focus at the moment, but it is visible and was the last editor that was given * focus. Returns null if no editors are active. - * @see getFocusedEditor() + * @see #getFocusedEditor * @return {?Editor} */ function getActiveEditor() { diff --git a/src/editor/InlineTextEditor.js b/src/editor/InlineTextEditor.js index 66e5f2fa696..e3f3b2b4739 100644 --- a/src/editor/InlineTextEditor.js +++ b/src/editor/InlineTextEditor.js @@ -141,9 +141,8 @@ define(function (require, exports, module) { /** * Update the inline editor's height when the number of lines change. The * base implementation of this method does nothing. - * @param {boolean} force the editor to resize */ - InlineTextEditor.prototype.sizeInlineWidgetToContents = function (force) { + InlineTextEditor.prototype.sizeInlineWidgetToContents = function () { // brackets_codemirror_overrides.css adds height:auto to CodeMirror // Inline editors themselves do not need to be sized, but layouts like // the one used in CSSInlineEditor do need some manual layout. @@ -265,7 +264,7 @@ define(function (require, exports, module) { // Always update the widget height when an inline editor completes a // display update $(this.editor).on("update.InlineTextEditor", function (event, editor) { - self.sizeInlineWidgetToContents(true); + self.sizeInlineWidgetToContents(); }); // Size editor to content whenever text changes (via edits here or any @@ -273,7 +272,7 @@ define(function (require, exports, module) { // changes, regardless of origin) $(this.editor).on("change.InlineTextEditor", function (event, editor) { if (self.hostEditor.isFullyVisible()) { - self.sizeInlineWidgetToContents(true); + self.sizeInlineWidgetToContents(); self._updateLineRange(editor); } }); @@ -326,7 +325,7 @@ define(function (require, exports, module) { } // We need to call this explicitly whenever the host editor is reshown - this.sizeInlineWidgetToContents(true); + this.sizeInlineWidgetToContents(); }; /** diff --git a/src/editor/MultiRangeInlineEditor.js b/src/editor/MultiRangeInlineEditor.js index 9356faebc27..aecb3289a42 100644 --- a/src/editor/MultiRangeInlineEditor.js +++ b/src/editor/MultiRangeInlineEditor.js @@ -44,6 +44,9 @@ define(function (require, exports, module) { var TextRange = require("document/TextRange").TextRange, InlineTextEditor = require("editor/InlineTextEditor").InlineTextEditor, EditorManager = require("editor/EditorManager"), + FileUtils = require("file/FileUtils"), + PreferencesManager = require("preferences/PreferencesManager"), + ProjectManager = require("project/ProjectManager"), Commands = require("command/Commands"), Strings = require("strings"), CommandManager = require("command/CommandManager"); @@ -60,6 +63,12 @@ define(function (require, exports, module) { return parseInt($target.css(styleName), 10); } + /** Returns a 'context' object for getting/setting project-specific preferences */ + function _getPrefsContext() { + var projectRoot = ProjectManager.getProjectRoot(); // note: null during unit tests! + return { location : { scope: "user", layer: "project", layerID: projectRoot && projectRoot.fullPath } }; + } + /** * Stores one search result: its source file, line range, etc. plus the DOM node representing it @@ -79,21 +88,26 @@ define(function (require, exports, module) { if (labelCB) { range.name = labelCB(range.textRange); } - var text = _.escape(range.name) + " — " + _.escape(range.textRange.document.file.name) + " : " + (range.textRange.startLine + 1) + ""; + var text = _.escape(range.name) + " :" + (range.textRange.startLine + 1) + ""; listItem.html(text); listItem.attr("title", listItem.text()); } + /** * @constructor - * @param {Array.<{name:String,document:Document,lineStart:number,lineEnd:number}>} ranges The text ranges to display. - * @param {function(): $.Promise} messageCB An optional callback that returns a promise that will be resolved with a message to show - * when no matches are available. - * @param {function(range): string} labelCB An optional callback that returns an updated label string for the given range. Called - * when we detect that the content of one of the ranges has changed. + * @param {Array.<{name:String,document:Document,lineStart:number,lineEnd:number}>} ranges The text + * ranges to display. Results within the same file are expected to be contiguous in this array. + * @param {?function(): $.Promise} messageCB Optional; returns a promise resolved with a message to + * show when no matches are available. The message should be already-escaped HTML. + * @param {?function(range): string} labelCB Optional; returns an updated label string for the given + * range. Called when we detect that the content of a range has changed. The label is plain + * text, not HTML. + * @param {?function(!File, !File):number} fileComparator Optional comparison function for sorting + * the results list (based on range.document.file). Defaults to FileUtils.comparePaths(). * @extends {InlineTextEditor} */ - function MultiRangeInlineEditor(ranges, messageCB, labelCB) { + function MultiRangeInlineEditor(ranges, messageCB, labelCB, fileComparator) { InlineTextEditor.call(this); // Store the results to show in the range list. This creates TextRanges bound to the Document, @@ -105,6 +119,15 @@ define(function (require, exports, module) { this._labelCB = labelCB; this._selectedRangeIndex = -1; + this._collapsedFiles = {}; + + // Set up list sort order + this._fileComparator = fileComparator || function defaultComparator(file1, file2) { + return FileUtils.comparePaths(file1.fullPath, file2.fullPath); + }; + this._ranges.sort(function (result1, result2) { + return this._fileComparator(result1.textRange.document.file, result2.textRange.document.file); + }.bind(this)); } MultiRangeInlineEditor.prototype = Object.create(InlineTextEditor.prototype); MultiRangeInlineEditor.prototype.constructor = MultiRangeInlineEditor; @@ -114,33 +137,48 @@ define(function (require, exports, module) { MultiRangeInlineEditor.prototype.$relatedContainer = null; MultiRangeInlineEditor.prototype.$related = null; MultiRangeInlineEditor.prototype.$selectedMarker = null; + + /** Includes all the _ranges[i].$listItem items, as well as section headers */ MultiRangeInlineEditor.prototype.$rangeList = null; /** - * List of search results - * @type {Array.} + * List of search results. Section headers are not represented in this list (they are implied before each group of + * of consecutive results from the same Document). + * @type {!Array.} */ MultiRangeInlineEditor.prototype._ranges = null; + + /** Index into this._ranges - indices do not include section headers */ MultiRangeInlineEditor.prototype._selectedRangeIndex = null; + + /** + * Map from fullPath to true if collapsed. May not agree with preferences, in cases where multiple inline editors make + * concurrent changes. + * @type {!Object.} + */ + MultiRangeInlineEditor.prototype._collapsedFiles = null; + MultiRangeInlineEditor.prototype._messageCB = null; MultiRangeInlineEditor.prototype._labelCB = null; + MultiRangeInlineEditor.prototype._fileComparator = null; + + /** @type {!Object.} Map from fullPath to section header DOM node */ + MultiRangeInlineEditor.prototype._$headers = null; + /** * @private - * Add a new range to the range list UI. + * Add a new result item
  • to the range list UI ($rangeList) and saves it in range.$listItem * @param {SearchResultItem} range The range to add. - * @param {number=} index Where to add the range in the list. Defaults to the end. */ - MultiRangeInlineEditor.prototype._createListItem = function (range, index) { + MultiRangeInlineEditor.prototype._createListItem = function (range) { var self = this, - $rangeItem = $("
  • "), - $rangeListChildren = this.$rangeList.children(); + $rangeItem = $("
  • "); - if (index === undefined || index === $rangeListChildren.length) { - $rangeItem.appendTo(this.$rangeList); - } else { - $rangeItem.insertBefore($rangeListChildren.get(index)); - } + // Attach filename for unit test use + $rangeItem.data("filename", range.textRange.document.file.name); + + $rangeItem.appendTo(this.$rangeList); _updateRangeLabel($rangeItem, range); $rangeItem.mousedown(function () { @@ -148,20 +186,97 @@ define(function (require, exports, module) { }); range.$listItem = $rangeItem; + }; + + /** Collapses/expands a file section in the range list UI */ + MultiRangeInlineEditor.prototype._toggleSection = function (fullPath, duringInit) { + var $headerItem = this._$headers[fullPath]; + var $disclosureIcon = $headerItem.find(".disclosure-triangle"); + var isCollapsing = $disclosureIcon.hasClass("expanded"); + $disclosureIcon.toggleClass("expanded"); + $headerItem.nextUntil(".section-header").toggle(!isCollapsing); // explicit visibility arg, since during load() jQ doesn't think nodes are visible + + // Update instance-specific state... + this._collapsedFiles[fullPath] = isCollapsing; + // ...AND persist as per-project view state + if (!duringInit) { + var setting = PreferencesManager.getViewState("inlineEditor.collapsedFiles", _getPrefsContext()) || {}; + if (isCollapsing) { + setting[fullPath] = true; + } else { + delete setting[fullPath]; + } + PreferencesManager.setViewState("inlineEditor.collapsedFiles", setting, _getPrefsContext()); + } + + // Show/hide selection indicator if selection was in collapsed section + this._updateSelectedMarker(false); - // Update list item as TextRange changes - $(range.textRange).on("change", function () { - _updateRangeLabel($rangeItem, range); - }).on("contentChange", function () { - _updateRangeLabel($rangeItem, range, self._labelCB); - }); + // Changing height of rule list may change ht of overall editor + this._ruleListHeightChanged(); - // If TextRange lost sync, remove it from the list (and close the widget if no other ranges are left) - $(range.textRange).on("lostSync", function () { - self._removeRange(range); - }); + // If user expands collapsed section and nothing selected yet, select first result in this section + if (this._selectedRangeIndex === -1 && !isCollapsing && !duringInit) { + var index = _.findIndex(this._ranges, function (resultItem) { + return resultItem.textRange.document.file.fullPath === fullPath; + }); + this.setSelectedIndex(index); + } }; - + + /** Adds a file section header
  • to the range list UI ($rangeList) and adds it to the this._$headers map */ + MultiRangeInlineEditor.prototype._createHeaderItem = function (doc) { + var $headerItem = $("
  • " + _.escape(doc.file.name) + "
  • ") + .attr("title", ProjectManager.makeProjectRelativeIfPossible(doc.file.fullPath)) + .appendTo(this.$rangeList); + + $headerItem.click(function () { + this._toggleSection(doc.file.fullPath); + }.bind(this)); + + this._$headers[doc.file.fullPath] = $headerItem; + }; + + /** Refresh the contents of $rangeList */ + MultiRangeInlineEditor.prototype._renderList = function () { + this.$rangeList.empty(); + this._$headers = {}; + + var self = this, + lastSectionDoc, + numItemsInSection = 0; + + // After seeing all results for a given file, update its header with total # of results + function finalizeSection() { + if (lastSectionDoc) { + self._$headers[lastSectionDoc.file.fullPath].append(" (" + numItemsInSection + ")"); + if (self._collapsedFiles[lastSectionDoc.file.fullPath]) { + self._toggleSection(lastSectionDoc.file.fullPath, true); + } + } + } + + this._ranges.forEach(function (resultItem) { + if (lastSectionDoc !== resultItem.textRange.document) { + // Finalize previous section + finalizeSection(); + + // Initialize new section + lastSectionDoc = resultItem.textRange.document; + numItemsInSection = 0; + + // Create filename header for new section + this._createHeaderItem(lastSectionDoc); + } + numItemsInSection++; + this._createListItem(resultItem); + }, this); + + // Finalize last section + finalizeSection(); + }; + + /** * @override * @param {!Editor} hostEditor Outer Editor instance that inline editor will sit within. @@ -191,16 +306,48 @@ define(function (require, exports, module) { // Range list this.$rangeList = $("