Merge branch 'master-redesign' into master-redesign-templates-and-blog

This commit is contained in:
Henry Oswald 2014-07-02 15:56:22 +01:00
commit ba4d585854
19 changed files with 348 additions and 140 deletions

View file

@ -8,7 +8,7 @@ block vars
block scripts
//- Only use the native bootstrap on the editor page,
//- since we use the Angular-based bootstrap elsewhere.
script(src=jsPath+'libs/bootstrap-3.1.1.js')
//- script(src=jsPath+'libs/bootstrap-3.1.1.js')
script(src=jsPath+'libs/jquery-layout.js')
script(src=jsPath+'libs/jquery.storage.js')
@ -35,17 +35,32 @@ block content
include ./editor/left-menu
include ./editor/header
include ./editor/share
#ide-body(ng-cloak, layout="main", ng-hide="state.loading")
.ui-layout-west
include ./editor/file-tree
#chat-wrapper(
layout="chat",
spacing-open="12",
spacing-closed="0",
initial-size-east="250",
init-closed-east="true",
open-east="ui.chatOpen",
ng-hide="state.loading",
ng-cloak
)
.ui-layout-center
include ./editor/editor
include ./editor/track-changes
include ./editor/header
include ./editor/share
#ide-body(ng-cloak, layout="main", ng-hide="state.loading", resize-on="layout:chat:resize")
.ui-layout-west
include ./editor/file-tree
.ui-layout-center
include ./editor/editor
include ./editor/track-changes
.ui-layout-east
| Chat!
script(src='/socket.io/socket.io.js')

View file

@ -2,6 +2,8 @@ div.full-size(
ng-show="ui.view == 'editor'"
layout="pdf"
resize-on="layout:main:resize"
resize-proportionally="true"
initial-size-east="'50%'"
)
.ui-layout-center
.loading-panel(ng-show="!editor.sharejs_doc || editor.opening")

View file

@ -29,5 +29,12 @@ header.toolbar.toolbar-header(ng-cloak, ng-hide="state.loading")
tooltip-placement="bottom"
)
i.fa.fa-fw.fa-history
a.btn.btn-full-height(href='#', tooltip="Chat", tooltip-placement="bottom")
a.btn.btn-full-height(
href,
tooltip="Chat",
tooltip-placement="bottom",
ng-class="{ active: ui.chatOpen }",
ng-click="toggleChat()",
ng-controller="ChatButtonController"
)
i.fa.fa-fw.fa-comment

View file

