Sfoglia il codice sorgente

Merge branch 'master' into pr-angular-1.6.x

Paulo Reis 9 anni fa
parent
commit
86e66bbed1

+ 1 - 1
services/web/app/coffee/Features/Errors/ErrorController.coffee

@@ -38,5 +38,5 @@ module.exports = ErrorController =
 			logger.warn {err: error, url: req.url}, "not found error"
 			res.sendStatus(404)
 		else
-			logger.error err: error, url:req.url, method:req.method, user:user, "error passed to top level next middlewear"
+			logger.error err: error, url:req.url, method:req.method, "error passed to top level next middlewear"
 			res.sendStatus(500)

+ 2 - 2
services/web/app/coffee/Features/Subscription/SubscriptionGroupController.coffee

@@ -54,8 +54,8 @@ module.exports =
 	renderSubscriptionGroupAdminPage: (req, res)->
 		user_id = AuthenticationController.getLoggedInUserId(req)
 		SubscriptionLocator.getUsersSubscription user_id, (err, subscription)->
-			if !subscription.groupPlan
-				return res.redirect("/")
+			if !subscription?.groupPlan
+				return res.redirect("/user/subscription")
 			SubscriptionGroupHandler.getPopulatedListOfMembers user_id, (err, users)->
 				res.render "subscriptions/group_admin",
 					title: 'group_admin'

+ 12 - 5
services/web/public/coffee/ide/editor/directives/aceEditor/labels/LabelsManager.coffee

