diff --git a/app/.jshintrc b/app/.jshintrc index cee569be..cfb4bd4e 100644 --- a/app/.jshintrc +++ b/app/.jshintrc @@ -1,49 +1,49 @@ { - "predef": [ - "server", - "document", - "window", - "-Promise", - "moment", - "$", - "_", - "is", - "Mousetrap", - "CodeMirror", - "Intercom", - "Materialize", - "tinymce", - "Tether", - "Tooltip", - "Drop", - "Dropzone", - "dragula", - "datetimepicker", - "Waypoint" - ], - "browser": true, - "boss": true, - "curly": true, - "debug": false, - "devel": true, - "eqeqeq": true, - "evil": true, - "forin": false, - "immed": false, - "laxbreak": false, - "newcap": true, - "noarg": true, - "noempty": false, - "nonew": false, - "nomen": false, - "onevar": false, - "plusplus": false, - "regexp": false, - "undef": true, - "sub": true, - "strict": false, - "white": false, - "eqnull": true, - "esnext": true, - "unused": true + "predef": [ + "server", + "document", + "window", + "-Promise", + "moment", + "$", + "_", + "is", + "Mousetrap", + "CodeMirror", + "Intercom", + "Materialize", + "tinymce", + "Tether", + "Tooltip", + "Drop", + "Dropzone", + "dragula", + "datetimepicker", + "Waypoint" + ], + "browser": true, + "boss": true, + "curly": true, + "debug": false, + "devel": true, + "eqeqeq": true, + "evil": true, + "forin": false, + "immed": false, + "laxbreak": false, + "newcap": true, + "noarg": true, + "noempty": false, + "nonew": false, + "nomen": false, + "onevar": false, + "plusplus": false, + "regexp": false, + "undef": true, + "sub": true, + "strict": false, + "white": false, + "eqnull": true, + "esnext": true, + "unused": true } diff --git a/app/app/components/document/edit-tools.js b/app/app/components/document/edit-tools.js index 6563e794..e9b785a2 100644 --- a/app/app/components/document/edit-tools.js +++ b/app/app/components/document/edit-tools.js @@ -32,21 +32,20 @@ export default Ember.Component.extend(TooltipMixin, { { label: 'Search', selected: false } ], - showSections: Ember.computed('tabs.@each.selected', function() { + showSections: Ember.computed('tabs.@each.selected', function () { return this.get('tabs').findBy('label', 'Section').selected; }), - showAttachments: Ember.computed('tabs.@each.selected', function() { + showAttachments: Ember.computed('tabs.@each.selected', function () { return this.get('tabs').findBy('label', 'Attachment').selected; }), - showSearch: Ember.computed('tabs.@each.selected', function() { + showSearch: Ember.computed('tabs.@each.selected', function () { return this.get('tabs').findBy('label', 'Search').selected; }), - hasMatches: Ember.computed('matches', function() { + hasMatches: Ember.computed('matches', function () { let m = this.get('matches'); return m.documents.length || m.pages.length || m.attachments.length; }), - init() { this._super(...arguments); let self = this; @@ -64,6 +63,7 @@ export default Ember.Component.extend(TooltipMixin, { didRender() { this.addTooltip(document.getElementById("content-linker-button")); + this.addTooltip(document.getElementById("content-counter-button")); }, willDestroyElement() { diff --git a/app/app/components/section/markdown/type-editor.js b/app/app/components/section/markdown/type-editor.js index f2f4ce7d..d04af87e 100644 --- a/app/app/components/section/markdown/type-editor.js +++ b/app/app/components/section/markdown/type-editor.js @@ -1,17 +1,24 @@ // Copyright 2016 Documize Inc. . All rights reserved. // -// This software (Documize Community Edition) is licensed under +// This software (Documize Community Edition) is licensed under // GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html // // You can operate outside the AGPL restrictions by purchasing // Documize Enterprise Edition and obtaining a commercial license -// by contacting . +// by contacting . // // https://documize.com import Ember from 'ember'; +import miscUtil from '../../../utils/misc'; + +const { + inject: { service } +} = Ember; export default Ember.Component.extend({ + link: service(), + isDirty: false, pageBody: "", @@ -45,6 +52,13 @@ export default Ember.Component.extend({ }, actions: { + onInsertLink(link) { + let linkMarkdown = this.get('link').buildLink(link); + miscUtil.insertAtCursor($("#section-markdown-editor")[0], linkMarkdown); + + return true; + }, + isDirty() { return this.get('isDirty'); }, @@ -62,4 +76,4 @@ export default Ember.Component.extend({ this.attrs.onAction(page, meta); } } -}); \ No newline at end of file +}); diff --git a/app/app/components/section/wysiwyg/type-editor.js b/app/app/components/section/wysiwyg/type-editor.js index c8219199..f63c9ecb 100644 --- a/app/app/components/section/wysiwyg/type-editor.js +++ b/app/app/components/section/wysiwyg/type-editor.js @@ -16,7 +16,7 @@ const { } = Ember; export default Ember.Component.extend({ - appMeta: Ember.inject.service(), + appMeta: service(), link: service(), pageBody: "", diff --git a/app/app/pods/document/route.js b/app/app/pods/document/route.js index 0d8ef34f..52d03ef4 100644 --- a/app/app/pods/document/route.js +++ b/app/app/pods/document/route.js @@ -1,11 +1,11 @@ // Copyright 2016 Documize Inc. . All rights reserved. // -// This software (Documize Community Edition) is licensed under +// This software (Documize Community Edition) is licensed under // GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html // // You can operate outside the AGPL restrictions by purchasing // Documize Enterprise Edition and obtaining a commercial license -// by contacting . +// by contacting . // // https://documize.com @@ -19,4 +19,13 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, { this.audit.record("viewed-document"); return this.get('documentService').getDocument(params.document_id); }, -}); \ No newline at end of file + + actions: { + error(error /*, transition*/ ) { + if (error) { + this.transitionTo('/not-found'); + return false; + } + } + } +}); diff --git a/app/app/pods/not-found/route.js b/app/app/pods/not-found/route.js index 3921fa3d..1833928e 100644 --- a/app/app/pods/not-found/route.js +++ b/app/app/pods/not-found/route.js @@ -1,11 +1,11 @@ // Copyright 2016 Documize Inc. . All rights reserved. // -// This software (Documize Community Edition) is licensed under +// This software (Documize Community Edition) is licensed under // GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html // // You can operate outside the AGPL restrictions by purchasing // Documize Enterprise Edition and obtaining a commercial license -// by contacting . +// by contacting . // // https://documize.com @@ -13,8 +13,7 @@ import Ember from 'ember'; import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin'; export default Ember.Route.extend(AuthenticatedRouteMixin, { - - beforeModel: function () { + beforeModel() { this.transitionTo('folders'); } -}); \ No newline at end of file +}); diff --git a/app/app/router.js b/app/app/router.js index b7a2b2c6..0fb3b03c 100644 --- a/app/app/router.js +++ b/app/app/router.js @@ -101,5 +101,5 @@ export default Router.map(function () { path: '/*wildcard' }); - this.route('pods', function () {}); + // this.route('pods', function () {}); }); diff --git a/app/app/services/link.js b/app/app/services/link.js index 030d58b3..e12496c7 100644 --- a/app/app/services/link.js +++ b/app/app/services/link.js @@ -107,7 +107,7 @@ export default Ember.Service.extend({ // handle section link if (link.linkType === "section") { let options = {}; - options['page'] = link.targetId; + options['page'] = link.targetId; router.transitionTo('document', link.folderId, folderSlug, link.documentId, documentSlug, { queryParams: options }); return; } @@ -127,12 +127,5 @@ export default Ember.Service.extend({ }); /* - when attachment deleted: - mark as orphan references where link.documentid = document.refId - - permission checks: - can view space - can view document - - Markdown editor support + doc meta to show inbound and outbound links. */ diff --git a/app/app/styles/view/document/edit-tools.scss b/app/app/styles/view/document/edit-tools.scss index 466d2e80..708a6c14 100644 --- a/app/app/styles/view/document/edit-tools.scss +++ b/app/app/styles/view/document/edit-tools.scss @@ -1,6 +1,21 @@ .edit-tools { margin: 0 0 0 20px; min-height: 600px; + + > .toolbar { + margin: 0; + padding: 0; + + > .item { + list-style-type: none; + margin: 0 0 20px; + } + } +} + +.content-counter-dialog { + width: 200px; + height: 200px; } .content-linker-dialog { diff --git a/app/app/templates/components/document/edit-tools.hbs b/app/app/templates/components/document/edit-tools.hbs index 2237ed8e..b6dcbf0a 100644 --- a/app/app/templates/components/document/edit-tools.hbs +++ b/app/app/templates/components/document/edit-tools.hbs @@ -1,8 +1,12 @@
-
- link -
+
    +
  • +
    + link +
    +
  • +
{{#dropdown-dialog target="content-linker-button" position="bottom right" button="Insert" color="flat-blue" onAction=(action 'onInsertLink')}}
diff --git a/app/app/templates/components/section/markdown/type-editor.hbs b/app/app/templates/components/section/markdown/type-editor.hbs index 3c53b789..78ade45c 100644 --- a/app/app/templates/components/section/markdown/type-editor.hbs +++ b/app/app/templates/components/section/markdown/type-editor.hbs @@ -1,13 +1,16 @@ {{#section/base-editor document=document folder=folder page=page isDirty=(action 'isDirty') onCancel=(action 'onCancel') onAction=(action 'onAction')}}
-
+
{{focus-textarea id="section-markdown-editor" class="mousetrap bordered" value=pageBody}}
-
+
+
+ {{document/edit-tools document=document folder=folder page=page onInsertLink=(action 'onInsertLink')}} +
{{/section/base-editor}} diff --git a/app/app/templates/components/section/wysiwyg/type-editor.hbs b/app/app/templates/components/section/wysiwyg/type-editor.hbs index 0e84aabf..f87fa594 100644 --- a/app/app/templates/components/section/wysiwyg/type-editor.hbs +++ b/app/app/templates/components/section/wysiwyg/type-editor.hbs @@ -1,11 +1,13 @@ {{#section/base-editor document=document folder=folder page=page isDirty=(action 'isDirty') onCancel=(action 'onCancel') onAction=(action 'onAction')}} +
+
+
+ {{focus-textarea value=pageBody id="rich-text-editor" class="mousetrap"}} +
-
- {{focus-textarea value=pageBody id="rich-text-editor" class="mousetrap"}} +
+ {{document/edit-tools document=document folder=folder page=page onInsertLink=(action 'onInsertLink')}} +
+
- -
- {{document/edit-tools document=document folder=folder page=page onInsertLink=(action 'onInsertLink')}} -
- {{/section/base-editor}} diff --git a/app/app/utils/misc.js b/app/app/utils/misc.js index 3c1958e8..55201deb 100644 --- a/app/app/utils/misc.js +++ b/app/app/utils/misc.js @@ -1,31 +1,31 @@ // Copyright 2016 Documize Inc. . All rights reserved. // -// This software (Documize Community Edition) is licensed under +// This software (Documize Community Edition) is licensed under // GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html // // You can operate outside the AGPL restrictions by purchasing // Documize Enterprise Edition and obtaining a commercial license -// by contacting . +// by contacting . // // https://documize.com // from http://thecodeship.com/web-development/alternative-to-javascript-evil-setinterval/ function interval(func, wait, times) { - var interv = function(w, t) { - return function() { - if (typeof t === "undefined" || t-- > 0) { - setTimeout(interv, w); - try { - func.call(null); - } catch (e) { - t = 0; - throw e.toString(); - } - } - }; - }(wait, times); + var interv = function (w, t) { + return function () { + if (typeof t === "undefined" || t-- > 0) { + setTimeout(interv, w); + try { + func.call(null); + } catch (e) { + t = 0; + throw e.toString(); + } + } + }; + }(wait, times); - setTimeout(interv, wait); + setTimeout(interv, wait); } // Function wrapping code. @@ -35,12 +35,34 @@ function interval(func, wait, times) { // e.g. var fun1 = wrapFunction(sayStuff, this, ["Hello, world!"]); // http://stackoverflow.com/questions/899102/how-do-i-store-javascript-functions-in-a-queue-for-them-to-be-executed-eventuall function wrapFunction(fn, context, params) { - return function() { - fn.apply(context, params); - }; + return function () { + fn.apply(context, params); + }; +} + +function insertAtCursor(myField, myValue) { + //IE support + if (document.selection) { + myField.focus(); + let sel = document.selection.createRange(); + sel.text = myValue; + } + //MOZILLA and others + else if (myField.selectionStart || myField.selectionStart === '0') { + var startPos = myField.selectionStart; + var endPos = myField.selectionEnd; + myField.value = myField.value.substring(0, startPos) + + myValue + + myField.value.substring(endPos, myField.value.length); + myField.selectionStart = startPos + myValue.length; + myField.selectionEnd = startPos + myValue.length; + } else { + myField.value += myValue; + } } export default { - interval, - wrapFunction -}; \ No newline at end of file + interval, + wrapFunction, + insertAtCursor +}; diff --git a/app/ember-cli-build.js b/app/ember-cli-build.js index 66bc23bd..fdb9e8bb 100644 --- a/app/ember-cli-build.js +++ b/app/ember-cli-build.js @@ -13,50 +13,50 @@ var EmberApp = require('ember-cli/lib/broccoli/ember-app'); var isDevelopment = EmberApp.env() === 'development'; -module.exports = function(defaults) { - var app = new EmberApp(defaults, { - fingerprint: { - enabled: true, - extensions: ['js', 'css'], - exclude: ['tinymce/**', 'codemirror/**'] - }, +module.exports = function (defaults) { + var app = new EmberApp(defaults, { + fingerprint: { + enabled: true, + extensions: ['js', 'css'], + exclude: ['tinymce/**', 'codemirror/**'] + }, - minifyJS: { - enabled: !isDevelopment, - options: { - exclude: ['tinymce/**', 'codemirror/**'] - } - }, + minifyJS: { + enabled: !isDevelopment, + options: { + exclude: ['tinymce/**', 'codemirror/**'] + } + }, - minifyCSS: { - enabled: !isDevelopment, - options: { - exclude: ['tinymce/**', 'codemirror/**'] - } - }, + minifyCSS: { + enabled: !isDevelopment, + options: { + exclude: ['tinymce/**', 'codemirror/**'] + } + }, - sourcemaps: { - enabled: isDevelopment, - extensions: ['js'] - } - }); + sourcemaps: { + enabled: isDevelopment, + extensions: ['js'] + } + }); - app.import('vendor/dropzone.js'); - app.import('vendor/is.js'); - app.import('vendor/md5.js'); - app.import('vendor/moment.js'); - app.import('vendor/mousetrap.js'); - app.import('vendor/table-editor.min.js'); - app.import('vendor/underscore.js'); - app.import('vendor/bootstrap.css'); - app.import('vendor/tether.js'); - app.import('vendor/drop.js'); - app.import('vendor/tooltip.js'); - app.import('vendor/markdown-it.min.js'); - app.import('vendor/dragula.js'); + app.import('vendor/dropzone.js'); + app.import('vendor/is.js'); + app.import('vendor/md5.js'); + app.import('vendor/moment.js'); + app.import('vendor/mousetrap.js'); + app.import('vendor/table-editor.min.js'); + app.import('vendor/underscore.js'); + app.import('vendor/bootstrap.css'); + app.import('vendor/tether.js'); + app.import('vendor/drop.js'); + app.import('vendor/tooltip.js'); + app.import('vendor/markdown-it.min.js'); + app.import('vendor/dragula.js'); app.import('vendor/datetimepicker.min.js'); app.import('vendor/hoverIntent.js'); app.import('vendor/waypoints.js'); - return app.toTree(); + return app.toTree(); };