@ -2,76 +2,120 @@ aside#left-menu.full-size(
ng-class="{ 'shown': ui.leftMenuShown }"
ng-cloak
)
h4 Download
ul.unformatted-list.nav.nav-downloads
li
a(
ng-href="/project/{{project_id}}/download/zip"
target="_blank"
)
i.fa.fa-file-archive-o.fa-2x
br
| Source
li
a(
ng-href="/project/{{project_id}}/{{pdf.url}}"
target="_blank"
ng-if="pdf.url"
)
i.fa.fa-file-pdf-o.fa-2x
br
| PDF
div.pdf-disabled(
ng-if="!pdf.url"
tooltip="Please compile your project before downloading the PDF"
tooltip-placement="bottom"
)
i.fa.fa-file-pdf-o.fa-2x
br
| PDF
h4 Settings
form(ng-controller="SettingsController")
.form-controls
label(for="compiler") Compiler
select.form-control(
name="compiler"
ng-model="project.compiler"
)
option(value='pdflatex') pdfLaTeX
option(value='latex') LaTeX
option(value='xelatex') XeLaTeX
option(value='lualatex') LuaLaTeX
form.settings(ng-controller="SettingsController")
.containter-fluid
.form-controls
.row
label.col-md-6(for="compiler") Compiler
.col-md-6
select.form-control(
name="compiler"
ng-model="project.compiler"
)
option(value='pdflatex') pdfLaTeX
option(value='latex') LaTeX
option(value='xelatex') XeLaTeX
option(value='lualatex') LuaLaTeX
.form-controls
label(for="spellCheckLanguage") Spell Check
select.form-control(
name="spellCheckLanguage"
ng-model="project.spellCheckLanguage"
)
option(value="") Off
optgroup(label="Language")
for language in languages
option(
value=language.code
)= language.name
.form-controls
.row
label.col-md-6(for="spellCheckLanguage") Spell Check
.col-md-6
select.form-control(
name="spellCheckLanguage"
ng-model="project.spellCheckLanguage"
)
option(value="") Off
optgroup(label="Language")
for language in languages
option(
value=language.code
)= language.name
.form-controls
label(for="autoComplete") Auto-Complete
input.form-control(
type="checkbox"
name="autoComplete"
ng-model="settings.autoComplete"
)
.form-controls
.row
label.col-md-6(for="autoComplete") Auto-Complete
.col-md-6
select.form-control(
name="autoComplete"
ng-model="settings.autoComplete"
ng-options="o.v as o.n for o in [{ n: 'On', v: true }, { n: 'Off', v: false }]"
)
.form-controls
label(for="theme") Theme
select.form-control(
name="theme"
ng-model="settings.theme"
)
each theme in themes
option(value=theme) #{theme}
.form-controls
label(for="mode") Keybindings
select.form-control(
name="mode"
ng-model="settings.mode"
)
option(value='default') None
option(value='vim') Vim
option(value='emacs') Emacs
.form-controls
.row
label.col-md-6(for="theme") Theme
.col-md-6
select.form-control(
name="theme"
ng-model="settings.theme"
)
each theme in themes
option(value=theme) #{theme}
.form-controls
label(for="fontSize") Font Size
select.form-control(
name="fontSize"
ng-model="settings.fontSize"
)
each size in ['10','11','12','13','14','16','20','24']
option(value=size) #{size}px
.form-controls
.row
label.col-md-6(for="mode") Keybindings
.col-md-6
select.form-control(
name="mode"
ng-model="settings.mode"
)
option(value='default') None
option(value='vim') Vim
option(value='emacs') Emacs
.form-controls
label(for="pdfViewer") PDF Viewer
select.form-control(
name="pdfViewer"
ng-model="settings.pdfViewer"
)
option(value="pdfjs") Built-In
option(value="native") Native
.form-controls
.row
label.col-md-6(for="fontSize") Font Size
.col-md-6
select.form-control(
name="fontSize"
ng-model="settings.fontSize"
)
each size in ['10','11','12','13','14','16','20','24']
option(value=size) #{size}px
.form-controls
.row
label.col-md-6(for="pdfViewer") PDF Viewer
.col-md-6
select.form-control(
name="pdfViewer"
ng-model="settings.pdfViewer"
)
option(value="pdfjs") Built-In
option(value="native") Native
#left-menu-mask(
ng-show="ui.leftMenuShown",

View file