@@ -11,7 +11,7 @@ define [
 
 	class LabelsManager
 		constructor: (@$scope, @editor, @element, @Labels) ->
-			@loadLabelsTimeout = null
+			@debouncer = {}  # DocId => Timeout
 
 			onChange = (change) =>
 				if change.remote
@@ -36,13 +36,20 @@ define [
 			currentDocId = @$scope.docId
 			@Labels.loadDocLabelsFromServer(currentDocId)
 
+		loadDocLabelsFromServer: (docId) ->
+			@Labels.loadDocLabelsFromServer(docId)
+
 		scheduleLoadCurrentDocLabelsFromServer: () ->
 			# De-bounce loading labels with a timeout
-			if @loadLabelsTimeout
-				clearTimeout(@loadLabelsTimeout)
-			@loadLabelsTimeout = setTimeout(
+			currentDocId = @$scope.docId
+			existingTimeout = @debouncer[currentDocId]
+			if existingTimeout?
+				clearTimeout(existingTimeout)
+				delete @debouncer[currentDocId]
+			@debouncer[currentDocId] = setTimeout(
 				() =>
-					@loadCurrentDocLabelsFromServer()
+					@loadDocLabelsFromServer(currentDocId)
+					delete @debouncer[currentDocId]
 				, 1000
 				, this
 			)

+ 20 - 0
services/web/public/coffee/ide/editor/directives/aceEditor/spell-check/SpellCheckManager.coffee

@@ -217,6 +217,7 @@ define [
 			words = []
 			positions = []
 			for line, row in lines
+				line = @blankOutBlacklistedCommands(line)
 				if !linesToProcess? or linesToProcess[row]
 					# Regex generated from /\\?['\p{L}]+/g via https://mothereff.in/regexpu.
 					# \p{L} matches unicode characters in the 'letter' category, but is not supported until ES6.
@@ -246,3 +247,22 @@ define [
 				error: (xhr, status, error) ->
 					callback error
 			return $.ajax options
+
+		blacklistedCommandRegex: ///
+			\\                    # initial backslash
+			(label                # any of these commands
+			|[a-z]{0,16}ref
+			|usepackage
+			|begin
+			|end
+			|[a-z]{0,16}cite
+			|input
+			|include
+			|includegraphics)
+			( \[ [^\]]* \] )?     # optional [...] args
+				\{ [^}]*  \}        # the {...} args
+		///g
+
+		blankOutBlacklistedCommands: (line) ->
+			line.replace @blacklistedCommandRegex, (command) ->
+				Array(command.length+1).join('.')

+ 49 - 0
services/web/public/coffee/ide/pdfng/directives/pdfViewer.coffee

@@ -323,6 +323,8 @@ define [
 									clearTimeout spinnerTimer
 								else
 									spinner.remove(element)
+								# stop displaying the text layer
+								element.removeClass 'pdfjs-viewer-show-text'
 								ctrl.redraw(origposition)
 								$timeout renderVisiblePages
 								scope.loadSuccess = true
@@ -405,6 +407,53 @@ define [
 						scope.adjustingScroll = true
 						element.scrollTop(currentScrollTop + delta)
 
+				element.on 'mousedown', (e) ->
+					# We're checking that the event target isn't the directive root element 
+					# to make sure that the click was within a PDF page - no point in showing
+					# the text layer when the click is outside.
+					# If the user clicks a PDF page, the mousedown target will be the canvas
+					# element (or the text layer one). Alternatively, if the event target is
+					# the root element, we can assume that the user has clicked either the 
+					# grey background area or the scrollbars.
+					if e.target != element[0] and !_hasSelection()
+						element.addClass 'pdfjs-viewer-show-text'
+						_setMouseUpHandler()
+
+				mouseUpHandler = null # keep track of the handler to avoid adding multiple times
+
+				_setMouseUpHandler = () ->
+					if not mouseUpHandler?
+						mouseUpHandler = $(document.body).one 'mouseup', _handleSelectionMouseUp
+
+				_handleSelectionMouseUp = () ->
+					mouseUpHandler = null # reset handler, has now fired
+					window.setTimeout () ->
+						removedClass = _removeClassIfNoSelection()
+						# if we still have a selection we need to keep the handler going
+						if not removedClass then _setMouseUpHandler()
+					, 10
+					return true
+
+				_removeClassIfNoSelection = () ->
+					if _hasSelection()
+						return false # didn't remove the text layer
+					else
+						element.removeClass 'pdfjs-viewer-show-text'
+						return true
+
+				_hasSelection = () ->
+					selection = window.getSelection?()
+					# check the selection collapsed state in preference to
+					# using selection.toString() as the latter is "" when 
+					# the selection is hidden (e.g. while viewing logs)
+					return selection? and _isSelectionWithinPDF(selection) and !selection.isCollapsed
+
+				_isSelectionWithinPDF = (selection) ->
+					if selection.rangeCount == 0
+						return false
+					selectionAncestorNode = selection.getRangeAt(0).commonAncestorContainer
+					return element.find(selectionAncestorNode).length > 0 or element.is(selectionAncestorNode)
+
 				element.on 'scroll', () ->
 					#console.log 'scroll event', element.scrollTop(), 'adjusting?', scope.adjustingScroll
 					#scope.scrollPosition = element.scrollTop()

+ 11 - 0
services/web/public/stylesheets/app/editor/pdf.less

@@ -37,6 +37,7 @@
 			margin: 10px auto;
 			padding: 0 10px;
 			box-sizing: content-box;
+			user-select: none;
 		}
 	}
 	.progress-thin {
@@ -338,3 +339,13 @@
 	.files-dropdown {
 		display: inline-block;
 	}
+
+.plv-text-layer {
+	display: none;
+	user-select: text;
+	
+	.pdf-page-container:hover &,
+	.pdfjs-viewer-show-text & {
+		display: block;
+	}
+}

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

@@ -10,6 +10,7 @@
 			right: 0;
 			padding: .15em .6em .2em;
 			font-size: 60%;
+			pointer-events: none; // Labels were capturing button/anchor clicks.
 		}
 	}
 

+ 10 - 1
services/web/test/UnitTests/coffee/Subscription/SubscriptionGroupControllerTests.coffee

@@ -96,7 +96,16 @@ describe "SubscriptionGroupController", ->
 
 			res =
 				redirect : (path)=>
-					path.should.equal("/")
+					path.should.equal("/user/subscription")
+					done()
+			@Controller.renderSubscriptionGroupAdminPage @req, res
+
+		it "should redirect you don't have a subscription", (done)->
+			@SubscriptionLocator.getUsersSubscription = sinon.stub().callsArgWith(1)
+
+			res =
+				redirect : (path)=>
+					path.should.equal("/user/subscription")
 					done()
 			@Controller.renderSubscriptionGroupAdminPage @req, res