Skip to content

Commit

Permalink
initial blueprint for the editor-plugin generator
Browse files Browse the repository at this point in the history
  • Loading branch information
nvdk committed Apr 23, 2018
1 parent 6a7173b commit 8fa0c84
Show file tree
Hide file tree
Showing 11 changed files with 270 additions and 11 deletions.
2 changes: 1 addition & 1 deletion .npmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
package-lock=false
package-lock=false
27 changes: 19 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
ember-rdfa-editor-plugin-generator
==============================================================================

[Short description of the addon.]

Installation
Addon to simplify the creation of a plugin for [https://github.com/lblod/ember-rdfa-editor](ember-rdfa-editor).

This package assumes you follow these conventions:
- package name: ember-rdfa-editor-*your-name*-plugin
- package scope: @lblod (to be added to your package name in `package.json` and `index.js`)
- no default blueprint has been defined (yet) in your plugin

Usage:
------------------------------------------------------------------------------

```
ember install ember-rdfa-editor-plugin-generator
#create an addon
ember addon ember-rdfa-editor-your-name-plugin
ember install @lblod/ember-rdfa-editor-plugin-generator
ember g editor-plugin your-name
```

The following generated files should be modified to your liking:

Usage
------------------------------------------------------------------------------
`blueprints/@lblod/ember-rdfa-editor-your-name-plugin/index.js`
This is a default blueprint which will add your plugin to the configured profile when it's installed

[Longer description of how to use the addon in apps.]
`addon/services/rdfa-editor-my-test-plugin.js`
The service providing hints to the editor, the execute task will be called when the content of the editor is updated.

`addon/components/editor-plugins/my-test-card.js` and `addon/templates/components/editor-plugins/my-test-card.hbs`
These components handle the display of hints and perform the necessary actions when they are triggered (eg applying the hint in the editor)

Contributing
------------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { reads } from '@ember/object/computed';
import Component from '@ember/component';
import layout from '../../templates/components/editor-plugins/<%= dasherizedModuleName %>-card';

/**
* Card displaying a hint of the Date plugin
*
* @module editor-<%= dasherizedModuleName %>-plugin
* @class <%= classifiedModuleName %>Card
* @extends Ember.Component
*/
export default Component.extend({
layout,

/**
* Region on which the card applies
* @property location
* @type [number,number]
* @private
*/
location: reads('info.location'),

/**
* Unique identifier of the event in the hints registry
* @property hrId
* @type Object
* @private
*/
hrId: reads('info.hrId'),

/**
* The RDFa editor instance
* @property editor
* @type RdfaEditor
* @private
*/
editor: reads('info.editor'),

/**
* Hints registry storing the cards
* @property hintsRegistry
* @type HintsRegistry
* @private
*/
hintsRegistry: reads('info.hintsRegistry'),

actions: {
insert(){
let mappedLocation = this.get('hintsRegistry').updateLocationToCurrentIndex(this.get('hrId'), this.get('location'));
this.get('hintsRegistry').removeHintsAtLocation(this.get('location'), this.get('hrId'), 'editor-plugins/date-card');
this.get('editor').replaceTextWithHTML(...mappedLocation, this.get('info').value);
}
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import { getOwner } from '@ember/application';
import Service from '@ember/service';
import EmberObject, { computed } from '@ember/object';
import moment from 'moment';
import { task } from 'ember-concurrency';

/**
* Service responsible for correct annotation of dates
*
* @module editor-<%= dasherizedModuleName %>-plugin
* @class RdfaEditor<%= classifiedModuleName %>Plugin
* @constructor
* @extends EmberService
*/
const RdfaEditor<%= classifiedModuleName %>Plugin = Service.extend({

init(){
this._super(...arguments);
const config = getOwner(this).resolveRegistration('config:environment');
},

/**
* Restartable task to handle the incoming events from the editor dispatcher
*
* @method execute
*
* @param {string} hrId Unique identifier of the event in the hintsRegistry
* @param {Array} contexts RDFa contexts of the text snippets the event applies on
* @param {Object} hintsRegistry Registry of hints in the editor
* @param {Object} editor The RDFa editor instance
*
* @public
*/
execute: task(function * (hrId, contexts, hintsRegistry, editor) {
if (contexts.length === 0) return [];

const hints = contexts.filter((context) => detectRelevantContext).forEach((context) => {
return generateHintsForContext(context);
});


return hints.forEach( (hint) => generateCard(hint));
}).restartable(),

/**
* Given context object, tries to detect a context the plugin can work on
*
* @method detectRelevantContext
*
* @param {Object} context Text snippet at a specific location with an RDFa context
*
* @return {String} URI of context if found, else empty string.
*
* @private
*/
detectRelevantContext(context){
return true;
},



/**
* Maps location of substring back within reference location
*
* @method normalizeLocation
*
* @param {[int,int]} [start, end] Location withing string
* @param {[int,int]} [start, end] reference location
*
* @return {[int,int]} [start, end] absolute location
*
* @private
*/
normalizeLocation(location, reference){
return [location[0] + reference[0], location[1] + reference[0]];
},

/**
* Generates a card given a hint
*
* @method generateCard
*
* @param {string} hrId Unique identifier of the event in the hintsRegistry
* @param {Object} rdfaAnnotation object
* @param {Object} hintsRegistry Registry of hints in the editor
* @param {Object} editor The RDFa editor instance
* @param {Object} hint containing the hinted string and the location of this string
*
* @return {Object} The card to hint for a given template
*
* @private
*/
generateCard(hrId, rdfaAnnotation, hintsRegistry, editor, hint){
return EmberObject.create({
info: {
label: this.get('who'),
plainValue: hint.text,
location: hint.location,
hrId, hintsRegistry, editor
},
location: hint.location,
card: this.get('who')
});
},

/**
* Generates a hint, given a context
*
* @method generateHintsForContext
*
* @param {Object} context Text snippet at a specific location with an RDFa context
*
* @return {Object} [{dateString, location}]
*
* @private
*/
generateHintsForContext(context){
const hints = [];
const text = context.text;
const location = this.normalizeLocation([0, stringToScan.length], context.region);
hints.push({text, location})
return hints;
}
});

RdfaEditor<%= classifiedModuleName %>Plugin.reopen({
who: 'editor-plugins/<%= dasherizedModuleName %>-card',

});
export default RdfaEditor<%= classifiedModuleName %>Plugin;
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<p class="u-spacer--tiny">{{info.label}} <br>
<strong>{{info.plainValue}}</strong>
</p>

{{#wu-button-group}}
{{wu-button label="Juist" size="small" isNarrow=true command="ctrl + j" commandLocation="below" onClick=(action "insert")}}
{{wu-button label="Negeer" size="tiny" isLink=true isDark=true isNarrow=true command="esc" commandLocation="below" onClick=null}}
{{/wu-button-group}}

{{yield}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '@lblod/ember-rdfa-editor-<%= dasherizedModuleName %>-plugin/components/editor-plugins/<%= dasherizedModuleName %>-card';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '@lblod/ember-rdfa-editor<%= dasherizedModuleName %>-plugin/services/rdfa-editor-<%= dasherizedModuleName %>-plugin';
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* eslint-env node */
const existsSync = require('exists-sync');

const profilesFile = 'app/config/editor-profiles.js';

module.exports = {
description: 'Adds the plugin to the default and all editor-profiles',

normalizeEntityName() { },

insertPluginNameAtKey( key, pluginName, afterContents="" ){
return this.insertIntoFile(
profilesFile,
` "${pluginName}",${afterContents}`,
{ after: ` ${key}: \\[\n` });
},

async afterInstall(options) {
const pluginName = options.originBlueprintName.substr('ember-'.length);

if( existsSync(profilesFile) ){
try {
await this.insertPluginNameAtKey("all", pluginName);
await this.insertPluginNameAtKey("default", pluginName, " "); /* the extra space here,
makes the line different
from the inserted line
above. This is makes
insertIntoFile consider
the lines to be different,
and hence insert the
contents. Sorry for the
somewhat uglier generated
files. */
} catch (err) {
throw 'Failed to insert all contents ' + err;
}
} else {
throw 'Could not insert into "all" profile';
}
return;
}
};
10 changes: 10 additions & 0 deletions blueprints/editor-plugin/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* eslint-env node */
module.exports = {
description: 'Generates the scaffold for a ember-rdfa-editor plugin',

afterInstall(options) {
// Perform extra work here.
this.addAddonToProject('ember-cli-release');
return this.addAddonToProject('ember-concurrency');
}
};
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use strict';

module.exports = {
name: 'ember-rdfa-editor-plugin-generator'
name: '@lblod/ember-rdfa-editor-plugin-generator'
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "ember-rdfa-editor-plugin-generator",
"name": "@lblod/ember-rdfa-editor-plugin-generator",
"version": "0.0.0",
"description": "The default blueprint for ember-cli addons.",
"keywords": [
Expand Down

0 comments on commit 8fa0c84

Please sign in to comment.