diff --git a/lib/reverse_coverage/formatters/html/assets/javascripts/application.js b/lib/reverse_coverage/formatters/html/assets/javascripts/application.js
index a671126..587afa8 100644
--- a/lib/reverse_coverage/formatters/html/assets/javascripts/application.js
+++ b/lib/reverse_coverage/formatters/html/assets/javascripts/application.js
@@ -153,6 +153,8 @@ $(document).ready(function() {
let node = {
name: currentNode.name,
example: currentNode.example,
+ is_file_name: currentNode.is_file_name,
+ path: currentNode.path,
expanded: true,
children: traverseTreeData([], paths.slice(1))
};
@@ -170,19 +172,21 @@ $(document).ready(function() {
$('.source_table.highlighted li.covered').live('click', function() {
const exampleRefs = $(this).children('.reverse_coverage')[0].dataset.exampleRefs.split(",");
- if(!$(this).children('.reverse_coverage').is(':visible')){
+ if(!$(this).children('.reverse_coverage').is(':visible')) {
let treeData = [];
const self = this;
exampleRefs.forEach(function(ref) {
- const example = window.examples[ref]
- const treeNodes = []
- example["file_path"].split('/').slice(1).forEach(function(node_path){
- treeNodes.push({ name: node_path })
+ const example = window.examples[ref];
+ const treeNodes = [];
+ const parts = example['file_path'].split('/').slice(1);
+ parts.forEach(function(node_path, i) {
+ var node = { name: node_path, is_file_name: (parts.length - 1 == i) };
+ if(node.is_file_name) node.path = example['file_path'];
+ treeNodes.push(node);
});
treeNodes.push({ example: example, name: example['full_description'] });
-
- treeData = traverseTreeData(treeData, treeNodes)
- })
+ treeData = traverseTreeData(treeData, treeNodes);
+ });
const domElement = self.querySelector('.reverse_coverage');
diff --git a/lib/reverse_coverage/formatters/html/assets/javascripts/treeview.js b/lib/reverse_coverage/formatters/html/assets/javascripts/treeview.js
index aee1b5f..cd23c42 100644
--- a/lib/reverse_coverage/formatters/html/assets/javascripts/treeview.js
+++ b/lib/reverse_coverage/formatters/html/assets/javascripts/treeview.js
@@ -83,11 +83,18 @@
var expando = document.createElement('div');
leaf.setAttribute('class', 'tree-leaf');
- content.setAttribute('class', 'tree-leaf-content');
+ content.setAttribute('class', 'tree-leaf-content' + (item.is_file_name ? ' file_name' : ''));
content.setAttribute('data-item', JSON.stringify(item));
text.setAttribute('class', 'tree-leaf-text');
text.textContent = item.name;
- expando.setAttribute('class', 'tree-expando ' + (item.expanded ? 'expanded' : ''));
+ if(item.is_file_name) {
+ var copyURL = document.createElement('a');
+ copyURL.setAttribute('href', 'Javascript:void(0)');
+ copyURL.setAttribute('class', 'copy-example-path');
+ copyURL.setAttribute('data-path', item.path);
+ text.appendChild(copyURL);
+ }
+ expando.setAttribute('class', 'tree-expando' + (item.expanded ? ' expanded' : ''));
expando.textContent = item.expanded ? '-' : '+';
content.appendChild(expando);
content.appendChild(text);
@@ -140,6 +147,13 @@
forEach(container.querySelectorAll('.tree-expando'), function (node) {
node.onclick = click;
});
+ forEach(container.querySelectorAll('.copy-example-path'), function (node) {
+ node.onclick = function(e) {
+ var el = (e.target || e.currentTarget);
+ e.stopPropagation();
+ navigator.clipboard.writeText(el.getAttribute('data-path'));
+ };
+ });
}
/**
diff --git a/lib/reverse_coverage/formatters/html/assets/stylesheets/screen.css.sass b/lib/reverse_coverage/formatters/html/assets/stylesheets/screen.css.sass
index 5cab8f9..0f87c2b 100644
--- a/lib/reverse_coverage/formatters/html/assets/stylesheets/screen.css.sass
+++ b/lib/reverse_coverage/formatters/html/assets/stylesheets/screen.css.sass
@@ -247,3 +247,10 @@ td
&:before
content: '↳ '
+
+a.copy-example-path
+ background: url('./clipboard.gif') no-repeat
+ display: inline-block
+ width: 11px
+ height: 13px
+ margin-left: 6px
diff --git a/lib/reverse_coverage/formatters/html/public/application.css b/lib/reverse_coverage/formatters/html/public/application.css
index 8003125..4f2d040 100644
--- a/lib/reverse_coverage/formatters/html/public/application.css
+++ b/lib/reverse_coverage/formatters/html/public/application.css
@@ -836,6 +836,13 @@ td {
.tree-expando.hidden + .tree-leaf-text:before {
content: "↳ "; }
+a.copy-example-path {
+ background: url("./clipboard.gif") no-repeat;
+ display: inline-block;
+ width: 11px;
+ height: 13px;
+ margin-left: 6px; }
+
diff --git a/lib/reverse_coverage/formatters/html/public/application.js b/lib/reverse_coverage/formatters/html/public/application.js
index 22439c5..a2d9b5c 100644
--- a/lib/reverse_coverage/formatters/html/public/application.js
+++ b/lib/reverse_coverage/formatters/html/public/application.js
@@ -1663,11 +1663,18 @@ jQuery.url = function()
var expando = document.createElement('div');
leaf.setAttribute('class', 'tree-leaf');
- content.setAttribute('class', 'tree-leaf-content');
+ content.setAttribute('class', 'tree-leaf-content' + (item.is_file_name ? ' file_name' : ''));
content.setAttribute('data-item', JSON.stringify(item));
text.setAttribute('class', 'tree-leaf-text');
text.textContent = item.name;
- expando.setAttribute('class', 'tree-expando ' + (item.expanded ? 'expanded' : ''));
+ if(item.is_file_name) {
+ var copyURL = document.createElement('a');
+ copyURL.setAttribute('href', 'Javascript:void(0)');
+ copyURL.setAttribute('class', 'copy-example-path');
+ copyURL.setAttribute('data-path', item.path);
+ text.appendChild(copyURL);
+ }
+ expando.setAttribute('class', 'tree-expando' + (item.expanded ? ' expanded' : ''));
expando.textContent = item.expanded ? '-' : '+';
content.appendChild(expando);
content.appendChild(text);
@@ -1720,6 +1727,13 @@ jQuery.url = function()
forEach(container.querySelectorAll('.tree-expando'), function (node) {
node.onclick = click;
});
+ forEach(container.querySelectorAll('.copy-example-path'), function (node) {
+ node.onclick = function(e) {
+ var el = (e.target || e.currentTarget);
+ e.stopPropagation();
+ navigator.clipboard.writeText(el.getAttribute('data-path'));
+ };
+ });
}
/**
@@ -1994,6 +2008,8 @@ $(document).ready(function() {
let node = {
name: currentNode.name,
example: currentNode.example,
+ is_file_name: currentNode.is_file_name,
+ path: currentNode.path,
expanded: true,
children: traverseTreeData([], paths.slice(1))
};
@@ -2011,19 +2027,21 @@ $(document).ready(function() {
$('.source_table.highlighted li.covered').live('click', function() {
const exampleRefs = $(this).children('.reverse_coverage')[0].dataset.exampleRefs.split(",");
- if(!$(this).children('.reverse_coverage').is(':visible')){
+ if(!$(this).children('.reverse_coverage').is(':visible')) {
let treeData = [];
const self = this;
exampleRefs.forEach(function(ref) {
- const example = window.examples[ref]
- const treeNodes = []
- example["file_path"].split('/').slice(1).forEach(function(node_path){
- treeNodes.push({ name: node_path })
+ const example = window.examples[ref];
+ const treeNodes = [];
+ const parts = example['file_path'].split('/').slice(1);
+ parts.forEach(function(node_path, i) {
+ var node = { name: node_path, is_file_name: (parts.length - 1 == i) };
+ if(node.is_file_name) node.path = example['file_path'];
+ treeNodes.push(node);
});
treeNodes.push({ example: example, name: example['full_description'] });
-
- treeData = traverseTreeData(treeData, treeNodes)
- })
+ treeData = traverseTreeData(treeData, treeNodes);
+ });
const domElement = self.querySelector('.reverse_coverage');
diff --git a/lib/reverse_coverage/formatters/html/public/clipboard.gif b/lib/reverse_coverage/formatters/html/public/clipboard.gif
new file mode 100644
index 0000000..cb4592b
Binary files /dev/null and b/lib/reverse_coverage/formatters/html/public/clipboard.gif differ