rangy.createModule('SafeWrapLink', function(api, module) {
var surroundSelectionWithLink;
surroundSelectionWithLink = (function(href) {
var after, afterLink, afterLinkHref, before, beforeLink, beforeLinkHref, currentLink, fullText, link, par, parNode, range, selectionText;
range = document.getSelection().getRangeAt(0);
selectionText = range.toString();
if (range.commonAncestorContainer.nodeName !== "#text") {
beforeLinkHref = range.commonAncestorContainer.childNodes[0].getAttribute('href');
afterLinkHref = range.commonAncestorContainer.childNodes[2].getAttribute('href');
par = range.commonAncestorContainer;
parNode = par;
} else {
par = range.commonAncestorContainer.parentNode;
currentLink = par.getAttribute('href');
parNode = par.parentNode;
}
fullText = par.innerText;
before = fullText.match(new RegExp("^(.*)" + selectionText))[1];
after = fullText.match(new RegExp(selectionText + "(.*)$"))[1];
// Build link for before selection
beforeLink = document.createElement('a');
beforeLink.href = beforeLinkHref || currentLink;
beforeLink.innerText = before;
// Build link to insert
link = document.createElement('a');
link.href = href;
link.innerText = selectionText;
// Build link for after selection
afterLink = document.createElement('a');
afterLink.href = afterLinkHref || currentLink;
afterLink.innerText = after;
// Append the links in order
if (beforeLink.innerText.length > 0) {
parNode.appendChild(beforeLink);
}
parNode.appendChild(link);
if (afterLink.innerText.length > 0) {
parNode.appendChild(afterLink);
}
// remove old linking
if (par === range.commonAncestorContainer) {
par.removeChild(par.childNodes[0]);
return par.removeChild(par.childNodes[1]);
} else {
return parNode.removeChild(par);
}
});
return api.util.extend(api, {
surroundSelectionWithLink: surroundSelectionWithLink
});
});
describe("add_source", function() {
var content, fixture, makeSelection;
fixture = $('<div id="fixture"></div>');
content = null;
beforeEach(function() {
return $('body').append(fixture);
});
afterEach(function() {
$('body #fixture').empty();
return $('body #fixture').remove();
});
makeSelection = (function(select) {
var endEl, html, range, startEl;
html = content.html();
html = html.replace(select, '<span id="start"></span>' + select + '<span id="end"></span>');
content.html(html);
range = document.createRange();
startEl = $('#start', content)[0];
range.setStartBefore(startEl);
endEl = $('#end', content)[0];
range.setEndBefore(endEl);
startEl.remove();
endEl.remove();
sel = rangy.getSelection();
sel.removeAllRanges();
sel.addRange(range);
});
it("inserts a link inside a an exsisting link", function() {
content = $('<div contenteditbale><a href="http://www.example.com/">Linked New Text</a></div>');
fixture.append(content);
makeSelection('New');
rangy.surroundSelectionWithLink('http://www.example.com/new');
return expect(fixture.find('[contenteditbale]').html()).toEqual('<a href="http://www.example.com/">Linked </a><a href="http://www.example.com/new">New</a><a href="http://www.example.com/"> Text</a>');
});
it("replaces link with new link", function() {
content = $('<div contenteditbale><a href="http://www.example.com/">Linked New Text</a></div>');
fixture.append(content);
makeSelection('Linked New Text');
rangy.surroundSelectionWithLink('http://www.example.com/replaced');
return expect(fixture.find('[contenteditbale]').html()).toEqual('<a href="http://www.example.com/replaced">Linked New Text</a>');
});
return it("inserts link between two links", function() {
content = $('<div contenteditbale><a href="http://www.example.com/">Linked <span id="start"></span>New</a> <a href="http://www.example.com/next">The<span id="end"></span> Text</a></div>');
fixture.append(content);
makeSelection("New The");
rangy.surroundSelectionWithLink('http://www.example.com/added');
return expect(fixture.find('[contenteditbale]').html()).toEqual(' <a href="http://www.example.com/">Linked </a><a href="http://www.example.com/added">New The</a><a href="http://www.example.com/next"> Text</a>');
});
});
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Selection Range test</title>
<script src="http://pivotal.github.com/jasmine/lib/jasmine-1.3.1/jasmine.js"></script>
<script src="http://pivotal.github.com/jasmine/lib/jasmine-1.3.1/jasmine-html.js"></script>
<link href="http://pivotal.github.com/jasmine/lib/jasmine-1.3.1/jasmine.css"
rel="stylesheet">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://rangy.googlecode.com/svn/trunk/currentrelease/rangy-core.js"></script>
<link rel="stylesheet" href="style.css">
<script src="app.js"></script>
<script src="appSpec.js"></script>
<script src="jasmineBootstrap.js"></script> <!-- bootstraps Jasmine -->
</head>
<body>
<div id="HTMLReporter" class="jasmine_reporter"></div>
</body>
</html>
(function() {
var jasmineEnv = jasmine.getEnv();
jasmineEnv.updateInterval = 250;
/**
Create the `HTMLReporter`, which Jasmine calls to provide results of each spec and each suite. The Reporter is responsible for presenting results to the user.
*/
var htmlReporter = new jasmine.HtmlReporter();
jasmineEnv.addReporter(htmlReporter);
/**
Delegate filtering of specs to the reporter. Allows for clicking on single suites or specs in the results to only run a subset of the suite.
*/
jasmineEnv.specFilter = function(spec) {
return htmlReporter.specFilter(spec);
};
/**
Run all of the tests when the page finishes loading - and make sure to run any previous `onload` handler
### Test Results
Scroll down to see the results of all of these specs.
*/
var currentWindowOnload = window.onload;
window.onload = function() {
if (currentWindowOnload) {
currentWindowOnload();
}
//document.querySelector('.version').innerHTML = jasmineEnv.versionString();
execJasmine();
};
function execJasmine() {
jasmineEnv.execute();
}
})();
/* restore "body" styling that were changes by "jasmine.css"... */
body { background-color: white; padding: 0; margin: 8px; }
/* ... but remain the "jasmine.css" styling for the Jasmine reporting */
.jasmine_reporter { background-color: #eeeeee; padding: 0; margin: 0; }