deckar01-task_list-2.3.2/ 0000755 0001750 0001750 00000000000 14054160365 014435 5 ustar nilesh nilesh deckar01-task_list-2.3.2/README.md 0000644 0001750 0001750 00000013204 14054160365 015714 0 ustar nilesh nilesh # Task Lists
[][travis]
[travis]: https://travis-ci.org/deckar01/task_list
This is a community fork of GitHub's archived [`task_list`][task_list] gem.
[task_list]: https://github.com/github-archive/task_list
```md
- [x] Get
- [x] More
- [ ] Done
```
> - [x] Get
> - [x] More
> - [ ] Done
## Components
The Task List feature is made of several different components:
* Markdown Ruby Filter
* Summary Ruby Model: summarizes task list items
* JavaScript: frontend task list update behavior
* CSS: styles Markdown task list items
## Usage & Integration
The backend components are designed for rendering the Task List item checkboxes, and the frontend components handle updating the Markdown source (embedded in the markup).
### Backend: Markdown pipeline filter
Rendering Task List item checkboxes from source Markdown depends on the `TaskList::Filter`, designed to integrate with the [`html-pipeline`](https://github.com/jch/html-pipeline) gem. For example:
``` ruby
require 'html/pipeline'
require 'task_list/filter'
pipeline = HTML::Pipeline.new [
HTML::Pipeline::MarkdownFilter,
TaskList::Filter
]
pipeline.call "- [ ] task list item"
```
### Frontend: Markdown Updates
Task List updates on the frontend require specific HTML markup structure, and must be enabled with JavaScript.
Rendered HTML (the `
` element below) should be contained in a `js-task-list-container` container element and include a sibling `textarea.js-task-list-field` element that is updated when checkboxes are changed.
``` markdown
- [ ] text
```
``` html
text
```
Enable Task List updates with:
``` javascript
// Vanilla JS API
var container = document.querySelector('.js-task-list-container')
new TaskList(container)
// or jQuery API
$('.js-task-list-container').taskList('enable')
```
NOTE: Updates are not persisted to the server automatically. Persistence is the responsibility of the integrating application, accomplished by hooking into the `tasklist:change` JavaScript event. For instance, we use AJAX to submit a hidden form on update.
Read through the documented behaviors and samples [in the source][frontend_behaviors] for more detail, including documented events.
[frontend_behaviors]: https://github.com/deckar01/task_list/blob/master/app/assets/javascripts/task_list.coffee
## Installation
Task Lists are packaged as both a RubyGem with both backend and frontend behavior, and a Bower package with just the frontend behavior.
### Backend: RubyGem
For the backend Ruby components, add this line to your application's Gemfile:
gem 'deckar01-task_list'
And then execute:
$ bundle
### Frontend: NPM / Yarn
For the frontend components, add `deckar01-task_list` to your npm dependencies config.
This is the preferred method for including the frontend assets in your application.
### Frontend: Bower
For the frontend components, add `deckar01-task_list` to your Bower dependencies config.
### Frontend: Rails 3+ Railtie method
``` ruby
# config/application.rb
require 'task_list/railtie'
```
### Frontend: Rails 2.3 Manual method
Wherever you have your Sprockets setup:
``` ruby
Sprockets::Environment.new(Rails.root) do |env|
# Load TaskList assets
require 'task_list/railtie'
TaskList.asset_paths.each do |path|
env.append_path path
end
end
```
If you're not using Sprockets, you're on your own but it's pretty straight
forward. `deckar01-task_list/railtie` defines `TaskList.asset_paths` which you can use
to manage building your asset bundles.
### Dependencies
- Ruby >= 2.1.0
At a high level, the Ruby components integrate with the [`html-pipeline`](https://github.com/jch/html-pipeline) library. The frontend components are vanilla JavaScript and include a thin jQuery wrapper that supports the original plugin interface. The frontend components are written in CoffeeScript and need to be preprocessed for production use.
[A polyfill for custom events](https://github.com/krambuhl/custom-event-polyfill) must be included to support IE10 and below.
### Known issues
The markdown parser used on the front end produces false positives when looking for checkboxes
in some complex nesting situations. To combat this issue, you can enable the `sourcepos` option
in your markdown parser. This will avoid parsing the markdown on the front end, because the line
numbers will be provided as attributes on the HTML elements. `task_list` checks for the source
position attribute and falls back to manually parsing the markown when needed.
### Upgrading
#### 1.x to 2.x
The event interface no longer passes data directly to the callbacks arguments
list. Instead the CustomEvent API is used, which adds data to the
`event.detail` object.
```js
// 1.x interface
el.on('tasklist:changed', function(event, index, checked) {
console.log(index, checked)
})
// 2.x interface
el.on('tasklist:changed', function(event) {
console.log(event.detail.index, event.detail.checked)
})
```
## Testing and Development
JavaScript unit tests can be run with `script/testsuite`.
Ruby unit tests can be run with `rake test`.
Functional tests are useful for manual testing in the browser. To run, install
the necessary components with `script/bootstrap` then run the server:
```
rackup -p 4011
```
Navigate to http://localhost:4011/test/functional/test_task_lists_behavior.html
## Community Integration
- [Waffle.io](http://waffle.io)
- [HuBoard](https://huboard.com/)
deckar01-task_list-2.3.2/app/ 0000755 0001750 0001750 00000000000 14054160365 015215 5 ustar nilesh nilesh deckar01-task_list-2.3.2/app/assets/ 0000755 0001750 0001750 00000000000 14054160365 016517 5 ustar nilesh nilesh deckar01-task_list-2.3.2/app/assets/javascripts/ 0000755 0001750 0001750 00000000000 14054160365 021050 5 ustar nilesh nilesh deckar01-task_list-2.3.2/app/assets/javascripts/task_list.coffee 0000644 0001750 0001750 00000021034 14054160365 024216 0 ustar nilesh nilesh # TaskList Behavior
#
#= provides TaskList
#
# Enables Task List update behavior.
#
# ### Example Markup
#
#
#
#
#
# text
#
#
#
#
#
# ### Specification
#
# TaskLists MUST be contained in a `(div).js-task-list-container`.
#
# TaskList Items SHOULD be an a list (`UL`/`OL`) element.
#
# Task list items MUST match `(input).task-list-item-checkbox` and MUST be
# `disabled` by default.
#
# TaskLists MUST have a `(textarea).js-task-list-field` form element whose
# `value` attribute is the source (Markdown) to be udpated. The source MUST
# follow the syntax guidelines.
#
# TaskList updates trigger `tasklist:change` events. If the change is
# successful, `tasklist:changed` is fired. The change can be canceled.
#
# ### Methods
#
# `.taskList('enable')` or `.taskList()`
#
# Enables TaskList updates for the container.
#
# `.taskList('disable')`
#
# Disables TaskList updates for the container.
#
## ### Events
#
# `tasklist:enabled`
#
# Fired when the TaskList is enabled.
#
# * **Synchronicity** Sync
# * **Bubbles** Yes
# * **Cancelable** No
# * **Target** `.js-task-list-container`
#
# `tasklist:disabled`
#
# Fired when the TaskList is disabled.
#
# * **Synchronicity** Sync
# * **Bubbles** Yes
# * **Cancelable** No
# * **Target** `.js-task-list-container`
#
# `tasklist:change`
#
# Fired before the TaskList item change takes affect.
#
# * **Synchronicity** Sync
# * **Bubbles** Yes
# * **Cancelable** Yes
# * **Target** `.js-task-list-field`
#
# `tasklist:changed`
#
# Fired once the TaskList item change has taken affect.
#
# * **Synchronicity** Sync
# * **Bubbles** Yes
# * **Cancelable** No
# * **Target** `.js-task-list-field`
#
# ### NOTE
#
# Task list checkboxes are rendered as disabled by default because rendered
# user content is cached without regard for the viewer.
NodeArray = (nodeList) -> Array.prototype.slice.apply(nodeList)
closest = (el, className) ->
while el && !el.classList.contains className
el = el.parentNode
el
createEvent = (eventName, detail) ->
if typeof Event == 'function'
event = new Event eventName, {bubbles: true, cancelable: true}
event.detail = detail
else
event = document.createEvent 'CustomEvent'
event.initCustomEvent eventName, true, true, detail
event
class TaskList
constructor: (@el) ->
@container = closest @el, 'js-task-list-container'
@field = @container.querySelector '.js-task-list-field'
# When the task list item checkbox is updated, submit the change
@container.addEventListener 'change', (event) =>
if event.target.classList.contains 'task-list-item-checkbox'
@updateTaskList(event.target)
@.enable()
enable: ->
if @container.querySelectorAll('.js-task-list-field').length > 0
NodeArray(@container.querySelectorAll('.task-list-item')).
forEach (item) ->
item.classList.add('enabled')
NodeArray(@container.querySelectorAll('.task-list-item-checkbox')).
forEach (checkbox) ->
checkbox.disabled = false
@container.classList.add 'is-task-list-enabled'
event = createEvent 'tasklist:enabled'
@container.dispatchEvent event
disable: ->
NodeArray(@container.querySelectorAll('.task-list-item')).
forEach (item) ->
item.classList.remove('enabled')
NodeArray(@container.querySelectorAll('.task-list-item-checkbox')).
forEach (checkbox) ->
checkbox.disabled = true
@container.classList.remove('is-task-list-enabled')
event = createEvent 'tasklist:disabled'
@container.dispatchEvent event
# Updates the field value to reflect the state of item.
# Triggers the `tasklist:change` event before the value has changed, and fires
# a `tasklist:changed` event once the value has changed.
updateTaskList: (item) ->
checkboxes = @container.querySelectorAll('.task-list-item-checkbox')
index = 1 + NodeArray(checkboxes).indexOf item
changeEvent = createEvent 'tasklist:change',
index: index
checked: item.checked
@field.dispatchEvent changeEvent
unless changeEvent.defaultPrevented
{ result, lineNumber, lineSource } =
TaskList.updateSource(@field.value, index, item.checked, item)
@field.value = result
changeEvent = createEvent 'change'
@field.dispatchEvent changeEvent
changedEvent = createEvent 'tasklist:changed', {
index: index
checked: item.checked
lineNumber: lineNumber
lineSource: lineSource
}
@field.dispatchEvent changedEvent
# Static interface
@incomplete: "[ ]"
@complete: "[x]"
# Escapes the String for regular expression matching.
@escapePattern: (str) ->
str.
replace(/([\[\]])/g, "\\$1"). # escape square brackets
replace(/\s/, "\\s"). # match all white space
replace("x", "[xX]") # match all cases
@incompletePattern: ///
#{@escapePattern(@incomplete)}
///
@completePattern: ///
#{@escapePattern(@complete)}
///
# Pattern used to identify all task list items.
# Useful when you need iterate over all items.
@itemPattern: ///
^
(?: # prefix, consisting of
\s* # optional leading whitespace
(?:>\s*)* # zero or more blockquotes
(?:[-+*]|(?:\d+\.)) # list item indicator
)
\s* # optional whitespace prefix
( # checkbox
#{@escapePattern(@complete)}|
#{@escapePattern(@incomplete)}
)
\s # is followed by whitespace
///
# Used to skip checkbox markup inside of code fences.
# http://rubular.com/r/TfCDNsy8x4
@startFencesPattern: /^`{3}.*$/
@endFencesPattern: /^`{3}\s*$/
# Used to filter out potential mismatches (items not in lists).
# http://rubular.com/r/OInl6CiePy
@itemsInParasPattern: ///
^
(
#{@escapePattern(@complete)}|
#{@escapePattern(@incomplete)}
)
.+
$
///g
# Given the source text, updates the appropriate task list item to match the
# given checked value.
#
# Returns the updated String text.
@updateSource: (source, itemIndex, checked, item) ->
if item.parentElement.hasAttribute('data-sourcepos')
@_updateSourcePosition(source, item, checked)
else
@_updateSourceRegex(source, itemIndex, checked)
# If we have sourcepos information, that tells us which line the task
# is on without the need for parsing
@_updateSourcePosition: (source, item, checked) ->
result = source.split("\n")
sourcepos = item.parentElement.getAttribute('data-sourcepos')
lineNumber = parseInt(sourcepos.split(":")[0])
lineSource = result[lineNumber - 1]
line =
if checked
lineSource.replace(@incompletePattern, @complete)
else
lineSource.replace(@completePattern, @incomplete)
result[lineNumber - 1] = line
return {
result: result.join("\n")
lineNumber: lineNumber
lineSource: lineSource
}
@_updateSourceRegex: (source, itemIndex, checked) ->
split_source = source.split("\n")
lineNumber
lineSource
clean = source.replace(/\r/g, '').
replace(@itemsInParasPattern, '').
split("\n")
index = 0
inCodeBlock = false
result = for line, i in split_source
if inCodeBlock
# Lines inside of a code block are ignored.
if line.match(@endFencesPattern)
# Stop ignoring lines once the code block is closed.
inCodeBlock = false
else if line.match(@startFencesPattern)
# Start ignoring lines inside a code block.
inCodeBlock = true
else if line in clean && line.trim().match(@itemPattern)
index += 1
if index == itemIndex
lineNumber = i + 1
lineSource = line
line =
if checked
line.replace(@incompletePattern, @complete)
else
line.replace(@completePattern, @incomplete)
line
return {
result: result.join("\n")
lineNumber: lineNumber
lineSource: lineSource
}
if typeof jQuery != 'undefined'
jQuery.fn.taskList = (method) ->
this.each (index, el) ->
taskList = jQuery(el).data('task-list')
if !taskList
taskList = new TaskList el
jQuery(el).data 'task-list', taskList
if !method || method == 'enable'
return
taskList[method || 'enable']()
module.exports = TaskList
deckar01-task_list-2.3.2/app/assets/stylesheets/ 0000755 0001750 0001750 00000000000 14054160365 021073 5 ustar nilesh nilesh deckar01-task_list-2.3.2/app/assets/stylesheets/task_list.scss 0000644 0001750 0001750 00000000604 14054160365 023765 0 ustar nilesh nilesh // Requires use of `.markdown-body` to override default markdown list styles
.markdown-body .task-list {
list-style-type: none;
padding-left: 10px;
}
.task-list-item {
padding-left: 20px;
}
.task-list-item label {
font-weight: normal;
}
.task-list-item + .task-list-item {
margin-top: 3px;
}
.task-list-item-checkbox {
float: left;
margin-left: -20px;
margin-top: 4px;
}
deckar01-task_list-2.3.2/Rakefile 0000644 0001750 0001750 00000000276 14054160365 016107 0 ustar nilesh nilesh require "bundler/gem_tasks"
require "rake/testtask"
task :default => :test
Rake::TestTask.new do |t|
t.libs << "lib"
t.test_files = FileList['test/**/*_test.rb']
t.verbose = true
end
deckar01-task_list-2.3.2/Gemfile 0000644 0001750 0001750 00000000046 14054160365 015730 0 ustar nilesh nilesh source "https://rubygems.org"
gemspec
deckar01-task_list-2.3.2/config.ru 0000644 0001750 0001750 00000001122 14054160365 016246 0 ustar nilesh nilesh # Rack environment for testing purposes
require 'coffee-script'
require 'json'
require 'sprockets'
Root = File.expand_path("..", __FILE__)
Assets = Sprockets::Environment.new(Root) do |env|
env.append_path "bower_components"
env.append_path "app/assets/javascripts"
env.append_path "app/assets/stylesheets"
env.append_path "test"
end
map "/assets" do
run Assets
end
map "/update" do
run lambda { |env|
sleep 0.5
req = Rack::Request.new(env)
[200, {'Content-Type' => 'application/json'}, [req.params.to_json]]
}
end
map "/" do
run Rack::Directory.new(Root)
end
deckar01-task_list-2.3.2/.gitignore 0000644 0001750 0001750 00000000312 14054160365 016421 0 ustar nilesh nilesh *.gem
*.rbc
.bundle
.config
.yardoc
Gemfile.lock
InstalledFiles
_yardoc
bin/
coverage
doc/
lib/bundler/man
pkg
rdoc
spec/reports
test/tmp
test/version_tmp
tmp
bower_components
node_modules
vendor/gems/
deckar01-task_list-2.3.2/webpack.config.js 0000644 0001750 0001750 00000000520 14054160365 017650 0 ustar nilesh nilesh module.exports = {
entry: './app/assets/javascripts/task_list.coffee',
output: {
filename: 'task_list.js',
libraryTarget: 'umd',
library: 'TaskList',
},
module: {
rules: [
{
test: /\.coffee$/,
loader: 'coffee-loader'
}
]
},
resolve: {
extensions: ['.coffee', '.js']
}
}
deckar01-task_list-2.3.2/package.json 0000644 0001750 0001750 00000002575 14054160365 016734 0 ustar nilesh nilesh {
"name": "deckar01-task_list",
"version": "2.3.2",
"description": "Markdown TaskList components",
"main": "dist/task_list.js",
"directories": {
"test": "test"
},
"files": [
"dist"
],
"scripts": {
"test": "script/cibuild",
"qunit": "karma start test/unit/config.js",
"lint": "coffeelint app/assets/javascripts/task_list.coffee",
"build:css": "node-sass -o dist/ app/assets/stylesheets/task_list.scss",
"build:js": "webpack",
"build": "npm run build:css && npm run build:js",
"prepublish": "npm run build"
},
"repository": {
"type": "git",
"url": "git+https://github.com/deckar01/task_list.git"
},
"keywords": [
"task",
"list",
"markdown",
"ruby",
"check"
],
"author": "Jared Deckard ",
"license": "MIT",
"bugs": {
"url": "https://github.com/deckar01/task_list/issues"
},
"homepage": "https://github.com/deckar01/task_list#readme",
"devDependencies": {
"bower": "^1.8.0",
"coffee-loader": "^0.9.0",
"coffeelint": "^1.16.0",
"coffeescript": "^2.4.1",
"jquery": "^2.2.4",
"karma": "^4.4.1",
"karma-chrome-launcher": "^3.1.0",
"karma-qunit": "^4.0.0",
"karma-webpack": "^4.0.2",
"node-sass": "^4.5.2",
"phantomjs": "^1.9.19",
"qunit": "^2.9.3",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10"
},
"dependencies": {}
}
deckar01-task_list-2.3.2/dist/ 0000755 0001750 0001750 00000000000 14054160365 015400 5 ustar nilesh nilesh deckar01-task_list-2.3.2/dist/.npmignore 0000644 0001750 0001750 00000000000 14054160365 017365 0 ustar nilesh nilesh deckar01-task_list-2.3.2/dist/.gitignore 0000644 0001750 0001750 00000000013 14054160365 017362 0 ustar nilesh nilesh *.css
*.js
deckar01-task_list-2.3.2/LICENSE 0000644 0001750 0001750 00000002130 14054160365 015436 0 ustar nilesh nilesh The MIT License (MIT)
Copyright (c) 2016 Jared Deckard
Copyright (c) 2014 GitHub, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
deckar01-task_list-2.3.2/lib/ 0000755 0001750 0001750 00000000000 14054160365 015203 5 ustar nilesh nilesh deckar01-task_list-2.3.2/lib/task_list/ 0000755 0001750 0001750 00000000000 14054160365 017200 5 ustar nilesh nilesh deckar01-task_list-2.3.2/lib/task_list/filter.rb 0000644 0001750 0001750 00000010735 14054160365 021020 0 ustar nilesh nilesh # encoding: utf-8
require 'html/pipeline'
require 'task_list'
class TaskList
# Returns a `Nokogiri::DocumentFragment` object.
def self.filter(*args)
Filter.call(*args)
end
# TaskList filter replaces task list item markers (`[ ]` and `[x]`) with
# checkboxes, marked up with metadata and behavior.
#
# This should be run on the HTML generated by the Markdown filter, after the
# SanitizationFilter.
#
# Syntax
# ------
#
# Task list items must be in a list format:
#
# ```
# - [ ] incomplete
# - [x] complete
# ```
#
# Results
# -------
#
# The following keys are written to the result hash:
# :task_list_items - An array of TaskList::Item objects.
class Filter < HTML::Pipeline::Filter
Incomplete = "[ ]".freeze
Complete = "[x]".freeze
IncompletePattern = /\[[[:space:]]\]/.freeze # matches all whitespace
CompletePattern = /\[[xX]\]/.freeze # matches any capitalization
# Pattern used to identify all task list items.
# Useful when you need iterate over all items.
ItemPattern = /
^
(?:\s*[-+*]|(?:\d+\.))? # optional list prefix
\s* # optional whitespace prefix
( # checkbox
#{CompletePattern}|
#{IncompletePattern}
)
(?=\s) # followed by whitespace
/x
ListItemSelector = ".//li[task_list_item(.)]".freeze
class XPathSelectorFunction
def self.task_list_item(nodes)
nodes.select { |node| node.text =~ ItemPattern }
end
end
# Selects first P tag of an LI, if present
ItemParaSelector = "./p[1]".freeze
# List of `TaskList::Item` objects that were recognized in the document.
# This is available in the result hash as `:task_list_items`.
#
# Returns an Array of TaskList::Item objects.
def task_list_items
result[:task_list_items] ||= []
end
# Renders the item checkbox in a span including the item state.
#
# Returns an HTML-safe String.
def render_item_checkbox(item)
%()
end
# Public: Marks up the task list item checkbox with metadata and behavior.
#
# NOTE: produces a string that, when assigned to a Node's `inner_html`,
# will corrupt the string contents' encodings. Instead, we parse the
# rendered HTML and explicitly set its encoding so that assignment will
# not change the encodings.
#
# See [this pull](https://github.com/github/github/pull/8505) for details.
#
# Returns the marked up task list item Nokogiri::XML::NodeSet object.
def render_task_list_item(item)
Nokogiri::HTML.fragment \
item.source.sub(ItemPattern, render_item_checkbox(item)), 'utf-8'
end
# Public: Select all task list items within `container`.
#
# Returns an Array of Nokogiri::XML::Element objects for ordered and
# unordered lists. The container can either be the entire document (as
# returned by `#doc`) or an Element object.
def list_items(container)
container.xpath(ListItemSelector, XPathSelectorFunction)
end
# Filters the source for task list items.
#
# Each item is wrapped in HTML to identify, style, and layer
# useful behavior on top of.
#
# Modifications apply to the parsed document directly.
#
# Returns nothing.
def filter!
list_items(doc).reverse.each do |li|
next if list_items(li.parent).empty?
add_css_class(li.parent, 'task-list')
outer, inner =
if p = li.xpath(ItemParaSelector)[0]
[p, p.inner_html]
else
[li, li.inner_html]
end
if match = (inner.chomp =~ ItemPattern && $1)
item = TaskList::Item.new(match, inner)
# prepend because we're iterating in reverse
task_list_items.unshift item
add_css_class(li, 'task-list-item')
outer.inner_html = render_task_list_item(item)
end
end
end
def call
filter!
doc
end
# Private: adds a CSS class name to a node, respecting existing class
# names.
def add_css_class(node, *new_class_names)
class_names = (node['class'] || '').split(' ')
return if new_class_names.all? { |klass| class_names.include?(klass) }
class_names.concat(new_class_names)
node['class'] = class_names.uniq.join(' ')
end
end
end
deckar01-task_list-2.3.2/lib/task_list/version.rb 0000644 0001750 0001750 00000000063 14054160365 021211 0 ustar nilesh nilesh class TaskList
VERSION = [2, 3, 2].join('.')
end
deckar01-task_list-2.3.2/lib/task_list/railtie.rb 0000644 0001750 0001750 00000000657 14054160365 021166 0 ustar nilesh nilesh class TaskList
def self.root_path
@root_path ||= Pathname.new(File.expand_path("../../../", __FILE__))
end
def self.asset_paths
@paths ||= Dir[root_path.join("app/assets/*")]
end
if defined? ::Rails::Railtie
class Railtie < ::Rails::Railtie
initializer "task_list" do |app|
TaskList.asset_paths.each do |path|
app.config.assets.paths << path
end
end
end
end
end
deckar01-task_list-2.3.2/lib/task_list/summary.rb 0000644 0001750 0001750 00000001347 14054160365 021227 0 ustar nilesh nilesh # encoding: utf-8
require 'html/pipeline'
require 'task_list'
class TaskList
# Provides a summary of provided TaskList `items`.
#
# `items` is an Array of TaskList::Item objects.
class Summary < Struct.new(:items)
# Public: returns true if there are any TaskList::Item objects.
def items?
item_count > 0
end
# Public: returns the number of TaskList::Item objects.
def item_count
items.size
end
# Public: returns the number of complete TaskList::Item objects.
def complete_count
items.select{ |i| i.complete? }.size
end
# Public: returns the number of incomplete TaskList::Item objects.
def incomplete_count
items.select{ |i| !i.complete? }.size
end
end
end
deckar01-task_list-2.3.2/lib/task_list.rb 0000644 0001750 0001750 00000001717 14054160365 017533 0 ustar nilesh nilesh require 'task_list/summary'
require 'task_list/version'
# encoding: utf-8
class TaskList
attr_reader :record
# `record` is the resource with the Markdown source text with task list items
# following this syntax:
#
# - [ ] a task list item
# - [ ] another item
# - [x] a completed item
#
def initialize(record)
@record = record
end
# Public: return the TaskList::Summary for this task list.
#
# Returns a TaskList::Summary.
def summary
@summary ||= TaskList::Summary.new(record.task_list_items)
end
class Item < Struct.new(:checkbox_text, :source)
Complete = /\[[xX]\]/.freeze # see TaskList::Filter
# Public: Check if a task list is complete.
#
# Examples
#
# Item.new("- [x]").complete?
# # => true
#
# Item.new("- [ ]").complete?
# # => false
#
# Returns true for checked list, false otherwise
def complete?
!!(checkbox_text =~ Complete)
end
end
end
deckar01-task_list-2.3.2/script/ 0000755 0001750 0001750 00000000000 14054160365 015741 5 ustar nilesh nilesh deckar01-task_list-2.3.2/script/cibuild 0000755 0001750 0001750 00000000152 14054160365 017300 0 ustar nilesh nilesh #!/bin/sh -e
# Usage: script/cibuild
# CI build script.
npm run lint
npm run qunit
bundle exec rake test
deckar01-task_list-2.3.2/script/bootstrap 0000755 0001750 0001750 00000000271 14054160365 017704 0 ustar nilesh nilesh #!/bin/sh
set -e 0
if ! bundle check 1>/dev/null 2>&1; then
bundle install --no-color --binstubs --path vendor/gems
fi
npm install
./node_modules/bower/bin/bower install --no-color
deckar01-task_list-2.3.2/bower.json 0000644 0001750 0001750 00000001051 14054160365 016443 0 ustar nilesh nilesh {
"name": "deckar01-task_list",
"version": "2.0.1",
"description": "Markdown TaskList components",
"homepage": "https://github.com/deckar01/task_list",
"devDependencies": {
"jquery": ">= 1.9.1 <3",
"qunit": "^1.0.0",
"rails-behaviors": "^0.8.4"
},
"main": [
"app/assets/javascripts/task_list.coffee",
"app/assets/stylesheets/task_list.scss"
],
"ignore": [
".gitignore",
".travis.yml",
"*.gemspec",
"*.md",
"config.ru",
"Gemfile",
"lib/",
"Rakefile",
"script/",
"test/"
]
}
deckar01-task_list-2.3.2/task_list.gemspec 0000644 0001750 0001750 00000002506 14054160365 020002 0 ustar nilesh nilesh # -*- encoding: utf-8 -*-
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'task_list/version'
Gem::Specification.new do |gem|
gem.name = "deckar01-task_list"
gem.version = TaskList::VERSION
gem.authors = ["Jared Deckard", "Matt Todd"]
gem.email = ["jared.deckard@gmail.com"]
gem.description = %q{Markdown TaskList components}
gem.summary = %q{Markdown TaskList components}
gem.files = `git ls-files`.split($/)
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
gem.require_paths = ["lib"]
gem.required_ruby_version = ">= 2.0.0"
gem.add_dependency "activesupport", "~> 4.0" if RUBY_VERSION < '2.2.2'
gem.add_dependency "nokogiri", "~> 1.6.0" if RUBY_VERSION < '2.1.0'
gem.add_dependency "html-pipeline"
gem.add_development_dependency "commonmarker"
gem.add_development_dependency "rake"
gem.add_development_dependency "coffee-script"
gem.add_development_dependency "json"
gem.add_development_dependency "rack", "~> 1.0" if RUBY_VERSION < '2.2.2'
gem.add_development_dependency "rack" if RUBY_VERSION >= '2.2.2'
gem.add_development_dependency "sprockets"
gem.add_development_dependency "minitest", "~> 5.3.2"
end
deckar01-task_list-2.3.2/test/ 0000755 0001750 0001750 00000000000 14054160365 015414 5 ustar nilesh nilesh deckar01-task_list-2.3.2/test/unit/ 0000755 0001750 0001750 00000000000 14054160365 016373 5 ustar nilesh nilesh deckar01-task_list-2.3.2/test/unit/config.js 0000644 0001750 0001750 00000004003 14054160365 020173 0 ustar nilesh nilesh // Karma configuration
// Generated on Tue Nov 12 2019 10:22:49 GMT-0600 (Central Standard Time)
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '../..',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['qunit'],
plugins: [
'karma-qunit',
'karma-webpack',
'karma-chrome-launcher',
],
// list of files / patterns to load in the browser
files: [
'app/assets/javascripts/*.coffee',
'test/unit/*.coffee'
],
// list of files / patterns to exclude
exclude: [
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'**/*.coffee': ['webpack']
},
webpack: {
...require('../../webpack.config.js'),
mode: 'development',
},
webpackMiddleware: {
stats: 'errors-only',
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['ChromeHeadless'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: true,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
})
}
deckar01-task_list-2.3.2/test/unit/test_updates.coffee 0000644 0001750 0001750 00000051723 14054160365 022260 0 ustar nilesh nilesh window.$ = window.jQuery = require('jquery')
window.TaskList = require('../../app/assets/javascripts/task_list')
QUnit.module "TaskList updates",
beforeEach: ->
@container = $ '