Skip to content

Commit

Permalink
Merge pull request danielearwicker#40 from creately/implement-hyperlinks
Browse files Browse the repository at this point in the history
Added link property to text content  and added some methods to select…
  • Loading branch information
thani-sh authored Aug 21, 2019
2 parents 51ea249 + 0607104 commit 2d6592f
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 33 deletions.
140 changes: 108 additions & 32 deletions src/doc.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,49 +127,84 @@ var prototype = node.derive({
if ( !word.text.parts || !word.text.parts.length || !word.text.parts[0] ) {
continue;
}
var text = word.text.parts[0];
if ( text.run.underline === true ) {
underLines.push({
baseline: line.baseline,
width: word.width, // text width + space width,
left,
color: text.run.color || this.defaultFormatting.color,
})
}

if ( text.run.strikeout === true ) {
strikLines.push({
ascent: word.ascent,
for (let k = 0; k < word.text.parts.length; k++) {
var text = word.text.parts[k];
if ( text.run.underline === true ) {
underLines.push({
baseline: line.baseline,
width: word.width, // text width + space width,
left,
color: text.run.color || this.defaultFormatting.color,
})
}

if ( text.run.strikeout === true ) {
strikLines.push({
ascent: word.ascent,
baseline: line.baseline,
width: word.width, // text width + space width,
left,
color: text.run.color || this.defaultFormatting.color,
})
}

words.push({
baseline: line.baseline,
width: word.width, // text width + space width,
left,
color: text.run.color || this.defaultFormatting.color,
content: {
text: he.encode( text.run.text.trim()) + '&#160;'.repeat( word.space.length ),
size: text.run.size || this.defaultFormatting.size,
font: text.run.font || this.defaultFormatting.font,
color: text.run.color || this.defaultFormatting.color,
bold: text.run.bold || this.defaultFormatting.bold,
italic: text.run.italic || this.defaultFormatting.italic,
underline: text.run.underline || this.defaultFormatting.underline,
strikeout: text.run.strikeout || this.defaultFormatting.strikeout,
align: text.run.align || this.defaultFormatting.align,
script: text.run.script || this.defaultFormatting.script,
}
})
left = left + text.width;
}

words.push({
baseline: line.baseline,
left,
content: {
text: he.encode( text.run.text.trim()) + '&#160;'.repeat( word.space.length ),
size: text.run.size || this.defaultFormatting.size,
font: text.run.font || this.defaultFormatting.font,
color: text.run.color || this.defaultFormatting.color,
bold: text.run.bold || this.defaultFormatting.bold,
italic: text.run.italic || this.defaultFormatting.italic,
underline: text.run.underline || this.defaultFormatting.underline,
strikeout: text.run.strikeout || this.defaultFormatting.strikeout,
align: text.run.align || this.defaultFormatting.align,
script: text.run.script || this.defaultFormatting.script,
}
})
}
}

}
return { words, underLines, strikLines };
},

getLinksData: function() {
var links = [];
for (let i = 0; i < this.frame.lines.length; i++) {
var line = this.frame.lines[i];
if ( line.positionedWords ) {
for (let j = 0; j < line.positionedWords.length; j++) {
var left = line.positionedWords[j].left;
var word = line.positionedWords[j].word;

if ( !word.text.parts || !word.text.parts.length || !word.text.parts[0] ) {
continue;
}
var text = word.text.parts[0];
for (let k = 0; k < word.text.parts.length; k++) {
var text = word.text.parts[k];
if ( text.run.link ) {
links.push({
value: text.run.link,
text: text.run.text,
x: left,
y: line.baseline - text.ascent,
width: text.width,
height: text.ascent + text.descent,
});
}
left = left + text.width;
}
}
}
}
return links;
},
isMultiLine: function() {
return this.frame.lines.length > 1;
},
Expand Down Expand Up @@ -552,6 +587,47 @@ var prototype = node.derive({
selectAll: function(){
this.select( 0, this.frame.length - 1, true );
},

/**
* Returns a range, to left and right, relative to the current caret position,
* where each value of specified properties are uniform.
* @param styles string array that specifies the properties to check
*/
selectByProperties: function( styles ){
const currentCaret = this.selection.start;
const currentFormat = this.selectedRange().getFormatting();
const middleFormat = {};
styles.map( key => {
middleFormat[ key ] = currentFormat[ key ];
});

let left = 0;
if ( currentCaret > 0 ) {
let leftFormat;
while ( currentCaret - left >= 0 ) {
left++;
leftFormat = this.range( currentCaret - left, currentCaret ).getFormatting();
if ( !Object.keys( middleFormat ).every( key => middleFormat[ key ] === leftFormat[ key ])) {
left--;
break;
}
}
}

let right = 0;
if ( currentCaret < this.frame.length - 1 ) {
let rightFormat;
while ( currentCaret + right <= this.frame.length ) {
right++;
rightFormat = this.range( currentCaret, currentCaret + right ).getFormatting();
if ( !Object.keys( middleFormat ).every( key => middleFormat[ key ] === rightFormat[ key ])) {
right--;
break;
}
}
}
return this.range( currentCaret - left, currentCaret + right );
},
moveCaretToPoint: function( point ){
var node = this.byCoordinate( point.x, point.y );
this.select( node.ordinal, node.ordinal, true );
Expand Down
2 changes: 1 addition & 1 deletion src/runs.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
exports.formattingKeys = [ 'bold', 'italic', 'underline', 'strikeout', 'color', 'font', 'size', 'align', 'script' ];
exports.formattingKeys = [ 'bold', 'italic', 'underline', 'strikeout', 'color', 'font', 'size', 'align', 'script', 'link' ];

exports.sameFormatting = function(run1, run2) {
return exports.formattingKeys.every(function(key) {
Expand Down
62 changes: 62 additions & 0 deletions test/doc.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,67 @@ test('select function should take end of text if second param is `end` ', () =>

});

test('getLinksData function should extract links data', () => {
// NOTE x, y, width, height are zero as tests are run on jsdom
// only checking the elements
document.load([
{ color: 'blue', font: 'sans-serif', size: 13, text: 'hi' },
{ color: 'red', strikeout: true, size: 10, text: 'there', link: 'link1' },
{ color: 'red', strikeout: true, size: 10, text: 'how', link: '' },
{ color: 'red', strikeout: true, size: 10, text: 'Areyou?', link: 'link2' },
]);
expect( document.getLinksData()).toEqual([
{
value: 'link1',
text: 'there',
x: 0,
y: 0,
width: 0,
height: 0,
},
{
value: 'link2',
text: 'Areyou?',
x: 0,
y: 0,
width: 0,
height: 0,
},
]);

document.load([
{ color: 'blue', font: 'sans-serif', size: 13, text: 'hi' },
{ color: 'blue', font: 'sans-serif', size: 13, text: 'there' },
]);
expect( document.getLinksData()).toEqual([]);
});

test('selectByProperties function should return a range', () => {
document.load([
{ color: 'blue', font: 'sans-serif', size: 13, text: 'hi' },
{ color: 'red', strikeout: true, size: 10, text: 'there', link: 'link1' },
{ color: 'green', strikeout: true, size: 10, text: 'how', link: 'link1' },
{ color: 'red', strikeout: true, size: 10, text: 'Areyou?', link: 'link2' },
]);
document.select( 4, 4, true ); // move caret to 4th
expect( document.selectByProperties([ 'link' ]).save()).toEqual([
{ color: 'red', strikeout: true, size: 10, text: 'there', link: 'link1', align: 'left', bold: true, font: 'lt_regular', italic: false, script: 'normal', underline: false },
{ color: 'green', strikeout: true, size: 10, text: 'how', link: 'link1', align: 'left', bold: true, font: 'lt_regular', italic: false, script: 'normal', underline: false },
]);
expect( document.selectByProperties([ 'link', 'size' ]).save()).toEqual([
{ color: 'red', strikeout: true, size: 10, text: 'there', link: 'link1', align: 'left', bold: true, font: 'lt_regular', italic: false, script: 'normal', underline: false },
{ color: 'green', strikeout: true, size: 10, text: 'how', link: 'link1', align: 'left', bold: true, font: 'lt_regular', italic: false, script: 'normal', underline: false },
]);
expect( document.selectByProperties([ 'size' ]).save()).toEqual([
{ color: 'red', strikeout: true, size: 10, text: 'there', link: 'link1', align: 'left', bold: true, font: 'lt_regular', italic: false, script: 'normal', underline: false },
{ color: 'green', strikeout: true, size: 10, text: 'how', link: 'link1', align: 'left', bold: true, font: 'lt_regular', italic: false, script: 'normal', underline: false },
{ color: 'red', strikeout: true, size: 10, text: 'Areyou?', link: 'link2', align: 'left', bold: true, font: 'lt_regular', italic: false, script: 'normal', underline: false },
]);
expect( document.selectByProperties([ 'link', 'color' ]).save()).toEqual([
{ color: 'red', strikeout: true, size: 10, text: 'there', link: 'link1', align: 'left', bold: true, font: 'lt_regular', italic: false, script: 'normal', underline: false },
]);
});




0 comments on commit 2d6592f

Please sign in to comment.