0
Fork 0
mirror of https://github.com/fastmail/Squire.git synced 2024-12-22 07:13:08 -05:00

Add make/remove link sugar.

Also:
Add getSelectedText method.
Fix bug in setting HTML after undo/redo in Opera.
This commit is contained in:
Neil Jenkins 2011-11-10 18:27:54 +11:00
parent 6726a0b33c
commit a2ef14e218
4 changed files with 89 additions and 12 deletions

View file

@ -118,6 +118,10 @@ Sets the HTML value for the editor. The value supplied should not contain `<body
Returns self.
### getSelectedText ###
Returns the text currently selected in the editor.
#### insertImage ####
Inserts an image at the current cursor location.
@ -217,11 +221,19 @@ Returns self.
### makeLink ###
Makes the currently selected text a link.
Makes the currently selected text a link. If no text is selected, the URL or email will be inserted as text at the current cursor point and made into a link.
#### Parameters ####
* **url**: The url to link to.
* **url**: The url or email to link to.
#### Returns ####
Returns self.
### removeLink ###
Removes any link that is currently at least partially selected.
#### Returns ####

File diff suppressed because one or more lines are too long

View file

@ -197,8 +197,11 @@ document.addEventListener( 'DOMContentLoaded', function () {
};
var setHTML = function ( html ) {
body.innerHTML = html;
body.fixCursor();
var node = body;
node.innerHTML = html;
do {
node.fixCursor();
} while ( node = node.getNextBlock() );
};
var insertElement = function ( el, range ) {
@ -478,7 +481,7 @@ document.addEventListener( 'DOMContentLoaded', function () {
return range;
};
var removeFormat = function ( tag, attributes, range ) {
var removeFormat = function ( tag, attributes, range, partial ) {
// Add bookmark
saveRangeToBookmark( range );
@ -552,9 +555,11 @@ document.addEventListener( 'DOMContentLoaded', function () {
}
);
if ( !partial ) {
formatTags.forEach( function ( node ) {
examineNode( node, node );
});
}
// Now wrap unselected nodes in the tag
toWrap.forEach( function ( item ) {
@ -581,7 +586,7 @@ document.addEventListener( 'DOMContentLoaded', function () {
return range;
};
var changeFormat = function ( add, remove, range ) {
var changeFormat = function ( add, remove, range, partial ) {
// Normalise the arguments and get selection
if ( !range && !( range = getSelection() ) ) {
return;
@ -593,7 +598,7 @@ document.addEventListener( 'DOMContentLoaded', function () {
if ( remove ) {
range = removeFormat( remove.tag.toUpperCase(),
remove.attributes || {}, range );
remove.attributes || {}, range, partial );
}
if ( add ) {
range = addFormat( add.tag.toUpperCase(),
@ -1421,6 +1426,10 @@ document.addEventListener( 'DOMContentLoaded', function () {
return this;
},
getSelectedText: function () {
return getSelection().getTextContent();
},
insertImage: function ( src ) {
var img = createElement( 'IMG', {
src: src
@ -1450,6 +1459,17 @@ document.addEventListener( 'DOMContentLoaded', function () {
removeUnderline: command( changeFormat, null, { tag: 'U' } ),
makeLink: function ( url ) {
url = encodeURI( url );
var range = getSelection();
if ( range.collapsed ) {
var protocolEnd = url.indexOf( ':' ) + 1;
if ( protocolEnd ) {
while ( url[ protocolEnd ] === '/' ) { protocolEnd += 1; }
}
range._insertNode(
doc.createTextNode( url.slice( protocolEnd ) )
);
}
changeFormat({
tag: 'A',
attributes: {
@ -1457,7 +1477,15 @@ document.addEventListener( 'DOMContentLoaded', function () {
}
}, {
tag: 'A'
});
}, range );
focus();
return this;
},
removeLink: function () {
changeFormat( null, {
tag: 'A'
}, getSelection(), true );
focus();
return this;
},

View file

@ -18,6 +18,8 @@ var indexOf = Array.prototype.indexOf;
var ELEMENT_NODE = 1, // Node.ELEMENT_NODE
TEXT_NODE = 3, // Node.TEXT_NODE
SHOW_TEXT = 4, // NodeFilter.SHOW_TEXT,
FILTER_ACCEPT = 1, // NodeFilter.FILTER_ACCEPT,
START_TO_START = 0, // Range.START_TO_START
START_TO_END = 1, // Range.START_TO_END
END_TO_END = 2, // Range.END_TO_END
@ -49,6 +51,41 @@ var getNodeAfter = function ( node, offset ) {
};
implement( Range, {
getTextContent: function () {
this.moveBoundariesDownTree();
var startContainer = this.startContainer,
endContainer = this.endContainer,
root = this.commonAncestorContainer,
walker = root.ownerDocument.createTreeWalker(
root, SHOW_TEXT, function ( node ) {
return FILTER_ACCEPT;
}, false ),
textnode = walker.currentNode = startContainer,
textContent = '',
value;
do {
value = textnode.data;
if ( value && ( /\S/.test( value ) ) ) {
if ( textnode === endContainer ) {
value = value.slice( 0, this.endOffset );
}
if ( textnode === startContainer ) {
value = value.slice( this.startOffset );
}
textContent += value;
}
if ( textnode === endContainer ) {
break;
}
} while ( textnode = walker.nextNode() );
return textContent;
},
// ---
_insertNode: function ( node ) {
// Insert at start.
var startContainer = this.startContainer,