draftjs-utils
Advanced tools
Comparing version 0.2.1 to 0.2.2
import { assert } from 'chai'; | ||
import { forEach, merge, size } from '../common'; | ||
import { forEach, size } from '../common'; | ||
import { spy } from 'sinon'; | ||
@@ -24,48 +24,2 @@ | ||
describe('merge test suite', () => { | ||
it('should return undefined if both operands are undefined', () => { | ||
assert.isUndefined(merge()); | ||
}); | ||
it('should return all objects of first if second is undefined', () => { | ||
const obj = { | ||
a: 1, | ||
b: 2, | ||
c: 3, | ||
}; | ||
const result = merge(obj); | ||
assert.equal(size(result), 3); | ||
assert.isDefined(result.a); | ||
assert.isDefined(result.b); | ||
assert.isDefined(result.c); | ||
}); | ||
it('should return all objects of second if first is undefined', () => { | ||
const obj = { | ||
a: 1, | ||
b: 2, | ||
c: 3, | ||
}; | ||
const result = merge(undefined, obj); | ||
assert.equal(size(result), 3); | ||
assert.isDefined(result.a); | ||
assert.isDefined(result.b); | ||
assert.isDefined(result.c); | ||
}); | ||
it('should return all objects of both if both params are defined', () => { | ||
const obj1 = { | ||
a: 1, | ||
b: 2, | ||
}; | ||
const obj2 = { | ||
c: 3, | ||
d: 4, | ||
}; | ||
const result = merge(obj1, obj2); | ||
assert.equal(size(result), 4); | ||
assert.isDefined(result.a); | ||
assert.isDefined(result.b); | ||
assert.isDefined(result.c); | ||
assert.isDefined(result.d); | ||
}); | ||
}); | ||
describe('size test suite', () => { | ||
@@ -72,0 +26,0 @@ it('should return undefined if both operands are undefined', () => { |
@@ -9,10 +9,18 @@ import { | ||
import { | ||
colors, | ||
fontSizes, | ||
fontFamilies, | ||
customStyleMap, | ||
toggleInlineStyle, | ||
customInlineStylesMap, | ||
getSelectionInlineStyle, | ||
getSelectionCustomInlineStyle, | ||
getSelectionEntity, | ||
getEntityRange, | ||
} from '../inline'; | ||
import { forEach, size } from '../common'; | ||
import { assert } from 'chai'; | ||
describe('getSelectionInlineStyle test suite', () => { | ||
it('should correctly get color of selection', () => { | ||
it('should correctly get inline styles', () => { | ||
const contentBlocks = convertFromHTML('<h1>aaaaaaaaaa</h1><ul><li>test</li></ul>'); | ||
@@ -34,2 +42,12 @@ const contentState = ContentState.createFromBlockArray(contentBlocks); | ||
assert.equal(getSelectionInlineStyle(editorState).BOLD, true); | ||
editorState = RichUtils.toggleInlineStyle( | ||
editorState, | ||
'STRIKETHROUGH' | ||
); | ||
assert.equal(getSelectionInlineStyle(editorState).STRIKETHROUGH, true); | ||
editorState = RichUtils.toggleInlineStyle( | ||
editorState, | ||
'CODE' | ||
); | ||
assert.equal(getSelectionInlineStyle(editorState).CODE, true); | ||
}); | ||
@@ -81,1 +99,62 @@ }); | ||
}); | ||
describe('Inline: custom styles test suite', () => { | ||
it('should initializa colors', () => { | ||
assert.isTrue(colors instanceof Array); | ||
}); | ||
it('should initializa fontSizes', () => { | ||
assert.isTrue(fontSizes instanceof Array); | ||
}); | ||
it('should initializa fontFamilies', () => { | ||
assert.isTrue(fontFamilies instanceof Array); | ||
}); | ||
it('should initialize customInlineStylesMap with a map of inline styles', () => { | ||
assert.isTrue(customInlineStylesMap instanceof Object); | ||
forEach(customInlineStylesMap.color, (key, value) => { | ||
assert.isDefined(value.color); | ||
}); | ||
forEach(customInlineStylesMap.bgcolor, (key, value) => { | ||
assert.isDefined(value['background-color']); | ||
}); | ||
forEach(customInlineStylesMap.fontSize, (key, value) => { | ||
assert.isDefined(value.fontSize); | ||
}); | ||
forEach(customInlineStylesMap.fontFamilies, (key, value) => { | ||
assert.isDefined(value.fontFamily); | ||
}); | ||
}); | ||
it('should initializa customStyleMap with colors, bg-colors, fontsizes and fontFamilies', () => { | ||
assert.isTrue(customStyleMap instanceof Object); | ||
forEach(customStyleMap, (key, value) => { | ||
assert.isDefined(value.color || value['background-color'] | ||
|| value.fontSize || value.fontFamily); | ||
}); | ||
assert.equal(size(customStyleMap), size(colors) * 2 + size(fontSizes) + size(fontFamilies)); | ||
}); | ||
}); | ||
describe('getSelectionInlineStyle, toggleInlineStyle test suite', () => { | ||
it('should correctly get color of selection', () => { | ||
const contentBlocks = convertFromHTML('<h1>aaaaaaaaaa</h1><ul><li>test</li></ul>'); | ||
const contentState = ContentState.createFromBlockArray(contentBlocks); | ||
let editorState = EditorState.createWithContent(contentState); | ||
const updatedSelection = editorState.getSelection().merge({ | ||
anchorOffset: 0, | ||
focusOffset: 10, | ||
}); | ||
editorState = EditorState.acceptSelection( | ||
editorState, | ||
updatedSelection | ||
); | ||
editorState = toggleInlineStyle(editorState, 'color', 'color-rgb(97,189,109)'); | ||
assert.equal(getSelectionCustomInlineStyle( | ||
editorState, | ||
['COLOR']).COLOR, 'color-rgb(97,189,109)' | ||
); | ||
editorState = toggleInlineStyle(editorState, 'bgcolor', 'bgcolor-rgb(97,189,109)'); | ||
assert.equal(getSelectionCustomInlineStyle( | ||
editorState, | ||
['BGCOLOR']).BGCOLOR, 'bgcolor-rgb(97,189,109)' | ||
); | ||
}); | ||
}); |
@@ -19,22 +19,2 @@ /* @flow */ | ||
*/ | ||
export function merge(obj1: Object, obj2: Object): any { | ||
let obj3; | ||
forEach(obj1, (key, value) => { | ||
if (!obj3) { | ||
obj3 = {}; | ||
} | ||
obj3[key] = value; | ||
}); | ||
forEach(obj2, (key, value) => { | ||
if (!obj3) { | ||
obj3 = {}; | ||
} | ||
obj3[key] = value; | ||
}); | ||
return obj3; | ||
} | ||
/** | ||
* Utility function to merge 2 objects. | ||
*/ | ||
export function size(object: Object): any { | ||
@@ -41,0 +21,0 @@ if (object) { |
/* @flow */ | ||
import { | ||
colors, | ||
fontSizes, | ||
fontFamilies, | ||
customStyleMap, | ||
getEntityRange, | ||
toggleInlineStyle, | ||
getSelectionEntity, | ||
getSelectionInlineStyle, | ||
getSelectionEntity, | ||
getEntityRange, | ||
getSelectionCustomInlineStyle, | ||
} from './inline'; | ||
@@ -41,5 +47,11 @@ import { | ||
// Functions related to inline styles | ||
colors, | ||
fontSizes, | ||
fontFamilies, | ||
customStyleMap, | ||
getEntityRange, | ||
toggleInlineStyle, | ||
getSelectionEntity, | ||
getSelectionInlineStyle, | ||
getSelectionEntity, | ||
getEntityRange, | ||
getSelectionCustomInlineStyle, | ||
// KeyPress related Functions | ||
@@ -46,0 +58,0 @@ handleNewLine, |
173
js/inline.js
@@ -5,3 +5,6 @@ /* @flow */ | ||
Entity, | ||
Modifier, | ||
RichUtils, | ||
EditorState, | ||
ContentBlock, | ||
} from 'draft-js'; | ||
@@ -14,8 +17,3 @@ import { | ||
/** | ||
* Function returns an object of inline styles currently applicable: | ||
* { | ||
* BOLD: true, | ||
* ITALIC: true, | ||
* UNDERLINE: true, | ||
* } | ||
* Function returns an object of inline styles currently applicable. | ||
* Following rules are applicable: | ||
@@ -38,2 +36,4 @@ * - styles are all false if editor is not focused | ||
UNDERLINE: true, | ||
STRIKETHROUGH: true, | ||
CODE: true, | ||
}; | ||
@@ -52,7 +52,5 @@ for (let i = 0; i < selectedBlocks.size; i++) { | ||
const inlineStylesAtOffset = selectedBlocks.get(i).getInlineStyleAt(j); | ||
inlineStyles.BOLD = inlineStyles.BOLD && inlineStylesAtOffset.get('BOLD') === 'BOLD'; | ||
inlineStyles.ITALIC = | ||
inlineStyles.ITALIC && inlineStylesAtOffset.get('ITALIC') === 'ITALIC'; | ||
inlineStyles.UNDERLINE = | ||
inlineStyles.UNDERLINE && inlineStylesAtOffset.get('UNDERLINE') === 'UNDERLINE'; | ||
['BOLD', 'ITALIC', 'UNDERLINE', 'STRIKETHROUGH', 'CODE'].forEach(style => { | ||
inlineStyles[style] = inlineStyles[style] && inlineStylesAtOffset.get(style) === style; | ||
}); | ||
} | ||
@@ -62,7 +60,3 @@ } | ||
} | ||
return { | ||
BOLD: false, | ||
ITALIC: false, | ||
UNDERLINE: false, | ||
}; | ||
return {}; | ||
} | ||
@@ -127,1 +121,148 @@ | ||
} | ||
/** | ||
* Array of colors supported for custom inline styles. | ||
*/ | ||
export const colors = ['rgb(97,189,109)', 'rgb(26,188,156)', 'rgb(84,172,210)', 'rgb(44,130,201)', | ||
'rgb(147,101,184)', 'rgb(71,85,119)', 'rgb(204,204,204)', 'rgb(65,168,95)', 'rgb(0,168,133)', | ||
'rgb(61,142,185)', 'rgb(41,105,176)', 'rgb(85,57,130)', 'rgb(40,50,78)', 'rgb(0,0,0)', | ||
'rgb(247,218,100)', 'rgb(251,160,38)', 'rgb(235,107,86)', 'rgb(226,80,65)', 'rgb(163,143,132)', | ||
'rgb(239,239,239)', 'rgb(255,255,255)', 'rgb(250,197,28)', 'rgb(243,121,52)', 'rgb(209,72,65)', | ||
'rgb(184,49,47)', 'rgb(124,112,107)', 'rgb(209,213,216)']; | ||
/** | ||
* Array of font-sizes supported for custom inline styles. | ||
*/ | ||
export const fontSizes = [8, 9, 10, 11, 12, 14, 18, 24, 30, 36, 48, 60, 72, 96]; | ||
/** | ||
* Array of font-sizes supported for custom inline styles. | ||
*/ | ||
export const fontFamilies = ['Arial', 'Georgia', 'Impact', 'Tahoma', 'Times New Roman', 'Verdana']; | ||
/** | ||
* Collection of all custom inline styles. | ||
*/ | ||
export const customInlineStylesMap = { | ||
color: {}, | ||
bgcolor: {}, | ||
fontSize: {}, | ||
fontFamily: {}, | ||
}; | ||
colors.forEach((color) => { | ||
customInlineStylesMap.color[`color-${color}`] = { | ||
color, | ||
}; | ||
customInlineStylesMap.bgcolor[`bgcolor-${color}`] = { | ||
'background-color': color, | ||
}; | ||
}); | ||
fontSizes.forEach((size) => { | ||
customInlineStylesMap.fontSize[`fontsize-${size}`] = { | ||
fontSize: size, | ||
}; | ||
}); | ||
fontFamilies.forEach((family) => { | ||
customInlineStylesMap.fontFamily[`fontfamily-${family}`] = { | ||
fontFamily: family, | ||
}; | ||
}); | ||
/** | ||
* Combined map of all custon inline styles used to initialize editor. | ||
*/ | ||
export const customStyleMap = { | ||
...customInlineStylesMap.color, | ||
...customInlineStylesMap.bgcolor, | ||
...customInlineStylesMap.fontSize, | ||
...customInlineStylesMap.fontFamily, | ||
}; | ||
/** | ||
* Function to toggle a custom inline style in current selection current selection. | ||
*/ | ||
export function toggleInlineStyle( | ||
editorState: EditorState, | ||
styleType: string, | ||
style: string | ||
): EditorState { | ||
const selection = editorState.getSelection(); | ||
const nextContentState = Object.keys(customInlineStylesMap[styleType]) | ||
.reduce((contentState, s) => Modifier.removeInlineStyle(contentState, selection, s), | ||
editorState.getCurrentContent()); | ||
let nextEditorState = EditorState.push( | ||
editorState, | ||
nextContentState, | ||
'changeinline-style' | ||
); | ||
const currentStyle = editorState.getCurrentInlineStyle(); | ||
if (selection.isCollapsed()) { | ||
nextEditorState = currentStyle | ||
.reduce((state, s) => RichUtils.toggleInlineStyle(state, s), | ||
nextEditorState); | ||
} | ||
if (!currentStyle.has(style)) { | ||
nextEditorState = RichUtils.toggleInlineStyle( | ||
nextEditorState, | ||
style | ||
); | ||
} | ||
return nextEditorState; | ||
} | ||
/** | ||
* Function returns size at a offset. | ||
*/ | ||
function getStyleAtOffset(block: ContentBlock, stylePrefix: string, offset: number): any { | ||
const styles = block.getInlineStyleAt(offset).toList(); | ||
const style = styles.filter((s) => s.startsWith(stylePrefix.toLowerCase())); | ||
if (style && style.size > 0) { | ||
return style.get(0); | ||
} | ||
return undefined; | ||
} | ||
/** | ||
* Function returns an object of custom inline styles currently applicable. | ||
*/ | ||
export function getSelectionCustomInlineStyle( | ||
editorState: EditorState, | ||
styles: Array<string> | ||
): Object { | ||
if (editorState && styles && styles.length > 0) { | ||
const currentSelection = editorState.getSelection(); | ||
const start = currentSelection.getStartOffset(); | ||
const end = currentSelection.getEndOffset(); | ||
const selectedBlocks = getSelectedBlocksList(editorState); | ||
if (selectedBlocks.size > 0) { | ||
const inlineStyles = {}; | ||
for (let i = 0; i < selectedBlocks.size; i++) { | ||
let blockStart = i === 0 ? start : 0; | ||
let blockEnd = | ||
i === (selectedBlocks.size - 1) ? end : selectedBlocks.get(i).getText().length; | ||
if (blockStart === blockEnd && blockStart === 0) { | ||
blockStart = 1; | ||
blockEnd = 2; | ||
} else if (blockStart === blockEnd) { | ||
blockStart -= 1; | ||
} | ||
for (let j = blockStart; j < blockEnd; j++) { | ||
if (j === blockStart) { | ||
styles.forEach(s => { | ||
inlineStyles[s] = getStyleAtOffset(selectedBlocks.get(i), s, j); | ||
}); | ||
} else { | ||
styles.forEach(s => { | ||
if (inlineStyles[s] && | ||
inlineStyles[s] !== getStyleAtOffset(selectedBlocks.get(i), s, j)) { | ||
inlineStyles[s] = undefined; | ||
} | ||
}); | ||
} | ||
} | ||
} | ||
return inlineStyles; | ||
} | ||
} | ||
return {}; | ||
} |
{ | ||
"name": "draftjs-utils", | ||
"version": "0.2.1", | ||
"version": "0.2.2", | ||
"description": "Collection of utility function for use with Draftjs.", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
3464713
2517
0