Skip to content

Commit

Permalink
Next/Previous feature (#7)
Browse files Browse the repository at this point in the history
* update deps
* Add previous/next feature
* documentation
* Build and bump
* Travis
  • Loading branch information
TheJaredWilcurt authored Apr 15, 2020
1 parent b824a58 commit 3adc340
Show file tree
Hide file tree
Showing 9 changed files with 246 additions and 94 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
sudo: required
os:
- linux
dist: trusty
language: node_js
node_js:
Expand Down
37 changes: 33 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ Adds "Ctrl+F" find box to highlight text in the DOM
findInNw.initialize();
</script>
```
1. Use `CTRL+F` and `ESC` to show/hide the search box
1. Use `CTRL+F` to display and give focus to the search box
1. After typing, press `ENTER` to go to highlight/scroll to the next match.
1. Use `TAB` to navigate to the "previous", "next", and "close" buttons.
1. Use `ENTER` or `SPACE` to activate a button when focused.
1. User `ESC` to hide the search box and return focus to the body



Expand Down Expand Up @@ -45,6 +49,11 @@ This is used to programmitcally hide the search box. `ESC` will still hide it to
This is used to programmitcally find text.


### `findInNw.highlightNext();` and `findInNw.highlightPrevious();`

This will highlight and scroll to the next or previous match.


### `findInNw.clearTokens();`

This is used to remove all the highlighted tokens.
Expand All @@ -57,12 +66,22 @@ This is used to remove all the highlighted tokens.

### Highlight tokens

All highlight tokens of matching searched text will be wrapped in a `<mark class="find-in-nw-token">searched text</mark>`. You can customize this by targeting the following
All highlight tokens of matching searched text will be wrapped in a `<mark class="find-in-nw-token">searched text</mark>`.

They will also contain a `data-find-in-nw-position="4"` data attribute, the number correlates to a zero-based index of all matches.

As you navigate from one match to the next, the currently selected match will have a class of `.find-in-nw-current-token`.

You can customize this by targeting the following

```css
mark.find-in-nw-token {
background-color: #00F;
}

mark.find-in-nw-current-token {
background-color: #38D878;
}
```


Expand All @@ -77,10 +96,20 @@ Each element of the search box is styled by targeting a class. They also all hav
/* The input field you type in */
#find-in-nw-input {}

/* The count of matching highlighted items */
/* The current selected match number. Ex: The number 1 in "1/5" */
#find-in-nw-current {}

/* The separator between the current and count. Ex: The slash (/) in "1/5" */
#find-in-nw-of {}

/* The count of matching highlighted items. Ex: The number 5 in "1/5" */
#find-in-nw-count {}

/* The X close button */
/* The previous and next buttons, ∧ and ∨ */
#find-in-nw-previous {}
#find-in-nw-next {}

/* The × close button */
#find-in-nw-close {}
```

Expand Down
2 changes: 1 addition & 1 deletion dev.html
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@

Quisque vel semper orci. Praesent sit amet tempor dolor. Sed eu ipsum vel justo maximus cursus nec sed orci. Nullam sagittis urna enim, eget egestas leo pretium quis. Etiam leo justo, semper vitae erat at, commodo vulputate massa. Suspendisse non gravida velit. Morbi commodo dignissim lacus, id laoreet risus. Vestibulum aliquam dapibus turpis quis pharetra. Ut eget ullamcorper magna. Donec et volutpat enim, a elementum lectus. Maecenas a porta turpis, nec venenatis odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque mi justo, dapibus eget risus at, dignissim eleifend neque. Pellentesque consequat lacus nec quam auctor, vel euismod arcu pharetra. Duis eget hendrerit justo. Nam sit amet lectus gravida, auctor diam eu, dapibus mauris. Mauris facilisis sapien commodo odio pulvinar, quis venenatis sapien posuere. Aenean nec egestas ipsum. Suspendisse cursus sed elit id consectetur. Fusce volutpat porta odio sed convallis. Proin faucibus sed felis vitae commodo. Suspendisse consequat eget mi ut accumsan. Nulla fermentum ligula eget tempus fermentum. Ut vel libero mollis, consequat ligula non, posuere ante. Etiam diam massa, tempus ut dignissim at, ultrices non urna.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque mi justo, dapibus eget risus at, dignissim eleifend neque. Pellentesque consequat lacus nec quam auctor, vel euismod arcu pharetra. Duis eget hendrerit justo. Nam sit amet lectus gravida, auctor diam eu, dapibus mauris. Mauris dolore facilisis sapien commodo odio pulvinar, quis venenatis sapien posuere. Aenean nec egestas ipsum. Suspendisse cursus sed elit id consectetur. Fusce volutpat porta odio sed convallis. Proin faucibus sed felis vitae commodo. Suspendisse consequat eget mi ut accumsan. Nulla fermentum ligula eget tempus fermentum. Ut vel libero mollis, consequat ligula non, posuere ante. Etiam diam massa, tempus ut dignissim at, ultrices non urna.

Pellentesque luctus rutrum enim, ac euismod lacus fermentum vel. In egestas non massa eget mollis. Mauris auctor vitae neque in lacinia. Donec lorem est, eleifend ut ipsum eu, euismod laoreet justo. Maecenas id viverra quam, nec ullamcorper enim. Duis turpis nisl, laoreet vitae dui ac, elementum aliquet nisl. Vivamus gravida sodales volutpat. Donec aliquet massa id interdum eleifend. Maecenas eu egestas lectus, nec venenatis tortor. Suspendisse vel rutrum ligula. Maecenas blandit tincidunt dolor, vel imperdiet ligula semper ullamcorper. Maecenas a lectus elit. Integer a quam ornare, sollicitudin risus at, finibus mi.

Expand Down
2 changes: 1 addition & 1 deletion dist/find-in-nw.js

Large diffs are not rendered by default.

Binary file modified find-in-nw.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "findinnw",
"version": "1.0.0",
"version": "1.1.0",
"description": "Simulate the Ctrl+F (find) feature from Chrome in NW.js",
"main": "test.html",
"scripts": {
Expand All @@ -21,14 +21,14 @@
"author": "",
"license": "MIT",
"devDependencies": {
"eslint": "^6.6.0",
"eslint": "^6.8.0",
"eslint-config-tjw-base": "^1.0.0",
"findandreplacedomtext": "^0.4.6",
"node-sass": "^4.13.0",
"node-sass": "^4.13.1",
"nw": "sdk",
"sass": "^1.23.1",
"sass": "^1.26.3",
"sass-lint": "^1.13.1",
"terser": "^4.3.9",
"terser": "^4.6.11",
"tjw-sasslint-rules": "^2.1.0"
},
"repository": "https://github.com/nwutils/find-in-nw"
Expand Down
166 changes: 137 additions & 29 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@
const findInNw = {
initialized: false,
lastSearched: '',
total: 0,
currentToken: 0,
dataAttribute: 'data-find-in-nw-position',

resetState: function () {
this.lastSearched = '';
this.total = 0;
this.currentToken = 0;
},

create: {
css: '/* PLACEHOLDER */',
Expand All @@ -27,42 +36,36 @@ const findInNw = {

return input;
},
count: function () {
const count = document.createElement('span');
count.setAttribute('id', 'find-in-nw-count');
count.setAttribute('class', 'find-in-nw-count');
count.innerHTML = '0';

return count;
},
close: function () {
const button = document.createElement('button');
button.setAttribute('id', 'find-in-nw-close');
button.setAttribute('class', 'find-in-nw-close');
button.innerHTML = '&times;';
element: function (el, id, value) {
const element = document.createElement(el);
element.setAttribute('id', 'find-in-nw-' + id);
element.setAttribute('class', 'find-in-nw-' + id);
element.innerHTML = value + '';

return button;
return element;
},

composeSearchBox: function () {
const container = this.container();
const input = this.input();
const count = this.count();
const close = this.close();

container.appendChild(input);
container.appendChild(count);
container.appendChild(close);
container.appendChild(this.input());
container.appendChild(this.element('span', 'current', 0));
container.appendChild(this.element('span', 'of', '/'));
container.appendChild(this.element('span', 'count', 0));
container.appendChild(this.element('button', 'previous', '&and;'));
container.appendChild(this.element('button', 'next', '&or;'));
container.appendChild(this.element('button', 'close', '&times;'));

return container;
}
},

closeButtonClicked: function () {
const close = document.getElementById('find-in-nw-close');
close.addEventListener('click', function (evt) {
evt.preventDefault();
this.hideSearchBox();
keyDownPressed: function () {
const input = document.getElementById('find-in-nw-input');
input.addEventListener('keydown', function (evt) {
if (evt.key === 'Enter') {
this.highlightNext();
}
}.bind(this));
},
inputChanged: function () {
Expand All @@ -77,10 +80,34 @@ const findInNw = {
}
}.bind(this));
},
previousButtonClicked: function () {
const previous = document.getElementById('find-in-nw-previous');
previous.addEventListener('click', function (evt) {
evt.preventDefault();
this.highlightPrevious();
}.bind(this));
},
nextButtonClicked: function () {
const next = document.getElementById('find-in-nw-next');
next.addEventListener('click', function (evt) {
evt.preventDefault();
this.highlightNext();
}.bind(this));
},
closeButtonClicked: function () {
const close = document.getElementById('find-in-nw-close');
close.addEventListener('click', function (evt) {
evt.preventDefault();
this.hideSearchBox();
}.bind(this));
},

eventBinding: function () {
this.closeButtonClicked();
this.keyDownPressed();
this.inputChanged();
this.previousButtonClicked();
this.nextButtonClicked();
this.closeButtonClicked();
},
keyBindings: function () {
document.onkeydown = function (pressed) {
Expand All @@ -98,6 +125,23 @@ const findInNw = {
}.bind(this);
},

highlightPrevious: function () {
this.currentToken = this.currentToken - 1;
if (this.currentToken < 0) {
this.currentToken = (this.total - 1);
}
this.updateCount();
this.highlightCurrentToken();
},
highlightNext: function () {
this.currentToken = this.currentToken + 1;
if (this.currentToken > (this.total - 1)) {
this.currentToken = 0;
}
this.updateCount();
this.highlightCurrentToken();
},

showSearchBox: function () {
const searchBox = document.getElementById('find-in-nw-search-box');
const input = document.getElementById('find-in-nw-input');
Expand Down Expand Up @@ -129,10 +173,72 @@ const findInNw = {
return elements;
},

updateCount: function () {
setDataPositionAttribute: function () {
let index = 0;
let searchLength = this.lastSearched.length;
let tempLength = searchLength;

const tokens = document.getElementsByClassName('find-in-nw-token');

[...tokens].forEach(function (token) {
let tokenLength = token.innerText.length;
token.setAttribute(this.dataAttribute, index);

if (tokenLength === searchLength) {
index = index + 1;
tempLength = searchLength;
} else {
tempLength = tempLength - tokenLength;
if (tempLength < 1) {
index = index + 1;
tempLength = searchLength;
}
}
}.bind(this));

if (!tokens) {
index = 0;
}
this.total = index;
},
highlightCurrentToken: function () {
const currentTokenClass = 'find-in-nw-current-token';

let previousTokens = document.getElementsByClassName(currentTokenClass);
let currentTokens = document.querySelectorAll('.find-in-nw-token[' + this.dataAttribute + '="' + this.currentToken + '"]');

if (previousTokens && previousTokens.length) {
previousTokens = [...previousTokens];
previousTokens.forEach(function (token) {
token.classList.remove(currentTokenClass);
});
}

if (currentTokens && currentTokens.length) {
currentTokens = [...currentTokens];
currentTokens.forEach(function (token) {
token.classList.add(currentTokenClass);
});

currentTokens[0].scrollIntoView({
behavior: 'auto',
block: 'center',
inline: 'center'
});
}
},

updateCount: function () {
const current = document.getElementById('find-in-nw-current');
const count = document.getElementById('find-in-nw-count');
count.innerHTML = tokens.length.toLocaleString();

let currentValue = 0;
if (this.total !== 0) {
currentValue = this.currentToken + 1;
}

current.innerHTML = (currentValue).toLocaleString();
count.innerHTML = this.total.toLocaleString();
},
clearTokens: function () {
const tokens = document.getElementsByClassName('find-in-nw-token');
Expand All @@ -149,7 +255,7 @@ const findInNw = {
element.normalize();
});

this.lastSearched = '';
this.resetState();
this.updateCount();
},
search: function (text) {
Expand All @@ -165,7 +271,9 @@ const findInNw = {
});

this.lastSearched = text;
this.setDataPositionAttribute();
this.updateCount();
this.highlightCurrentToken();
},
initialize: function () {
if (!this.initialized) {
Expand Down
Loading

0 comments on commit 3adc340

Please sign in to comment.