Merge pull request #432 from sharelatex/es-modules

Set up compilation of ES code in modules and extract RT management code
This commit is contained in:
Alasdair Smith 2018-03-26 13:51:59 +01:00 committed by GitHub
commit 47e2d8c9f9
13 changed files with 36 additions and 139 deletions

View file

@ -49,6 +49,8 @@ TpdsWorker.js
BackgroundJobsWorker.js
UserAndProjectPopulator.coffee
public/es/modules
public/js/*.js
public/js/*.map
public/js/libs/sharejs.js

View file

@ -1,13 +1,16 @@
MODULE_NAME := $(notdir $(shell pwd))
MODULE_DIR := modules/$(MODULE_NAME)
COFFEE := ../../node_modules/.bin/coffee
APP_COFFEE_FILES := $(shell find app/coffee -name '*.coffee') \
APP_COFFEE_FILES := $(shell [ -e app/coffee ] && find app/coffee -name '*.coffee') \
$(shell [ -e test/unit/coffee ] && find test/unit/coffee -name '*.coffee') \
$(shell [ -e test/acceptance/coffee ] && find test/acceptance/coffee -name '*.coffee')
APP_JS_FILES := $(subst coffee,js,$(APP_COFFEE_FILES))
IDE_COFFEE_FILES := $(shell [ -e public/coffee/ide ] && find public/coffee/ide -name '*.coffee')
IDE_JS_FILES := $(subst public/coffee/ide,../../public/js/ide/$(MODULE_NAME),$(IDE_COFFEE_FILES))
IDE_JS_FILES := $(subst coffee,js,$(IDE_JS_FILES))
IDE_TEST_COFFEE_FILES := $(shell [ -e test/unit_frontend/coffee ] && find test/unit_frontend/coffee -name '*.coffee')
IDE_TEST_JS_FILES := $(subst test/unit_frontend/coffee/ide,../../test/unit_frontend/js/ide/$(MODULE_NAME),$(IDE_TEST_COFFEE_FILES))
IDE_TEST_JS_FILES := $(subst coffee,js,$(IDE_TEST_JS_FILES))
MAIN_COFFEE_FILES := $(shell [ -e public/coffee/main ] && find public/coffee/main -name '*.coffee')
MAIN_JS_FILES := $(subst public/coffee/main,../../public/js/main/$(MODULE_NAME),$(MAIN_COFFEE_FILES))
MAIN_JS_FILES := $(subst coffee,js,$(MAIN_JS_FILES))
@ -26,6 +29,10 @@ test/acceptance/js/%.js: test/acceptance/coffee/%.coffee
@mkdir -p $(dir $@)
$(COFFEE) --compile --print $< > $@
../../test/unit_frontend/js/ide/$(MODULE_NAME)/%.js: test/unit_frontend/coffee/ide/%.coffee
@mkdir -p $(dir $@)
$(COFFEE) --compile --print $< > $@
../../public/js/ide/$(MODULE_NAME)/%.js: public/coffee/ide/%.coffee
@mkdir -p $(dir $@)
$(COFFEE) --compile --print $< > $@
@ -37,7 +44,7 @@ test/acceptance/js/%.js: test/acceptance/coffee/%.coffee
index.js: index.coffee
$(COFFEE) --compile --print $< > $@
compile: $(APP_JS_FILES) $(IDE_JS_FILES) $(MAIN_JS_FILES) index.js
compile: $(APP_JS_FILES) $(IDE_JS_FILES) $(MAIN_JS_FILES) $(IDE_TEST_JS_FILES) index.js
@echo > /dev/null
compile_full:

View file

@ -150,6 +150,8 @@ module.exports = (app, webRouter, privateApiRouter, publicApiRouter)->
res.locals.buildWebpackPath = (jsFile, opts = {}) ->
if Settings.webpack? and !Settings.useMinifiedJs
path = Path.join(jsPath, jsFile)
if opts.removeExtension == true
path = path.slice(0,-3)
return "#{Settings.webpack.url}/public#{path}"
else
return res.locals.buildJsPath(jsFile, opts)

View file

@ -133,6 +133,7 @@ block requirejs
"fineuploader": "libs/#{lib('fineuploader')}",
"ide": "#{buildJsPath('ide.js', {hashedPath:settings.useMinifiedJs, removeExtension:true})}",
"libraries": "#{buildJsPath('libraries.js', {hashedPath:settings.useMinifiedJs, removeExtension:true})}",
!{moduleIncludes("editor:script", locals)}
},
"waitSeconds": 0,
"shim": {
@ -159,12 +160,6 @@ block requirejs
window.pdfCMapsPath = "#{pdfCMapsPath}"
window.uiConfig = JSON.parse('!{JSON.stringify(uiConfig).replace(/\//g, "\\/")}');
if hasFeature('rich-text')
script(
src=buildWebpackPath('es/richText.js', {hashedPath:settings.useMinifiedJs})
type="text/javascript"
)
script(
data-main=buildJsPath("ide.js", {hashedPath:false}),
baseurl=fullJsPath,

View file

@ -30,9 +30,7 @@ div.full-size(
i.fa.fa-arrow-left
| &nbsp;&nbsp;#{translate("open_a_file_on_the_left")}
if hasFeature('rich-text')
.toolbar.toolbar-editor(ng-controller="EditorToolbarController")
button(ng-click="toggleRichText()") Rich Text
!= moduleIncludes('editor:toolbar', locals)
#editor(
ace-editor="editor",
@ -68,13 +66,7 @@ div.full-size(
renderer-data="reviewPanel.rendererData"
)
if hasFeature('rich-text')
#editor-rich-text(
cm-editor,
ng-if="editor.richText"
ng-show="!!editor.sharejs_doc && !editor.opening"
sharejs-doc="editor.sharejs_doc"
)
!= moduleIncludes('editor:body', locals)
include ./review-panel

View file

@ -25,13 +25,15 @@ module.exports = function (config) {
{ pattern: 'public/js/**/*.js', included: false },
{ pattern: 'test/unit_frontend/js/**/*.js', included: false },
// Include ES test files
'test/unit_frontend/es/**/*.js'
'test/unit_frontend/es/**/*.js',
'modules/**/test/unit_frontend/es/**/*.js'
],
middleware: ['fake-img'],
preprocessors: {
// Run ES test files through webpack (which will then include source
// files in bundle)
'test/unit_frontend/es/**/*.js': ['webpack']
'test/unit_frontend/es/**/*.js': ['webpack'],
'modules/**/test/unit_frontend/es/**/*.js': ['webpack']
},
frameworks: ['requirejs', 'mocha', 'chai-sinon'],
// Configure webpack in the tests