@ -8,6 +8,7 @@ define [
"ide/pdf/PdfManager"
"ide/settings/index"
"ide/share/index"
"ide/chat/index"
"ide/directives/layout"
"ide/services/ide"
"directives/focus"
@ -40,6 +41,7 @@ define [
$scope.ui = {
leftMenuShown: false
view: "editor"
chatOpen: false
}
$scope.user = window.user
$scope.settings = window.userSettings

View file

@ -0,0 +1,7 @@
define [
"base"
], (App) ->
App.controller "ChatButtonController", ["$scope", ($scope) ->
$scope.toggleChat = () ->
$scope.ui.chatOpen = !$scope.ui.chatOpen
]

View file

@ -0,0 +1,3 @@
define [
"ide/chat/controllers/ChatButtonController"
], () ->

View file

@ -1,46 +1,101 @@
define [
"base"
], (App) ->
App.directive "layout", () ->
App.directive "layout", ["$parse", ($parse) ->
return {
link: (scope, element, attrs) ->
name = attrs.layout
compile: () ->
pre: (scope, element, attrs) ->
name = attrs.layout
options =
spacing_open: 24
spacing_closed: 24
onresize: () =>
onResize()
maskIframesOnResize: scope.$eval(
attrs.maskIframesOnResize or "false"
)
if attrs.spacingOpen?
spacingOpen = parseInt(attrs.spacingOpen, 10)
else
spacingOpen = 24
onResize = () ->
state = element.layout().readState()
scope.$broadcast "layout:#{name}:resize", state
repositionControls()
if attrs.spacingClosed?
spacingClosed = parseInt(attrs.spacingClosed, 10)
else
spacingClosed = 24
# Restore previously recorded state
if (state = $.localStorage("layout.#{name}"))?
options.west = state.west
options.east = state.east
options =
spacing_open: spacingOpen
spacing_closed: spacingClosed
slidable: false
onresize: () =>
onInternalResize()
maskIframesOnResize: scope.$eval(
attrs.maskIframesOnResize or "false"
)
east:
size: scope.$eval(attrs.initialSizeEast)
initClosed: scope.$eval(attrs.initClosedEast)
west:
size: scope.$eval(attrs.initialSizeEast)
initClosed: scope.$eval(attrs.initClosedWest)
element.layout options
element.layout().resizeAll()
# Restore previously recorded state
if (state = $.localStorage("layout.#{name}"))?
options.west = state.west
options.east = state.east
if attrs.resizeOn?
scope.$on attrs.resizeOn, () -> element.layout().resizeAll()
# Someone moved the resizer
onInternalResize = () ->
state = element.layout().readState()
scope.$broadcast "layout:#{name}:resize", state
repositionControls()
resetOpenStates()
# Save state when exiting
$(window).unload () ->
$.localStorage("layout.#{name}", element.layout().readState())
oldWidth = element.width()
# Something resized our parent element
onExternalResize = () ->
console.log "EXTERNAL RESIOZE", name, attrs.resizeProportionally
if attrs.resizeProportionally? and scope.$eval(attrs.resizeProportionally)
eastState = element.layout().readState().east
if eastState?
newInternalWidth = eastState.size / oldWidth * element.width()
oldWidth = element.width()
element.layout().sizePane("east", newInternalWidth)
return
element.layout().resizeAll()
repositionControls = () ->
state = element.layout().readState()
if state.east?
element.find(".ui-layout-resizer-controls").css({
position: "absolute"
right: state.east.size
"z-index": 10
})
}
element.layout options
element.layout().resizeAll()
if attrs.resizeOn?
scope.$on attrs.resizeOn, () -> onExternalResize()
# Save state when exiting
$(window).unload () ->
$.localStorage("layout.#{name}", element.layout().readState())
repositionControls = () ->
state = element.layout().readState()
if state.east?
element.find("> .ui-layout-resizer-controls").css({
position: "absolute"
right: state.east.size
"z-index": 10
})
resetOpenStates = () ->
state = element.layout().readState()
if attrs.openEast?
openEast = $parse(attrs.openEast)
openEast.assign(scope, !state.east.initClosed)
if attrs.openEast?
scope.$watch attrs.openEast, (value, oldValue) ->
console.log "Open East", value, oldValue
if value? and value != oldValue
if value
element.layout().open("east")
else
element.layout().close("east")
setTimeout () ->
scope.$digest()
, 0
resetOpenStates()
}
]

View file

@ -9,7 +9,7 @@ define [
last_updated: null
open_doc_id: null
opening: true
cursorPosition: null
cursorPosition: {}
gotoLine: null
}

View file

@ -29,19 +29,23 @@ define [
constructor: (@$scope, @editor) ->
@suggestionManager = new SuggestionManager()
insertMatch = Autocomplete::insertMatch
editor = @editor
Autocomplete::insertMatch = (data) ->
pos = editor.getCursorPosition()
range = new Range(pos.row, pos.column, pos.row, pos.column + 1)
nextChar = editor.session.getTextRange(range)
if !Autocomplete::_insertMatch?
# Only override this once since it's global but we may create multiple
# autocomplete handlers
Autocomplete::_insertMatch = Autocomplete::insertMatch
Autocomplete::insertMatch = (data) ->
pos = editor.getCursorPosition()
range = new Range(pos.row, pos.column, pos.row, pos.column + 1)
nextChar = editor.session.getTextRange(range)
# If we are in \begin{it|}, then we need to remove the trailing }
# since it will be adding in with the autocomplete of \begin{item}...
if this.completions.filterText.match(/^\\begin\{/) and nextChar == "}"
editor.session.remove(range)
insertMatch.call editor.completer, data
console.log "INSERT MATCH", this
# If we are in \begin{it|}, then we need to remove the trailing }
# since it will be adding in with the autocomplete of \begin{item}...
if this.completions.filterText.match(/^\\begin\{/) and nextChar == "}"
editor.session.remove(range)
Autocomplete::_insertMatch.call this, data
@$scope.$watch "autoComplete", (autocomplete) =>
console.log "autocomplete change", autocomplete

View file

@ -13,9 +13,9 @@ define [], () ->
@editor.on "changeSelection", () =>
cursor = @editor.getCursorPosition()
console.log "Updating cursor position", cursor
@$scope.$apply () =>
@$scope.cursorPosition = cursor
if @$scope.cursorPosition?
@$scope.cursorPosition = cursor
@$scope.$watch "gotoLine", (value) =>
console.log "Going to line", value

View file

@ -10,7 +10,7 @@ define [
"ace/keyboard/emacs"
"ace/mode/latex"
"ace/edit_session"
], (App, Ace, UndoManager, AutoCompleteManager, SpellCheckManager, AnnotationsManager, CursorPositionManager) ->
], (App, Ace, UndoManager, AutoCompleteManager, SpellCheckManager, HighlightsManager, CursorPositionManager) ->
LatexMode = require("ace/mode/latex").Mode
EditSession = require('ace/edit_session').EditSession
@ -42,12 +42,14 @@ define [
else
@$originalApply(fn);
window.editor = editor = Ace.edit(element.find(".ace-editor-body")[0])
editor = Ace.edit(element.find(".ace-editor-body")[0])
window.editors ||= []
window.editors.push editor
autoCompleteManager = new AutoCompleteManager(scope, editor, element)
spellCheckManager = new SpellCheckManager(scope, editor, element)
undoManager = new UndoManager(scope, editor, element)
annotationsManager = new AnnotationsManager(scope, editor, element)
highlightsManager = new HighlightsManager(scope, editor, element)
cursorPositionManager = new CursorPositionManager(scope, editor, element)
# Prevert Ctrl|Cmd-S from triggering save dialog
@ -117,9 +119,6 @@ define [
resetSession()
session = editor.getSession()
autoCompleteManager.bindToSession(session)
annotationsManager.redrawAnnotations()
doc = session.getDocument()
doc.on "change", () ->
scope.$apply () ->

View file

@ -29,6 +29,9 @@ define [
e.position = position
@showAnnotationLabels(position)
@editor.on "changeSession", () =>
@redrawAnnotations()
redrawAnnotations: () ->
@_clearMarkers()
@_clearLabels()

View file

@ -28,6 +28,7 @@ define [
$(document).on "click", (e) =>
@closeContextMenu(e)
return true
# $(document).on "contextmenu", (e) =>
# @closeContextMenu(e)

View file

@ -227,7 +227,6 @@ define [
App.controller "PdfSynctexController", ["$scope", "synctex", "ide", ($scope, synctex, ide) ->
$scope.showControls = true
$scope.$on "layout:pdf:resize", (event, data) ->
console.log "RESIZE DATA", data.east
if data.east.initClosed
$scope.showControls = false
else

View file

@ -47,6 +47,8 @@ define [
range = new Range(pos.row, pos.column, pos.row, pos.column + 1)
nextChar = editor.session.getTextRange(range)
console.log "CALLING OLD"
# If we are in \begin{it|}, then we need to remove the trailing }
# since it will be adding in with the autocomplete of \begin{item}...
if this.completions.filterText.match(/^\\begin\{/) and nextChar == "}"

View file

@ -22,6 +22,13 @@
margin-left: -200px;
}
#chat-wrapper {
.full-size;
> .ui-layout-resizer > .ui-layout-toggler {
display: none !important;
}
}
#ide-body {
.full-size;
top: 40px;

View file

@ -1,14 +1,16 @@
#left-menu {
position: absolute;
width: 210px;
padding: 10px;
width: 260px;
padding: (@line-height-computed / 2);
top: 0;
bottom: 0;
background-color: #f4f4f4;
z-index: 100;
overflow: auto;
overflow-y: auto;
overflow-x: hidden;
-webkit-transition: left ease-in-out 0.35s;
transition: left ease-in-out 0.35s;
font-size: 14px;
left: -280px;
&.shown {
@ -16,14 +18,69 @@
}
h4 {
font-family: @font-family-serif;
font-family: @font-family-sans-serif;
font-weight: 400;
font-size: 1rem;
margin: (@line-height-computed / 2) 0;
padding-bottom: (@line-height-computed / 4);
color: @gray-light;
border-bottom: 1px solid @gray-light;
text-transform: uppercase;
border-bottom: 1px solid @gray-lighter;
}
h4:first-child {
margin-top: 0;
}
ul.nav-downloads {
li {
display: inline-block;
text-align: center;
width: 100px;
a {
color: @gray-dark;
&:hover, &:active {
background-color: @link-color;
color: white;
}
}
.pdf-disabled {
color: @gray-light;
}
i {
margin-bottom: (@line-height-computed / 4);
}
}
}
form.settings {
label {
font-weight: normal;
color: @gray-dark;
margin-bottom: 0;
padding-top: 8px;
}
select.form-control {
height: 34px;
background: none;
border: none;
box-shadow: none;
color: @link-color;
cursor: pointer;
font-size: 14px;
font-weight: 700;
}
.form-controls {
padding: 0 (@line-height-computed / 4);
&:hover {
background-color: @link-color;
select.form-control {
color: white;
}
label {
color: white;
}
}
}
}
}

View file

@ -25,7 +25,8 @@
border-radius: 0;
border-right: 1px solid @toolbar-border-color;
color: @link-color;
padding: 6px 12px 8px;
padding: 3px 10px 5px;
font-size: 20px;
&:hover {
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.15);
background-color: darken(white, 10%);