highlight-within-textarea-rails 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/Gemfile +6 -0
- data/README.md +47 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/highlight-within-textarea-rails.gemspec +25 -0
- data/lib/highlight/within/textarea/rails.rb +12 -0
- data/lib/highlight/within/textarea/rails/version.rb +9 -0
- data/vendor/assets/javascripts/jquery.highlight-within-textarea.js +380 -0
- data/vendor/assets/stylesheets/jquery.highlight-within-textarea.css +48 -0
- metadata +82 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fca4600b2958b37492eefd322d3eccbbaef6d568
|
4
|
+
data.tar.gz: 769b20b03f15f7df573be62a25dedcdacdd9d99f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: '01228d403dfbb99b0e471e2f6905a8f6953022b7c0c5368e0bed5069053396eb06a171568940e82e550b15a5e320eff1543063054f45d1624344f84ad1ebc47b'
|
7
|
+
data.tar.gz: f14ba7338a1c2ad920185232736decc7d9ab02f73966d56f13ceafb9928efb03c5418a79048b12c8b6a3d8567c018cec5c0aa3b3da8b27b37b5e6df68af4e744
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# Highlight::Within::Textarea::Rails
|
2
|
+
|
3
|
+
## What is this?
|
4
|
+
|
5
|
+
A gemified version of **highlight-within-textarea** (jQuery plugin for highlighting bits of text within a textarea).
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'highlight-within-textarea-rails'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install highlight-within-textarea-rails
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
Add the following line to `app/assets/javascripts/application.js`:
|
26
|
+
|
27
|
+
```javascript
|
28
|
+
//= require jquery.highlight-within-textarea.js
|
29
|
+
```
|
30
|
+
|
31
|
+
and `app/assets/stylesheets/application.css`:
|
32
|
+
|
33
|
+
```css
|
34
|
+
*= require jquery.highlight-within-textarea.css
|
35
|
+
```
|
36
|
+
|
37
|
+
and then [RTFM](https://github.com/lonekorean/highlight-within-textarea).
|
38
|
+
|
39
|
+
## Development
|
40
|
+
|
41
|
+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
42
|
+
|
43
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
44
|
+
|
45
|
+
## Contributing
|
46
|
+
|
47
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ukazap/highlight-within-textarea-rails.
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "highlight/within/textarea/rails"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "highlight/within/textarea/rails/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "highlight-within-textarea-rails"
|
8
|
+
spec.version = Highlight::Within::Textarea::Rails::VERSION
|
9
|
+
spec.authors = ["Ukaza Perdana"]
|
10
|
+
spec.email = ["hello@ukazap.space"]
|
11
|
+
|
12
|
+
spec.summary = "Gemified version of highlight-within-textarea"
|
13
|
+
spec.description = "jQuery plugin for highlighting bits of text within a textarea."
|
14
|
+
spec.homepage = "https://github.com/ukazap/highlight-within-textarea-rails"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
17
|
+
f.match(%r{^(test|spec|features)/})
|
18
|
+
end
|
19
|
+
spec.bindir = "exe"
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.15"
|
24
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
25
|
+
end
|
@@ -0,0 +1,380 @@
|
|
1
|
+
/*
|
2
|
+
* highlight-within-textarea
|
3
|
+
*
|
4
|
+
* @author Will Boyd
|
5
|
+
* @github https://github.com/lonekorean/highlight-within-textarea
|
6
|
+
*/
|
7
|
+
|
8
|
+
(function($) {
|
9
|
+
let ID = 'hwt';
|
10
|
+
|
11
|
+
let HighlightWithinTextarea = function($el, config) {
|
12
|
+
this.init($el, config);
|
13
|
+
};
|
14
|
+
|
15
|
+
HighlightWithinTextarea.prototype = {
|
16
|
+
init: function($el, config) {
|
17
|
+
this.$el = $el;
|
18
|
+
|
19
|
+
// backwards compatibility with v1 (deprecated)
|
20
|
+
if (this.getType(config) === 'function') {
|
21
|
+
config = { highlight: config };
|
22
|
+
}
|
23
|
+
|
24
|
+
if (this.getType(config) === 'custom') {
|
25
|
+
this.highlight = config;
|
26
|
+
this.generate();
|
27
|
+
} else {
|
28
|
+
console.error('valid config object not provided');
|
29
|
+
}
|
30
|
+
},
|
31
|
+
|
32
|
+
// returns identifier strings that aren't necessarily "real" JavaScript types
|
33
|
+
getType: function(instance) {
|
34
|
+
let type = typeof instance;
|
35
|
+
if (!instance) {
|
36
|
+
return 'falsey';
|
37
|
+
} else if (Array.isArray(instance)) {
|
38
|
+
if (instance.length === 2 && typeof instance[0] === 'number' && typeof instance[1] === 'number') {
|
39
|
+
return 'range';
|
40
|
+
} else {
|
41
|
+
return 'array';
|
42
|
+
}
|
43
|
+
} else if (type === 'object') {
|
44
|
+
if (instance instanceof RegExp) {
|
45
|
+
return 'regexp';
|
46
|
+
} else if (instance.hasOwnProperty('highlight')) {
|
47
|
+
return 'custom';
|
48
|
+
}
|
49
|
+
} else if (type === 'function' || type === 'string') {
|
50
|
+
return type;
|
51
|
+
}
|
52
|
+
|
53
|
+
return 'other';
|
54
|
+
},
|
55
|
+
|
56
|
+
generate: function() {
|
57
|
+
this.$el
|
58
|
+
.addClass(ID + '-input ' + ID + '-content')
|
59
|
+
.on('input.' + ID, this.handleInput.bind(this))
|
60
|
+
.on('scroll.' + ID, this.handleScroll.bind(this));
|
61
|
+
|
62
|
+
this.$highlights = $('<div>', { class: ID + '-highlights ' + ID + '-content' });
|
63
|
+
|
64
|
+
this.$backdrop = $('<div>', { class: ID + '-backdrop' })
|
65
|
+
.append(this.$highlights);
|
66
|
+
|
67
|
+
this.$container = $('<div>', { class: ID + '-container' })
|
68
|
+
.insertAfter(this.$el)
|
69
|
+
.append(this.$backdrop, this.$el) // moves $el into $container
|
70
|
+
.on('scroll', this.blockContainerScroll.bind(this));
|
71
|
+
|
72
|
+
this.browser = this.detectBrowser();
|
73
|
+
switch (this.browser) {
|
74
|
+
case 'firefox':
|
75
|
+
this.fixFirefox();
|
76
|
+
break;
|
77
|
+
case 'ios':
|
78
|
+
this.fixIOS();
|
79
|
+
break;
|
80
|
+
}
|
81
|
+
|
82
|
+
// plugin function checks this for success
|
83
|
+
this.isGenerated = true;
|
84
|
+
|
85
|
+
// trigger input event to highlight any existing input
|
86
|
+
this.handleInput();
|
87
|
+
},
|
88
|
+
|
89
|
+
// browser sniffing sucks, but there are browser-specific quirks to handle
|
90
|
+
// that are not a matter of feature detection
|
91
|
+
detectBrowser: function() {
|
92
|
+
let ua = window.navigator.userAgent.toLowerCase();
|
93
|
+
if (ua.indexOf('firefox') !== -1) {
|
94
|
+
return 'firefox';
|
95
|
+
} else if (!!ua.match(/msie|trident\/7|edge/)) {
|
96
|
+
return 'ie';
|
97
|
+
} else if (!!ua.match(/ipad|iphone|ipod/) && ua.indexOf('windows phone') === -1) {
|
98
|
+
// Windows Phone flags itself as "like iPhone", thus the extra check
|
99
|
+
return 'ios';
|
100
|
+
} else {
|
101
|
+
return 'other';
|
102
|
+
}
|
103
|
+
},
|
104
|
+
|
105
|
+
// Firefox doesn't show text that scrolls into the padding of a textarea, so
|
106
|
+
// rearrange a couple box models to make highlights behave the same way
|
107
|
+
fixFirefox: function() {
|
108
|
+
// take padding and border pixels from highlights div
|
109
|
+
let padding = this.$highlights.css([
|
110
|
+
'padding-top', 'padding-right', 'padding-bottom', 'padding-left'
|
111
|
+
]);
|
112
|
+
let border = this.$highlights.css([
|
113
|
+
'border-top-width', 'border-right-width', 'border-bottom-width', 'border-left-width'
|
114
|
+
]);
|
115
|
+
this.$highlights.css({
|
116
|
+
'padding': '0',
|
117
|
+
'border-width': '0'
|
118
|
+
});
|
119
|
+
|
120
|
+
this.$backdrop
|
121
|
+
.css({
|
122
|
+
// give padding pixels to backdrop div
|
123
|
+
'margin-top': '+=' + padding['padding-top'],
|
124
|
+
'margin-right': '+=' + padding['padding-right'],
|
125
|
+
'margin-bottom': '+=' + padding['padding-bottom'],
|
126
|
+
'margin-left': '+=' + padding['padding-left'],
|
127
|
+
})
|
128
|
+
.css({
|
129
|
+
// give border pixels to backdrop div
|
130
|
+
'margin-top': '+=' + border['border-top-width'],
|
131
|
+
'margin-right': '+=' + border['border-right-width'],
|
132
|
+
'margin-bottom': '+=' + border['border-bottom-width'],
|
133
|
+
'margin-left': '+=' + border['border-left-width'],
|
134
|
+
});
|
135
|
+
},
|
136
|
+
|
137
|
+
// iOS adds 3px of (unremovable) padding to the left and right of a textarea,
|
138
|
+
// so adjust highlights div to match
|
139
|
+
fixIOS: function() {
|
140
|
+
this.$highlights.css({
|
141
|
+
'padding-left': '+=3px',
|
142
|
+
'padding-right': '+=3px'
|
143
|
+
});
|
144
|
+
},
|
145
|
+
|
146
|
+
handleInput: function() {
|
147
|
+
let input = this.$el.val();
|
148
|
+
let ranges = this.getRanges(input, this.highlight);
|
149
|
+
let unstaggeredRanges = this.removeStaggeredRanges(ranges);
|
150
|
+
let boundaries = this.getBoundaries(unstaggeredRanges);
|
151
|
+
this.renderMarks(boundaries);
|
152
|
+
},
|
153
|
+
|
154
|
+
getRanges: function(input, highlight) {
|
155
|
+
let type = this.getType(highlight);
|
156
|
+
switch (type) {
|
157
|
+
case 'array':
|
158
|
+
return this.getArrayRanges(input, highlight);
|
159
|
+
case 'function':
|
160
|
+
return this.getFunctionRanges(input, highlight);
|
161
|
+
case 'regexp':
|
162
|
+
return this.getRegExpRanges(input, highlight);
|
163
|
+
case 'string':
|
164
|
+
return this.getStringRanges(input, highlight);
|
165
|
+
case 'range':
|
166
|
+
return this.getRangeRanges(input, highlight);
|
167
|
+
case 'custom':
|
168
|
+
return this.getCustomRanges(input, highlight);
|
169
|
+
default:
|
170
|
+
if (!highlight) {
|
171
|
+
// do nothing for falsey values
|
172
|
+
return [];
|
173
|
+
} else {
|
174
|
+
console.error('unrecognized highlight type');
|
175
|
+
}
|
176
|
+
}
|
177
|
+
},
|
178
|
+
|
179
|
+
getArrayRanges: function(input, arr) {
|
180
|
+
let ranges = arr.map(this.getRanges.bind(this, input));
|
181
|
+
return Array.prototype.concat.apply([], ranges);
|
182
|
+
},
|
183
|
+
|
184
|
+
getFunctionRanges: function(input, func) {
|
185
|
+
return this.getRanges(input, func(input));
|
186
|
+
},
|
187
|
+
|
188
|
+
getRegExpRanges: function(input, regex) {
|
189
|
+
let ranges = [];
|
190
|
+
let match;
|
191
|
+
while (match = regex.exec(input), match !== null) {
|
192
|
+
ranges.push([match.index, match.index + match[0].length]);
|
193
|
+
if (!regex.global) {
|
194
|
+
// non-global regexes do not increase lastIndex, causing an infinite loop,
|
195
|
+
// but we can just break manually after the first match
|
196
|
+
break;
|
197
|
+
}
|
198
|
+
}
|
199
|
+
return ranges;
|
200
|
+
},
|
201
|
+
|
202
|
+
getStringRanges: function(input, str) {
|
203
|
+
let ranges = [];
|
204
|
+
let inputLower = input.toLowerCase();
|
205
|
+
let strLower = str.toLowerCase();
|
206
|
+
let index = 0;
|
207
|
+
while (index = inputLower.indexOf(strLower, index), index !== -1) {
|
208
|
+
ranges.push([index, index + strLower.length]);
|
209
|
+
index += strLower.length;
|
210
|
+
}
|
211
|
+
return ranges;
|
212
|
+
},
|
213
|
+
|
214
|
+
getRangeRanges: function(input, range) {
|
215
|
+
return [range];
|
216
|
+
},
|
217
|
+
|
218
|
+
getCustomRanges: function(input, custom) {
|
219
|
+
let ranges = this.getRanges(input, custom.highlight);
|
220
|
+
if (custom.className) {
|
221
|
+
ranges.forEach(function(range) {
|
222
|
+
// persist class name as a property of the array
|
223
|
+
if (range.className) {
|
224
|
+
range.className = custom.className + ' ' + range.className;
|
225
|
+
} else {
|
226
|
+
range.className = custom.className;
|
227
|
+
}
|
228
|
+
});
|
229
|
+
}
|
230
|
+
return ranges;
|
231
|
+
},
|
232
|
+
|
233
|
+
// prevent staggered overlaps (clean nesting is fine)
|
234
|
+
removeStaggeredRanges: function(ranges) {
|
235
|
+
let unstaggeredRanges = [];
|
236
|
+
ranges.forEach(function(range) {
|
237
|
+
let isStaggered = unstaggeredRanges.some(function(unstaggeredRange) {
|
238
|
+
let isStartInside = range[0] > unstaggeredRange[0] && range[0] < unstaggeredRange[1];
|
239
|
+
let isStopInside = range[1] > unstaggeredRange[0] && range[1] < unstaggeredRange[1];
|
240
|
+
return isStartInside !== isStopInside; // xor
|
241
|
+
});
|
242
|
+
if (!isStaggered) {
|
243
|
+
unstaggeredRanges.push(range);
|
244
|
+
}
|
245
|
+
});
|
246
|
+
return unstaggeredRanges;
|
247
|
+
},
|
248
|
+
|
249
|
+
getBoundaries: function(ranges) {
|
250
|
+
let boundaries = [];
|
251
|
+
ranges.forEach(function(range) {
|
252
|
+
boundaries.push({
|
253
|
+
type: 'start',
|
254
|
+
index: range[0],
|
255
|
+
className: range.className
|
256
|
+
});
|
257
|
+
boundaries.push({
|
258
|
+
type: 'stop',
|
259
|
+
index: range[1]
|
260
|
+
});
|
261
|
+
});
|
262
|
+
|
263
|
+
this.sortBoundaries(boundaries);
|
264
|
+
return boundaries;
|
265
|
+
},
|
266
|
+
|
267
|
+
sortBoundaries: function(boundaries) {
|
268
|
+
// backwards sort (since marks are inserted right to left)
|
269
|
+
boundaries.sort(function(a, b) {
|
270
|
+
if (a.index !== b.index) {
|
271
|
+
return b.index - a.index;
|
272
|
+
} else if (a.type === 'stop' && b.type === 'start') {
|
273
|
+
return 1;
|
274
|
+
} else if (a.type === 'start' && b.type === 'stop') {
|
275
|
+
return -1;
|
276
|
+
} else {
|
277
|
+
return 0;
|
278
|
+
}
|
279
|
+
});
|
280
|
+
},
|
281
|
+
|
282
|
+
renderMarks: function(boundaries) {
|
283
|
+
let input = this.$el.val();
|
284
|
+
boundaries.forEach(function(boundary, index) {
|
285
|
+
let markup;
|
286
|
+
if (boundary.type === 'start') {
|
287
|
+
markup = '{{hwt-mark-start|' + index + '}}';
|
288
|
+
} else {
|
289
|
+
markup = '{{hwt-mark-stop}}';
|
290
|
+
}
|
291
|
+
input = input.slice(0, boundary.index) + markup + input.slice(boundary.index);
|
292
|
+
});
|
293
|
+
|
294
|
+
// this keeps scrolling aligned when input ends with a newline
|
295
|
+
input = input.replace(/\n(\{\{hwt-mark-stop\}\})?$/, '\n\n$1');
|
296
|
+
|
297
|
+
// encode HTML entities
|
298
|
+
input = input.replace(/</g, '<').replace(/>/g, '>');
|
299
|
+
|
300
|
+
if (this.browser === 'ie') {
|
301
|
+
// IE/Edge wraps whitespace differently in a div vs textarea, this fixes it
|
302
|
+
input = input.replace(/ /g, ' <wbr>');
|
303
|
+
}
|
304
|
+
|
305
|
+
// replace start tokens with opening <mark> tags with class name
|
306
|
+
input = input.replace(/\{\{hwt-mark-start\|(\d+)\}\}/g, function(match, submatch) {
|
307
|
+
var className = boundaries[+submatch].className;
|
308
|
+
if (className) {
|
309
|
+
return '<mark class="' + className + '">';
|
310
|
+
} else {
|
311
|
+
return '<mark>';
|
312
|
+
}
|
313
|
+
});
|
314
|
+
|
315
|
+
// replace stop tokens with closing </mark> tags
|
316
|
+
input = input.replace(/\{\{hwt-mark-stop\}\}/g, '</mark>');
|
317
|
+
|
318
|
+
this.$highlights.html(input);
|
319
|
+
},
|
320
|
+
|
321
|
+
handleScroll: function() {
|
322
|
+
let scrollTop = this.$el.scrollTop();
|
323
|
+
this.$backdrop.scrollTop(scrollTop);
|
324
|
+
|
325
|
+
// Chrome and Safari won't break long strings of spaces, which can cause
|
326
|
+
// horizontal scrolling, this compensates by shifting highlights by the
|
327
|
+
// horizontally scrolled amount to keep things aligned
|
328
|
+
let scrollLeft = this.$el.scrollLeft();
|
329
|
+
this.$backdrop.css('transform', (scrollLeft > 0) ? 'translateX(' + -scrollLeft + 'px)' : '');
|
330
|
+
},
|
331
|
+
|
332
|
+
// in Chrome, page up/down in the textarea will shift stuff within the
|
333
|
+
// container (despite the CSS), this immediately reverts the shift
|
334
|
+
blockContainerScroll: function() {
|
335
|
+
this.$container.scrollLeft(0);
|
336
|
+
},
|
337
|
+
|
338
|
+
destroy: function() {
|
339
|
+
this.$backdrop.remove();
|
340
|
+
this.$el
|
341
|
+
.unwrap()
|
342
|
+
.removeClass(ID + '-text ' + ID + '-input')
|
343
|
+
.off(ID)
|
344
|
+
.removeData(ID);
|
345
|
+
},
|
346
|
+
};
|
347
|
+
|
348
|
+
// register the jQuery plugin
|
349
|
+
$.fn.highlightWithinTextarea = function(options) {
|
350
|
+
return this.each(function() {
|
351
|
+
let $this = $(this);
|
352
|
+
let plugin = $this.data(ID);
|
353
|
+
|
354
|
+
if (typeof options === 'string') {
|
355
|
+
if (plugin) {
|
356
|
+
switch (options) {
|
357
|
+
case 'update':
|
358
|
+
plugin.handleInput();
|
359
|
+
break;
|
360
|
+
case 'destroy':
|
361
|
+
plugin.destroy();
|
362
|
+
break;
|
363
|
+
default:
|
364
|
+
console.error('unrecognized method string');
|
365
|
+
}
|
366
|
+
} else {
|
367
|
+
console.error('plugin must be instantiated first');
|
368
|
+
}
|
369
|
+
} else {
|
370
|
+
if (plugin) {
|
371
|
+
plugin.destroy();
|
372
|
+
}
|
373
|
+
plugin = new HighlightWithinTextarea($this, options);
|
374
|
+
if (plugin.isGenerated) {
|
375
|
+
$this.data(ID, plugin);
|
376
|
+
}
|
377
|
+
}
|
378
|
+
});
|
379
|
+
};
|
380
|
+
})(jQuery);
|
@@ -0,0 +1,48 @@
|
|
1
|
+
.hwt-container {
|
2
|
+
display: inline-block;
|
3
|
+
position: relative;
|
4
|
+
overflow: hidden !important;
|
5
|
+
-webkit-text-size-adjust: none !important;
|
6
|
+
}
|
7
|
+
|
8
|
+
.hwt-backdrop {
|
9
|
+
position: absolute !important;
|
10
|
+
top: 0 !important;
|
11
|
+
right: -99px !important;
|
12
|
+
bottom: 0 !important;
|
13
|
+
left: 0 !important;
|
14
|
+
padding-right: 99px !important;
|
15
|
+
overflow-x: hidden !important;
|
16
|
+
overflow-y: auto !important;
|
17
|
+
}
|
18
|
+
|
19
|
+
.hwt-highlights {
|
20
|
+
width: auto !important;
|
21
|
+
height: auto !important;
|
22
|
+
border-color: transparent !important;
|
23
|
+
white-space: pre-wrap !important;
|
24
|
+
word-wrap: break-word !important;
|
25
|
+
color: transparent !important;
|
26
|
+
overflow: hidden !important;
|
27
|
+
}
|
28
|
+
|
29
|
+
.hwt-input {
|
30
|
+
display: block !important;
|
31
|
+
position: relative !important;
|
32
|
+
margin: 0;
|
33
|
+
padding: 0;
|
34
|
+
border-radius: 0;
|
35
|
+
font: inherit;
|
36
|
+
overflow-x: hidden !important;
|
37
|
+
overflow-y: auto !important;
|
38
|
+
}
|
39
|
+
|
40
|
+
.hwt-content {
|
41
|
+
border: 1px solid;
|
42
|
+
background: none transparent !important;
|
43
|
+
}
|
44
|
+
|
45
|
+
.hwt-content mark {
|
46
|
+
padding: 0 !important;
|
47
|
+
color: inherit;
|
48
|
+
}
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: highlight-within-textarea-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ukaza Perdana
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-11-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.15'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.15'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
description: jQuery plugin for highlighting bits of text within a textarea.
|
42
|
+
email:
|
43
|
+
- hello@ukazap.space
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- ".gitignore"
|
49
|
+
- Gemfile
|
50
|
+
- README.md
|
51
|
+
- Rakefile
|
52
|
+
- bin/console
|
53
|
+
- bin/setup
|
54
|
+
- highlight-within-textarea-rails.gemspec
|
55
|
+
- lib/highlight/within/textarea/rails.rb
|
56
|
+
- lib/highlight/within/textarea/rails/version.rb
|
57
|
+
- vendor/assets/javascripts/jquery.highlight-within-textarea.js
|
58
|
+
- vendor/assets/stylesheets/jquery.highlight-within-textarea.css
|
59
|
+
homepage: https://github.com/ukazap/highlight-within-textarea-rails
|
60
|
+
licenses: []
|
61
|
+
metadata: {}
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options: []
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
requirements: []
|
77
|
+
rubyforge_project:
|
78
|
+
rubygems_version: 2.6.11
|
79
|
+
signing_key:
|
80
|
+
specification_version: 4
|
81
|
+
summary: Gemified version of highlight-within-textarea
|
82
|
+
test_files: []
|