Skip to content

Commit

Permalink
Merge branch 'export-text-service'
Browse files Browse the repository at this point in the history
  • Loading branch information
jessy1092 committed Mar 2, 2016
2 parents 6c6b1c2 + 2b1a974 commit 54e2c9f
Show file tree
Hide file tree
Showing 18 changed files with 396 additions and 73 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
node_modules/
coverage/

*.log
40 changes: 7 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,43 +39,17 @@ npm install nime
`ime.json` is to configure IME.

The usage will look like following. If you have any suggestion, welcome feedback.
```js
'use strict';
There are two way to implement IME.
- [Event-based](/example/event-based/README.md): It uses the `EventEmitter` to listening key event.
- [Class-based](/example/class-based/README.md): It should inheritance `TextService` to customize and let server to use it.

let NIME = require('nime');

let server = NIME.createServer();
## Example

// Listening new connection
server.on('connection', (service) => {
It already implements meow IME for example in two way.

// Listening key event, You can see ../src/textServer.js to see key event
service.on('filterKeyDown', (msg, keyHandler) => {

console.log('Custom Listener Message: ', msg);
console.log('Key Code: ', keyHandler.keyCode);

// You can custom your response
let response = {
'success': true,
'seqNum': msg['seqNum']
};

// Reply to IME client
service.write(response);
});

// You can also listen end event that would emit after key event finish
service.on('end', (msg) => {
console.log('Event finish');
});

});

// Start server listening
server.listen();
```
- Event-based: `npm run ex-event`
- Class-based: `npm run ex-class`


## Reference
Expand Down
18 changes: 0 additions & 18 deletions example/README.md

This file was deleted.

71 changes: 71 additions & 0 deletions example/class-based/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
喵喵輸入法
=============
This is reimplement of [PIME's 喵喵輸入法](https://github.com/EasyIME/PIME/tree/master/server/input_methods/meow) by using NIME.

The `chi.ico`, `icon.ico` and `ime.json` are copied from [PIME's 喵喵輸入法](https://github.com/EasyIME/PIME/tree/master/server/input_methods/meow). These are under LGPL 2.0 License.

NIME is under MIT License.


## Requirement

- [nodejs 4.x 32bit](https://nodejs.org/en/)
- Install [node-gyp](https://github.com/nodejs/node-gyp) dependecise for c binding through [node-ffi](https://github.com/node-ffi/node-ffi). Please see [node-gyp document](https://github.com/nodejs/node-gyp#installation) to setup your environment.


## Run

- `node index.js`


## Implement

It is the class-based implement. It should inheritance `TextService` to customize and let server to use it.

```js
'use strict';

let NIME = require('../../index');
let TextService = require('../../index').TextService;

let server = NIME.createServer();

class YourTextService extends TextService {

constructor() {
super();
}

// Handle filterKeyDown key event, You can see ../src/textServer.js to see key event type
filterKeyDown(msg, keyHandler) {

console.log('Custom Key Event handler Message: ', msg);
console.log('Key Code: ', keyHandler.keyCode);

// You can custom your response
let response = {
'success': true,
'seqNum': msg['seqNum']
};

// Reply to IME client
return response;
}
}

// Register the Text Service
server.use(new YourTextService());

// Listening new connection
server.on('connection', (service) => {

// You can also listen end event that would emit after key event finish
service.on('end', (msg, response) => {
console.log('Event finish ' + JSON.stringify(response));
});

});

// Start server listening
server.listen();
```
File renamed without changes.
File renamed without changes.
File renamed without changes.
150 changes: 150 additions & 0 deletions example/class-based/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
'use strict';

let NIME = require('../../index');
let TextService = require('../../index').TextService;
let KEYCODE = require('../../lib/keyCodes');

let server = NIME.createServer();

class MeowTextService extends TextService {

constructor() {
super();
this.candidateList = ['喵', '描', '秒', '妙'];
this.showCandidates = false;
this.compositionString = '';
this.compositionCursor = 0;
}

// Handle filterKeyDown key event, You can see ../src/textServer.js to see key event type
filterKeyDown(msg, keyHandler) {

console.log('Custom filter Key Down Message:', JSON.stringify(msg));

let keyCode = keyHandler.keyCode;
let seqNum = msg['seqNum'];

// You can custom your response
let response = {
'return': true // It means need to process this key event, it would trigger onKeyDown.
};

// Handle delete event, just pass to normal handle
if (this.compositionString === '' && (
keyCode === KEYCODE.VK_RETURN || keyCode === KEYCODE.VK_BACK ||
keyCode === KEYCODE.VK_LEFT || keyCode === KEYCODE.VK_UP ||
keyCode === KEYCODE.VK_DOWN || keyCode === KEYCODE.VK_RIGHT)) {
response['return'] = false;
}
return response;
}

onKeyDown(msg, keyHandler) {

console.log('Custom on Key Down Message: ', JSON.stringify(msg));

let keyCode = keyHandler.keyCode;
let seqNum = msg['seqNum'];

// You can custom your response
let response = {
'return': true
};

// Select the candidate
if (this.showCandidates) {

if (keyCode === KEYCODE.VK_UP || keyCode === KEYCODE.VK_ESCAPE) {
response['showCandidates'] = false;
this.showCandidates = false;

} else if (keyCode >= '1'.charCodeAt(0) && keyCode <= '4'.charCodeAt(0)) {
let selectCandidate = this.candidateList[keyCode - '1'.charCodeAt(0)];
let cursor = this.compositionCursor - 1;

if (cursor < 0) {
cursor = 0;
}

this.compositionString = this.compositionString.substring(0, cursor) + selectCandidate + this.compositionString.substring(cursor + 1);

response['compositionString'] = this.compositionString;
response['showCandidates'] = false;
this.showCandidates = false;
}

} else {
switch (keyCode) {

case KEYCODE.VK_DOWN: // Show Candidate List
this.showCandidates = true;
response['showCandidates'] = this.showCandidates;
response['candidateList'] = this.candidateList;
break;

case KEYCODE.VK_RETURN: // Comfirm String
response['commitString'] = this.compositionString;
response['compositionString'] = '';

// Set compositionSting default;
this.compositionString = '';
this.compositionCursor = 0;
break;

case KEYCODE.VK_BACK: // Delete compositionString
if (this.compositionString !== '') {
let cursor = this.compositionCursor;
this.compositionCursor -= 1;
this.compositionString = this.compositionString.substring(0, this.compositionCursor) + this.compositionString.substring(cursor);
response['compositionString'] = this.compositionString;
response['compositionCursor'] = this.compositionCursor;
}
break;

case KEYCODE.VK_LEFT: // Move cursor left
if (this.compositionCursor > 0) {
this.compositionCursor -= 1;
response['compositionCursor'] = this.compositionCursor;
}
break;

case KEYCODE.VK_RIGHT: // Move cursor right
if (this.compositionCursor < this.compositionString.length) {
this.compositionCursor += 1;
response['compositionCursor'] = this.compositionCursor;
}
break;

default:
this.compositionString = this.compositionString.substring(0, this.compositionCursor) + '喵' + this.compositionString.substring(this.compositionCursor);
this.compositionCursor += 1;

response['compositionString'] = this.compositionString;
response['compositionCursor'] = this.compositionCursor;
break;
}
}
return response;
}

onCompositionTerminated() {
// Clear composition data
this.compositionString = '';
this.compositionCursor = 0;
}
}

server.use(new MeowTextService());

// Listening new connection
server.on('connection', (service) => {

// You can also listen end event that would emit after key event finish
service.on('end', (msg, response) => {
console.log('Event finish ' + JSON.stringify(response));
});

});

// Start server listening
server.listen();
60 changes: 60 additions & 0 deletions example/event-based/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
喵喵輸入法
=============
This is reimplement of [PIME's 喵喵輸入法](https://github.com/EasyIME/PIME/tree/master/server/input_methods/meow) by using NIME.

The `chi.ico`, `icon.ico` and `ime.json` are copied from [PIME's 喵喵輸入法](https://github.com/EasyIME/PIME/tree/master/server/input_methods/meow). These are under LGPL 2.0 License.

NIME is under MIT License.


## Requirement

- [nodejs 4.x 32bit](https://nodejs.org/en/)
- Install [node-gyp](https://github.com/nodejs/node-gyp) dependecise for c binding through [node-ffi](https://github.com/node-ffi/node-ffi). Please see [node-gyp document](https://github.com/nodejs/node-gyp#installation) to setup your environment.


## Run

- `node index.js`


## Implement

It is the event-based implement. It uses the `EventEmitter` to listening key event.

```js
'use strict';

let NIME = require('nime');

let server = NIME.createServer();

// Listening new connection
server.on('connection', (service) => {

// Listening key event, You can see ../src/textServer.js to see key event
service.on('filterKeyDown', (msg, keyHandler) => {

console.log('Custom Listener Message: ', msg);
console.log('Key Code: ', keyHandler.keyCode);

// You can custom your response
let response = {
'success': true,
'seqNum': msg['seqNum']
};

// Reply to IME client
service.write(response);
});

// You can also listen end event that would emit after key event finish
service.on('end', (msg) => {
console.log('Event finish');
});

});

// Start server listening
server.listen();
```
Binary file added example/event-based/chi.ico
Binary file not shown.
Binary file added example/event-based/icon.ico
Binary file not shown.
10 changes: 10 additions & 0 deletions example/event-based/ime.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name":"喵喵輸入法",
"version": "0.1",
"guid": "{C5F37DA0-274E-4837-9B7C-9BB79FE85D9D}",
"locale": "zh-TW",
"icon": "icon.ico",
"win8_icon": "",
"moduleName": "ime_meow",
"serviceName": "MeowTextService"
}
4 changes: 2 additions & 2 deletions example/index.js → example/event-based/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';

let NIME = require('../index');
let KEYCODE = require('../lib/keyCodes');
let NIME = require('../../index');
let KEYCODE = require('../../lib/keyCodes');

let server = NIME.createServer();

Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
"description": "Implement input methods easily for Windows with nodejs",
"main": "index.js",
"scripts": {
"start": "cd example && cross-env NODE_ENV=development node index.js",
"start": "npm run ex-event",
"ex-event": "cd example/event-based && cross-env NODE_ENV=development node index.js",
"ex-class": "cd example/class-based && cross-env NODE_ENV=development node index.js",
"test": "istanbul cover node_modules/mocha/bin/_mocha -- tests --require tests/helpers/chai.js --reporter spec",
"coveralls": "npm test && cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage"
},
Expand Down
Loading

0 comments on commit 54e2c9f

Please sign in to comment.