فهرست منبع

Merge branch 'master' of https://github.com/sharelatex/web-sharelatex

Henry Oswald 12 سال پیش
والد
کامیت
ecd5d5274c
28فایلهای تغییر یافته به همراه286 افزوده شده و 93 حذف شده
  1. 2 7
      services/web/app/coffee/Features/StaticPages/HomeController.coffee
  2. 1 1
      services/web/app/coffee/Features/User/UserPagesController.coffee
  3. 46 0
      services/web/app/coffee/Features/Wiki/WikiController.coffee
  4. 3 0
      services/web/app/coffee/router.coffee
  5. 4 4
      services/web/app/views/layout.jade
  6. 7 4
      services/web/app/views/project/editor/dropbox.jade
  7. 1 0
      services/web/app/views/project/editor/editor.jade
  8. 28 35
      services/web/app/views/project/editor/file-tree.jade
  9. 8 5
      services/web/app/views/project/editor/pdf.jade
  10. 6 6
      services/web/app/views/project/list/project-list.jade
  11. 4 4
      services/web/app/views/templates/index.jade
  12. 2 1
      services/web/app/views/user/settings.jade
  13. 14 0
      services/web/app/views/wiki/page.jade
  14. 9 9
      services/web/public/coffee/directives/equals.coffee
  15. 12 0
      services/web/public/coffee/directives/rightClick.coffee
  16. 2 0
      services/web/public/coffee/ide.coffee
  17. 3 3
      services/web/public/coffee/ide/chat/controllers/ChatController.coffee
  18. 1 2
      services/web/public/coffee/ide/clone/controllers/CloneProjectModalController.coffee
  19. 1 1
      services/web/public/coffee/ide/dropbox/controllers/DropboxController.coffee
  20. 11 5
      services/web/public/coffee/ide/file-tree/FileTreeManager.coffee
  21. BIN
      services/web/public/img/lion-128.png
  22. 2 2
      services/web/public/js/ace/ace.js
  23. 1 1
      services/web/public/js/libs/ng-context-menu-0.1.4.js
  24. 1 1
      services/web/public/stylesheets/app/about-page.less
  25. 8 1
      services/web/public/stylesheets/app/editor.less
  26. 107 0
      services/web/public/stylesheets/app/wiki.less
  27. 1 0
      services/web/public/stylesheets/style.less
  28. 1 1
      services/web/test/smoke/coffee/SmokeTests.coffee

+ 2 - 7
services/web/app/coffee/Features/StaticPages/HomeController.coffee

@@ -16,16 +16,11 @@ module.exports = HomeController =
 			else
 				res.redirect '/project'
 		else
-			if homepageExists
-				res.render 'external/home',
-					title: 'ShareLaTeX.com'
-			else
-				res.redirect "/login"
+			HomeController.home(req, res)
 
 	home: (req, res)->
 		if homepageExists
-			res.render 'external/home',
-				title: 'ShareLaTeX.com'
+			res.render 'external/home'
 		else
 			res.redirect "/login"
 

+ 1 - 1
services/web/app/coffee/Features/User/UserPagesController.coffee

@@ -34,7 +34,7 @@ module.exports =
 			dropboxHandler.getUserRegistrationStatus user._id, (err, status)->
 				userIsRegisteredWithDropbox = !err? and status.registered
 				res.render 'user/settings',
-					title:'Your settings',
+					title:'Account Settings',
 					userHasDropboxFeature: user.features.dropbox
 					userIsRegisteredWithDropbox: userIsRegisteredWithDropbox
 					user: user,

+ 46 - 0
services/web/app/coffee/Features/Wiki/WikiController.coffee

