mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
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:
commit
47e2d8c9f9
13 changed files with 36 additions and 139 deletions
2
services/web/.gitignore
vendored
2
services/web/.gitignore
vendored
|
@ -49,6 +49,8 @@ TpdsWorker.js
|
|||
BackgroundJobsWorker.js
|
||||
UserAndProjectPopulator.coffee
|
||||
|
||||
public/es/modules
|
||||
|
||||
public/js/*.js
|
||||
public/js/*.map
|
||||
public/js/libs/sharejs.js
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -30,9 +30,7 @@ div.full-size(
|
|||
i.fa.fa-arrow-left
|
||||
| #{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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) ->
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
define [
|
||||
"base"
|
||||
"ide/editor/Document"
|
||||
], (App, Document) ->
|
||||
App.controller "EditorToolbarController", ($scope, ide) ->
|
||||
$scope.toggleRichText = () ->
|
||||
ide.editorManager.toggleRichText()
|
|
@ -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>
|
||||
"""
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue