summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSoreine <nicolas@gitbook.com>2016-05-09 19:51:54 +0200
committerSoreine <nicolas@gitbook.com>2016-05-11 13:11:32 +0200
commit2fef898a1e13dc6b3f2627ed83af2865f51d2ffa (patch)
tree61d3b98e7f80a1883462eb8da4dbb694ac91fc31
parent0945807184907d4aac47d370d05b39d4029d07fa (diff)
downloadgitbook-2fef898a1e13dc6b3f2627ed83af2865f51d2ffa.zip
gitbook-2fef898a1e13dc6b3f2627ed83af2865f51d2ffa.tar.gz
gitbook-2fef898a1e13dc6b3f2627ed83af2865f51d2ffa.tar.bz2
Modifier moveArticleAfter
-rw-r--r--lib/modifiers/summary/__tests__/moveArticleAfter.js82
-rw-r--r--lib/modifiers/summary/index.js1
-rw-r--r--lib/modifiers/summary/moveArticleAfter.js58
3 files changed, 141 insertions, 0 deletions
diff --git a/lib/modifiers/summary/__tests__/moveArticleAfter.js b/lib/modifiers/summary/__tests__/moveArticleAfter.js
new file mode 100644
index 0000000..c380575
--- /dev/null
+++ b/lib/modifiers/summary/__tests__/moveArticleAfter.js
@@ -0,0 +1,82 @@
+var Immutable = require('immutable');
+var Summary = require('../../../models/summary');
+var File = require('../../../models/file');
+
+describe('moveArticleAfter', function() {
+ var moveArticleAfter = require('../moveArticleAfter');
+ var summary = Summary.createFromParts(File(), [
+ {
+ articles: [
+ {
+ title: '1.1',
+ path: '1.1'
+ },
+ {
+ title: '1.2',
+ path: '1.2'
+ }
+ ]
+ },
+ {
+ title: 'Part I',
+ articles: [
+ {
+ title: '2.1',
+ path: '2.1',
+ articles: [
+ {
+ title: '2.1.1',
+ path: '2.1.1'
+ },
+ {
+ title: '2.1.2',
+ path: '2.1.2'
+ }
+ ]
+ },
+ {
+ title: '2.2',
+ path: '2.2'
+ }
+ ]
+ }
+ ]);
+
+ it('moving right after itself should be invariant', function() {
+ var newSummary = moveArticleAfter(summary, '2.1', '2.1');
+
+ expect(Immutable.is(summary, newSummary)).toBe(true);
+ });
+
+ it('moving after previous one should be invariant too', function() {
+ var newSummary = moveArticleAfter(summary, '2.1', '2.0');
+
+ expect(Immutable.is(summary, newSummary)).toBe(true);
+ });
+
+ it('should move an article after a previous level', function() {
+ var newSummary = moveArticleAfter(summary, '2.2', '2.0');
+ var moved = newSummary.getByLevel('2.1');
+
+ expect(moved.getTitle()).toBe('2.2');
+ expect(newSummary.getByLevel('2.2').getTitle()).toBe('2.1');
+ });
+
+ it('should move an article after a previous and less deep level', function() {
+ var newSummary = moveArticleAfter(summary, '2.1.1', '2.0');
+ var moved = newSummary.getByLevel('2.1');
+
+ expect(moved.getTitle()).toBe('2.1.1');
+ expect(newSummary.getByLevel('2.2.1').getTitle()).toBe('2.1.2');
+ expect(newSummary.getByLevel('2.2').getTitle()).toBe('2.1');
+ });
+
+ it('should move an article after a next level', function() {
+ var newSummary = moveArticleAfter(summary, '2.1', '2.2');
+ var moved = newSummary.getByLevel('2.2');
+
+ expect(moved.getTitle()).toBe('2.1');
+ expect(newSummary.getByLevel('2.1').getTitle()).toBe('2.2');
+ });
+
+});
diff --git a/lib/modifiers/summary/index.js b/lib/modifiers/summary/index.js
index 2b84f66..3ee0367 100644
--- a/lib/modifiers/summary/index.js
+++ b/lib/modifiers/summary/index.js
@@ -1,6 +1,7 @@
module.exports = {
insertArticle: require('./insertArticle'),
moveArticle: require('./moveArticle'),
+ moveArticleAfter: require('./moveArticleAfter'),
removeArticle: require('./removeArticle'),
unshiftArticle: require('./unshiftArticle'),
editArticleTitle: require('./editArticleTitle'),
diff --git a/lib/modifiers/summary/moveArticleAfter.js b/lib/modifiers/summary/moveArticleAfter.js
new file mode 100644
index 0000000..e03eae9
--- /dev/null
+++ b/lib/modifiers/summary/moveArticleAfter.js
@@ -0,0 +1,58 @@
+var is = require('is');
+var removeArticle = require('./removeArticle');
+var insertArticle = require('./insertArticle');
+
+/**
+ Returns a new summary, with the an article moved after another article.
+
+ @param {Summary} summary
+ @param {String|SummaryArticle} origin
+ @param {String|SummaryArticle} afterTarget
+ @return {Summary}
+*/
+function moveArticleAfter(summary, origin, afterTarget) {
+ // Coerce to level
+ var originLevel = is.string(origin)? origin : origin.getLevel();
+ var afterTargetLevel = is.string(afterTarget)? afterTarget : afterTarget.getLevel();
+ var article = summary.getByLevel(originLevel);
+
+ var targetLevel = increment(afterTargetLevel);
+
+ if (targetLevel < origin) {
+ // Remove first
+ var removed = removeArticle(summary, originLevel);
+ // Insert then
+ return insertArticle(removed, article, targetLevel);
+ } else {
+ // Insert right after first
+ var inserted = insertArticle(summary, article, targetLevel);
+ // Remove old one
+ return removeArticle(inserted, originLevel);
+ }
+}
+
+/**
+ @param {String}
+ @return {Array<Number>}
+ */
+function levelToArray(l) {
+ return l.split('.').map(function (char) {
+ return parseInt(char, 10);
+ });
+}
+
+/**
+ @param {Array<Number>}
+ @return {String}
+ */
+function arrayToLevel(a) {
+ return a.join('.');
+}
+
+function increment(level) {
+ level = levelToArray(level);
+ level[level.length - 1]++;
+ return arrayToLevel(level);
+}
+
+module.exports = moveArticleAfter;