@@ -0,0 +1,46 @@
+request = require("request")
+settings = require("settings-sharelatex")
+logger = require("logger-sharelatex")
+ErrorController = require "../Errors/ErrorController"
+
+module.exports = WikiController = 
+	getPage: (req, res, next) ->
+		page = req.url.replace(/^\/learn/, "").replace(/^\//, "")
+		if page == ""
+			page = "Main_Page"
+
+		logger.log page: page, "getting page from wiki"
+		
+		WikiController._getPageContent "Contents", (error, contents) ->
+			return next(error) if error?
+			WikiController._getPageContent page, (error, page) ->
+				return next(error) if error?
+				if page.title == "Main Page"
+					title = "Documentation"
+				else
+					title = page.title
+					
+				res.render "wiki/page", {
+					page: page
+					contents: contents
+					title: title
+				}
+		
+	_getPageContent: (page, callback = (error, data = { content: "", title: "" }) ->) ->
+		request {
+			url: "#{settings.apis.wiki.url}/learn-scripts/api.php"
+			qs: {
+				page: decodeURI(page)
+				action: "parse"
+				format: "json"
+			}
+		}, (err, response, data)->
+			return callback(err) if err?
+			try
+				data = JSON.parse(data)
+			catch err
+				logger.err err:err, data:data, "error parsing data from wiki"
+			callback null, {
+				content: data?.parse?.text?['*']
+				title: data?.parse?.title
+			}

+ 3 - 0
services/web/app/coffee/router.coffee

@@ -37,6 +37,7 @@ PasswordResetRouter = require("./Features/PasswordReset/PasswordResetRouter")
 StaticPagesRouter = require("./Features/StaticPages/StaticPagesRouter")
 ChatController = require("./Features/Chat/ChatController")
 BlogController = require("./Features/Blog/BlogController")
+WikiController = require("./Features/Wiki/WikiController")
 ConnectedUsersController = require("./Features/ConnectedUsers/ConnectedUsersController")
 
 logger = require("logger-sharelatex")
@@ -162,6 +163,8 @@ module.exports = class Router
 
 		app.get  "/project/:Project_id/messages", SecurityManager.requestCanAccessProject, ChatController.getMessages
 		app.post "/project/:Project_id/messages", SecurityManager.requestCanAccessProject, ChatController.sendMessage
+		
+		app.get  /learn(\/.*)?/, WikiController.getPage
 
 		#Admin Stuff
 		app.get  '/admin', SecurityManager.requestIsAdmin, AdminController.index

+ 4 - 4
services/web/app/views/layout.jade

@@ -3,10 +3,10 @@ html(itemscope, itemtype='http://schema.org/Product')
 	block vars
 
 	head
-		- if (typeof(priority_title) !== "undefined" && priority_title)
-			title= title + ' - Online LaTeX Editor ShareLaTeX'
-		- else
-			title= 'Online LaTeX Editor ShareLaTeX - ' +title
+		-if (typeof(title) == "undefined")
+			title ShareLaTeX, the Online LaTeX Editor
+		-else
+			title= title + ' - ShareLaTeX, the Online LaTeX Editor'
 		link(rel="icon", href="/favicon.ico")
 		link(rel='stylesheet', href='/stylesheets/style.css?fingerprint='+fingerprint('/stylesheets/style.css'))
 		link(href="//netdna.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css",rel="stylesheet")

+ 7 - 4
services/web/app/views/project/editor/dropbox.jade

@@ -5,7 +5,7 @@ script(type="text/ng-template", id="dropboxModalTemplate")
 			data-dismiss="modal"
 			ng-click="cancel()"
 		) ×
-		h3 Dropbox link
+		h3 Dropbox Sync
 	.modal-body.modal-body-share
 
 		div(ng-show="dbState.gotLinkStatus")
@@ -21,9 +21,12 @@ script(type="text/ng-template", id="dropboxModalTemplate")
 
 			div(ng-show="dbState.hasDropboxFeature && dbState.userIsLinkedToDropbox")
 				progressbar.progress-striped.active(value='dbState.percentageLeftTillNextPoll', type="info")
-				span 
+				p
 					strong {{dbState.minsTillNextPoll}} minutes 
-					span until dropbox is next checked for changes.
+					span until Dropbox is next checked for changes.
+				p.small
+					| This project will appear in your Dropbox folder at 
+					strong Dropbox/sharelatex/{{ project.name }}
 
 			div.text-center(ng-hide="dbState.hasDropboxFeature")
 				p You need to upgrade your account to link to dropbox.
@@ -33,8 +36,8 @@ script(type="text/ng-template", id="dropboxModalTemplate")
 					| Please refresh this page after starting your free trial.
 
 		div(ng-hide="dbState.gotLinkStatus")