View file

@ -1,9 +1,7 @@
define [
"ide/editor/Document"
"ide/editor/directives/aceEditor"
"ide/editor/directives/cmEditor"
"ide/editor/controllers/SavingNotificationController"
"ide/editor/controllers/EditorToolbarController"
], (Document) ->
class EditorManager
constructor: (@ide, @$scope) ->

View file

@ -1,7 +0,0 @@
define [
"base"
"ide/editor/Document"
], (App, Document) ->
App.controller "EditorToolbarController", ($scope, ide) ->
$scope.toggleRichText = () ->
ide.editorManager.toggleRichText()

View file

@ -1,33 +0,0 @@
define [
"base"
], (App) ->
App.directive "cmEditor", () ->
return {
scope: {
sharejsDoc: "="
}
link: (scope, element, attrs) ->
cm = Frontend.richText.init(element.find('.cm-editor-wrapper')[0])
scope.$watch "sharejsDoc", (sharejsDoc, oldSharejsDoc) ->
if oldSharejsDoc?
detachFromCM(oldSharejsDoc)
if sharejsDoc?
attachToCM(sharejsDoc)
attachToCM = (sharejsDoc) ->
scope.$applyAsync () ->
Frontend.richText.openDoc(cm, sharejsDoc.getSnapshot())
sharejsDoc.attachToCM(cm)
detachFromCM = (sharejsDoc) ->
sharejsDoc.detachFromCM()
scope.$on 'destroy', () ->
detachFromCM(scope.sharejsDoc)
template: """
<div class="cm-editor-wrapper"></div>
"""
}

View file

@ -1,16 +0,0 @@
import CodeMirror, { Doc } from 'codemirror'
export function init (rootEl) {
CodeMirror.defineMIME('application/x-tex', 'latex')
CodeMirror.defineMIME('application/x-latex', 'latex')
return CodeMirror(rootEl, {
mode: 'latex'
})
}
export function openDoc (cm, content) {
const newDoc = Doc(content, 'latex')
cm.swapDoc(newDoc)
return newDoc
}

View file

@ -1,58 +0,0 @@
define ['ide/editor/directives/cmEditor'], () ->
describe 'cmEditor', () ->
beforeEach(module('SharelatexApp'))
beforeEach () ->
@richTextInit = sinon.stub()
@richTextOpenDoc = sinon.stub()
window.Frontend = {
richText: {
init: @richTextInit,
openDoc: @richTextOpenDoc
}
}
afterEach () -> window.Frontend = null
it 'inits Rich Text', () ->
inject ($compile, $rootScope) =>
$compile('<div cm-editor></div>')($rootScope)
expect(@richTextInit).to.have.been.called
it 'attaches to CM', () ->
inject ($compile, $rootScope, $browser) =>
getSnapshot = sinon.stub()
detachFromCM = sinon.stub()
attachToCM = sinon.stub()
$rootScope.sharejsDoc = {
getSnapshot: getSnapshot
detachFromCM: detachFromCM
attachToCM: attachToCM
}
$compile('<div cm-editor sharejs-doc="sharejsDoc"></div>')($rootScope)
$rootScope.$digest()
# Trigger $applyAsync to evaluate the expression, normally done in the
# next tick
$browser.defer.flush()
expect(detachFromCM).to.have.been.called
expect(getSnapshot).to.have.been.called
expect(@richTextOpenDoc).to.have.been.called
expect(attachToCM).to.have.been.called
it 'detaches from CM when destroyed', () ->
inject ($compile, $rootScope) =>
@richTextInit.returns({ setValue: sinon.stub() })
detachFromCM = sinon.stub()
$rootScope.sharejsDoc = {
getSnapshot: sinon.stub()
detachFromCM: detachFromCM
attachToCM: sinon.stub()
}
$compile('<div cm-editor sharejs-doc="sharejsDoc"></div>')($rootScope)
$rootScope.$digest()
$rootScope.$broadcast('destroy')
expect(detachFromCM).to.have.been.called

View file

@ -1,11 +1,24 @@
const fs = require('fs')
const path = require('path')
const MODULES_PATH = path.join(__dirname, '/modules')
// Generate a hash of entry points, including modules
const entryPoints = {}
if (fs.existsSync(MODULES_PATH)) {
fs.readdirSync(MODULES_PATH).reduce((acc, module) => {
const entryPath = path.join(MODULES_PATH, module, '/public/es/index.js')
if (fs.existsSync(entryPath)) {
acc[module] = entryPath
}
return acc
}, entryPoints)
}
module.exports = {
// Defines the "entry point(s)" for the application - i.e. the file which
// bootstraps the application
entry: {
richText: './public/es/rich-text.js'
},
entry: entryPoints,
// Define where and how the bundle will be output to disk
// Note: webpack-dev-server does not write the bundle to disk, instead it is