-			span.small   checking dropbox status  
 			i.fa.fa-refresh.fa-spin 
+			span.small   Checking dropbox status
 
 
 

+ 1 - 0
services/web/app/views/project/editor/editor.jade

@@ -2,6 +2,7 @@ div.full-size(
 	ng-show="ui.view == 'editor'"
 	layout="pdf"
 	layout-disabled="ui.pdfLayout != 'sideBySide'"
+	mask-iframes-on-resize="true"
 	resize-on="layout:main:resize"
 	resize-proportionally="true"
 	initial-size-east="'50%'"

+ 28 - 35
services/web/app/views/project/editor/file-tree.jade

@@ -134,15 +134,15 @@ script(type='text/ng-template', id='entityListItemTemplate')
 					ul.dropdown-menu.dropdown-menu-right
 						li
 							a(
-								href="#"
-								prevent-default="click"
+								href
 								ng-click="startRenaming()"
+								right-click="startRenaming()"
 							) Rename
 						li
 							a(
-								href="#"
-								prevent-default="click"
+								href
 								ng-click="openDeleteModal()"
+								right-click="openDeleteModal()"
 							) Delete
 
 				div.dropdown.context-menu(
@@ -152,17 +152,15 @@ script(type='text/ng-template', id='entityListItemTemplate')
 					ul.dropdown-menu
 						li
 							a(
-								href="#"
-								prevent-default="click"
-								stop-propagation="click"
+								href
 								ng-click="startRenaming()"
+								right-click="startRenaming()"
 							) Rename
 						li
 							a(
-								href="#"
-								prevent-default="click"
-								stop-propagation="click"
+								href
 								ng-click="openDeleteModal()"
+								right-click="openDeleteModal()"
 							) Delete
 
 
@@ -218,34 +216,34 @@ script(type='text/ng-template', id='entityListItemTemplate')
 						ul.dropdown-menu.dropdown-menu-right
 							li
 								a(
-									href="#"
-									prevent-default="click"
+									href
 									ng-click="startRenaming()"
+									right-click="startRenaming()"
 								) Rename
 							li
 								a(
-									href="#"
-									prevent-default="click"
+									href
 									ng-click="openDeleteModal()"
+									right-click="openDeleteModal()"
 								) Delete
 							li.divider
 							li
 								a(
-									href="#"
-									prevent-default="click"
+									href
 									ng-click="openNewDocModal()"
+									right-click="openNewDocModal()"
 								) New File
 							li
 								a(
-									href="#"
-									prevent-default="click"
+									href
 									ng-click="openNewFolderModal()"
+									right-click="openNewFolderModal()"
 								) New Folder
 							li
 								a(
-									href="#"
-									prevent-default="click"
+									href
 									ng-click="openUploadFileModal()"
+									right-click="openUploadFileModal()"
 								) Upload File
 
 					.dropdown.context-menu(
@@ -255,39 +253,34 @@ script(type='text/ng-template', id='entityListItemTemplate')
 						ul.dropdown-menu
 							li
 								a(
-									href="#"
-									prevent-default="click"
-									stop-propagation="click"
+									href
 									ng-click="startRenaming()"
+									right-click="startRenaming()"
 								) Rename
 							li
 								a(
-									href="#"
-									prevent-default="click"
-									stop-propagation="click"
+									href
 									ng-click="openDeleteModal()"
+									right-click="openDeleteModal()"
 								) Delete
 							li.divider
 							li
 								a(
-									href="#"
-									prevent-default="click"
-									stop-propagation="click"
+									href
 									ng-click="openNewDocModal()"
+									right-click="openNewDocModal()"
 								) New File
 							li
 								a(
-									href="#"
-									prevent-default="click"
-									stop-propagation="click"
+									href
 									ng-click="openNewFolderModal()"
+									right-click="openNewFolderModal()"
 								) New Folder
 							li
 								a(
-									href="#"
-									prevent-default="click"
-									stop-propagation="click"
+									href
 									ng-click="openUploadFileModal()"
+									right-click="openUploadFileModal()"
 								) Upload File
 
 			ul.list-unstyled(

+ 8 - 5
services/web/app/views/project/editor/pdf.jade

@@ -83,11 +83,14 @@ div.full-size.pdf(ng-controller="PdfController")
 			strong Server Error. 
 			span Sorry, something went wrong and your project could not be compiled. Please try again in a few moments.
 
-		.alert.alert-danger(ng-show="pdf.timedout")
-			strong Timed out. 
-			span Sorry, your compile was taking too long and timed out.
-				| This may be due to a large number of high-res images, or lots of complicated diagrams. 
-				| Please try to make your document simpler, or contact support for help.
+		.alert.alert-danger(ng-show="pdf.timedout") 
+			p
+				strong Your compile timed out.
+				|  Sorry, your compile was taking too long and timed out.
+				| This may be due to a problem with your LaTeX code, or too many high-res images.
+			p
+				a.text-info(href="https://www.sharelatex.com/learn/Debugging_Compilation_timeout_errors", target="_blank")
+					| Please see our help guide for more information.
 
 	.pdf-logs(ng-show="(pdf.view == 'logs' || pdf.failure) && !pdf.error && !pdf.timeout && !pdf.uncompiled")
 		.alert.alert-success(ng-show="pdf.logEntries.all.length == 0")

+ 6 - 6
services/web/app/views/project/list/project-list.jade

@@ -118,18 +118,18 @@
 			)
 				li.container-fluid
 					.row
-						.col-xs-6(ng-click="changePredicate('name')")
+						.col-xs-6
 							input.select-all(
 								select-all,
 								type="checkbox"
 							)
-							span.header.clickable Title
+							span.header.clickable(ng-click="changePredicate('name')") Title
 								i.tablesort.fa(ng-class="getSortIconClass('name')")
-						.col-xs-2(ng-click="changePredicate('accessLevel')")
-							span.header.clickable Owner
+						.col-xs-2
+							span.header.clickable(ng-click="changePredicate('accessLevel')") Owner
 								i.tablesort.fa(ng-class="getSortIconClass('accessLevel')")
-						.col-xs-4(ng-click="changePredicate('lastUpdated')")
-							span.header.clickable Last Modified
+						.col-xs-4
+							span.header.clickable(ng-click="changePredicate('lastUpdated')") Last Modified
 								i.tablesort.fa(ng-class="getSortIconClass('lastUpdated')")
 				li.project_entry.container-fluid(
 					ng-repeat="project in visibleProjects | orderBy:predicate:reverse",

+ 4 - 4
services/web/app/views/templates/index.jade

@@ -47,10 +47,10 @@ block content
 										div.caption
 											h3.txt-middle #{template.name}
 
-							-if(tag.totalNumberOfTemplates > 4)
-								.row-fluid
-									.col-md-6.offset3.more-templates
-										a(href=tag.tagPagePath) View all #{tag.totalNumberOfTemplates} #{tag.name} templates »
+						-if(tag.totalNumberOfTemplates > 4)
+							.row
+								.col-md-12.text-center
+									a(href=tag.tagPagePath) View all #{tag.totalNumberOfTemplates} #{tag.name} templates »
 
 
 

+ 2 - 1
services/web/app/views/user/settings.jade

@@ -70,6 +70,7 @@ block content
 											.form-group
 												label(for='newPassword1') New Password
 												input.form-control(
+													id='newPassword1',
 													type='password',
 													name='newPassword1',
 													placeholder='*********',
@@ -85,7 +86,7 @@ block content
 													name='newPassword2',
 													placeholder='*********',
 													ng-model="newPassword2",
-													equals="{{newPassword1}}"
+													equals="newPassword1"
 												)
 												span.small.text-primary(ng-show="changePasswordForm.newPassword2.$invalid && changePasswordForm.newPassword2.$dirty")
 													| Doesn't match

+ 14 - 0
services/web/app/views/wiki/page.jade

@@ -0,0 +1,14 @@
+extends ../layout
+
+block content
+	.content.content-alt
+		.container.wiki
+			.row
+				.col-xs-3.contents
+					| !{contents.content}
+				.col-xs-9.page
+					.card
+						.page-header
+							h1 #{title}
+							
+						| !{page.content}

+ 9 - 9
services/web/public/coffee/directives/equals.coffee

@@ -2,14 +2,14 @@ define [
 	"base"
 ], (App) ->
 
-	App.directive 'equals', () ->
+	App.directive "equals", [->
 		return {
-			require: "ngModel",
-			link: (scope, element, attrs, ngModel) ->
-				scope.$watch attrs.ngModel, () -> validate()
-				attrs.$observe 'equals', () -> validate()
-
-				validate = () ->
-					equal = (attrs.equals == ngModel.$viewValue)
-					ngModel.$setValidity('areEqual', equal)
+			require: "ngModel"
+			link: (scope, elem, attrs, ctrl) ->
+				firstField = "#" + attrs.equals
+				elem.add(firstField).on "keyup", ->
+					scope.$apply ->
+						equal = elem.val() == $(firstField).val()
+						ctrl.$setValidity "areEqual", equal
 		}
+	]

+ 12 - 0
services/web/public/coffee/directives/rightClick.coffee

@@ -0,0 +1,12 @@
+define [
+	"base"
+], (App) ->
+	App.directive "rightClick", () ->
+		return {
+			restrict: "A",
+			link: (scope, element, attrs) ->
+				element.bind "contextmenu", (e) ->
+					e.preventDefault()
+					e.stopPropagation()
+					scope.$eval(attrs.rightClick)
+		}

+ 2 - 0
services/web/public/coffee/ide.coffee

@@ -21,6 +21,8 @@ define [
 	"directives/fineUpload"
 	"directives/scroll"
 	"directives/onEnter"
+	"directives/stopPropagation"
+	"directives/rightClick"
 	"filters/formatDate"
 	"main/event-tracking"
 ], (

+ 3 - 3
services/web/public/coffee/ide/chat/controllers/ChatController.coffee

@@ -21,10 +21,10 @@ define [
 			ide.$scope.$broadcast "chat:resetUnreadMessages"
 				
 		$scope.sendMessage = ->
+			message = $scope.newMessageContent
+			$scope.newMessageContent = ""
 			chatMessages
-				.sendMessage $scope.newMessageContent
-				.then () ->
-					$scope.newMessageContent = ""
+				.sendMessage message
 				
 		$scope.loadMoreMessages = ->
 			chatMessages.loadMoreMessages()

+ 1 - 2
services/web/public/coffee/ide/clone/controllers/CloneProjectModalController.coffee

@@ -22,8 +22,7 @@ define [
 			$scope.state.inflight = true
 			cloneProject($scope.inputs.projectName)
 				.then (data) ->
-					console.log "DATA", data
-					#window.location = "/project/#{data.project_id}"
+					window.location = "/project/#{data.data.project_id}"
 
 		$scope.cancel = () ->
 			$modalInstance.dismiss('cancel')

+ 1 - 1
services/web/public/coffee/ide/dropbox/controllers/DropboxController.coffee

@@ -38,10 +38,10 @@ define [
 				$timeout calculatePollTime, 60 * 1000
 
 		ide.socket.emit "getUserDropboxLinkStatus", user_id, (err, status)=>
+			$scope.dbState.gotLinkStatus = true
 			if status.registered 
 				calculatePollTime()
 				$scope.dbState.userIsLinkedToDropbox = true
-				$scope.dbState.gotLinkStatus = true
 				cachedState = $scope.dbState
 		
 		$scope.linkToDropbox = ->

+ 11 - 5
services/web/public/coffee/ide/file-tree/FileTreeManager.coffee

@@ -23,49 +23,55 @@ define [
 		_bindToSocketEvents: () ->
 			@ide.socket.on "reciveNewDoc", (parent_folder_id, doc) =>
 				parent_folder = @findEntityById(parent_folder_id) or @$scope.rootFolder
-				@$scope.$apply () ->
+				@$scope.$apply () =>
 					parent_folder.children.push {
 						name: doc.name
 						id:   doc._id
 						type: "doc"
 					}
+					@recalculateDocList()
 
 			@ide.socket.on "reciveNewFile", (parent_folder_id, file) =>
 				parent_folder = @findEntityById(parent_folder_id) or @$scope.rootFolder
-				@$scope.$apply () ->
+				@$scope.$apply () =>
 					parent_folder.children.push {
 						name: file.name
 						id:   file._id
 						type: "file"
 					}
-
+					@recalculateDocList()
+					
 			@ide.socket.on "reciveNewFolder", (parent_folder_id, folder) =>
 				parent_folder = @findEntityById(parent_folder_id) or @$scope.rootFolder
-				@$scope.$apply () ->
+				@$scope.$apply () =>
 					parent_folder.children.push {
 						name: folder.name
 						id:   folder._id
 						type: "folder"
 						children: []
 					}
+					@recalculateDocList()
 
 			@ide.socket.on "reciveEntityRename", (entity_id, name) =>
 				entity = @findEntityById(entity_id)
 				return if !entity?
-				@$scope.$apply () ->
+				@$scope.$apply () =>
 					entity.name = name
+					@recalculateDocList()
 
 			@ide.socket.on "removeEntity", (entity_id) =>
 				entity = @findEntityById(entity_id)
 				return if !entity?
 				@$scope.$apply () =>
 					@_deleteEntityFromScope entity
+					@recalculateDocList()
 
 			@ide.socket.on "reciveEntityMove", (entity_id, folder_id) =>
 				entity = @findEntityById(entity_id)
 				folder = @findEntityById(folder_id)
 				@$scope.$apply () =>
 					@_moveEntityInScope(entity, folder)
+					@recalculateDocList()
 
 		selectEntity: (entity) ->
 			@selected_entity_id = entity.id # For reselecting after a reconnect

BIN
services/web/public/img/lion-128.png


+ 2 - 2
services/web/public/js/ace/ace.js

@@ -2313,14 +2313,14 @@ var TextInput = function(parentNode, host) {
             }
         }, 0);
     }
-    if (!useragent.isGecko || useragent.isMac) {
+    // if (!useragent.isGecko || useragent.isMac) {
         var onContextMenu = function(e) {
             host.textInput.onContextMenu(e);
             onContextMenuClose();
         };
         event.addListener(host.renderer.scroller, "contextmenu", onContextMenu);
         event.addListener(text, "contextmenu", onContextMenu);
-    }
+    // }
 };
 
 exports.TextInput = TextInput;

+ 1 - 1
services/web/public/js/libs/ng-context-menu-0.1.4.js

@@ -61,7 +61,7 @@ angular
               ContextMenuService.container = angular.element($attrs.contextMenuContainer)
             }
             ContextMenuService.element = event.target;
-            console.log('set', ContextMenuService.element);
+            // console.log('set', ContextMenuService.element);
 
             event.preventDefault();
             event.stopPropagation();

+ 1 - 1
services/web/public/stylesheets/app/about-page.less

@@ -3,6 +3,6 @@
 	.img-container {
 		float: left;
 		overflow: hidden;
-		margin: (@line-height-computed / 2) @line-height-computed @line-height-computed (@line-height-computed / 2);
+		margin: (@line-height-computed / 4) @line-height-computed @line-height-computed (@line-height-computed / 2);
 	}
 }

+ 8 - 1
services/web/public/stylesheets/app/editor.less

@@ -50,15 +50,22 @@
 }
 
 .loading-screen {
+	h3 {
+		padding-top: 136px;
+		background-image: url(/img/lion-128.png);
+		background-repeat: no-repeat;
+		background-position: top center;
+	}
 	.full-size;
 	background-color: #fafafa;
 	.container {
 		text-align: center;
 		position: absolute;
-		top: 30%;
+		top: 50%;
 		left: 50%;
 		width: 400px;
 		margin-left: -200px;
+		margin-top: -200px;
 	}
 }
 

+ 107 - 0
services/web/public/stylesheets/app/wiki.less

@@ -0,0 +1,107 @@
+.wiki {
+	.contents {
+		ul {
+			padding: 0;
+			li {
+				font-size: 14px;
+				list-style: none;
+				margin-bottom: 6px;
+			}
+		}
+		
+		h2 {
+			font-size: 18px;
+		}
+	}
+	
+	.page-header {
+		a {
+			font-size: 0.8em;
+			line-height: 1;
+		}
+	}
+	
+	.editsection {
+		display: none;
+	}
+	
+	table {
+		th, td {
+			padding: (@line-height-computed / 4) (@line-height-computed / 2);
+			border-bottom: 1px solid @gray-lighter;
+		}
+		th {
+			font-weight: 700;
+			text-align: left;
+			font-family: @font-family-serif;
+		}
+		margin-bottom: @line-height-computed / 2;
+	}
+	
+	.example {
+		.code {
+			pre {
+				background-color: @gray-lightest;
+				border-radius: 6px;
+				padding: (@line-height-computed / 2);
+				white-space: pre-wrap;
+				margin: 0;
+			}
+		}
+		.output {
+			img {
+				width: auto !important;
+				height: auto !important;
+				max-width: 100% !important;
+				box-shadow: 0 1px 3px @gray-light;
+				border-radius: 6px;
+			}
+		}
+	}
+	@media (min-width: 1360px) {
+		.example {
+			margin-right: -200px;
+		}
+	}
+	
+	/*<![CDATA[*/
+	.source-latex {line-height: normal;}
+	.source-latex li, .source-latex pre {
+		line-height: normal; border: 0px none white;
+	}
+	/**
+	 * GeSHi Dynamically Generated Stylesheet
+	 * --------------------------------------
+	 * Dynamically generated stylesheet for latex
+	 * CSS class: source-latex, CSS id: 
+	 * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann
+	 * (http://qbnz.com/highlighter/ and http://geshi.org/)
+	 * --------------------------------------
+	 */
+	.latex.source-latex .imp {font-weight: bold; color: red;}
+	.latex.source-latex li, .latex.source-latex .li1 {font-weight: normal; vertical-align:top;}
+	.latex.source-latex .ln {width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}
+	.latex.source-latex .li2 {font-weight: bold; vertical-align:top;}
+	.latex.source-latex .kw1 {color: #800000;}
+	.latex.source-latex .co1 {color: #2C922C; font-style: italic;}
+	.latex.source-latex .es0 {color: #000000; font-weight: bold;}
+	.latex.source-latex .sy0 {color: #E02020; }
+	.latex.source-latex .st0 {color: #000000;}
+	.latex.source-latex .re1 {color: #8020E0; font-weight: normal;}
+	.latex.source-latex .re2 {color: #C08020; font-weight: normal;}
+	.latex.source-latex .re3 {color: #8020E0; font-weight: normal;}
+	.latex.source-latex .re4 {color: #800000; font-weight: normal;}
+	.latex.source-latex .re5 {color: #00008B; font-weight: bold;}
+	.latex.source-latex .re6 {color: #800000; font-weight: normal;}
+	.latex.source-latex .re7 {color: #0000D0; font-weight: normal;}
+	.latex.source-latex .re8 {color: #C00000; font-weight: normal;}
+	.latex.source-latex .re9 {color: #2020C0; font-weight: normal;}
+	.latex.source-latex .re10 {color: #800000; font-weight: normal;}
+	.latex.source-latex .re11 {color: #E00000; font-weight: normal;}
+	.latex.source-latex .re12 {color: #800000; font-weight: normal;}
+	.latex.source-latex .ln-xtra, .latex.source-latex li.ln-xtra, .latex.source-latex div.ln-xtra {background-color: #ffc;}
+	.latex.source-latex span.xtra { display:block; }
+
+	/*]]>*/
+
+}

+ 1 - 0
services/web/public/stylesheets/style.less

@@ -65,3 +65,4 @@
 @import "app/blog.less";
 @import "app/features.less";
 @import "app/templates.less";
+@import "app/wiki.less";

+ 1 - 1
services/web/test/smoke/coffee/SmokeTests.coffee

@@ -66,7 +66,7 @@ describe "Opening", ->
 		}, (error, response, body) ->
 			expect(error, "smoke test: error returned in getting project list").to.not.exist
 			expect(response.statusCode, "smoke test: response code is not 200 getting project list").to.equal(200)
-			expect(!!body.match("<title>Your Projects - Online LaTeX Editor ShareLaTeX</title>"), "smoke test: body does not have correct title").to.equal true
+			expect(!!body.match("<title>Your Projects - ShareLaTeX, the Online LaTeX Editor</title>"), "smoke test: body does not have correct title").to.equal true
 			expect(!!body.match("ProjectPageController"), "smoke test: body does not have correct angular controller").to.equal true
 			done()