Merge remote-tracking branch 'origin/master'

# Conflicts:
#	xml/RELEASE_NOTES.md
#	xml/source/client_info.xml
#	xml/source/snippets/company_info.xml
#	xml/source/snippets/offerte/en/conditions.xml
#	xml/source/snippets/offerte/en/crystal-box.xml
#	xml/source/snippets/offerte/en/disclaimer.xml
#	xml/source/snippets/offerte/en/disclaimer_code-audit.xml
#	xml/source/snippets/offerte/en/examplewaiver.xml
#	xml/source/snippets/offerte/en/grey-box.xml
#	xml/source/snippets/offerte/en/introandscope.xml
#	xml/source/snippets/offerte/en/introandscope_retest.xml
#	xml/source/snippets/offerte/en/methodology_code-audit.xml
#	xml/source/snippets/offerte/en/prerequisites_training.xml
#	xml/source/snippets/offerte/en/projectoverview.xml
#	xml/source/snippets/offerte/en/projectoverview_retest.xml
#	xml/source/snippets/offerte/en/projectoverview_training.xml
#	xml/source/snippets/offerte/en/teamandreporting.xml
#	xml/xslt/auto.xslt
This commit is contained in:
Marcus Bointon
2017-04-13 11:26:29 +02:00
380 changed files with 62926 additions and 607 deletions

View File

@@ -29,7 +29,7 @@ Listo! That's all you need. Now you can build PDF reports using the content.
### Toolchain
To convert the XML content into PDF files the tools the *Apache FOP* library and the *Java* library *Saxon* will be used
It is easiest to install the toolchain using Ansible: check out the role PeterMosmans.docbuilder (https://galaxy.ansible.com/PeterMosmans/docbuilder/)
It is easiest to install the toolchain using Ansible: https://github.com/radicallyopensecurity/docbuilder
To edit (and view) the content you'll need a XML editor - which could be any text editor like *JEdit*, to a full IDE- for editing of course ;). Preferably something that can check XML file validity. To view the resulting PDF files a PDF viewer is necessary.
@@ -47,3 +47,42 @@ See for more detailed information the [tools manual](https://github.com/radicall
### Example documents
Besides the reports and quotations, generic documents can also be created.
Those can be found [here](xml/doc/examples)
## PenText Visual Editor (Beta)
The pentext framework is shipped with an editor that facilitates the redacting of findings and non-findings. As the pentext framework relies heavily on xml to be able to generate documents,
the writer(s) of these documents are faced with an extra challenge. Not only do they have to worry about content, now the structure of the document is also of importance.
In practice this has led to annoying errors like file-inclusion errors and tag mismatch errors.
The editor tries to relieve the writer from the burden of having to maintain proper document structure, so he/she can focus on content only.
An added feature of the editor is that is has built in support for the pentester's library. This means that standard findings from the library
can be easily integrated into the document.
The editor is a meteor application that runs locally. In the future, when more components are added to it, it can be easily extended to a network facing application
so it can be used by multiple collaborators.
To start:
1. Go to the <pentext_root>/editor directory
2. Execute ./start.sh. It will pull in its dependencies, and if all went will run the service on localhost:4000
3. Open a browser and go to localhost:4000
Here you see two tabs, edit findings and edit non-findings. These tabs will let you handle findings and non-findings respectively
The general workflow for these tabs is the same, the difference is that they handle different sections of the document.
In both tabs, two directories can be specified. The [non]findings directory is mandatory. Point this to a clone of the gitrepository of the test you
are working on.
The Library directory is optional and should point to a directory which contains generic [non]findings that could be used.
Click update to update the system.
Now two tabs appear. One represents the directory with the pentest's findings, the other represents the library findings.
All .xml files that are found will appear in the screen. Even the ones that do not necessasily belong to the pentext framework.
When you click on the arrow in the file, an editor opens up and all the fields are copied from the file to the editor fields.
A file is outlined red when the structure of the file does not match the framework's specification. This means that when the file is selected, not all fields can be filled. It is advised to copy+paste from the raw file view (click file) to the fields.
When a file is saved, the correct structure is used and when the directory is updated, the file should show up green and should be handled by the pentext system without hassle.
**Please keep in mind that this Visual Editor is in Beta, and may still contain some bugs. It is NOT necessary to use the Visual Editor to make use of the OWASP PenText framework.**

View File

@@ -34,13 +34,23 @@ The scripts use multiple environment variables, that can be set by the user unde
+ `GITWEB` :: the URL of the gitlab webinterface (defaults to `https://$GITSERVER`)
+ `NAMESPACE` :: the namespace of the user which is used to set up gitlab repositories (defaults to `ros`)
+ `PENTEXTREPO` :: the location of the PenText repository (defaults to `https://github.com/radicallyopensecurity/pentext`)
+ `KB_USER` :: The username of the kanboard account (required when using the kanboard interface)
+ `KB_APIKEY` :: The API key with which the kanboard account can be user (required when using the kanboard interface)
+ `KB_ENDPOINT` :: The URL of the kanboard API
+ `CHECKLIST_TEMPLATE_URL `:: URL of checklist template. This will be displayed when a checklist isn't available in the KBB task decription.
## Prerequisites
The Bash scripts use the python-gitlab command-line interface to talk to the gitlab instance. This interface can be installed using `sudo pip install git+https://github.com/gpocentek/python-gitlab`. Obviously, Python needs to be installed as well.
### python-gitlab
The Bash scripts use the *python-gitlab* command-line interface to talk to the gitlab instance. This interface can be installed using `sudo pip install git+https://github.com/gpocentek/python-gitlab`. Obviously, Python needs to be installed as well.
This command line interface expects a configuration file `.python-gitlab.cfg` for the user under which rosbot is running, which it uses to connect to gitlab. Make sure it contains the correct details so that you can connect to gitlab.
If you want to convert and build documents, the pentext toolchain is necessary. Use the ansible playbook https://galaxy.ansible.com/PeterMosmans/docbuilder/ or install the tools (Java, Saxon and Apache FOP) by hand, see https://github.com/radicallyopensecurity/pentext/blob/master/xml/doc/Tools%20manual.md for more information.
If you want to convert and build documents, the pentext toolchain is necessary. Use the Ansible playbook https://galaxy.ansible.com/PeterMosmans/docbuilder/ or install the tools (Java, Saxon and Apache FOP) by hand, see https://github.com/radicallyopensecurity/pentext/blob/master/xml/doc/Tools%20manual.md for more information.
### Python libraries
Pandoc is necessary in order to automatically convert gitlab issues written in markdown to XML format.
The *pypandoc* library is also necessary: `sudo pip install pypandoc`.
## Test the configuration
Test out whether the configuration is successful by manually executing the Bash script [bash/test_pentext](bash/test_pentext) - this should return an OK.
@@ -121,3 +131,68 @@ Handled by [bash/handler_invoice](bash/handler_invoice)
Usage: `invoice REPO_NAME INVOICE_NO [NAMESPACE [[BRANCH]] [-PARAMETERS]`
### checklist
Handled by [python/kanboard_pm.py](python/kanboard_pm.py)
The "checklist" family of commands are used to manipulate the checklist of a kanboard task.
The following commands have been implemented:
* checklist show Shows the checklist for the column the task is in.
* checklist toggle Toggles a certain item
### checklist show
Handled by [python/kanboard_pm.py](python/kanboard_pm.py)
Shows the checklist for the column the kanboard task is in. It is required that the task's description contains the full checklist.
The script will connect to kanboard, open the Pentesting project and tries to find the kanboard task. It will then pull the description
and look for the checklist associated with the column the task is in.
Usage: `checklist show <kanboard task>`
* <kanboard task> Specifies the title of the kanboard task. This should be an exact match and is mandatory.
### checklist toggle
Handled by [python/kanboard_pm.py](python/kanboard_pm.py)
Pulls the checklist from the kanboard task's description and toggles its items
Usage: `checklist toggle <kanboard task> <index>`
* <kanboard task> Specifies the title of the kanboard task. This should be an exact match and is mandatory.
* <index> Should be an integer or comma separated list of integers as indices to the items. Mandatory.
### column
Handled by [python/kanboard_pm.py](python/kanboard_pm.py)
The "column" family of commands are used to move a kanboard task across the board.
The following commands are implemented:
* column show Shows the column the kanboard task is in
* column next Moves the kanboard task to the next column
* column prev Moves the kanboard task to the previous column
### column show
Handled by [python/kanboard_pm.py](python/kanboard_pm.py)
Shows the column the kanboard task is currently in.
Usage: `column show <kanboard task>`
* <kanboard task> Specifies the title of the kanboard task. This should be an exact match and is mandatory.
### column next
Handled by [python/kanboard_pm.py](python/kanboard_pm.py)
Moves the kanboard task to the next column.
Usage: `column next <kanboard task>`
* <kanboard task> Specifies the title of the kanboard task. This should be an exact match and is mandatory.
### column prev
Handled by [python/kanboard_pm.py](python/kanboard_pm.py)
Moves the kanboard task to the previous column.
Usage: `column prev <kanboard task>`
* <kanboard task> Specifies the title of the kanboard task. This should be an exact match and is mandatory.

View File

@@ -0,0 +1,124 @@
#!/bin/bash
# handler_ratecard - builds PDF ratecards from thin air (using client_info.xml)
#
# This script is part of the PenText framework
# https://pentext.org
#
# Copyright (C) 2016 Radically Open Security
# https://www.radicallyopensecurity.com
#
# Author(s): Peter Mosmans
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
VERSION=0.1
DOCBUILDER=/usr/local/bin/docbuilder.py
TEMPLOC=$(mktemp -d)
# These variables should be set environment-specific
[ -z $GITSERVER ] && GITSERVER=gitlab.local
[ -z $GITWEB ] && GITWEB=https://${GITSERVER}
[ -z $NAMESPACE ] && NAMESPACE=ros
BRANCH=master
TARGET=snippets/ratecard/ratecard
# Read standard 'command line' variables
[[ ! -z $1 ]] && REPO=$1
[[ ! -z $2 ]] && RATECARD=$2
# Reading positional parms is a bit ugly, shifting parms or getopt would be nicer
if [[ ! -z $3 ]]; then
if [[ ! $3 == -* ]]; then
NAMESPACE=$3
else
PARMS=$3
fi
fi
if [[ ! -z $4 ]]; then
if [[ ! $3 == -* ]]; then
BRANCH=$4
else
PARMS="$PARMS $4"
fi
fi
if [[ $# -ge 5 ]]; then
shift 4
PARMS="$PARMS $@"
fi
trap cleanup EXIT QUIT
# Make sure that the temporary files are always removed
cleanup() {
trap '' EXIT INT QUIT
[ -d $TEMPLOC ] && rm -rf $TEMPLOC &>/dev/null
exit
}
# As quote used to be called offerte or offer,
# this function retains backward compatibility - v0.2
backwards_compatible() {
if [[ $TARGET == "quote" ]] && [ ! -f $TARGET.xml ]; then
TARGET="offerte"
fi
}
# Clones repo using global (!) variables - v0.2
clone_repo() {
pushd $TEMPLOC 1>/dev/null
git clone -b $BRANCH --depth=1 -q ssh://git@${GITSERVER}/${NAMESPACE}/${REPO}.git &>/dev/null
if [ ! -d $TEMPLOC/$REPO ]; then
echo "[-] could not clone repo ${NAMESPACE}/${REPO}"
exit 1
else
cd $REPO
fi
}
# Preflight checks using global (!) variables - v0.2
preflight_checks() {
if [ -z $REPO ]; then
echo "Usage: ratecard REPOSITORY [NAMESPACE [BRANCH]] [-v]"
exit
fi
if [ ! -f $DOCBUILDER ]; then
echo "[-] this script needs docbuilder.py ($DOCBUILDER)"
fi
}
build() {
if [ ! -d source ]; then
echo "[-] missing necessary pentext framework files"
exit 1
fi
pushd source &>/dev/null
backwards_compatible
targetpdf=target/ratecard-latest.pdf
$DOCBUILDER -c -i $TARGET.xml -o ../$targetpdf -x ../xslt/generate_ratecard.xsl --fop ../target/ratecard.fo $PARMS
if [[ $? -ne 0 ]]; then
echo "[-] Sorry, failed to generate $targetpdf"
exit 1
fi
popd &>/dev/null
if [ ! -f target/ratecard-latest.pdf ]; then
echo "[-] hmmm... failed to build PDF file (could not find $targetpdf)"
exit 1
fi
}
add_to_repo() {
git add target/ratecard-latest.pdf
git commit -q -m "Ratecard automatically generated using ChatOps" &>/dev/null
git push -q >/dev/null
}
preflight_checks
echo "Ratecard v$VERSION - Congrats, another project from conception to ka-CHING"
clone_repo
build
add_to_repo
echo "[+] listo! Check out $GITWEB/$NAMESPACE/$REPO/raw/$BRANCH/$targetpdf"

View File

@@ -7,7 +7,7 @@ Gitlab bridge for PenText: imports and updates gitlab issues into PenText
This script is part of the PenText framework
https://pentext.org
Copyright (C) 2016 Radically Open Security
Copyright (C) 2016-2017 Radically Open Security
https://www.radicallyopensecurity.com
Author(s): Peter Mosmans
@@ -24,100 +24,162 @@ from __future__ import print_function
from __future__ import unicode_literals
import argparse
import collections
import io
import os
import sys
import textwrap
try:
import gitlab
import jxmlease
import pypandoc
# Path of this script. The validate_report module is on the same path.
sys.path.append(os.path.dirname(__file__))
import validate_report
except ImportError as exception:
print('[-] This script needs python-gitlab, jxmlease and validate_report library',
except (NameError, ImportError) as exception:
print('[-] This script needs python-gitlab, pypandoc and validate_report library',
file=sys.stderr)
print("validate_report is part of the pentext framework", file=sys.stderr)
print("Install python-gitlab with: sudo pip install python-gitlab", file=sys.stderr)
print("Install jxmlease with: sudo pip install jxmlease", file=sys.stderr)
print("", file=sys.stderr)
print("Install pypandoc with: sudo pip install pypandoc\n", file=sys.stderr)
print("Currently missing: " + exception.message, file=sys.stderr)
sys.exit(-1)
def add_finding(issue, options):
class BaseItem(object):
"""
Writes issue as XML finding to file.
Base class for Pentext items
"""
title = validate_report.capitalize(issue.title.strip())
print_status('{0} - {1} - {2}'.format(issue.state, issue.labels,
title), options)
threat_level = 'Moderate'
finding_type = 'TODO'
finding_id = '{0}-{1}'.format(issue.iid, valid_filename(title))
filename = 'findings/{0}.xml'.format(finding_id)
finding = collections.OrderedDict()
finding['title'] = title
finding['description'] = unicode.replace(issue.description,
'\r\n', '\n')
finding['technicaldescription'] = ''
for note in [x for x in issue.notes.list() if not x.system]:
finding['technicaldescription'] += unicode.replace(note.body,
'\r\n', '\n')
finding['impact'] = {}
finding['impact']['p'] = 'TODO'
finding['recommendation'] = {}
finding['recommendation']['ul'] = {}
finding['recommendation']['ul']['li'] = 'TODO'
finding_xml = jxmlease.XMLDictNode(finding, tag='finding',
xml_attrs={'id': finding_id,
'threatLevel': threat_level,
'type': finding_type})
if options['dry_run']:
print_line('[+] {0}'.format(filename))
print(finding_xml.emit_xml())
else:
if os.path.isfile(filename) and not options['overwrite']:
print_line('Finding {0} already exists (use --overwrite to overwrite)'.
format(filename))
else:
if options['y'] or ask_permission('Create file ' + filename):
with open(filename, 'w') as xmlfile:
xmlfile.write(finding_xml.emit_xml().encode('utf-8'))
print_line('[+] Created {0}'.format(filename))
DECLARATION = '<?xml version="1.0" encoding="utf-8"?>\n'
def __init__(self, item_type):
if item_type not in ('finding', 'non-finding'):
raise ValueError('Only finding and non-finding are currently supported')
self.item_type = item_type
self.__path = '{0}s'.format(self.item_type)
self.root_open = '<{0}>\n'.format(self.item_type)
self.root_close = '</{0}>\n'.format(self.item_type)
self.title = ''
self.content = ''
@property
def filename(self):
"""
Filename.
"""
return '{0}/{1}.xml'.format(self.__path, valid_filename(self.identifier))
def __str__(self):
"""
Return a XML version of the class
"""
return self.DECLARATION + self.root_open + self.element('title') + \
self.content + self.root_close
def element(self, attribute):
"""
Return opening and closing attribute tags, including attribute value.
"""
return '<{0}>{1}</{0}>\n'.format(attribute, getattr(self, attribute))
def write_file(self):
"""
Write item as XML to file.
"""
try:
with io.open(self.filename, 'w') as xmlfile:
xmlfile.write(unicode(self))
print_line('[+] Wrote {0}'.format(self.filename))
except IOError:
print_error('Could not write to %s', self.filename)
def add_non_finding(issue, options):
class Finding(BaseItem):
"""
Adds a non-finding.
Encapsulates finding.
"""
title = validate_report.capitalize(issue.title.strip())
print_status('{0} - {1} - {2}'.format(issue.state, issue.labels,
title), options)
non_finding_id = '{0}-{1}'.format(issue.iid, valid_filename(title))
filename = 'non-findings/{0}.xml'.format(non_finding_id)
non_finding = collections.OrderedDict()
non_finding['title'] = title
non_finding['p'] = unicode.replace(issue.description,
'\r\n', '\n')
for note in [x for x in issue.notes.list() if not x.system]:
non_finding['p'] += unicode.replace(note.body,
'\r\n', '\n')
non_finding_xml = jxmlease.XMLDictNode(non_finding, tag='non-finding',
xml_attrs={'id': non_finding_id})
if options['dry_run']:
print_line('[+] {0}'.format(filename))
print(non_finding_xml.emit_xml())
def __init__(self):
BaseItem.__init__(self, 'finding')
self.threat_level = 'Moderate'
self.finding_type = 'TODO'
self.description = '<p>TODO</p>'
self.technicaldescription = '<p>TODO</p>'
self.impact = '<p>TODO</p>'
self.recommendation = '<ul><li>TODO</li></ul>'
def __str__(self):
"""
Return a XML version of the class
"""
self.root_open = '<finding id="{0}" threatLevel="{1}" type="{2}">\n'.format(self.identifier,
self.threat_level,
self.finding_type)
self.content = self.element('description') + \
self.element('technicaldescription') + \
self.element('impact') + \
self.element('recommendation')
return BaseItem.__str__(self)
class NonFinding(BaseItem):
"""
Encapsulates non-finding.
"""
def __init__(self):
BaseItem.__init__(self, 'non-finding')
def from_issue(issue):
"""
Parse gitlab issue and return Finding, NonFinding or None
"""
if 'finding' in [x.lower() for x in issue.labels]:
item = Finding()
item.description = convert_text(issue.description)
for note in [x for x in reversed(issue.notes.list()) if not x.system]:
if len(note.body.splitlines()):
if 'impact' in note.body.split()[0].lower():
item.impact = convert_text(''.join(note.body.splitlines(True)[1:]))
elif 'recommendation' in note.body.split()[0].lower():
item.recommendation = convert_text(''.join(note.body.splitlines(True)[1:]))
else:
item.technicaldescription += u'{0}\n'.format(convert_text(note.body))
elif 'non-finding' in [x.lower() for x in issue.labels]:
item = NonFinding()
for note in [x for x in reversed(issue.notes.list()) if not x.system]:
item.content += convert_text(note.body) + '\n'
else:
if os.path.isfile(filename) and not options['overwrite']:
print_line('Non-finding {0} already exists (use --overwrite to overwrite)'.
format(filename))
else:
if options['y'] or ask_permission('Create file ' + filename):
with open(filename, 'w') as xmlfile:
xmlfile.write(non_finding_xml.emit_xml().encode('utf-8'))
print_line('[+] Created {0}'.format(filename))
return None
item.title = validate_report.capitalize(issue.title.strip())
item.identifier = 'f{0}-{1}'.format(issue.iid, valid_filename(item.title))
return item
def add_item(issue, options):
"""
Convert issue into XML finding and create file.
"""
item = from_issue(issue)
if not item:
return
if os.path.isfile(item.filename) and not options['overwrite']:
print_line('{0} {1} already exists (use --overwrite to overwrite)'.
format(item.item_type, item.filename))
return
if options['dry_run']:
print_line('[+] {0}\n{1}'.format(item.filename, item))
else:
if options['y'] or ask_permission('Create file ' + item.filename):
item.write_file()
def convert_text(text):
"""
Convert (gitlab) markdown to 'XML' (actually HTML5).
"""
return unicode.replace(pypandoc.convert_text(text, 'html5', format='markdown_github'), '\r\n', '\n')
def ask_permission(question):
@@ -128,34 +190,15 @@ def ask_permission(question):
return raw_input().lower() == 'y'
def convert_markdown(text):
"""
Replace markdown monospace with monospace tags
"""
result = text
return result
# print('EXAMINING ' + text + ' END')
# monospace = re.findall("\`\`\`(.*?)\`\`\`", text, re.DOTALL)
# if len(monospace):
# result = {}
# result['monospace'] = ''.join(monospace)
def list_issues(gitserver, options):
"""
Lists all issues for options['issues']
"""
try:
for issue in gitserver.project_issues.list(project_id=options['issues'],
per_page=99):
if issue.state == 'closed' and not options['closed']:
continue
if 'finding' in issue.labels:
add_finding(issue, options)
if 'non-finding' in issue.labels:
add_non_finding(issue, options)
except Exception as exception:
print_error('could not find any issues ({0})'.format(exception), -1)
for issue in gitserver.project_issues.list(project_id=options['issues'],
per_page=999):
if issue.state == 'closed' and not options['closed']:
continue
add_item(issue, options)
def list_projects(gitserver):
@@ -176,7 +219,7 @@ def parse_arguments():
description=textwrap.dedent('''\
gitlab-to-pentext - imports and updates gitlab issues into PenText (XML) format
Copyright (C) 2015-2016 Radically Open Security (Peter Mosmans)
Copyright (C) 2015-2017 Radically Open Security (Peter Mosmans)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -206,11 +249,15 @@ def preflight_checks():
Checks if all tools are there.
Exits with 0 if everything went okilydokily.
"""
gitserver = None
try:
gitserver = gitlab.Gitlab.from_config('remote')
gitserver.auth()
except gitlab.config.GitlabDataError as exception:
print_error('could not connect {0}'.format(exception), -1)
for path in ('findings', 'non-findings'):
if not os.path.isdir(path):
print_error('Path {0} does not exist: Is this a Pentext repository ?'.format(path), -1)
return gitserver
@@ -252,7 +299,7 @@ def valid_filename(filename):
"""
result = ''
for char in filename.strip():
if char in ['*', ':', '/', '.', '\\', ' ', '[', ']', '(', ')', '\'']:
if char in ['*', ':', '/', '.', '\\', ' ', '[', ']', '(', ')', '\'', '\"']:
if len(char) and not result.endswith('-'):
result += '-'
else:

View File

@@ -6,10 +6,10 @@ Cross-checks findings, validates XML files, offerte and report files.
This script is part of the PenText framework
https://pentext.org
Copyright (C) 2015-2016 Radically Open Security
Copyright (C) 2015-2017 Radically Open Security
https://www.radicallyopensecurity.com
Author(s): Peter Mosmans
Author: Peter Mosmans
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -97,7 +97,7 @@ def parse_arguments():
description=textwrap.dedent('''\
validate_report - validates offer letters and reports
Copyright (C) 2015-2016 Radically Open Security (Peter Mosmans)
Copyright (C) 2015-2017 Radically Open Security (Peter Mosmans)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -354,8 +354,8 @@ def validate_type(tree, filename, options, speller):
else:
if attribute == 'threatLevel' and root.attrib[attribute] not in \
('Low', 'Moderate', 'Elevated', 'High', 'Extreme'):
print('[-] threatLevel is not Low, Moderate, High, Elevated or Extreme: {0}'.
format(root.attrib[attribute]))
print('[-] threatLevel is not Low, Moderate, High, Elevated or Extreme: {0} {1}'.
format(filename, root.attrib[attribute]))
result = False
if attribute == 'type' and (options['capitalization'] and not \
is_capitalized(root.attrib[attribute])):
@@ -590,7 +590,7 @@ def main():
else:
logging.warning('Validation failed')
if options['spelling'] and options['learn']:
logging.log(STATUS('Don\'t forget to check the vocabulary file %s', VOCABULARY))
logging.log(STATUS, 'Don\'t forget to check the vocabulary file %s', VOCABULARY)
if __name__ == "__main__":

View File

@@ -192,6 +192,13 @@ module.exports = (robot) ->
cmd = "bash/handler_invoice";
run_cmd cmd, args, (text) -> msg.send text.replace("\n","");
robot.respond /ratecard (.*)/i, id:'chatops.ratecard', (msg) ->
msg.match[0] = msg.match[0].replace(/^[a-z0-9]+$/i);
msg.match.shift();
args = msg.match[0].split(" ");
cmd = "bash/handler_ratecard";
run_cmd cmd, args, (text) -> msg.send text.replace("\n","");
robot.respond /quickscope (.*)/i, id:'chatops.quickscope', (msg) ->
msg.match[0] = msg.match[0].replace(/^[a-z0-9]+$/i);
msg.match.shift();

1
editor/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
.idea

View File

@@ -0,0 +1,15 @@
# This file contains information which helps Meteor properly upgrade your
# app when you run 'meteor update'. You should check it into version control
# with your project.
notices-for-0.9.0
notices-for-0.9.1
0.9.4-platform-file
notices-for-facebook-graph-api-2
1.2.0-standard-minifiers-package
1.2.0-meteor-platform-split
1.2.0-cordova-changes
1.2.0-breaking-changes
1.3.0-split-minifiers-package
1.4.0-remove-old-dev-bundle-link
1.4.1-add-shell-server-package

1
editor/.meteor/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
local

7
editor/.meteor/.id Normal file
View File

@@ -0,0 +1,7 @@
# This file contains a token that is unique to your project.
# Check it into your repository along with the rest of this directory.
# It can be used for purposes such as:
# - ensuring you don't accidentally deploy one app on top of another
# - providing package authors with aggregated statistics
1sqa2bi1ckkmr3l54m0o

27
editor/.meteor/packages Normal file
View File

@@ -0,0 +1,27 @@
# Meteor packages used by this project, one per line.
# Check this file (and the other files in this directory) into your repository.
#
# 'meteor add' and 'meteor remove' will edit this file for you,
# but you can also edit it by hand.
meteor-base@1.0.4 # Packages every Meteor app needs to have
mobile-experience@1.0.4 # Packages for a great mobile UX
mongo@1.1.12 # The database Meteor supports right now
blaze-html-templates@1.0.4 # Compile .html files into Meteor Blaze views
reactive-var@1.0.10 # Reactive variable for tracker
jquery@1.11.9 # Helpful client-side library
tracker@1.1.0 # Meteor's client-side reactive programming library
standard-minifier-css@1.2.0 # CSS minifier run for production mode
standard-minifier-js@1.2.0 # JS minifier run for production mode
es5-shim@4.6.14 # ECMAScript 5 compatibility for older browsers.
ecmascript@0.5.8 # Enable ECMAScript2015+ syntax in app code
insecure@1.0.7 # Allow all DB writes from clients (for prototyping)
session@1.1.6
easy:search
aldeed:simple-schema
aldeed:autoform
aldeed:collection2
shell-server
matb33:collection-hooks

2
editor/.meteor/platforms Normal file
View File

@@ -0,0 +1,2 @@
server
browser

1
editor/.meteor/release Normal file
View File

@@ -0,0 +1 @@
METEOR@1.4.1.1

91
editor/.meteor/versions Normal file
View File

@@ -0,0 +1,91 @@
aldeed:autoform@5.8.1
aldeed:collection2@2.10.0
aldeed:collection2-core@1.2.0
aldeed:schema-deny@1.1.0
aldeed:schema-index@1.1.0
aldeed:simple-schema@1.5.3
allow-deny@1.0.5
autoupdate@1.2.11
babel-compiler@6.9.1
babel-runtime@0.1.11
base64@1.0.9
binary-heap@1.0.9
blaze@2.1.8
blaze-html-templates@1.0.4
blaze-tools@1.0.9
boilerplate-generator@1.0.9
caching-compiler@1.0.6
caching-html-compiler@1.0.6
callback-hook@1.0.9
check@1.2.3
coffeescript@1.0.17
ddp@1.2.5
ddp-client@1.2.9
ddp-common@1.2.6
ddp-server@1.2.10
deps@1.0.12
diff-sequence@1.0.6
easy:search@2.0.9
easysearch:components@2.0.9
easysearch:core@2.0.9
ecmascript@0.5.8
ecmascript-runtime@0.3.14
ejson@1.0.12
es5-shim@4.6.14
fastclick@1.0.12
geojson-utils@1.0.9
hot-code-push@1.0.4
html-tools@1.0.10
htmljs@1.0.10
http@1.1.8
id-map@1.0.8
insecure@1.0.7
jquery@1.11.9
launch-screen@1.0.12
livedata@1.0.18
logging@1.1.15
matb33:collection-hooks@0.8.4
mdg:validation-error@0.2.0
meteor@1.2.17
meteor-base@1.0.4
minifier-css@1.2.14
minifier-js@1.2.14
minimongo@1.0.17
mobile-experience@1.0.4
mobile-status-bar@1.0.12
modules@0.7.6
modules-runtime@0.7.6
momentjs:moment@2.10.6
mongo@1.1.12
mongo-id@1.0.5
npm-mongo@1.5.49
observe-sequence@1.0.12
ordered-dict@1.0.8
peerlibrary:assert@0.2.5
peerlibrary:base-component@0.14.0
peerlibrary:blaze-components@0.16.2
peerlibrary:computed-field@0.3.1
peerlibrary:data-lookup@0.1.0
peerlibrary:reactive-field@0.1.0
promise@0.8.4
raix:eventemitter@0.1.3
random@1.0.10
reactive-dict@1.1.8
reactive-var@1.0.10
reload@1.1.10
retry@1.0.8
routepolicy@1.0.11
session@1.1.6
shell-server@0.2.1
spacebars@1.0.12
spacebars-compiler@1.0.12
standard-minifier-css@1.2.0
standard-minifier-js@1.2.0
templating@1.1.14
templating-tools@1.0.4
tracker@1.1.0
ui@1.0.11
underscore@1.0.9
url@1.0.10
webapp@1.3.11
webapp-hashing@1.0.9

172
editor/client/main.css Normal file
View File

@@ -0,0 +1,172 @@
/* CSS declarations go here */
body {
background: url('ros-logo.gif') no-repeat left 50px top 100px;
font-family:Droid-Sans;
color: #cd7e00;
background-color: rgba(0, 0, 0, 0.75);
}
fieldset {
border-radius: 10px;
border-color: #cd7e00;
}
input,textarea {
background-color:rgba(0, 0, 0, 0);
color: white;
height: 18px;
padding: 5px;
margin: 2px;
border-color: #cd7e00;
border-radius: 10px;
}
input:focus,textarea:focus {
background: black;
}
input:hover,textarea:hover {
background: black;
}
button {
background-color:rgba(0, 0, 0, 0);
color: #cd7e00;
height: 28px;
border-color: #cd7e00;
border-radius: 10px;
}
button:hover {
color: #000000;
background-color: #cd7e00;
}
button.active {
color: #000000;
background-color: #cd7e00;
}
.directory {
width: 600px;
}
.selected {
color: #000000;
background-color: #cd7e00;
}
.box {
border-radius: 10px;
border: 2px solid #cd7e00;
padding: 5px;
margin: 2px;
}
.search_pane input {
width: 96.5%;
margin-bottom: 20px;
}
.search_button {
background-color:rgba(0, 0, 0, 0);
width: 35px;
height: 35px;
}
.search_result {
display: flex;
flex-direction: column;
}
.search_result button {
float: right;
}
.search_result textarea {
box-sizing: border-box;
height: 500px;
}
.selectable:hover {
color: #000000;
background-color: #cd7e00;
}
.top_menu {
height: 40px;
}
.left_pane {
order: 1;
width: 40%;
}
.middle_pane {
order: 2;
flex-grow: 1
}
.right_pane {
order: 3;
flex-grow: 1;
}
.bottom_pane {
display: flex;
}
/* Line 1 */
.form-control
{
/*display: block;*/
}
textarea.form-control {
width: 98%;
height: 300px;
}
input.form-control {
width: 600px;
}
label.control-label {
width: 100px;
clear: both;
float:left;
margin-right:15px;
color: white;
}
.help-block {
color: red;
}
.green {
border-color: green;
color:green;
}
.green button {
border-color: green;
color:green;
}
.red {
border-color: red;
color:red;
}
.red button {
border-color: red;
color:red;
}

228
editor/client/main.html Normal file
View File

@@ -0,0 +1,228 @@
<head>
<title>PenText editor</title>
</head>
<body>
{{>main}}
</body>
<template name="main">
<div class="top_menu box">
<button class="edit_findings_button {{findingButtonActive}}" name="edit_findings">EDIT FINDINGS</button>
<button class="edit_non_findings_button {{nonFindingButtonActive}}" name="edit_non_findings">EDIT NON-FINDINGS</button>
</div>
{{#if editModeIs "findings"}}
<div class="box">{{> findings_settings}}</div>
<div class="bottom_pane">
<fieldset class="left_pane box">
<legend>Findings</legend>
{{> findings_pane}}
</fieldset>
{{#if findingsEditorActive}}
<div class="middle_pane box">{{> findings_editor}}</div>
{{/if}}
</div>
{{/if}}
{{#if editModeIs "non_findings"}}
<div class="box">{{> non_findings_settings}}</div>
<div class="bottom_pane">
<fieldset class="left_pane box">
<legend>Non-Findings</legend>
{{> findings_pane}}
</fieldset>
{{#if nonFindingsEditorActive}}
<div class="middle_pane box">{{> non_findings_editor}}</div>
{{/if}}
</div>
{{/if}}
</template>
<template name="findings_settings">
<form class="update_findings_directory">
<label for="findings_directory">Pentest Findings directory: </label>
<input id="findings_directory"
name="findings_directory"
class="directory"
value="{{findings_directory}}"/>
<button type="submit">UPDATE</button>
</form>
<form class="update_findings_library_directory">
<label for="findings_directory">Findings library directory: </label>
<input id="findings_library_directory"
name="library_findings_directory"
class="directory"
value="{{findings_library_directory}}"/>
<button type="submit">UPDATE</button>
</form>
</template>
<template name="non_findings_settings">
<form class="update_non_findings_directory">
<label for="non_findings_directory">Pentest Non-Findings directory: </label>
<input id="non_findings_directory"
name="non_findings_directory"
class="directory"
value="{{non_findings_directory}}"/>
<button type="submit">UPDATE</button>
</form>
<form class="update_non_findings_library_directory">
<label for="non_findings_library_directory">Non-Findings library directory: </label>
<input id="non_findings_library_directory"
name="non_findings_library_directory"
class="directory"
value="{{non_findings_library_directory}}"/>
<button type="submit">UPDATE</button>
</form>
</template>
<template name="finding">
<div id="{{filename}}" class="search_result selectable box {{bordercolor}}" title="{{tooltip}}">
<div class="search_result_title">
<span>{{{filename}}}</span>
{{#if typeIs "findings"}}
{{> use_finding_button}}
{{/if}}
{{#if typeIs "library_findings"}}
{{> use_library_finding_button }}
{{/if}}
{{#if typeIs "non_findings"}}
{{> use_non_finding_button}}
{{/if}}
{{#if typeIs "library_non_findings"}}
{{> use_library_non_finding_button }}
{{/if}}
</div>
{{#if shouldShowContent}}
<textarea>{{{raw}}}</textarea>
{{/if}}
</div>
</template>
<template name="use_finding_button">
<button title="Use this finding in editor">&#9658;</button>
</template>
<template name="use_library_finding_button">
<button title="Use this library finding to update the fields of a pentests finding in the editor">&#9658;</button>
</template>
<template name="use_non_finding_button">
<button title="Use this non-finding in editor">&#9658;</button>
</template>
<template name="use_library_non_finding_button">
<button title="Use this library non-finding to update the fields of a pentests non-finding in the editor">&#9658;</button>
</template>
<template name="findings_editor">
{{#autoForm collection="Findings" doc=getSelectedFinding type="update" id="findingForm"}}
<!--{{> afQuickField name="filename"}}-->
{{> afQuickField name="id"}}
{{> afQuickField name="threat_level" options="allowed"}}
{{> afQuickField name="type"}}
{{> afQuickField name="title"}}
{{> afQuickField name="description"}}
{{> afQuickField name="technical_description"}}
{{> afQuickField name="impact"}}
{{> afQuickField name="recommendation"}}
<div>
<button type="submit" class="btn btn-primary">UPDATE</button>
</div>
{{/autoForm}}
</template>
<template name="non_findings_editor">
{{#autoForm collection="NonFindings" doc=getSelectedNonFinding type="update" id="nonfindingForm"}}
<!--{{> afQuickField name="filename"}}-->
{{> afQuickField name="id"}}
{{> afQuickField name="title"}}
{{> afQuickField name="description"}}
<div>
<button type="submit" class="btn btn-primary">UPDATE</button>
</div>
{{/autoForm}}
</template>
<template name="findings_pane">
<div class="box">
<button class="pentest {{isPentestTabActive}}">PENTEST</button>
<button class="library {{isLibraryTabActive}}">LIBRARY</button>
</div>
<div>
{{#if isPentestTabActive}}
{{#if editModeIs "findings"}}
{{> findings}}
{{/if}}
{{# if editModeIs "non_findings"}}
{{> non_findings}}
{{/if}}
{{/if}}
{{#if isLibraryTabActive}}
{{# if editModeIs "findings"}}
{{> library_findings}}
{{/if}}
{{# if editModeIs "non_findings"}}
{{> library_non_findings }}
{{/if}}
{{/if}}
</div>
</template>
<template name="findings">
<div class="search_pane">
{{> EasySearch.Input attributes=properties index=FindingsIndex timeout="200" count=10000}}
{{#EasySearch.Each index=FindingsIndex}}
{{> finding}}
{{/EasySearch.Each}}
{{#EasySearch.IfNoResults index=FindingsIndex}}
<div class="no-results">No results found!</div>
{{/EasySearch.IfNoResults}}
</div>
</template>
<template name="library_findings">
<div class="search_pane">
{{> EasySearch.Input attributes=properties index=LibraryFindingsIndex timeout="200" count=10000}}
{{#EasySearch.Each index=LibraryFindingsIndex}}
{{> finding}}
{{/EasySearch.Each}}
{{#EasySearch.IfNoResults index=LibraryFindingsIndex}}
<div class="no-results">No results found!</div>
{{/EasySearch.IfNoResults}}
</div>
</template>
<template name="non_findings">
<div class="search_pane">
{{> EasySearch.Input attributes=properties index=NonFindingsIndex timeout="200" count=10000}}
{{#EasySearch.Each index=NonFindingsIndex}}
{{> finding}}
{{/EasySearch.Each}}
{{#EasySearch.IfNoResults index=NonFindingsIndex}}
<div class="no-results">No results found!</div>
{{/EasySearch.IfNoResults}}
</div>
</template>
<template name="library_non_findings">
<div class="search_pane">
{{> EasySearch.Input attributes=properties index=LibraryNonFindingsIndex timeout="200" count=10000}}
{{#EasySearch.Each index=LibraryNonFindingsIndex}}
{{> finding}}
{{/EasySearch.Each}}
{{#EasySearch.IfNoResults index=LibraryNonFindingsIndex}}
<div class="no-results">No results found!</div>
{{/EasySearch.IfNoResults}}
</div>
</template>

414
editor/client/main.js Normal file
View File

@@ -0,0 +1,414 @@
import { Template } from 'meteor/templating';
import { Session } from 'meteor/session';
import { ReactiveVar } from 'meteor/reactive-var';
import { FindingsIndex } from '../imports/api/findings.js'
import { NonFindingsIndex } from '../imports/api/nonfindings';
import { LibraryFindingsIndex } from '../imports/api/library_findings.js'
import { LibraryNonFindingsIndex } from '../imports/api/library_non_findings.js'
import Findings from '../imports/api/findings';
import NonFindings from '../imports/api/nonfindings';
import { Settings } from '../imports/api/settings.js';
import './main.html';
Meteor.subscribe("snippets");
Meteor.subscribe("oneReport");
Meteor.subscribe("settings");
Meteor.subscribe("findings");
Meteor.subscribe("library_findings");
Meteor.subscribe("non_findings");
Meteor.subscribe("library_non_findings");
Findings.attachSchema(new SimpleSchema({
// filename: {
// type: String,
// label: "Filename",
// min: 1,
// max: 200
// },
id: {
type: String,
label: "ID",
min: 1,
max: 200,
},
threat_level: {
type: String,
allowedValues: [
"Low",
"Moderate",
"Elevated",
"High",
"Extreme"
],
label: "Threat level",
},
type: {
type: String,
label: "Type",
min: 1,
max: 200,
},
title: {
type: String,
label: "Title",
min: 1,
max: 200,
},
description: {
type: String,
label: "Description",
min: 1,
autoform: {
rows: 5
},
},
technical_description: {
type: String,
label: "Technical Description",
min: 1,
autoform: {
rows: 5
},
},
impact: {
type: String,
min: 1,
label: "Impact",
autoform: {
rows: 5
},
},
recommendation: {
type: String,
min: 1,
label: "Recommendation",
autoform: {
rows: 5
},
}
}));
NonFindings.attachSchema({
// filename: {
// type: String,
// label: "Filename",
// min: 1,
// max: 200
// },
id: {
type: String,
label: "ID",
min: 1,
max: 200,
},
title: {
type: String,
label: "Title",
min: 1,
max: 200,
},
description: {
type: String,
label: "Description",
min: 1,
autoform: {
rows: 5
},
},
});
/** ******************************** EDITOR PANE HELPERS *************************************/
/**
* FINDINGS_EDITOR
*/
Template.findings_editor.helpers({
getFormType:function () {
var finding_id = Session.get("selected_finding");
return finding_id ? "update" : "insert";
},
getSelectedFinding:function () {
return Findings.findOne(Session.get("selected_finding"));
}
});
/**
* NON-FINDINGS EDITOR
*/
Template.non_findings_editor.helpers({
getFormType:function () {
var finding_id = Session.get("selected_finding");
return finding_id ? "update" : "insert";
},
getSelectedNonFinding:function () {
return NonFindings.findOne(Session.get("selected_non_finding"));
}
});
// Template.editor.event = {
// 'click .btn_reset': function () {
// AutoForm.resetForm('findingForm');
// Session.set("selected_finding", null);
// }
// };
/**
* MAIN
*/
Template.main.events = {
'click .edit_findings_button': function (event, template) {
Session.set("edit_mode", "findings");
},
'click .edit_non_findings_button': function (event, template) {
Session.set("edit_mode", "non_findings");
},
};
Template.main.created = function () {
Session.set("edit_mode", null);
};
Template.main.helpers({
editMode:function() {
return Session.get("edit_mode");
},
findingButtonActive:function(){
return Session.get("edit_mode") == "findings" ? "active" : "";
},
nonFindingButtonActive:function(){
return Session.get("edit_mode") == "non_findings" ? "active" : "";
},
findingsEditorActive: function () {
return Session.get("selected_finding");
},
nonFindingsEditorActive: function () {
return Session.get("selected_non_finding");
},
editModeIs: function (mode) {
return Session.get("edit_mode") == mode;
},
});
/**
* Findings Settings
*/
Template.findings_settings.helpers({
findings_directory: function () {
return Settings.findOne({_id: "findings_directory"}).value;
},
findings_library_directory: function () {
return Settings.findOne({_id: "library_findings_directory"}).value;
}
});
Template.findings_settings.events({
"submit .update_findings_directory": function(event){
event.preventDefault();
var newvalue = event.target.findings_directory.value;
Settings.update({_id: "findings_directory"}, {$set: {value: newvalue}});
Session.set("selected_finding", null); // Prevents editor from emptying out on update
},
"submit .update_findings_library_directory": function(event){
event.preventDefault();
var newvalue = event.target.library_findings_directory.value;
Settings.update({_id: "library_findings_directory"}, {$set: {value: newvalue}});
}
});
/**
* Non-Findings Settings
*/
Template.non_findings_settings.helpers({
non_findings_directory: function () {
return Settings.findOne({_id: "non_findings_directory"}).value;
},
non_findings_library_directory: function () {
return Settings.findOne({_id: "non_findings_library_directory"}).value;
}
});
Template.non_findings_settings.events({
"submit .update_non_findings_directory": function(event){
event.preventDefault();
var newvalue = event.target.non_findings_directory.value;
Settings.update({_id: "non_findings_directory"}, {$set: {value: newvalue}});
Session.set("selected_non_finding", null); // Prevents editor from emptying out on update
},
"submit .update_non_findings_library_directory": function(event){
event.preventDefault();
var newvalue = event.target.non_findings_library_directory.value;
Settings.update({_id: "non_findings_library_directory"}, {$set: {value: newvalue}});
}
});
/**
* FINDINGS_PANE
*/
Template.findings_pane.created = function () {
this.activeTab = new ReactiveVar("pentest");
};
Template.findings_pane.helpers({
isPentestTabActive:function () {
return Template.instance().activeTab.get() == "pentest" ? "active" : null;
},
isLibraryTabActive:function () {
return Template.instance().activeTab.get() == "library" ? "active" : null
},
editModeIs: function (mode) {
return Session.get("edit_mode") == mode;
},
editMode: function() {
return Session.get("edit_mode");
}
});
Template.findings_pane.events({
'click .pentest': function (event, template) {
template.activeTab.set("pentest");
},
'click .library': function (event, template) {
template.activeTab.set("library");
},
});
/**
* FINDINGS
*/
Template.findings.helpers({
FindingsIndex: () => FindingsIndex,
properties: () => { return {placeholder: "Enter filter term .."}},
});
/**
* LIBRARY FINDINGS
*/
Template.library_findings.helpers({
LibraryFindingsIndex: () => LibraryFindingsIndex,
properties: () => { return {placeholder: "Enter filter term .."}}
});
/**
* LIBRARY NON FINDINGS
*/
Template.library_non_findings.helpers({
LibraryNonFindingsIndex: () => LibraryNonFindingsIndex,
properties: () => { return {placeholder: "Enter filter term .."}}
});
/**
* NON-FINDINGS
*/
Template.non_findings.helpers({
NonFindingsIndex: () => NonFindingsIndex,
properties: () => { return {placeholder: "Enter filter term .."}}
});
/**
* FINDING
*/
Template.finding.events = {
'click .search_result_title': function (e) {
if (Session.get(this._id)) {
Session.set(this._id, false);
} else {
Session.set(this._id, true);
}
}
};
Template.finding.helpers({
shouldShowContent:function () {
return Session.get(this._id);
},
bordercolor:function() {
switch (this.valid) {
case true:
return "green";
case false:
return "red";
default:
return "";
}
},
tooltip:function() {
switch (this.valid) {
case true:
return "This file is a valid XML file. All elements can be copied to the editor";
case false:
return "This file is not a valid XML file. This means that not all elements can be copied to the editor. If your are missing text, manually copy and paste it from the raw view.";
default:
return "";
}
},
typeIs: function (type) {
return Template.parentData(1).index.config.name == type;
}
});
/**
* USE FINDING BUTTON
*/
Template.use_finding_button.events({
"click": function () {
Session.set("selected_finding", this._id);
return false;
}
});
Template.use_library_finding_button.events({
"click": function () {
var id = Session.get("selected_finding");
if (!id) return false;
Findings.update(id, {
$set: {
threat_level: this.threat_level,
type: this.type,
title: this.title,
description: this.description,
technical_description: this.technical_description,
impact: this.impact,
recommendation: this.recommendation
}
});
return false;
}
});
/**
* LIBRARY NON FINDING BUTTON
*/
Template.use_library_non_finding_button.events({
"click": function () {
var id = Session.get("selected_non_finding");
console.log(id);
if (!id) return false;
NonFindings.update(id, {
$set: {
title: this.title,
description: this.description,
}
});
return false;
}
});
Template.use_non_finding_button.events({
"click": function () {
Session.set("selected_non_finding", this._id);
return false;
}
});

1
editor/dtd/README.md Normal file
View File

@@ -0,0 +1 @@
This is a temporary directory. This should point to the directory where the xsd of a document is stored

View File

@@ -0,0 +1,15 @@
/**
* Created by osboxes on 20/09/16.
*/
import { Mongo } from 'meteor/mongo';
export default Findings = new Mongo.Collection('findings');
export const FindingsIndex = new EasySearch.Index({
collection: Findings,
fields: ['filename', 'content'],
engine: new EasySearch.Minimongo(),
defaultSearchOptions: {
null,
limit: 10000
}
});

View File

@@ -0,0 +1,12 @@
import { Mongo } from 'meteor/mongo';
export const LibraryFindings = new Mongo.Collection('library_findings');
export const LibraryFindingsIndex = new EasySearch.Index({
collection: LibraryFindings,
fields: ['filename', 'content'],
engine: new EasySearch.Minimongo(),
defaultSearchOptions: {
null,
limit: 10000
}
});

View File

@@ -0,0 +1,12 @@
import { Mongo } from 'meteor/mongo';
export const LibraryNonFindings = new Mongo.Collection('library_non_findings');
export const LibraryNonFindingsIndex = new EasySearch.Index({
collection: LibraryNonFindings,
fields: ['filename', 'content'],
engine: new EasySearch.Minimongo(),
defaultSearchOptions: {
null,
limit: 10000
}
});

View File

@@ -0,0 +1,15 @@
/**
* Created by osboxes on 20/09/16.
*/
import { Mongo } from 'meteor/mongo';
export default NonFindings = new Mongo.Collection('non_findings');
export const NonFindingsIndex = new EasySearch.Index({
collection: NonFindings,
fields: ['filename', 'content'],
engine: new EasySearch.Minimongo(),
defaultSearchOptions: {
null,
limit: 10000
}
});

View File

@@ -0,0 +1,3 @@
import { Mongo } from 'meteor/mongo';
export const Reports = new Mongo.Collection('reports');

View File

@@ -0,0 +1,4 @@
import { Mongo } from 'meteor/mongo';
export const Settings = new Mongo.Collection('settings');

File diff suppressed because it is too large Load Diff

1
editor/node_modules/.bin/xml-js generated vendored Symbolic link
View File

@@ -0,0 +1 @@
../xml-js/bin/cli.js

1
editor/node_modules/boolbase/.meteor-portable generated vendored Normal file
View File

@@ -0,0 +1 @@
true

10
editor/node_modules/boolbase/README.md generated vendored Normal file
View File

@@ -0,0 +1,10 @@
#boolbase
This very simple module provides two basic functions, one that always returns true (`trueFunc`) and one that always returns false (`falseFunc`).
###WTF?
By having only a single instance of these functions around, it's possible to do some nice optimizations. Eg. [`CSSselect`](https://github.com/fb55/CSSselect) uses these functions to determine whether a selector won't match any elements. If that's the case, the DOM doesn't even have to be touched.
###And why is this a separate module?
I'm trying to modularize `CSSselect` and most modules depend on these functions. IMHO, having a separate module is the easiest solution to this problem.

8
editor/node_modules/boolbase/index.js generated vendored Normal file
View File

@@ -0,0 +1,8 @@
module.exports = {
trueFunc: function trueFunc(){
return true;
},
falseFunc: function falseFunc(){
return false;
}
};

75
editor/node_modules/boolbase/package.json generated vendored Normal file
View File

@@ -0,0 +1,75 @@
{
"_args": [
[
"boolbase@~1.0.0",
"/home/osboxes/code/pentext/editor/node_modules/css-select"
]
],
"_from": "boolbase@>=1.0.0 <1.1.0",
"_id": "boolbase@1.0.0",
"_inCache": true,
"_installable": true,
"_location": "/boolbase",
"_npmUser": {
"email": "me@feedic.com",
"name": "feedic"
},
"_npmVersion": "1.4.2",
"_phantomChildren": {},
"_requested": {
"name": "boolbase",
"raw": "boolbase@~1.0.0",
"rawSpec": "~1.0.0",
"scope": null,
"spec": ">=1.0.0 <1.1.0",
"type": "range"
},
"_requiredBy": [
"/css-select",
"/nth-check"
],
"_resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"_shasum": "68dff5fbe60c51eb37725ea9e3ed310dcc1e776e",
"_shrinkwrap": null,
"_spec": "boolbase@~1.0.0",
"_where": "/home/osboxes/code/pentext/editor/node_modules/css-select",
"author": {
"email": "me@feedic.com",
"name": "Felix Boehm"
},
"bugs": {
"url": "https://github.com/fb55/boolbase/issues"
},
"dependencies": {},
"description": "two functions: One that returns true, one that returns false",
"devDependencies": {},
"directories": {},
"dist": {
"shasum": "68dff5fbe60c51eb37725ea9e3ed310dcc1e776e",
"tarball": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz"
},
"homepage": "https://github.com/fb55/boolbase",
"keywords": [
"boolean",
"function"
],
"license": "ISC",
"main": "index.js",
"maintainers": [
{
"name": "feedic",
"email": "me@feedic.com"
}
],
"name": "boolbase",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/fb55/boolbase.git"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"version": "1.0.0"
}

1
editor/node_modules/buffer-shims/.meteor-portable generated vendored Normal file
View File

@@ -0,0 +1 @@
true

108
editor/node_modules/buffer-shims/index.js generated vendored Normal file
View File

@@ -0,0 +1,108 @@
'use strict';
var buffer = require('buffer');
var Buffer = buffer.Buffer;
var SlowBuffer = buffer.SlowBuffer;
var MAX_LEN = buffer.kMaxLength || 2147483647;
exports.alloc = function alloc(size, fill, encoding) {
if (typeof Buffer.alloc === 'function') {
return Buffer.alloc(size, fill, encoding);
}
if (typeof encoding === 'number') {
throw new TypeError('encoding must not be number');
}
if (typeof size !== 'number') {
throw new TypeError('size must be a number');
}
if (size > MAX_LEN) {
throw new RangeError('size is too large');
}
var enc = encoding;
var _fill = fill;
if (_fill === undefined) {
enc = undefined;
_fill = 0;
}
var buf = new Buffer(size);
if (typeof _fill === 'string') {
var fillBuf = new Buffer(_fill, enc);
var flen = fillBuf.length;
var i = -1;
while (++i < size) {
buf[i] = fillBuf[i % flen];
}
} else {
buf.fill(_fill);
}
return buf;
}
exports.allocUnsafe = function allocUnsafe(size) {
if (typeof Buffer.allocUnsafe === 'function') {
return Buffer.allocUnsafe(size);
}
if (typeof size !== 'number') {
throw new TypeError('size must be a number');
}
if (size > MAX_LEN) {
throw new RangeError('size is too large');
}
return new Buffer(size);
}
exports.from = function from(value, encodingOrOffset, length) {
if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) {
return Buffer.from(value, encodingOrOffset, length);
}
if (typeof value === 'number') {
throw new TypeError('"value" argument must not be a number');
}
if (typeof value === 'string') {
return new Buffer(value, encodingOrOffset);
}
if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {
var offset = encodingOrOffset;
if (arguments.length === 1) {
return new Buffer(value);
}
if (typeof offset === 'undefined') {
offset = 0;
}
var len = length;
if (typeof len === 'undefined') {
len = value.byteLength - offset;
}
if (offset >= value.byteLength) {
throw new RangeError('\'offset\' is out of bounds');
}
if (len > value.byteLength - offset) {
throw new RangeError('\'length\' is out of bounds');
}
return new Buffer(value.slice(offset, offset + len));
}
if (Buffer.isBuffer(value)) {
var out = new Buffer(value.length);
value.copy(out, 0, 0, value.length);
return out;
}
if (value) {
if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) {
return new Buffer(value);
}
if (value.type === 'Buffer' && Array.isArray(value.data)) {
return new Buffer(value.data);
}
}
throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.');
}
exports.allocUnsafeSlow = function allocUnsafeSlow(size) {
if (typeof Buffer.allocUnsafeSlow === 'function') {
return Buffer.allocUnsafeSlow(size);
}
if (typeof size !== 'number') {
throw new TypeError('size must be a number');
}
if (size >= MAX_LEN) {
throw new RangeError('size is too large');
}
return new SlowBuffer(size);
}

19
editor/node_modules/buffer-shims/license.md generated vendored Normal file
View File

@@ -0,0 +1,19 @@
# Copyright (c) 2016 Calvin Metcalf
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.**

77
editor/node_modules/buffer-shims/package.json generated vendored Normal file
View File

@@ -0,0 +1,77 @@
{
"_args": [
[
"buffer-shims@^1.0.0",
"/home/osboxes/code/pentext/editor/node_modules/readable-stream"
]
],
"_from": "buffer-shims@>=1.0.0 <2.0.0",
"_id": "buffer-shims@1.0.0",
"_inCache": true,
"_installable": true,
"_location": "/buffer-shims",
"_nodeVersion": "5.11.0",
"_npmOperationalInternal": {
"host": "packages-16-east.internal.npmjs.com",
"tmp": "tmp/buffer-shims-1.0.0.tgz_1462560889323_0.8640750856138766"
},
"_npmUser": {
"email": "calvin.metcalf@gmail.com",
"name": "cwmma"
},
"_npmVersion": "3.8.6",
"_phantomChildren": {},
"_requested": {
"name": "buffer-shims",
"raw": "buffer-shims@^1.0.0",
"rawSpec": "^1.0.0",
"scope": null,
"spec": ">=1.0.0 <2.0.0",
"type": "range"
},
"_requiredBy": [
"/readable-stream"
],
"_resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz",
"_shasum": "9978ce317388c649ad8793028c3477ef044a8b51",
"_shrinkwrap": null,
"_spec": "buffer-shims@^1.0.0",
"_where": "/home/osboxes/code/pentext/editor/node_modules/readable-stream",
"bugs": {
"url": "https://github.com/calvinmetcalf/buffer-shims/issues"
},
"dependencies": {},
"description": "some shims for node buffers",
"devDependencies": {
"tape": "^4.5.1"
},
"directories": {},
"dist": {
"shasum": "9978ce317388c649ad8793028c3477ef044a8b51",
"tarball": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz"
},
"files": [
"index.js"
],
"gitHead": "ea89b3857ab5b8203957922a84e9a48cf4c47e0a",
"homepage": "https://github.com/calvinmetcalf/buffer-shims#readme",
"license": "MIT",
"main": "index.js",
"maintainers": [
{
"name": "cwmma",
"email": "calvin.metcalf@gmail.com"
}
],
"name": "buffer-shims",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/calvinmetcalf/buffer-shims.git"
},
"scripts": {
"test": "tape test/*.js"
},
"version": "1.0.0"
}

21
editor/node_modules/buffer-shims/readme.md generated vendored Normal file
View File

@@ -0,0 +1,21 @@
buffer-shims
===
functions to make sure the new buffer methods work in older browsers.
```js
var bufferShim = require('buffer-shims');
bufferShim.from('foo');
bufferShim.alloc(9, 'cafeface', 'hex');
bufferShim.allocUnsafe(15);
bufferShim.allocUnsafeSlow(21);
```
should just use the original in newer nodes and on older nodes uses fallbacks.
Known Issues
===
- this does not patch the buffer object, only the constructor stuff
- it's actually a polyfill
![](https://i.imgur.com/zxII3jJ.gif)

1
editor/node_modules/cheerio/.meteor-portable generated vendored Normal file
View File

@@ -0,0 +1 @@
true

576
editor/node_modules/cheerio/History.md generated vendored Normal file
View File

@@ -0,0 +1,576 @@
0.22.0 / 2016-08-23
==================
* Return undefined in .prop if given an invalid element or tag (#880)
* Merge pull request #884 from cheeriojs/readme-cleanup
* readme updates
* Merge pull request #881 from piamancini/patch-1
* Added backers and sponsors from OpenCollective
* Use jQuery from the jquery module in benchmarks (#871)
* Document, test, and extend static `$.text` method (#855)
* Fix typo on calling _.extend (#861)
* Update versions (#870)
* Use individual lodash functions (#864)
* Added `.serialize()` support. Fixes #69 (#827)
* Update Readme.md (#857)
* add extension for JSON require call
* remove gittask badge
* Merge pull request #672 from underdogio/dev/checkbox.radio.values.sqwished
* Added default value for checkboxes/radios
0.20.0 / 2016-02-01
==================
* Add coveralls badge, remove link to old report (Felix Böhm)
* Update lodash dependeny to 4.1.0 (leif.hanack)
* Fix PR #726 adding 'appendTo()' and 'prependTo()' (Delgan)
* Added appendTo and prependTo with tests #641 (digihaven)
* Fix #780 by changing options context in '.find()' (Felix Böhm)
* Add an unit test checking the query of child (Delgan)
* fix #667: attr({foo: null}) removes attribute foo, like attr('foo', null) (Ray Waldin)
* Include reference to dedicated "Loading" section (Mike Pennisi)
* Added load method to $ (alanev)
* update css-select to 1.2.0 (Felix Böhm)
* Fixing Grammatical Error (Dan Corman)
* Test against node v0.12 --> v4.2 (Jason Kurian)
* Correct output in example (Felix Böhm)
* Fix npm files filter (Bogdan Chadkin)
* Enable setting data on all elements in selection (Mike Pennisi)
* Reinstate `$.fn.toArray` (Mike Pennisi)
* update css-select to 1.1.0 (Thomas Shafer)
* Complete implementation of `wrap` (Mike Pennisi)
* Correct name of unit test (Mike Pennisi)
* Correct grammar in test titles (Mike Pennisi)
* Normalize whitespace (Mike Pennisi)
* Insert omitted assertion (Mike Pennisi)
* Update invocation of `children` (Mike Pennisi)
* Begin implementation of `wrap` method (Dandlezzz)
* Update Readme.md (Sven Slootweg)
* fix document's mistake in Readme.md (exoticknight)
* Add tests for setting text and html as non-strings (Ryc O'Chet)
* Fix for passing non-string values to .html or .text (Ryc O'Chet)
* use a selector to filter form elements (fb55)
* fix README.md typo (Yutian Li)
* README: fix spelling (Chris Rebert)
* Added support for options without a `value` attribute. Fixes #633 (Todd Wolfson)
* responding to pull request feedback - remove item() method and related tests (Ray Waldin)
* add length property and item method to object returned by prop('style'), plus tests (Ray Waldin)
* Added .prop method to readme (Artem Burtsev)
* Added .prop method (Artem Burtsev)
* Added Gitter badge (The Gitter Badger)
0.19.0 / 2015-03-21
==================
* fixed allignment (fb55)
* added test case for malformed json in data attributes (fb55)
* fix: handle some extreme cases like `data-custom="{{templatevar}}"`. There is possibility error while parsing json . (Harish.K)
* Add missing optional selector doc for {prev,next}{All,Until} (Jérémie Astori)
* update to dom-serializer@0.1.0 (Felix Böhm)
* Document `Cheerio#serialzeArray` (Mike Pennisi)
* Fixed up `serializeArray()` and added multiple support (Todd Wolfson)
* Implement serializeArray() (Jarno Leppänen)
* recognize options in $.xml() (fb55)
* lib/static.js: text(): rm errant space before ++ (Chris Rebert)
* Do not expose internal `children` array (Mike Pennisi)
* Change lodash dependencies to ^3.1.0 (Samy Pessé)
* Update lodash@3.1.0 (Samy Pessé)
* Updates Readme.md: .not(function (index, elem)) (Patrick Ward)
* update to css-select@1.0.0 (fb55)
* Allow failures in Node.js v0.11 (Mike Pennisi)
* Added: Gittask badge (Matthew Mueller)
* Isolate prototypes of functions created via `load` (Mike Pennisi)
* Updates Readme.md: adds JS syntax highlighting (frankcash)
* #608 -- Add support for insertBefore/insertAfter syntax. Supports target types of: $, [$], selector (both single and multiple results) (Ben Cochran)
* Clone input nodes when inserting over a set (Mike Pennisi)
* Move unit test files (Mike Pennisi)
* remove unnecessarily tricky code (David Chambers)
* pass options to $.html in toString (fb55)
* add license info to package.json (Chris Rebert)
* xyz@~0.5.0 (David Chambers)
* Remove unofficial signature of `children` (Mike Pennisi)
* Fix bug in `css` method (Mike Pennisi)
* Correct bug in implementation of `Cheerio#val` (Mike Pennisi)
0.18.0 / 2014-11-06
==================
* bump htmlparser2 dependency to ~3.8.1 (Chris Rebert)
* Correct unit test titles (Mike Pennisi)
* Correct behavior of `after` and `before` (Mike Pennisi)
* implement jQuery's .has() (Chris Rebert)
* Update repository url (haqii)
* attr() should return undefined or name for booleans (Raoul Millais)
* Update Readme.md (Ryan Breen)
* Implement `Cheerio#not` (Mike Pennisi)
* Clone nodes according to original parsing options (Mike Pennisi)
* fix lint error (David Chambers)
* Add explicit tests for DOM level 1 API (Mike Pennisi)
* Expose DOM level 1 API for Node-like objects (Mike Pennisi)
* Correct error in documentation (Mike Pennisi)
* Return a fully-qualified Function from `$.load` (Mike Pennisi)
* Update tests to avoid duck typing (Mike Pennisi)
* Alter "loaded" functions to produce true instances (Mike Pennisi)
* Organize tests for `cheerio.load` (Mike Pennisi)
* Complete `$.prototype.find` (Mike Pennisi)
* Use JSHint's `extends` option (Mike Pennisi)
* Remove aliases for exported methods (Mike Pennisi)
* Disallow unused variables (Mike Pennisi)
* Remove unused internal variables (Mike Pennisi)
* Remove unused variables from unit tests (Mike Pennisi)
* Remove unused API method references (Mike Pennisi)
* Move tests for `contains` method (Mike Pennisi)
* xyz@0.4.0 (David Chambers)
* Created a wiki for companies using cheerio in production (Matthew Mueller)
* Implement `$.prototype.index` (Mike Pennisi)
* Implement `$.prototype.addBack` (Mike Pennisi)
* Added double quotes to radio attribute name to account for characters such as brackets (akant10)
* Update History.md (Gabriel Falkenberg)
* add 0.17.0 changelog (David Chambers)
* exit prepublish script if tag not found (David Chambers)
* alphabetize devDependencies (fb55)
* ignore coverage dir (fb55)
* submit coverage to coveralls (fb55)
* replace jscoverage with istanbul (fb55)
0.17.0 / 2014-06-10
==================
* Fix bug in internal `uniqueSplice` function (Mike Pennisi)
* accept buffer argument to cheerio.load (David Chambers)
* Respect options on the element level (Alex Indigo)
* Change state definition to more readable (Artem Burtsev)
* added test (0xBADC0FFEE)
* add class only if doesn't exist (Artem Burtsev)
* Made it less insane. (Alex Indigo)
* Implement `Cheerio#add` (Mike Pennisi)
* Use "loaded" instance of Cheerio in unit tests (Mike Pennisi)
* Be more strict with object check. (Alex Indigo)
* Added options argument to .html() static method. (Alex Indigo)
* Fixed encoding mishaps. Adjusted tests. (Alex Indigo)
* use dom-serializer module (fb55)
* don't test on 0.8, don't ignore 0.11 (Felix Böhm)
* parse: rm unused variables (coderaiser)
* cheerio: rm unused variable (coderaiser)
* Fixed test (Avi Kohn)
* Added test (Avi Kohn)
* Changed == to === (Avi Kohn)
* Fixed a bug in removing type="hidden" attr (Avi Kohn)
* sorted (Alexey Raspopov)
* add `muted` attr to booleanAttributes (Alexey Raspopov)
* fixed context of `this` in .html (Felix Böhm)
* append new elements for each element in selection (fb55)
0.16.0 / 2014-05-08
==================
* fix `make bench` (David Chambers)
* makefile: add release-* targets (David Chambers)
* alphabetize dependencies (David Chambers)
* Rewrite `data` internals with caching behavior (Mike Pennisi)
* Fence .val example as js (Kevin Sawicki)
* Fixed typos. Deleted trailing whitespace from test/render.js (Nattaphoom Ch)
* Fix manipulation APIs with removed elements (kpdecker)
* Perform manual string parsing for hasClass (kpdecker)
* Fix existing element removal (kpdecker)
* update render tests (Felix Böhm)
* fixed cheerio path (Felix Böhm)
* use `entities.escape` for attribute values (Felix Böhm)
* bump entities version (Felix Böhm)
* remove lowerCaseTags option from readme (Felix Böhm)
* added test case for .html in xmlMode (fb55)
* render xml in `html()` when `xmlMode: true` (fb55)
* use a map for booleanAttributes (fb55)
* update singleTags, use utils.isTag (fb55)
* update travis badge URL (Felix Böhm)
* use typeof instead of _.isString and _.isNumber (fb55)
* use Array.isArray instead of _.isArray (fb55)
* replace _.isFunction with typeof (fb55)
* removed unnecessary error message (fb55)
* decode entities in htmlparser2 (fb55)
* pass options object to CSSselect (fb55)
0.15.0 / 2014-04-08
==================
* Update callbacks to pass element per docs (@kpdecker)
* preserve options (@fb55)
* Use SVG travis badge (@t3chnoboy)
* only use static requires (@fb55)
* Optimize manipulation methods (@kpdecker)
* Optimize add and remove class cases (@kpdecker)
* accept dom of DomHandler to cheerio.load (@nleush)
* added parentsUntil method (@finspin)
* Add performance optimization and bug fix `empty` method (@kpdecker)
0.14.0 / 2014-04-01
==================
* call encodeXML and directly expose decodeHTML (@fb55)
* use latest htmlparser2 and entities versions (@fb55)
* Deprecate `$.fn.toArray` (@jugglinmike)
* Implement `$.fn.get` (@jugglinmike)
* .replaceWith now replaces all selected elements. (@xavi-)
* Correct arguments for 'replaceWith' callback (@jugglinmike)
* switch to lodash (@fb55)
* update to entities@0.5.0 (@fb55)
* Fix attr when $ collection contains text modules (@kpdecker)
* Update to latest version of expect.js (@jugglinmike)
* Remove nodes from their previous structures (@jugglinmike)
* Update render.js (@stevenvachon)
* CDATA test (@stevenvachon)
* only ever one child index for cdata (@stevenvachon)
* don't loop through cdata children array (@stevenvachon)
* proper rendering of CDATA (@stevenvachon)
* Add cheerio-only bench option (@kpdecker)
* Avoid delete operations (@kpdecker)
* Add independent html benchmark (@kpdecker)
* Cache tag check in render (@kpdecker)
* Simplify attribute rendering step (@kpdecker)
* Add html rendering bench case (@kpdecker)
* Remove unnecessary check from removeAttr (@kpdecker)
* Remove unnecessary encoding step for attrs (@kpdecker)
* Add test for removeAttr+attr on boolean attributes (@kpdecker)
* Add single element benchmark case (@kpdecker)
* Optimize filter with selector (@kpdecker)
* Fix passing context as dom node (@alfred-nsh)
* Fix bug in `nextUntil` (@jugglinmike)
* Fix bug in `nextAll` (@jugglinmike)
* Implement `selector` argument of `next` method (@jugglinmike)
* Fix bug in `prevUntil` (@jugglinmike)
* Implement `selector` argument of `prev` method (@jugglinmike)
* Fix bug in `prevAll` (@jugglinmike)
* Fix bug in `siblings` (@jugglinmike)
* Avoid unnecessary indexOf from toggleClass (@kpdecker)
* Use strict equality rather than falsy check in eq (@kpdecker)
* Add benchmark coverage for all $ APIs (@kpdecker)
* Optimize filter Cheerio intermediate creation (@kpdecker)
* Optimize siblings cheerio instance creation (@kpdecker)
* Optimize identity cases for first/last/eq (@kpdecker)
* Use domEach for traversal (@kpdecker)
* Inline children lookup in find (@kpdecker)
* Use domEach in data accessor (@kpdecker)
* Avoid cheerio creation in add/remove/toggleClass (@kpdecker)
* Implement getAttr local helper (@kpdecker)
0.13.1 / 2014-01-07
==================
* Fix select with context in Cheerio function (@jugglinmike)
* Remove unecessary DOM maintenance logic (@jugglinmike)
* Deprecate support for node 0.6
0.13.0 / 2013-12-30
==================
* Remove "root" node (@jugglinmike)
* Fix bug in `prevAll`, `prev`, `nextAll`, `next`, `prevUntil`, `nextUntil` (@jugglinmike)
* Fix `replaceWith` method (@jugglinmike)
* added nextUntil() and prevUntil() (@finspin)
* Remove internal `connect` function (@jugglinmike)
* Rename `Cheerio#make` to document private status (@jugginmike)
* Remove extraneous call to `_.uniq` (@jugglinmike)
* Use CSSselect library directly (@jugglinmike)
* Run CI against Node v0.11 as an allowed failure (@jugginmike)
* Correct bug in `Cheerio#parents` (@jugglinmike)
* Implement `$.fn.end` (@jugginmike)
* Ignore colons inside of url(.*) when parsing css (@Meekohi)
* Introduce rudimentary benchmark suite (@jugglinmike)
* Update HtmlParser2 version (@jugglinmike)
* Correct inconsistency in `$.fn.map` (@jugglinmike)
* fixed traversing tests (@finspin)
* Simplify `make` method (@jugglinmike)
* Avoid shadowing instance methods from arrays (@jugglinmike)
0.12.4 / 2013-11-12
==================
* Coerce JSON values returned by `data` (@jugglinmike)
* issue #284: when rendering HTML, use original data attributes (@Trott)
* Introduce JSHint for automated code linting (@jugglinmike)
* Prevent `find` from returning duplicate elements (@jugglinmike)
* Implement function signature of `replaceWith` (@jugglinmike)
* Implement function signature of `before` (@jugglinmike)
* Implement function signature of `after` (@jugglinmike)
* Implement function signature of `append`/`prepend` (@jugglinmike)
* Extend iteration methods to accept nodes (@jugglinmike)
* Improve `removeClass` (@jugglinmike)
* Complete function signature of `addClass` (@jugglinmike)
* Fix bug in `removeClass` (@jugglinmike)
* Improve contributing.md (@jugglinmike)
* Fix and document .css() (@jugglinmike)
0.12.3 / 2013-10-04
===================
* Add .toggleClass() function (@cyberthom)
* Add contributing guidelines (@jugglinmike)
* Fix bug in `siblings` (@jugglinmike)
* Correct the implementation `filter` and `is` (@jugglinmike)
* add .data() function (@andi-neck)
* add .css() (@yields)
* Implements contents() (@jlep)
0.12.2 / 2013-09-04
==================
* Correct implementation of `$.fn.text` (@jugglinmike)
* Refactor Cheerio array creation (@jugglinmike)
* Extend manipulation methods to accept Arrays (@jugglinmike)
* support .attr(attributeName, function(index, attr)) (@xiaohwan)
0.12.1 / 2013-07-30
==================
* Correct behavior of `Cheerio#parents` (@jugglinmike)
* Double quotes inside attributes kills HTML (@khoomeister)
* Making next({}) and prev({}) return empty object (@absentTelegraph)
* Implement $.parseHTML (@jugglinmike)
* Correct bug in jQuery.fn.closest (@jugglinmike)
* Correct behavior of $.fn.val on 'option' elements (@jugglinmike)
0.12.0 / 2013-06-09
===================
* Breaking Change: Changed context from parent to the actual passed one (@swissmanu)
* Fixed: jquery checkbox val behavior (@jhubble)
* Added: output xml with $.xml() (@Maciek416)
* Bumped: htmlparser2 to 3.1.1
* Fixed: bug in attr(key, val) on empty objects (@farhadi)
* Added: prevAll, nextAll (@lessmind)
* Fixed: Safety check in parents and closest (@zero21xxx)
* Added: .is(sel) (@zero21xxx)
0.11.0 / 2013-04-22
==================
* Added: .closest() (@jeremy-dentel)
* Added: .parents() (@zero21xxx)
* Added: .val() (@rschmukler & @leahciMic)
* Added: Travis support for node 0.10.0 (@jeremy-dentel)
* Fixed: .find() if no selector (@davidchambers)
* Fixed: Propagate syntax errors caused by invalid selectors (@davidchambers)
0.10.8 / 2013-03-11
==================
* Add slice method (SBoudrias)
0.10.7 / 2013-02-10
==================
* Code & doc cleanup (davidchambers)
* Fixed bug in filter (jugglinmike)
0.10.6 / 2013-01-29
==================
* Added `$.contains(...)` (jugglinmike)
* formatting cleanup (davidchambers)
* Bug fix for `.children()` (jugglinmike & davidchambers)
* Remove global `render` bug (wvl)
0.10.5 / 2012-12-18
===================
* Fixed botched publish from 0.10.4 - changes should now be present
0.10.4 / 2012-12-16
==================
* $.find should query descendants only (@jugglinmike)
* Tighter underscore dependency
0.10.3 / 2012-11-18
===================
* fixed outer html bug
* Updated documentation for $(...).html() and $.html()
0.10.2 / 2012-11-17
===================
* Added a toString() method (@bensheldon)
* use `_.each` and `_.map` to simplify cheerio namesakes (@davidchambers)
* Added filter() with tests and updated readme (@bensheldon & @davidchambers)
* Added spaces between attributes rewritten by removeClass (@jos3000)
* updated docs to remove reference to size method (@ironchefpython)
* removed HTML tidy/pretty print from cheerio
0.10.1 / 2012-10-04
===================
* Fixed regression, filtering with a context (#106)
0.10.0 / 2012-09-24
===================
* Greatly simplified and reorganized the library, reducing the loc by 30%
* Now supports mocha's test-coverage
* Deprecated self-closing tags (HTML5 doesn't require them)
* Fixed error thrown in removeClass(...) @robashton
0.9.2 / 2012-08-10
==================
* added $(...).map(fn)
* manipulation: refactor `makeCheerioArray`
* make .removeClass() remove *all* occurrences (#64)
0.9.1 / 2012-08-03
==================
* fixed bug causing options not to make it to the parser
0.9.0 / 2012-07-24
==================
* Added node 8.x support
* Removed node 4.x support
* Add html(dom) support (@wvl)
* fixed xss vulnerabilities on .attr(), .text(), & .html() (@benatkin, @FB55)
* Rewrote tests into javascript, removing coffeescript dependency (@davidchambers)
* Tons of cleanup (@davidchambers)
0.8.3 / 2012-06-12
==================
* Fixed minor package regression (closes #60)
0.8.2 / 2012-06-11
==================
* Now fails gracefully in cases that involve special chars, which is inline with jQuery (closes #59)
* text() now decode special entities (closes #52)
* updated travis.yml to test node 4.x
0.8.1 / 2012-06-02
==================
* fixed regression where if you created an element, it would update the root
* compatible with node 4.x (again)
0.8.0 / 2012-05-27
==================
* Updated CSS parser to use FB55/CSSselect. Cheerio now supports most CSS3 psuedo selectors thanks to @FB55.
* ignoreWhitespace now on by default again. See #55 for context.
* Changed $(':root') to $.root(), cleaned up $.clone()
* Support for .eq(i) thanks to @alexbardas
* Removed support for node 0.4.x
* Fixed memory leak where package.json was continually loaded
* Tons more tests
0.7.0 / 2012-04-08
==================
* Now testing with node v0.7.7
* Added travis-ci integration
* Replaced should.js with expect.js. Browser testing to come
* Fixed spacing between attributes and their values
* Added HTML tidy/pretty print
* Exposed node-htmlparser2 parsing options
* Revert .replaceWith(...) to be consistent with jQuery
0.6.2 / 2012-02-12
==================
* Fixed .replaceWith(...) regression
0.6.1 / 2012-02-12
==================
* Added .first(), .last(), and .clone() commands.
* Option to parse using whitespace added to `.load`.
* Many bug fixes to make cheerio more aligned with jQuery.
* Added $(':root') to select the highest level element.
Many thanks to the contributors that made this release happen: @ironchefpython and @siddMahen
0.6.0 / 2012-02-07
==================
* *Important:* `$(...).html()` now returns inner HTML, which is in line with the jQuery spec
* `$.html()` returns the full HTML string. `$.html([cheerioObject])` will return the outer(selected element's tag) and inner HTML of that object
* Fixed bug that prevented HTML strings with depth (eg. `append('<ul><li><li></ul>')`) from getting `parent`, `next`, `prev` attributes.
* Halted [htmlparser2](https://github.com/FB55/node-htmlparser) at v2.2.2 until single attributes bug gets fixed.
0.5.1 / 2012-02-05
==================
* Fixed minor regression: $(...).text(fn) would fail
0.5.1 / 2012-02-05
==================
* Fixed regression: HTML pages with comments would fail
0.5.0 / 2012-02-04
==================
* Transitioned from Coffeescript back to Javascript
* Parser now ignores whitespace
* Fixed issue with double slashes on self-enclosing tags
* Added boolean attributes to html rendering
0.4.2 / 2012-01-16
==================
* Multiple selectors support: $('.apple, .orange'). Thanks @siddMahen!
* Update package.json to always use latest cheerio-soupselect
* Fix memory leak in index.js
0.4.1 / 2011-12-19
==================
* Minor packaging changes to allow `make test` to work from npm installation
0.4.0 / 2011-12-19
==================
* Rewrote all unit tests as cheerio transitioned from vows -> mocha
* Internally, renderer.render -> render(...), parser.parse -> parse(...)
* Append, prepend, html, before, after all work with only text (no tags)
* Bugfix: Attributes can now be removed from script and style tags
* Added yield as a single tag
* Cheerio now compatible with node >=0.4.7
0.3.2 / 2011-12-1
=================
* Fixed $(...).text(...) to work with "root" element
0.3.1 / 2011-11-25
==================
* Now relying on cheerio-soupselect instead of node-soupselect
* Removed all lingering htmlparser dependencies
* parser now returns parent "root" element. Root now never needs to be updated when there is multiple roots. This fixes ongoing issues with before(...), after(...) and other manipulation functions
* Added jQuery's $(...).replaceWith(...)
0.3.0 / 2011-11-19
==================
* Now using htmlparser2 for parsing (2x speed increase, cleaner, actively developed)
* Added benchmark directory for future speed tests
* $('...').dom() was funky, so it was removed in favor of $('...').get(). $.dom() still works the same.
* $.root now correctly static across all instances of $
* Added a screencast
0.2.2 / 2011-11-9
=================
* Traversing will select `<script>` and `<style>` tags (Closes Issue: #8)
* .text(string) now working with empty elements (Closes Issue: #7)
* Fixed before(...) & after(...) again if there is no parent (Closes Issue: #2)
0.2.1 / 2011-11-5
=================
* Fixed before(...) & after(...) if there is no parent (Closes Issue: #2)
* Comments now rendered correctly (Closes Issue: #5)
< 0.2.0 / 2011-10-31
====================
* Initial release (untracked development)

1093
editor/node_modules/cheerio/Readme.md generated vendored Normal file

File diff suppressed because it is too large Load Diff

11
editor/node_modules/cheerio/index.js generated vendored Normal file
View File

@@ -0,0 +1,11 @@
/**
* Export cheerio (with )
*/
exports = module.exports = require('./lib/cheerio');
/*
Export the version
*/
exports.version = require('./package.json').version;

495
editor/node_modules/cheerio/lib/api/attributes.js generated vendored Normal file
View File

@@ -0,0 +1,495 @@
var $ = require('../static'),
utils = require('../utils'),
isTag = utils.isTag,
domEach = utils.domEach,
hasOwn = Object.prototype.hasOwnProperty,
camelCase = utils.camelCase,
cssCase = utils.cssCase,
rspace = /\s+/,
dataAttrPrefix = 'data-',
_ = {
forEach: require('lodash.foreach'),
extend: require('lodash.assignin'),
some: require('lodash.some')
},
// Lookup table for coercing string data-* attributes to their corresponding
// JavaScript primitives
primitives = {
null: null,
true: true,
false: false
},
// Attributes that are booleans
rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
// Matches strings that look like JSON objects or arrays
rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/;
var getAttr = function(elem, name) {
if (!elem || !isTag(elem)) return;
if (!elem.attribs) {
elem.attribs = {};
}
// Return the entire attribs object if no attribute specified
if (!name) {
return elem.attribs;
}
if (hasOwn.call(elem.attribs, name)) {
// Get the (decoded) attribute
return rboolean.test(name) ? name : elem.attribs[name];
}
// Mimic the DOM and return text content as value for `option's`
if (elem.name === 'option' && name === 'value') {
return $.text(elem.children);
}
// Mimic DOM with default value for radios/checkboxes
if (elem.name === 'input' &&
(elem.attribs.type === 'radio' || elem.attribs.type === 'checkbox') &&
name === 'value') {
return 'on';
}
};
var setAttr = function(el, name, value) {
if (value === null) {
removeAttribute(el, name);
} else {
el.attribs[name] = value+'';
}
};
exports.attr = function(name, value) {
// Set the value (with attr map support)
if (typeof name === 'object' || value !== undefined) {
if (typeof value === 'function') {
return domEach(this, function(i, el) {
setAttr(el, name, value.call(el, i, el.attribs[name]));
});
}
return domEach(this, function(i, el) {
if (!isTag(el)) return;
if (typeof name === 'object') {
_.forEach(name, function(value, name) {
setAttr(el, name, value);
});
} else {
setAttr(el, name, value);
}
});
}
return getAttr(this[0], name);
};
var getProp = function (el, name) {
if (!el || !isTag(el)) return;
return el.hasOwnProperty(name)
? el[name]
: rboolean.test(name)
? getAttr(el, name) !== undefined
: getAttr(el, name);
};
var setProp = function (el, name, value) {
el[name] = rboolean.test(name) ? !!value : value;
};
exports.prop = function (name, value) {
var i = 0,
property;
if (typeof name === 'string' && value === undefined) {
switch (name) {
case 'style':
property = this.css();
_.forEach(property, function (v, p) {
property[i++] = p;
});
property.length = i;
break;
case 'tagName':
case 'nodeName':
property = this[0].name.toUpperCase();
break;
default:
property = getProp(this[0], name);
}
return property;
}
if (typeof name === 'object' || value !== undefined) {
if (typeof value === 'function') {
return domEach(this, function(i, el) {
setProp(el, name, value.call(el, i, getProp(el, name)));
});
}
return domEach(this, function(i, el) {
if (!isTag(el)) return;
if (typeof name === 'object') {
_.forEach(name, function(val, name) {
setProp(el, name, val);
});
} else {
setProp(el, name, value);
}
});
}
};
var setData = function(el, name, value) {
if (!el.data) {
el.data = {};
}
if (typeof name === 'object') return _.extend(el.data, name);
if (typeof name === 'string' && value !== undefined) {
el.data[name] = value;
} else if (typeof name === 'object') {
_.extend(el.data, name);
}
};
// Read the specified attribute from the equivalent HTML5 `data-*` attribute,
// and (if present) cache the value in the node's internal data store. If no
// attribute name is specified, read *all* HTML5 `data-*` attributes in this
// manner.
var readData = function(el, name) {
var readAll = arguments.length === 1;
var domNames, domName, jsNames, jsName, value, idx, length;
if (readAll) {
domNames = Object.keys(el.attribs).filter(function(attrName) {
return attrName.slice(0, dataAttrPrefix.length) === dataAttrPrefix;
});
jsNames = domNames.map(function(domName) {
return camelCase(domName.slice(dataAttrPrefix.length));
});
} else {
domNames = [dataAttrPrefix + cssCase(name)];
jsNames = [name];
}
for (idx = 0, length = domNames.length; idx < length; ++idx) {
domName = domNames[idx];
jsName = jsNames[idx];
if (hasOwn.call(el.attribs, domName)) {
value = el.attribs[domName];
if (hasOwn.call(primitives, value)) {
value = primitives[value];
} else if (value === String(Number(value))) {
value = Number(value);
} else if (rbrace.test(value)) {
try {
value = JSON.parse(value);
} catch(e){ }
}
el.data[jsName] = value;
}
}
return readAll ? el.data : value;
};
exports.data = function(name, value) {
var elem = this[0];
if (!elem || !isTag(elem)) return;
if (!elem.data) {
elem.data = {};
}
// Return the entire data object if no data specified
if (!name) {
return readData(elem);
}
// Set the value (with attr map support)
if (typeof name === 'object' || value !== undefined) {
domEach(this, function(i, el) {
setData(el, name, value);
});
return this;
} else if (hasOwn.call(elem.data, name)) {
return elem.data[name];
}
return readData(elem, name);
};
/**
* Get the value of an element
*/
exports.val = function(value) {
var querying = arguments.length === 0,
element = this[0];
if(!element) return;
switch (element.name) {
case 'textarea':
return this.text(value);
case 'input':
switch (this.attr('type')) {
case 'radio':
if (querying) {
return this.attr('value');
} else {
this.attr('value', value);
return this;
}
break;
default:
return this.attr('value', value);
}
return;
case 'select':
var option = this.find('option:selected'),
returnValue;
if (option === undefined) return undefined;
if (!querying) {
if (!this.attr().hasOwnProperty('multiple') && typeof value == 'object') {
return this;
}
if (typeof value != 'object') {
value = [value];
}
this.find('option').removeAttr('selected');
for (var i = 0; i < value.length; i++) {
this.find('option[value="' + value[i] + '"]').attr('selected', '');
}
return this;
}
returnValue = option.attr('value');
if (this.attr().hasOwnProperty('multiple')) {
returnValue = [];
domEach(option, function(i, el) {
returnValue.push(getAttr(el, 'value'));
});
}
return returnValue;
case 'option':
if (!querying) {
this.attr('value', value);
return this;
}
return this.attr('value');
}
};
/**
* Remove an attribute
*/
var removeAttribute = function(elem, name) {
if (!elem.attribs || !hasOwn.call(elem.attribs, name))
return;
delete elem.attribs[name];
};
exports.removeAttr = function(name) {
domEach(this, function(i, elem) {
removeAttribute(elem, name);
});
return this;
};
exports.hasClass = function(className) {
return _.some(this, function(elem) {
var attrs = elem.attribs,
clazz = attrs && attrs['class'],
idx = -1,
end;
if (clazz) {
while ((idx = clazz.indexOf(className, idx+1)) > -1) {
end = idx + className.length;
if ((idx === 0 || rspace.test(clazz[idx-1]))
&& (end === clazz.length || rspace.test(clazz[end]))) {
return true;
}
}
}
});
};
exports.addClass = function(value) {
// Support functions
if (typeof value === 'function') {
return domEach(this, function(i, el) {
var className = el.attribs['class'] || '';
exports.addClass.call([el], value.call(el, i, className));
});
}
// Return if no value or not a string or function
if (!value || typeof value !== 'string') return this;
var classNames = value.split(rspace),
numElements = this.length;
for (var i = 0; i < numElements; i++) {
// If selected element isn't a tag, move on
if (!isTag(this[i])) continue;
// If we don't already have classes
var className = getAttr(this[i], 'class'),
numClasses,
setClass;
if (!className) {
setAttr(this[i], 'class', classNames.join(' ').trim());
} else {
setClass = ' ' + className + ' ';
numClasses = classNames.length;
// Check if class already exists
for (var j = 0; j < numClasses; j++) {
var appendClass = classNames[j] + ' ';
if (setClass.indexOf(' ' + appendClass) < 0)
setClass += appendClass;
}
setAttr(this[i], 'class', setClass.trim());
}
}
return this;
};
var splitClass = function(className) {
return className ? className.trim().split(rspace) : [];
};
exports.removeClass = function(value) {
var classes,
numClasses,
removeAll;
// Handle if value is a function
if (typeof value === 'function') {
return domEach(this, function(i, el) {
exports.removeClass.call(
[el], value.call(el, i, el.attribs['class'] || '')
);
});
}
classes = splitClass(value);
numClasses = classes.length;
removeAll = arguments.length === 0;
return domEach(this, function(i, el) {
if (!isTag(el)) return;
if (removeAll) {
// Short circuit the remove all case as this is the nice one
el.attribs.class = '';
} else {
var elClasses = splitClass(el.attribs.class),
index,
changed;
for (var j = 0; j < numClasses; j++) {
index = elClasses.indexOf(classes[j]);
if (index >= 0) {
elClasses.splice(index, 1);
changed = true;
// We have to do another pass to ensure that there are not duplicate
// classes listed
j--;
}
}
if (changed) {
el.attribs.class = elClasses.join(' ');
}
}
});
};
exports.toggleClass = function(value, stateVal) {
// Support functions
if (typeof value === 'function') {
return domEach(this, function(i, el) {
exports.toggleClass.call(
[el],
value.call(el, i, el.attribs['class'] || '', stateVal),
stateVal
);
});
}
// Return if no value or not a string or function
if (!value || typeof value !== 'string') return this;
var classNames = value.split(rspace),
numClasses = classNames.length,
state = typeof stateVal === 'boolean' ? stateVal ? 1 : -1 : 0,
numElements = this.length,
elementClasses,
index;
for (var i = 0; i < numElements; i++) {
// If selected element isn't a tag, move on
if (!isTag(this[i])) continue;
elementClasses = splitClass(this[i].attribs.class);
// Check if class already exists
for (var j = 0; j < numClasses; j++) {
// Check if the class name is currently defined
index = elementClasses.indexOf(classNames[j]);
// Add if stateValue === true or we are toggling and there is no value
if (state >= 0 && index < 0) {
elementClasses.push(classNames[j]);
} else if (state <= 0 && index >= 0) {
// Otherwise remove but only if the item exists
elementClasses.splice(index, 1);
}
}
this[i].attribs.class = elementClasses.join(' ');
}
return this;
};
exports.is = function (selector) {
if (selector) {
return this.filter(selector).length > 0;
}
return false;
};

121
editor/node_modules/cheerio/lib/api/css.js generated vendored Normal file
View File

@@ -0,0 +1,121 @@
var domEach = require('../utils').domEach,
_ = {
pick: require('lodash.pick'),
};
var toString = Object.prototype.toString;
/**
* Set / Get css.
*
* @param {String|Object} prop
* @param {String} val
* @return {self}
* @api public
*/
exports.css = function(prop, val) {
if (arguments.length === 2 ||
// When `prop` is a "plain" object
(toString.call(prop) === '[object Object]')) {
return domEach(this, function(idx, el) {
setCss(el, prop, val, idx);
});
} else {
return getCss(this[0], prop);
}
};
/**
* Set styles of all elements.
*
* @param {String|Object} prop
* @param {String} val
* @param {Number} idx - optional index within the selection
* @return {self}
* @api private
*/
function setCss(el, prop, val, idx) {
if ('string' == typeof prop) {
var styles = getCss(el);
if (typeof val === 'function') {
val = val.call(el, idx, styles[prop]);
}
if (val === '') {
delete styles[prop];
} else if (val != null) {
styles[prop] = val;
}
el.attribs.style = stringify(styles);
} else if ('object' == typeof prop) {
Object.keys(prop).forEach(function(k){
setCss(el, k, prop[k]);
});
}
}
/**
* Get parsed styles of the first element.
*
* @param {String} prop
* @return {Object}
* @api private
*/
function getCss(el, prop) {
var styles = parse(el.attribs.style);
if (typeof prop === 'string') {
return styles[prop];
} else if (Array.isArray(prop)) {
return _.pick(styles, prop);
} else {
return styles;
}
}
/**
* Stringify `obj` to styles.
*
* @param {Object} obj
* @return {Object}
* @api private
*/
function stringify(obj) {
return Object.keys(obj || {})
.reduce(function(str, prop){
return str += ''
+ (str ? ' ' : '')
+ prop
+ ': '
+ obj[prop]
+ ';';
}, '');
}
/**
* Parse `styles`.
*
* @param {String} styles
* @return {Object}
* @api private
*/
function parse(styles) {
styles = (styles || '').trim();
if (!styles) return {};
return styles
.split(';')
.reduce(function(obj, str){
var n = str.indexOf(':');
// skip if there is no :, or if it is the first/last character
if (n < 1 || n === str.length-1) return obj;
obj[str.slice(0,n).trim()] = str.slice(n+1).trim();
return obj;
}, {});
}

65
editor/node_modules/cheerio/lib/api/forms.js generated vendored Normal file
View File

@@ -0,0 +1,65 @@
// https://github.com/jquery/jquery/blob/2.1.3/src/manipulation/var/rcheckableType.js
// https://github.com/jquery/jquery/blob/2.1.3/src/serialize.js
var submittableSelector = 'input,select,textarea,keygen',
r20 = /%20/g,
rCRLF = /\r?\n/g,
_ = {
map: require('lodash.map')
};
exports.serialize = function() {
// Convert form elements into name/value objects
var arr = this.serializeArray();
// Serialize each element into a key/value string
var retArr = _.map(arr, function(data) {
return encodeURIComponent(data.name) + '=' + encodeURIComponent(data.value);
});
// Return the resulting serialization
return retArr.join('&').replace(r20, '+');
};
exports.serializeArray = function() {
// Resolve all form elements from either forms or collections of form elements
var Cheerio = this.constructor;
return this.map(function() {
var elem = this;
var $elem = Cheerio(elem);
if (elem.name === 'form') {
return $elem.find(submittableSelector).toArray();
} else {
return $elem.filter(submittableSelector).toArray();
}
}).filter(
// Verify elements have a name (`attr.name`) and are not disabled (`:disabled`)
'[name!=""]:not(:disabled)'
// and cannot be clicked (`[type=submit]`) or are used in `x-www-form-urlencoded` (`[type=file]`)
+ ':not(:submit, :button, :image, :reset, :file)'
// and are either checked/don't have a checkable state
+ ':matches([checked], :not(:checkbox, :radio))'
// Convert each of the elements to its value(s)
).map(function(i, elem) {
var $elem = Cheerio(elem);
var name = $elem.attr('name');
var val = $elem.val();
// If there is no value set (e.g. `undefined`, `null`), then return nothing
if (val == null) {
return null;
} else {
// If we have an array of values (e.g. `<select multiple>`), return an array of key/value pairs
if (Array.isArray(val)) {
return _.map(val, function(val) {
// We trim replace any line endings (e.g. `\r` or `\r\n` with `\r\n`) to guarantee consistency across platforms
// These can occur inside of `<textarea>'s`
return {name: name, value: val.replace( rCRLF, '\r\n' )};
});
// Otherwise (e.g. `<input type="text">`, return only one key/value pair
} else {
return {name: name, value: val.replace( rCRLF, '\r\n' )};
}
}
// Convert our result to an array
}).get();
};

425
editor/node_modules/cheerio/lib/api/manipulation.js generated vendored Normal file
View File

@@ -0,0 +1,425 @@
var parse = require('../parse'),
$ = require('../static'),
updateDOM = parse.update,
evaluate = parse.evaluate,
utils = require('../utils'),
domEach = utils.domEach,
cloneDom = utils.cloneDom,
isHtml = utils.isHtml,
slice = Array.prototype.slice,
_ = {
flatten: require('lodash.flatten'),
bind: require('lodash.bind'),
forEach: require('lodash.foreach')
};
// Create an array of nodes, recursing into arrays and parsing strings if
// necessary
exports._makeDomArray = function makeDomArray(elem, clone) {
if (elem == null) {
return [];
} else if (elem.cheerio) {
return clone ? cloneDom(elem.get(), elem.options) : elem.get();
} else if (Array.isArray(elem)) {
return _.flatten(elem.map(function(el) {
return this._makeDomArray(el, clone);
}, this));
} else if (typeof elem === 'string') {
return evaluate(elem, this.options);
} else {
return clone ? cloneDom([elem]) : [elem];
}
};
var _insert = function(concatenator) {
return function() {
var elems = slice.call(arguments),
lastIdx = this.length - 1;
return domEach(this, function(i, el) {
var dom, domSrc;
if (typeof elems[0] === 'function') {
domSrc = elems[0].call(el, i, $.html(el.children));
} else {
domSrc = elems;
}
dom = this._makeDomArray(domSrc, i < lastIdx);
concatenator(dom, el.children, el);
});
};
};
/*
* Modify an array in-place, removing some number of elements and adding new
* elements directly following them.
*
* @param {Array} array Target array to splice.
* @param {Number} spliceIdx Index at which to begin changing the array.
* @param {Number} spliceCount Number of elements to remove from the array.
* @param {Array} newElems Elements to insert into the array.
*
* @api private
*/
var uniqueSplice = function(array, spliceIdx, spliceCount, newElems, parent) {
var spliceArgs = [spliceIdx, spliceCount].concat(newElems),
prev = array[spliceIdx - 1] || null,
next = array[spliceIdx] || null;
var idx, len, prevIdx, node, oldParent;
// Before splicing in new elements, ensure they do not already appear in the
// current array.
for (idx = 0, len = newElems.length; idx < len; ++idx) {
node = newElems[idx];
oldParent = node.parent || node.root;
prevIdx = oldParent && oldParent.children.indexOf(newElems[idx]);
if (oldParent && prevIdx > -1) {
oldParent.children.splice(prevIdx, 1);
if (parent === oldParent && spliceIdx > prevIdx) {
spliceArgs[0]--;
}
}
node.root = null;
node.parent = parent;
if (node.prev) {
node.prev.next = node.next || null;
}
if (node.next) {
node.next.prev = node.prev || null;
}
node.prev = newElems[idx - 1] || prev;
node.next = newElems[idx + 1] || next;
}
if (prev) {
prev.next = newElems[0];
}
if (next) {
next.prev = newElems[newElems.length - 1];
}
return array.splice.apply(array, spliceArgs);
};
exports.appendTo = function(target) {
if (!target.cheerio) {
target = this.constructor.call(this.constructor, target, null, this._originalRoot);
}
target.append(this);
return this;
};
exports.prependTo = function(target) {
if (!target.cheerio) {
target = this.constructor.call(this.constructor, target, null, this._originalRoot);
}
target.prepend(this);
return this;
};
exports.append = _insert(function(dom, children, parent) {
uniqueSplice(children, children.length, 0, dom, parent);
});
exports.prepend = _insert(function(dom, children, parent) {
uniqueSplice(children, 0, 0, dom, parent);
});
exports.wrap = function(wrapper) {
var wrapperFn = typeof wrapper === 'function' && wrapper,
lastIdx = this.length - 1;
_.forEach(this, _.bind(function(el, i) {
var parent = el.parent || el.root,
siblings = parent.children,
dom, index;
if (!parent) {
return;
}
if (wrapperFn) {
wrapper = wrapperFn.call(el, i);
}
if (typeof wrapper === 'string' && !isHtml(wrapper)) {
wrapper = this.parents().last().find(wrapper).clone();
}
dom = this._makeDomArray(wrapper, i < lastIdx).slice(0, 1);
index = siblings.indexOf(el);
updateDOM([el], dom[0]);
// The previous operation removed the current element from the `siblings`
// array, so the `dom` array can be inserted without removing any
// additional elements.
uniqueSplice(siblings, index, 0, dom, parent);
}, this));
return this;
};
exports.after = function() {
var elems = slice.call(arguments),
lastIdx = this.length - 1;
domEach(this, function(i, el) {
var parent = el.parent || el.root;
if (!parent) {
return;
}
var siblings = parent.children,
index = siblings.indexOf(el),
domSrc, dom;
// If not found, move on
if (index < 0) return;
if (typeof elems[0] === 'function') {
domSrc = elems[0].call(el, i, $.html(el.children));
} else {
domSrc = elems;
}
dom = this._makeDomArray(domSrc, i < lastIdx);
// Add element after `this` element
uniqueSplice(siblings, index + 1, 0, dom, parent);
});
return this;
};
exports.insertAfter = function(target) {
var clones = [],
self = this;
if (typeof target === 'string') {
target = this.constructor.call(this.constructor, target, null, this._originalRoot);
}
target = this._makeDomArray(target);
self.remove();
domEach(target, function(i, el) {
var clonedSelf = self._makeDomArray(self.clone());
var parent = el.parent || el.root;
if (!parent) {
return;
}
var siblings = parent.children,
index = siblings.indexOf(el);
// If not found, move on
if (index < 0) return;
// Add cloned `this` element(s) after target element
uniqueSplice(siblings, index + 1, 0, clonedSelf, parent);
clones.push(clonedSelf);
});
return this.constructor.call(this.constructor, this._makeDomArray(clones));
};
exports.before = function() {
var elems = slice.call(arguments),
lastIdx = this.length - 1;
domEach(this, function(i, el) {
var parent = el.parent || el.root;
if (!parent) {
return;
}
var siblings = parent.children,
index = siblings.indexOf(el),
domSrc, dom;
// If not found, move on
if (index < 0) return;
if (typeof elems[0] === 'function') {
domSrc = elems[0].call(el, i, $.html(el.children));
} else {
domSrc = elems;
}
dom = this._makeDomArray(domSrc, i < lastIdx);
// Add element before `el` element
uniqueSplice(siblings, index, 0, dom, parent);
});
return this;
};
exports.insertBefore = function(target) {
var clones = [],
self = this;
if (typeof target === 'string') {
target = this.constructor.call(this.constructor, target, null, this._originalRoot);
}
target = this._makeDomArray(target);
self.remove();
domEach(target, function(i, el) {
var clonedSelf = self._makeDomArray(self.clone());
var parent = el.parent || el.root;
if (!parent) {
return;
}
var siblings = parent.children,
index = siblings.indexOf(el);
// If not found, move on
if (index < 0) return;
// Add cloned `this` element(s) after target element
uniqueSplice(siblings, index, 0, clonedSelf, parent);
clones.push(clonedSelf);
});
return this.constructor.call(this.constructor, this._makeDomArray(clones));
};
/*
remove([selector])
*/
exports.remove = function(selector) {
var elems = this;
// Filter if we have selector
if (selector)
elems = elems.filter(selector);
domEach(elems, function(i, el) {
var parent = el.parent || el.root;
if (!parent) {
return;
}
var siblings = parent.children,
index = siblings.indexOf(el);
if (index < 0) return;
siblings.splice(index, 1);
if (el.prev) {
el.prev.next = el.next;
}
if (el.next) {
el.next.prev = el.prev;
}
el.prev = el.next = el.parent = el.root = null;
});
return this;
};
exports.replaceWith = function(content) {
var self = this;
domEach(this, function(i, el) {
var parent = el.parent || el.root;
if (!parent) {
return;
}
var siblings = parent.children,
dom = self._makeDomArray(typeof content === 'function' ? content.call(el, i, el) : content),
index;
// In the case that `dom` contains nodes that already exist in other
// structures, ensure those nodes are properly removed.
updateDOM(dom, null);
index = siblings.indexOf(el);
// Completely remove old element
uniqueSplice(siblings, index, 1, dom, parent);
el.parent = el.prev = el.next = el.root = null;
});
return this;
};
exports.empty = function() {
domEach(this, function(i, el) {
_.forEach(el.children, function(el) {
el.next = el.prev = el.parent = null;
});
el.children.length = 0;
});
return this;
};
/**
* Set/Get the HTML
*/
exports.html = function(str) {
if (str === undefined) {
if (!this[0] || !this[0].children) return null;
return $.html(this[0].children, this.options);
}
var opts = this.options;
domEach(this, function(i, el) {
_.forEach(el.children, function(el) {
el.next = el.prev = el.parent = null;
});
var content = str.cheerio ? str.clone().get() : evaluate('' + str, opts);
updateDOM(content, el);
});
return this;
};
exports.toString = function() {
return $.html(this, this.options);
};
exports.text = function(str) {
// If `str` is undefined, act as a "getter"
if (str === undefined) {
return $.text(this);
} else if (typeof str === 'function') {
// Function support
return domEach(this, function(i, el) {
var $el = [el];
return exports.text.call($el, str.call(el, i, $.text($el)));
});
}
// Append text node to each selected elements
domEach(this, function(i, el) {
_.forEach(el.children, function(el) {
el.next = el.prev = el.parent = null;
});
var elem = {
data: '' + str,
type: 'text',
parent: el,
prev: null,
next: null,
children: []
};
updateDOM(elem, el);
});
return this;
};
exports.clone = function() {
return this._make(cloneDom(this.get(), this.options));
};

429
editor/node_modules/cheerio/lib/api/traversing.js generated vendored Normal file
View File

@@ -0,0 +1,429 @@
var select = require('css-select'),
utils = require('../utils'),
domEach = utils.domEach,
uniqueSort = require('htmlparser2').DomUtils.uniqueSort,
isTag = utils.isTag,
_ = {
bind: require('lodash.bind'),
forEach: require('lodash.foreach'),
reject: require('lodash.reject'),
filter: require('lodash.filter'),
reduce: require('lodash.reduce')
};
exports.find = function(selectorOrHaystack) {
var elems = _.reduce(this, function(memo, elem) {
return memo.concat(_.filter(elem.children, isTag));
}, []);
var contains = this.constructor.contains;
var haystack;
if (selectorOrHaystack && typeof selectorOrHaystack !== 'string') {
if (selectorOrHaystack.cheerio) {
haystack = selectorOrHaystack.get();
} else {
haystack = [selectorOrHaystack];
}
return this._make(haystack.filter(function(elem) {
var idx, len;
for (idx = 0, len = this.length; idx < len; ++idx) {
if (contains(this[idx], elem)) {
return true;
}
}
}, this));
}
var options = {__proto__: this.options, context: this.toArray()};
return this._make(select(selectorOrHaystack, elems, options));
};
// Get the parent of each element in the current set of matched elements,
// optionally filtered by a selector.
exports.parent = function(selector) {
var set = [];
domEach(this, function(idx, elem) {
var parentElem = elem.parent;
if (parentElem && set.indexOf(parentElem) < 0) {
set.push(parentElem);
}
});
if (arguments.length) {
set = exports.filter.call(set, selector, this);
}
return this._make(set);
};
exports.parents = function(selector) {
var parentNodes = [];
// When multiple DOM elements are in the original set, the resulting set will
// be in *reverse* order of the original elements as well, with duplicates
// removed.
this.get().reverse().forEach(function(elem) {
traverseParents(this, elem.parent, selector, Infinity)
.forEach(function(node) {
if (parentNodes.indexOf(node) === -1) {
parentNodes.push(node);
}
}
);
}, this);
return this._make(parentNodes);
};
exports.parentsUntil = function(selector, filter) {
var parentNodes = [], untilNode, untilNodes;
if (typeof selector === 'string') {
untilNode = select(selector, this.parents().toArray(), this.options)[0];
} else if (selector && selector.cheerio) {
untilNodes = selector.toArray();
} else if (selector) {
untilNode = selector;
}
// When multiple DOM elements are in the original set, the resulting set will
// be in *reverse* order of the original elements as well, with duplicates
// removed.
this.toArray().reverse().forEach(function(elem) {
while ((elem = elem.parent)) {
if ((untilNode && elem !== untilNode) ||
(untilNodes && untilNodes.indexOf(elem) === -1) ||
(!untilNode && !untilNodes)) {
if (isTag(elem) && parentNodes.indexOf(elem) === -1) { parentNodes.push(elem); }
} else {
break;
}
}
}, this);
return this._make(filter ? select(filter, parentNodes, this.options) : parentNodes);
};
// For each element in the set, get the first element that matches the selector
// by testing the element itself and traversing up through its ancestors in the
// DOM tree.
exports.closest = function(selector) {
var set = [];
if (!selector) {
return this._make(set);
}
domEach(this, function(idx, elem) {
var closestElem = traverseParents(this, elem, selector, 1)[0];
// Do not add duplicate elements to the set
if (closestElem && set.indexOf(closestElem) < 0) {
set.push(closestElem);
}
}.bind(this));
return this._make(set);
};
exports.next = function(selector) {
if (!this[0]) { return this; }
var elems = [];
_.forEach(this, function(elem) {
while ((elem = elem.next)) {
if (isTag(elem)) {
elems.push(elem);
return;
}
}
});
return selector ?
exports.filter.call(elems, selector, this) :
this._make(elems);
};
exports.nextAll = function(selector) {
if (!this[0]) { return this; }
var elems = [];
_.forEach(this, function(elem) {
while ((elem = elem.next)) {
if (isTag(elem) && elems.indexOf(elem) === -1) {
elems.push(elem);
}
}
});
return selector ?
exports.filter.call(elems, selector, this) :
this._make(elems);
};
exports.nextUntil = function(selector, filterSelector) {
if (!this[0]) { return this; }
var elems = [], untilNode, untilNodes;
if (typeof selector === 'string') {
untilNode = select(selector, this.nextAll().get(), this.options)[0];
} else if (selector && selector.cheerio) {
untilNodes = selector.get();
} else if (selector) {
untilNode = selector;
}
_.forEach(this, function(elem) {
while ((elem = elem.next)) {
if ((untilNode && elem !== untilNode) ||
(untilNodes && untilNodes.indexOf(elem) === -1) ||
(!untilNode && !untilNodes)) {
if (isTag(elem) && elems.indexOf(elem) === -1) {
elems.push(elem);
}
} else {
break;
}
}
});
return filterSelector ?
exports.filter.call(elems, filterSelector, this) :
this._make(elems);
};
exports.prev = function(selector) {
if (!this[0]) { return this; }
var elems = [];
_.forEach(this, function(elem) {
while ((elem = elem.prev)) {
if (isTag(elem)) {
elems.push(elem);
return;
}
}
});
return selector ?
exports.filter.call(elems, selector, this) :
this._make(elems);
};
exports.prevAll = function(selector) {
if (!this[0]) { return this; }
var elems = [];
_.forEach(this, function(elem) {
while ((elem = elem.prev)) {
if (isTag(elem) && elems.indexOf(elem) === -1) {
elems.push(elem);
}
}
});
return selector ?
exports.filter.call(elems, selector, this) :
this._make(elems);
};
exports.prevUntil = function(selector, filterSelector) {
if (!this[0]) { return this; }
var elems = [], untilNode, untilNodes;
if (typeof selector === 'string') {
untilNode = select(selector, this.prevAll().get(), this.options)[0];
} else if (selector && selector.cheerio) {
untilNodes = selector.get();
} else if (selector) {
untilNode = selector;
}
_.forEach(this, function(elem) {
while ((elem = elem.prev)) {
if ((untilNode && elem !== untilNode) ||
(untilNodes && untilNodes.indexOf(elem) === -1) ||
(!untilNode && !untilNodes)) {
if (isTag(elem) && elems.indexOf(elem) === -1) {
elems.push(elem);
}
} else {
break;
}
}
});
return filterSelector ?
exports.filter.call(elems, filterSelector, this) :
this._make(elems);
};
exports.siblings = function(selector) {
var parent = this.parent();
var elems = _.filter(
parent ? parent.children() : this.siblingsAndMe(),
_.bind(function(elem) { return isTag(elem) && !this.is(elem); }, this)
);
if (selector !== undefined) {
return exports.filter.call(elems, selector, this);
} else {
return this._make(elems);
}
};
exports.children = function(selector) {
var elems = _.reduce(this, function(memo, elem) {
return memo.concat(_.filter(elem.children, isTag));
}, []);
if (selector === undefined) return this._make(elems);
return exports.filter.call(elems, selector, this);
};
exports.contents = function() {
return this._make(_.reduce(this, function(all, elem) {
all.push.apply(all, elem.children);
return all;
}, []));
};
exports.each = function(fn) {
var i = 0, len = this.length;
while (i < len && fn.call(this[i], i, this[i]) !== false) ++i;
return this;
};
exports.map = function(fn) {
return this._make(_.reduce(this, function(memo, el, i) {
var val = fn.call(el, i, el);
return val == null ? memo : memo.concat(val);
}, []));
};
var makeFilterMethod = function(filterFn) {
return function(match, container) {
var testFn;
container = container || this;
if (typeof match === 'string') {
testFn = select.compile(match, container.options);
} else if (typeof match === 'function') {
testFn = function(el, i) {
return match.call(el, i, el);
};
} else if (match.cheerio) {
testFn = match.is.bind(match);
} else {
testFn = function(el) {
return match === el;
};
}
return container._make(filterFn(this, testFn));
};
};
exports.filter = makeFilterMethod(_.filter);
exports.not = makeFilterMethod(_.reject);
exports.has = function(selectorOrHaystack) {
var that = this;
return exports.filter.call(this, function() {
return that._make(this).find(selectorOrHaystack).length > 0;
});
};
exports.first = function() {
return this.length > 1 ? this._make(this[0]) : this;
};
exports.last = function() {
return this.length > 1 ? this._make(this[this.length - 1]) : this;
};
// Reduce the set of matched elements to the one at the specified index.
exports.eq = function(i) {
i = +i;
// Use the first identity optimization if possible
if (i === 0 && this.length <= 1) return this;
if (i < 0) i = this.length + i;
return this[i] ? this._make(this[i]) : this._make([]);
};
// Retrieve the DOM elements matched by the jQuery object.
exports.get = function(i) {
if (i == null) {
return Array.prototype.slice.call(this);
} else {
return this[i < 0 ? (this.length + i) : i];
}
};
// Search for a given element from among the matched elements.
exports.index = function(selectorOrNeedle) {
var $haystack, needle;
if (arguments.length === 0) {
$haystack = this.parent().children();
needle = this[0];
} else if (typeof selectorOrNeedle === 'string') {
$haystack = this._make(selectorOrNeedle);
needle = this[0];
} else {
$haystack = this;
needle = selectorOrNeedle.cheerio ? selectorOrNeedle[0] : selectorOrNeedle;
}
return $haystack.get().indexOf(needle);
};
exports.slice = function() {
return this._make([].slice.apply(this, arguments));
};
function traverseParents(self, elem, selector, limit) {
var elems = [];
while (elem && elems.length < limit) {
if (!selector || exports.filter.call([elem], selector, self).length) {
elems.push(elem);
}
elem = elem.parent;
}
return elems;
}
// End the most recent filtering operation in the current chain and return the
// set of matched elements to its previous state.
exports.end = function() {
return this.prevObject || this._make([]);
};
exports.add = function(other, context) {
var selection = this._make(other, context);
var contents = uniqueSort(selection.get().concat(this.get()));
for (var i = 0; i < contents.length; ++i) {
selection[i] = contents[i];
}
selection.length = contents.length;
return selection;
};
// Add the previous set of elements on the stack to the current set, optionally
// filtered by a selector.
exports.addBack = function(selector) {
return this.add(
arguments.length ? this.prevObject.filter(selector) : this.prevObject
);
};

148
editor/node_modules/cheerio/lib/cheerio.js generated vendored Normal file
View File

@@ -0,0 +1,148 @@
/*
Module dependencies
*/
var parse = require('./parse'),
isHtml = require('./utils').isHtml,
_ = {
extend: require('lodash.assignin'),
bind: require('lodash.bind'),
forEach: require('lodash.foreach'),
defaults: require('lodash.defaults')
};
/*
* The API
*/
var api = [
require('./api/attributes'),
require('./api/traversing'),
require('./api/manipulation'),
require('./api/css'),
require('./api/forms')
];
/*
* Instance of cheerio
*/
var Cheerio = module.exports = function(selector, context, root, options) {
if (!(this instanceof Cheerio)) return new Cheerio(selector, context, root, options);
this.options = _.defaults(options || {}, this.options);
// $(), $(null), $(undefined), $(false)
if (!selector) return this;
if (root) {
if (typeof root === 'string') root = parse(root, this.options);
this._root = Cheerio.call(this, root);
}
// $($)
if (selector.cheerio) return selector;
// $(dom)
if (isNode(selector))
selector = [selector];
// $([dom])
if (Array.isArray(selector)) {
_.forEach(selector, _.bind(function(elem, idx) {
this[idx] = elem;
}, this));
this.length = selector.length;
return this;
}
// $(<html>)
if (typeof selector === 'string' && isHtml(selector)) {
return Cheerio.call(this, parse(selector, this.options).children);
}
// If we don't have a context, maybe we have a root, from loading
if (!context) {
context = this._root;
} else if (typeof context === 'string') {
if (isHtml(context)) {
// $('li', '<ul>...</ul>')
context = parse(context, this.options);
context = Cheerio.call(this, context);
} else {
// $('li', 'ul')
selector = [context, selector].join(' ');
context = this._root;
}
// $('li', node), $('li', [nodes])
} else if (!context.cheerio) {
context = Cheerio.call(this, context);
}
// If we still don't have a context, return
if (!context) return this;
// #id, .class, tag
return context.find(selector);
};
/**
* Mix in `static`
*/
_.extend(Cheerio, require('./static'));
/*
* Set a signature of the object
*/
Cheerio.prototype.cheerio = '[cheerio object]';
/*
* Cheerio default options
*/
Cheerio.prototype.options = {
withDomLvl1: true,
normalizeWhitespace: false,
xmlMode: false,
decodeEntities: true
};
/*
* Make cheerio an array-like object
*/
Cheerio.prototype.length = 0;
Cheerio.prototype.splice = Array.prototype.splice;
/*
* Make a cheerio object
*
* @api private
*/
Cheerio.prototype._make = function(dom, context) {
var cheerio = new this.constructor(dom, context, this._root, this.options);
cheerio.prevObject = this;
return cheerio;
};
/**
* Turn a cheerio object into an array
*/
Cheerio.prototype.toArray = function() {
return this.get();
};
/**
* Plug in the API
*/
api.forEach(function(mod) {
_.extend(Cheerio.prototype, mod);
});
var isNode = function(obj) {
return obj.name || obj.type === 'text' || obj.type === 'comment';
};

86
editor/node_modules/cheerio/lib/parse.js generated vendored Normal file
View File

@@ -0,0 +1,86 @@
/*
Module Dependencies
*/
var htmlparser = require('htmlparser2');
/*
Parser
*/
exports = module.exports = function(content, options) {
var dom = exports.evaluate(content, options),
// Generic root element
root = exports.evaluate('<root></root>', options)[0];
root.type = 'root';
// Update the dom using the root
exports.update(dom, root);
return root;
};
exports.evaluate = function(content, options) {
// options = options || $.fn.options;
var dom;
if (typeof content === 'string' || Buffer.isBuffer(content)) {
dom = htmlparser.parseDOM(content, options);
} else {
dom = content;
}
return dom;
};
/*
Update the dom structure, for one changed layer
*/
exports.update = function(arr, parent) {
// normalize
if (!Array.isArray(arr)) arr = [arr];
// Update parent
if (parent) {
parent.children = arr;
} else {
parent = null;
}
// Update neighbors
for (var i = 0; i < arr.length; i++) {
var node = arr[i];
// Cleanly remove existing nodes from their previous structures.
var oldParent = node.parent || node.root,
oldSiblings = oldParent && oldParent.children;
if (oldSiblings && oldSiblings !== arr) {
oldSiblings.splice(oldSiblings.indexOf(node), 1);
if (node.prev) {
node.prev.next = node.next;
}
if (node.next) {
node.next.prev = node.prev;
}
}
if (parent) {
node.prev = arr[i - 1] || null;
node.next = arr[i + 1] || null;
} else {
node.prev = node.next = null;
}
if (parent && parent.type === 'root') {
node.root = parent;
node.parent = null;
} else {
node.root = null;
node.parent = parent;
}
}
return parent;
};
// module.exports = $.extend(exports);

187
editor/node_modules/cheerio/lib/static.js generated vendored Normal file
View File

@@ -0,0 +1,187 @@
/**
* Module dependencies
*/
var serialize = require('dom-serializer'),
select = require('css-select'),
parse = require('./parse'),
_ = {
merge: require('lodash.merge'),
defaults: require('lodash.defaults')
};
/**
* $.load(str)
*/
exports.load = function(content, options) {
var Cheerio = require('./cheerio');
options = _.defaults(options || {}, Cheerio.prototype.options);
var root = parse(content, options);
var initialize = function(selector, context, r, opts) {
if (!(this instanceof initialize)) {
return new initialize(selector, context, r, opts);
}
opts = _.defaults(opts || {}, options);
return Cheerio.call(this, selector, context, r || root, opts);
};
// Ensure that selections created by the "loaded" `initialize` function are
// true Cheerio instances.
initialize.prototype = Object.create(Cheerio.prototype);
initialize.prototype.constructor = initialize;
// Mimic jQuery's prototype alias for plugin authors.
initialize.fn = initialize.prototype;
// Keep a reference to the top-level scope so we can chain methods that implicitly
// resolve selectors; e.g. $("<span>").(".bar"), which otherwise loses ._root
initialize.prototype._originalRoot = root;
// Add in the static methods
_.merge(initialize, exports);
// Add in the root
initialize._root = root;
// store options
initialize._options = options;
return initialize;
};
/*
* Helper function
*/
function render(that, dom, options) {
if (!dom) {
if (that._root && that._root.children) {
dom = that._root.children;
} else {
return '';
}
} else if (typeof dom === 'string') {
dom = select(dom, that._root, options);
}
return serialize(dom, options);
}
/**
* $.html([selector | dom], [options])
*/
exports.html = function(dom, options) {
var Cheerio = require('./cheerio');
// be flexible about parameters, sometimes we call html(),
// with options as only parameter
// check dom argument for dom element specific properties
// assume there is no 'length' or 'type' properties in the options object
if (Object.prototype.toString.call(dom) === '[object Object]' && !options && !('length' in dom) && !('type' in dom))
{
options = dom;
dom = undefined;
}
// sometimes $.html() used without preloading html
// so fallback non existing options to the default ones
options = _.defaults(options || {}, this._options, Cheerio.prototype.options);
return render(this, dom, options);
};
/**
* $.xml([selector | dom])
*/
exports.xml = function(dom) {
var options = _.defaults({xmlMode: true}, this._options);
return render(this, dom, options);
};
/**
* $.text(dom)
*/
exports.text = function(elems) {
if (!elems) {
elems = this.root();
}
var ret = '',
len = elems.length,
elem;
for (var i = 0; i < len; i++) {
elem = elems[i];
if (elem.type === 'text') ret += elem.data;
else if (elem.children && elem.type !== 'comment') {
ret += exports.text(elem.children);
}
}
return ret;
};
/**
* $.parseHTML(data [, context ] [, keepScripts ])
* Parses a string into an array of DOM nodes. The `context` argument has no
* meaning for Cheerio, but it is maintained for API compatibility with jQuery.
*/
exports.parseHTML = function(data, context, keepScripts) {
var parsed;
if (!data || typeof data !== 'string') {
return null;
}
if (typeof context === 'boolean') {
keepScripts = context;
}
parsed = this.load(data);
if (!keepScripts) {
parsed('script').remove();
}
// The `children` array is used by Cheerio internally to group elements that
// share the same parents. When nodes created through `parseHTML` are
// inserted into previously-existing DOM structures, they will be removed
// from the `children` array. The results of `parseHTML` should remain
// constant across these operations, so a shallow copy should be returned.
return parsed.root()[0].children.slice();
};
/**
* $.root()
*/
exports.root = function() {
return this(this._root);
};
/**
* $.contains()
*/
exports.contains = function(container, contained) {
// According to the jQuery API, an element does not "contain" itself
if (contained === container) {
return false;
}
// Step up the descendants, stopping when the root element is reached
// (signaled by `.parent` returning a reference to the same object)
while (contained && contained !== contained.parent) {
contained = contained.parent;
if (contained === container) {
return true;
}
}
return false;
};

83
editor/node_modules/cheerio/lib/utils.js generated vendored Normal file
View File

@@ -0,0 +1,83 @@
var parse = require('./parse'),
render = require('dom-serializer');
/**
* HTML Tags
*/
var tags = { tag: true, script: true, style: true };
/**
* Check if the DOM element is a tag
*
* isTag(type) includes <script> and <style> tags
*/
exports.isTag = function(type) {
if (type.type) type = type.type;
return tags[type] || false;
};
/**
* Convert a string to camel case notation.
* @param {String} str String to be converted.
* @return {String} String in camel case notation.
*/
exports.camelCase = function(str) {
return str.replace(/[_.-](\w|$)/g, function(_, x) {
return x.toUpperCase();
});
};
/**
* Convert a string from camel case to "CSS case", where word boundaries are
* described by hyphens ("-") and all characters are lower-case.
* @param {String} str String to be converted.
* @return {string} String in "CSS case".
*/
exports.cssCase = function(str) {
return str.replace(/[A-Z]/g, '-$&').toLowerCase();
};
/**
* Iterate over each DOM element without creating intermediary Cheerio instances.
*
* This is indented for use internally to avoid otherwise unnecessary memory pressure introduced
* by _make.
*/
exports.domEach = function(cheerio, fn) {
var i = 0, len = cheerio.length;
while (i < len && fn.call(cheerio, i, cheerio[i]) !== false) ++i;
return cheerio;
};
/**
* Create a deep copy of the given DOM structure by first rendering it to a
* string and then parsing the resultant markup.
*
* @argument {Object} dom - The htmlparser2-compliant DOM structure
* @argument {Object} options - The parsing/rendering options
*/
exports.cloneDom = function(dom, options) {
return parse(render(dom, options), options).children;
};
/*
* A simple way to check for HTML strings or ID strings
*/
var quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/;
/*
* Check if string is HTML
*/
exports.isHtml = function(str) {
// Faster than running regex, if str starts with `<` and ends with `>`, assume it's HTML
if (str.charAt(0) === '<' && str.charAt(str.length - 1) === '>' && str.length >= 3) return true;
// Run the regex
var match = quickExpr.exec(str);
return !!(match && match[1]);
};

131
editor/node_modules/cheerio/package.json generated vendored Normal file
View File

@@ -0,0 +1,131 @@
{
"_args": [
[
"cheerio",
"/home/osboxes/code/pentext/editor"
]
],
"_from": "cheerio@latest",
"_id": "cheerio@0.22.0",
"_inCache": true,
"_installable": true,
"_location": "/cheerio",
"_nodeVersion": "6.2.2",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/cheerio-0.22.0.tgz_1471954900169_0.12557715992443264"
},
"_npmUser": {
"email": "mattmuelle@gmail.com",
"name": "mattmueller"
},
"_npmVersion": "3.10.6",
"_phantomChildren": {},
"_requested": {
"name": "cheerio",
"raw": "cheerio",
"rawSpec": "",
"scope": null,
"spec": "latest",
"type": "tag"
},
"_requiredBy": [
"#USER"
],
"_resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz",
"_shasum": "a9baa860a3f9b595a6b81b1a86873121ed3a269e",
"_shrinkwrap": null,
"_spec": "cheerio",
"_where": "/home/osboxes/code/pentext/editor",
"author": {
"email": "mattmuelle@gmail.com",
"name": "Matt Mueller",
"url": "mat.io"
},
"bugs": {
"url": "https://github.com/cheeriojs/cheerio/issues"
},
"dependencies": {
"css-select": "~1.2.0",
"dom-serializer": "~0.1.0",
"entities": "~1.1.1",
"htmlparser2": "^3.9.1",
"lodash.assignin": "^4.0.9",
"lodash.bind": "^4.1.4",
"lodash.defaults": "^4.0.1",
"lodash.filter": "^4.4.0",
"lodash.flatten": "^4.2.0",
"lodash.foreach": "^4.3.0",
"lodash.map": "^4.4.0",
"lodash.merge": "^4.4.0",
"lodash.pick": "^4.2.1",
"lodash.reduce": "^4.4.0",
"lodash.reject": "^4.4.0",
"lodash.some": "^4.4.0"
},
"description": "Tiny, fast, and elegant implementation of core jQuery designed specifically for the server",
"devDependencies": {
"benchmark": "^2.1.0",
"coveralls": "^2.11.9",
"expect.js": "~0.3.1",
"istanbul": "^0.4.3",
"jquery": "^3.0.0",
"jsdom": "^9.2.1",
"jshint": "^2.9.2",
"mocha": "^2.5.3",
"xyz": "~0.5.0"
},
"directories": {},
"dist": {
"shasum": "a9baa860a3f9b595a6b81b1a86873121ed3a269e",
"tarball": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz"
},
"engines": {
"node": ">= 0.6"
},
"files": [
"index.js",
"lib"
],
"gitHead": "35c4917205dca9d08139c95419e2626c0689e38a",
"homepage": "https://github.com/cheeriojs/cheerio#readme",
"keywords": [
"html",
"htmlparser",
"jquery",
"parser",
"scraper",
"selector"
],
"license": "MIT",
"main": "./index.js",
"maintainers": [
{
"name": "mattmueller",
"email": "mattmuelle@gmail.com"
},
{
"name": "davidchambers",
"email": "dc@davidchambers.me"
},
{
"name": "jugglinmike",
"email": "mike@mikepennisi.com"
},
{
"name": "feedic",
"email": "me@feedic.com"
}
],
"name": "cheerio",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git://github.com/cheeriojs/cheerio.git"
},
"scripts": {
"test": "make test"
},
"version": "0.22.0"
}

1
editor/node_modules/core-util-is/.meteor-portable generated vendored Normal file
View File

@@ -0,0 +1 @@
true

19
editor/node_modules/core-util-is/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright Node.js contributors. All rights reserved.
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.

3
editor/node_modules/core-util-is/README.md generated vendored Normal file
View File

@@ -0,0 +1,3 @@
# core-util-is
The `util.is*` functions introduced in Node v0.12.

604
editor/node_modules/core-util-is/float.patch generated vendored Normal file
View File

@@ -0,0 +1,604 @@
diff --git a/lib/util.js b/lib/util.js
index a03e874..9074e8e 100644
--- a/lib/util.js
+++ b/lib/util.js
@@ -19,430 +19,6 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
-var formatRegExp = /%[sdj%]/g;
-exports.format = function(f) {
- if (!isString(f)) {
- var objects = [];
- for (var i = 0; i < arguments.length; i++) {
- objects.push(inspect(arguments[i]));
- }
- return objects.join(' ');
- }
-
- var i = 1;
- var args = arguments;
- var len = args.length;
- var str = String(f).replace(formatRegExp, function(x) {
- if (x === '%%') return '%';
- if (i >= len) return x;
- switch (x) {
- case '%s': return String(args[i++]);
- case '%d': return Number(args[i++]);
- case '%j':
- try {
- return JSON.stringify(args[i++]);
- } catch (_) {
- return '[Circular]';
- }
- default:
- return x;
- }
- });
- for (var x = args[i]; i < len; x = args[++i]) {
- if (isNull(x) || !isObject(x)) {
- str += ' ' + x;
- } else {
- str += ' ' + inspect(x);
- }
- }
- return str;
-};
-
-
-// Mark that a method should not be used.
-// Returns a modified function which warns once by default.
-// If --no-deprecation is set, then it is a no-op.
-exports.deprecate = function(fn, msg) {
- // Allow for deprecating things in the process of starting up.
- if (isUndefined(global.process)) {
- return function() {
- return exports.deprecate(fn, msg).apply(this, arguments);
- };
- }
-
- if (process.noDeprecation === true) {
- return fn;
- }
-
- var warned = false;
- function deprecated() {
- if (!warned) {
- if (process.throwDeprecation) {
- throw new Error(msg);
- } else if (process.traceDeprecation) {
- console.trace(msg);
- } else {
- console.error(msg);
- }
- warned = true;
- }
- return fn.apply(this, arguments);
- }
-
- return deprecated;
-};
-
-
-var debugs = {};
-var debugEnviron;
-exports.debuglog = function(set) {
- if (isUndefined(debugEnviron))
- debugEnviron = process.env.NODE_DEBUG || '';
- set = set.toUpperCase();
- if (!debugs[set]) {
- if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
- var pid = process.pid;
- debugs[set] = function() {
- var msg = exports.format.apply(exports, arguments);
- console.error('%s %d: %s', set, pid, msg);
- };
- } else {
- debugs[set] = function() {};
- }
- }
- return debugs[set];
-};
-
-
-/**
- * Echos the value of a value. Trys to print the value out
- * in the best way possible given the different types.
- *
- * @param {Object} obj The object to print out.
- * @param {Object} opts Optional options object that alters the output.
- */
-/* legacy: obj, showHidden, depth, colors*/
-function inspect(obj, opts) {
- // default options
- var ctx = {
- seen: [],
- stylize: stylizeNoColor
- };
- // legacy...
- if (arguments.length >= 3) ctx.depth = arguments[2];
- if (arguments.length >= 4) ctx.colors = arguments[3];
- if (isBoolean(opts)) {
- // legacy...
- ctx.showHidden = opts;
- } else if (opts) {
- // got an "options" object
- exports._extend(ctx, opts);
- }
- // set default options
- if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
- if (isUndefined(ctx.depth)) ctx.depth = 2;
- if (isUndefined(ctx.colors)) ctx.colors = false;
- if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
- if (ctx.colors) ctx.stylize = stylizeWithColor;
- return formatValue(ctx, obj, ctx.depth);
-}
-exports.inspect = inspect;
-
-
-// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
-inspect.colors = {
- 'bold' : [1, 22],
- 'italic' : [3, 23],
- 'underline' : [4, 24],
- 'inverse' : [7, 27],
- 'white' : [37, 39],
- 'grey' : [90, 39],
- 'black' : [30, 39],
- 'blue' : [34, 39],
- 'cyan' : [36, 39],
- 'green' : [32, 39],
- 'magenta' : [35, 39],
- 'red' : [31, 39],
- 'yellow' : [33, 39]
-};
-
-// Don't use 'blue' not visible on cmd.exe
-inspect.styles = {
- 'special': 'cyan',
- 'number': 'yellow',
- 'boolean': 'yellow',
- 'undefined': 'grey',
- 'null': 'bold',
- 'string': 'green',
- 'date': 'magenta',
- // "name": intentionally not styling
- 'regexp': 'red'
-};
-
-
-function stylizeWithColor(str, styleType) {
- var style = inspect.styles[styleType];
-
- if (style) {
- return '\u001b[' + inspect.colors[style][0] + 'm' + str +
- '\u001b[' + inspect.colors[style][1] + 'm';
- } else {
- return str;
- }
-}
-
-
-function stylizeNoColor(str, styleType) {
- return str;
-}
-
-
-function arrayToHash(array) {
- var hash = {};
-
- array.forEach(function(val, idx) {
- hash[val] = true;
- });
-
- return hash;
-}
-
-
-function formatValue(ctx, value, recurseTimes) {
- // Provide a hook for user-specified inspect functions.
- // Check that value is an object with an inspect function on it
- if (ctx.customInspect &&
- value &&
- isFunction(value.inspect) &&
- // Filter out the util module, it's inspect function is special
- value.inspect !== exports.inspect &&
- // Also filter out any prototype objects using the circular check.
- !(value.constructor && value.constructor.prototype === value)) {
- var ret = value.inspect(recurseTimes, ctx);
- if (!isString(ret)) {
- ret = formatValue(ctx, ret, recurseTimes);
- }
- return ret;
- }
-
- // Primitive types cannot have properties
- var primitive = formatPrimitive(ctx, value);
- if (primitive) {
- return primitive;
- }
-
- // Look up the keys of the object.
- var keys = Object.keys(value);
- var visibleKeys = arrayToHash(keys);
-
- if (ctx.showHidden) {
- keys = Object.getOwnPropertyNames(value);
- }
-
- // Some type of object without properties can be shortcutted.
- if (keys.length === 0) {
- if (isFunction(value)) {
- var name = value.name ? ': ' + value.name : '';
- return ctx.stylize('[Function' + name + ']', 'special');
- }
- if (isRegExp(value)) {
- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
- }
- if (isDate(value)) {
- return ctx.stylize(Date.prototype.toString.call(value), 'date');
- }
- if (isError(value)) {
- return formatError(value);
- }
- }
-
- var base = '', array = false, braces = ['{', '}'];
-
- // Make Array say that they are Array
- if (isArray(value)) {
- array = true;
- braces = ['[', ']'];
- }
-
- // Make functions say that they are functions
- if (isFunction(value)) {
- var n = value.name ? ': ' + value.name : '';
- base = ' [Function' + n + ']';
- }
-
- // Make RegExps say that they are RegExps
- if (isRegExp(value)) {
- base = ' ' + RegExp.prototype.toString.call(value);
- }
-
- // Make dates with properties first say the date
- if (isDate(value)) {
- base = ' ' + Date.prototype.toUTCString.call(value);
- }
-
- // Make error with message first say the error
- if (isError(value)) {
- base = ' ' + formatError(value);
- }
-
- if (keys.length === 0 && (!array || value.length == 0)) {
- return braces[0] + base + braces[1];
- }
-
- if (recurseTimes < 0) {
- if (isRegExp(value)) {
- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
- } else {
- return ctx.stylize('[Object]', 'special');
- }
- }
-
- ctx.seen.push(value);
-
- var output;
- if (array) {
- output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
- } else {
- output = keys.map(function(key) {
- return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
- });
- }
-
- ctx.seen.pop();
-
- return reduceToSingleString(output, base, braces);
-}
-
-
-function formatPrimitive(ctx, value) {
- if (isUndefined(value))
- return ctx.stylize('undefined', 'undefined');
- if (isString(value)) {
- var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
- .replace(/'/g, "\\'")
- .replace(/\\"/g, '"') + '\'';
- return ctx.stylize(simple, 'string');
- }
- if (isNumber(value)) {
- // Format -0 as '-0'. Strict equality won't distinguish 0 from -0,
- // so instead we use the fact that 1 / -0 < 0 whereas 1 / 0 > 0 .
- if (value === 0 && 1 / value < 0)
- return ctx.stylize('-0', 'number');
- return ctx.stylize('' + value, 'number');
- }
- if (isBoolean(value))
- return ctx.stylize('' + value, 'boolean');
- // For some reason typeof null is "object", so special case here.
- if (isNull(value))
- return ctx.stylize('null', 'null');
-}
-
-
-function formatError(value) {
- return '[' + Error.prototype.toString.call(value) + ']';
-}
-
-
-function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
- var output = [];
- for (var i = 0, l = value.length; i < l; ++i) {
- if (hasOwnProperty(value, String(i))) {
- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
- String(i), true));
- } else {
- output.push('');
- }
- }
- keys.forEach(function(key) {
- if (!key.match(/^\d+$/)) {
- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
- key, true));
- }
- });
- return output;
-}
-
-
-function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
- var name, str, desc;
- desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
- if (desc.get) {
- if (desc.set) {
- str = ctx.stylize('[Getter/Setter]', 'special');
- } else {
- str = ctx.stylize('[Getter]', 'special');
- }
- } else {
- if (desc.set) {
- str = ctx.stylize('[Setter]', 'special');
- }
- }
- if (!hasOwnProperty(visibleKeys, key)) {
- name = '[' + key + ']';
- }
- if (!str) {
- if (ctx.seen.indexOf(desc.value) < 0) {
- if (isNull(recurseTimes)) {
- str = formatValue(ctx, desc.value, null);
- } else {
- str = formatValue(ctx, desc.value, recurseTimes - 1);
- }
- if (str.indexOf('\n') > -1) {
- if (array) {
- str = str.split('\n').map(function(line) {
- return ' ' + line;
- }).join('\n').substr(2);
- } else {
- str = '\n' + str.split('\n').map(function(line) {
- return ' ' + line;
- }).join('\n');
- }
- }
- } else {
- str = ctx.stylize('[Circular]', 'special');
- }
- }
- if (isUndefined(name)) {
- if (array && key.match(/^\d+$/)) {
- return str;
- }
- name = JSON.stringify('' + key);
- if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
- name = name.substr(1, name.length - 2);
- name = ctx.stylize(name, 'name');
- } else {
- name = name.replace(/'/g, "\\'")
- .replace(/\\"/g, '"')
- .replace(/(^"|"$)/g, "'");
- name = ctx.stylize(name, 'string');
- }
- }
-
- return name + ': ' + str;
-}
-
-
-function reduceToSingleString(output, base, braces) {
- var numLinesEst = 0;
- var length = output.reduce(function(prev, cur) {
- numLinesEst++;
- if (cur.indexOf('\n') >= 0) numLinesEst++;
- return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
- }, 0);
-
- if (length > 60) {
- return braces[0] +
- (base === '' ? '' : base + '\n ') +
- ' ' +
- output.join(',\n ') +
- ' ' +
- braces[1];
- }
-
- return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
-}
-
-
// NOTE: These type checking functions intentionally don't use `instanceof`
// because it is fragile and can be easily faked with `Object.create()`.
function isArray(ar) {
@@ -522,166 +98,10 @@ function isPrimitive(arg) {
exports.isPrimitive = isPrimitive;
function isBuffer(arg) {
- return arg instanceof Buffer;
+ return Buffer.isBuffer(arg);
}
exports.isBuffer = isBuffer;
function objectToString(o) {
return Object.prototype.toString.call(o);
-}
-
-
-function pad(n) {
- return n < 10 ? '0' + n.toString(10) : n.toString(10);
-}
-
-
-var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
- 'Oct', 'Nov', 'Dec'];
-
-// 26 Feb 16:19:34
-function timestamp() {
- var d = new Date();
- var time = [pad(d.getHours()),
- pad(d.getMinutes()),
- pad(d.getSeconds())].join(':');
- return [d.getDate(), months[d.getMonth()], time].join(' ');
-}
-
-
-// log is just a thin wrapper to console.log that prepends a timestamp
-exports.log = function() {
- console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
-};
-
-
-/**
- * Inherit the prototype methods from one constructor into another.
- *
- * The Function.prototype.inherits from lang.js rewritten as a standalone
- * function (not on Function.prototype). NOTE: If this file is to be loaded
- * during bootstrapping this function needs to be rewritten using some native
- * functions as prototype setup using normal JavaScript does not work as
- * expected during bootstrapping (see mirror.js in r114903).
- *
- * @param {function} ctor Constructor function which needs to inherit the
- * prototype.
- * @param {function} superCtor Constructor function to inherit prototype from.
- */
-exports.inherits = function(ctor, superCtor) {
- ctor.super_ = superCtor;
- ctor.prototype = Object.create(superCtor.prototype, {
- constructor: {
- value: ctor,
- enumerable: false,
- writable: true,
- configurable: true
- }
- });
-};
-
-exports._extend = function(origin, add) {
- // Don't do anything if add isn't an object
- if (!add || !isObject(add)) return origin;
-
- var keys = Object.keys(add);
- var i = keys.length;
- while (i--) {
- origin[keys[i]] = add[keys[i]];
- }
- return origin;
-};
-
-function hasOwnProperty(obj, prop) {
- return Object.prototype.hasOwnProperty.call(obj, prop);
-}
-
-
-// Deprecated old stuff.
-
-exports.p = exports.deprecate(function() {
- for (var i = 0, len = arguments.length; i < len; ++i) {
- console.error(exports.inspect(arguments[i]));
- }
-}, 'util.p: Use console.error() instead');
-
-
-exports.exec = exports.deprecate(function() {
- return require('child_process').exec.apply(this, arguments);
-}, 'util.exec is now called `child_process.exec`.');
-
-
-exports.print = exports.deprecate(function() {
- for (var i = 0, len = arguments.length; i < len; ++i) {
- process.stdout.write(String(arguments[i]));
- }
-}, 'util.print: Use console.log instead');
-
-
-exports.puts = exports.deprecate(function() {
- for (var i = 0, len = arguments.length; i < len; ++i) {
- process.stdout.write(arguments[i] + '\n');
- }
-}, 'util.puts: Use console.log instead');
-
-
-exports.debug = exports.deprecate(function(x) {
- process.stderr.write('DEBUG: ' + x + '\n');
-}, 'util.debug: Use console.error instead');
-
-
-exports.error = exports.deprecate(function(x) {
- for (var i = 0, len = arguments.length; i < len; ++i) {
- process.stderr.write(arguments[i] + '\n');
- }
-}, 'util.error: Use console.error instead');
-
-
-exports.pump = exports.deprecate(function(readStream, writeStream, callback) {
- var callbackCalled = false;
-
- function call(a, b, c) {
- if (callback && !callbackCalled) {
- callback(a, b, c);
- callbackCalled = true;
- }
- }
-
- readStream.addListener('data', function(chunk) {
- if (writeStream.write(chunk) === false) readStream.pause();
- });
-
- writeStream.addListener('drain', function() {
- readStream.resume();
- });
-
- readStream.addListener('end', function() {
- writeStream.end();
- });
-
- readStream.addListener('close', function() {
- call();
- });
-
- readStream.addListener('error', function(err) {
- writeStream.end();
- call(err);
- });
-
- writeStream.addListener('error', function(err) {
- readStream.destroy();
- call(err);
- });
-}, 'util.pump(): Use readableStream.pipe() instead');
-
-
-var uv;
-exports._errnoException = function(err, syscall) {
- if (isUndefined(uv)) uv = process.binding('uv');
- var errname = uv.errname(err);
- var e = new Error(syscall + ' ' + errname);
- e.code = errname;
- e.errno = errname;
- e.syscall = syscall;
- return e;
-};
+}

107
editor/node_modules/core-util-is/lib/util.js generated vendored Normal file
View File

@@ -0,0 +1,107 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// 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.
// NOTE: These type checking functions intentionally don't use `instanceof`
// because it is fragile and can be easily faked with `Object.create()`.
function isArray(arg) {
if (Array.isArray) {
return Array.isArray(arg);
}
return objectToString(arg) === '[object Array]';
}
exports.isArray = isArray;
function isBoolean(arg) {
return typeof arg === 'boolean';
}
exports.isBoolean = isBoolean;
function isNull(arg) {
return arg === null;
}
exports.isNull = isNull;
function isNullOrUndefined(arg) {
return arg == null;
}
exports.isNullOrUndefined = isNullOrUndefined;
function isNumber(arg) {
return typeof arg === 'number';
}
exports.isNumber = isNumber;
function isString(arg) {
return typeof arg === 'string';
}
exports.isString = isString;
function isSymbol(arg) {
return typeof arg === 'symbol';
}
exports.isSymbol = isSymbol;
function isUndefined(arg) {
return arg === void 0;
}
exports.isUndefined = isUndefined;
function isRegExp(re) {
return objectToString(re) === '[object RegExp]';
}
exports.isRegExp = isRegExp;
function isObject(arg) {
return typeof arg === 'object' && arg !== null;
}
exports.isObject = isObject;
function isDate(d) {
return objectToString(d) === '[object Date]';
}
exports.isDate = isDate;
function isError(e) {
return (objectToString(e) === '[object Error]' || e instanceof Error);
}
exports.isError = isError;
function isFunction(arg) {
return typeof arg === 'function';
}
exports.isFunction = isFunction;
function isPrimitive(arg) {
return arg === null ||
typeof arg === 'boolean' ||
typeof arg === 'number' ||
typeof arg === 'string' ||
typeof arg === 'symbol' || // ES6 symbol
typeof arg === 'undefined';
}
exports.isPrimitive = isPrimitive;
exports.isBuffer = Buffer.isBuffer;
function objectToString(o) {
return Object.prototype.toString.call(o);
}

86
editor/node_modules/core-util-is/package.json generated vendored Normal file
View File

@@ -0,0 +1,86 @@
{
"_args": [
[
"core-util-is@~1.0.0",
"/home/osboxes/code/pentext/editor/node_modules/readable-stream"
]
],
"_from": "core-util-is@>=1.0.0 <1.1.0",
"_id": "core-util-is@1.0.2",
"_inCache": true,
"_installable": true,
"_location": "/core-util-is",
"_nodeVersion": "4.0.0",
"_npmUser": {
"email": "i@izs.me",
"name": "isaacs"
},
"_npmVersion": "3.3.2",
"_phantomChildren": {},
"_requested": {
"name": "core-util-is",
"raw": "core-util-is@~1.0.0",
"rawSpec": "~1.0.0",
"scope": null,
"spec": ">=1.0.0 <1.1.0",
"type": "range"
},
"_requiredBy": [
"/readable-stream"
],
"_resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"_shasum": "b5fd54220aa2bc5ab57aab7140c940754503c1a7",
"_shrinkwrap": null,
"_spec": "core-util-is@~1.0.0",
"_where": "/home/osboxes/code/pentext/editor/node_modules/readable-stream",
"author": {
"email": "i@izs.me",
"name": "Isaac Z. Schlueter",
"url": "http://blog.izs.me/"
},
"bugs": {
"url": "https://github.com/isaacs/core-util-is/issues"
},
"dependencies": {},
"description": "The `util.is*` functions introduced in Node v0.12.",
"devDependencies": {
"tap": "^2.3.0"
},
"directories": {},
"dist": {
"shasum": "b5fd54220aa2bc5ab57aab7140c940754503c1a7",
"tarball": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
},
"gitHead": "a177da234df5638b363ddc15fa324619a38577c8",
"homepage": "https://github.com/isaacs/core-util-is#readme",
"keywords": [
"isArray",
"isBuffer",
"isNumber",
"isRegExp",
"isString",
"isThat",
"isThis",
"polyfill",
"util"
],
"license": "MIT",
"main": "lib/util.js",
"maintainers": [
{
"name": "isaacs",
"email": "i@izs.me"
}
],
"name": "core-util-is",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/core-util-is.git"
},
"scripts": {
"test": "tap test.js"
},
"version": "1.0.2"
}

68
editor/node_modules/core-util-is/test.js generated vendored Normal file
View File

@@ -0,0 +1,68 @@
var assert = require('tap');
var t = require('./lib/util');
assert.equal(t.isArray([]), true);
assert.equal(t.isArray({}), false);
assert.equal(t.isBoolean(null), false);
assert.equal(t.isBoolean(true), true);
assert.equal(t.isBoolean(false), true);
assert.equal(t.isNull(null), true);
assert.equal(t.isNull(undefined), false);
assert.equal(t.isNull(false), false);
assert.equal(t.isNull(), false);
assert.equal(t.isNullOrUndefined(null), true);
assert.equal(t.isNullOrUndefined(undefined), true);
assert.equal(t.isNullOrUndefined(false), false);
assert.equal(t.isNullOrUndefined(), true);
assert.equal(t.isNumber(null), false);
assert.equal(t.isNumber('1'), false);
assert.equal(t.isNumber(1), true);
assert.equal(t.isString(null), false);
assert.equal(t.isString('1'), true);
assert.equal(t.isString(1), false);
assert.equal(t.isSymbol(null), false);
assert.equal(t.isSymbol('1'), false);
assert.equal(t.isSymbol(1), false);
assert.equal(t.isSymbol(Symbol()), true);
assert.equal(t.isUndefined(null), false);
assert.equal(t.isUndefined(undefined), true);
assert.equal(t.isUndefined(false), false);
assert.equal(t.isUndefined(), true);
assert.equal(t.isRegExp(null), false);
assert.equal(t.isRegExp('1'), false);
assert.equal(t.isRegExp(new RegExp()), true);
assert.equal(t.isObject({}), true);
assert.equal(t.isObject([]), true);
assert.equal(t.isObject(new RegExp()), true);
assert.equal(t.isObject(new Date()), true);
assert.equal(t.isDate(null), false);
assert.equal(t.isDate('1'), false);
assert.equal(t.isDate(new Date()), true);
assert.equal(t.isError(null), false);
assert.equal(t.isError({ err: true }), false);
assert.equal(t.isError(new Error()), true);
assert.equal(t.isFunction(null), false);
assert.equal(t.isFunction({ }), false);
assert.equal(t.isFunction(function() {}), true);
assert.equal(t.isPrimitive(null), true);
assert.equal(t.isPrimitive(''), true);
assert.equal(t.isPrimitive(0), true);
assert.equal(t.isPrimitive(new Date()), false);
assert.equal(t.isBuffer(null), false);
assert.equal(t.isBuffer({}), false);
assert.equal(t.isBuffer(new Buffer(0)), true);

1
editor/node_modules/css-select/.meteor-portable generated vendored Normal file
View File

@@ -0,0 +1 @@
true

11
editor/node_modules/css-select/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,11 @@
Copyright (c) Felix Böhm
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

133
editor/node_modules/css-select/README.md generated vendored Normal file
View File

@@ -0,0 +1,133 @@
# css-select [![NPM version](http://img.shields.io/npm/v/css-select.svg)](https://npmjs.org/package/css-select) [![Build Status](https://travis-ci.org/fb55/css-select.svg?branch=master)](http://travis-ci.org/fb55/css-select) [![Downloads](https://img.shields.io/npm/dm/css-select.svg)](https://npmjs.org/package/css-select) [![Coverage](https://coveralls.io/repos/fb55/css-select/badge.svg?branch=master)](https://coveralls.io/r/fb55/css-select)
a CSS selector compiler/engine
## What?
css-select turns CSS selectors into functions that tests if elements match them. When searching for elements, testing is executed "from the top", similar to how browsers execute CSS selectors.
In its default configuration, css-select queries the DOM structure of the [`domhandler`](https://github.com/fb55/domhandler) module (also known as htmlparser2 DOM).
__Features:__
- Full implementation of CSS3 selectors
- Partial implementation of jQuery/Sizzle extensions
- Very high test coverage
- Pretty good performance
## Why?
The traditional approach of executing CSS selectors, named left-to-right execution, is to execute every component of the selector in order, from left to right _(duh)_. The execution of the selector `a b` for example will first query for `a` elements, then search these for `b` elements. (That's the approach of eg. [`Sizzle`](https://github.com/jquery/sizzle), [`nwmatcher`](https://github.com/dperini/nwmatcher/) and [`qwery`](https://github.com/ded/qwery).)
While this works, it has some downsides: Children of `a`s will be checked multiple times; first, to check if they are also `a`s, then, for every superior `a` once, if they are `b`s. Using [Big O notation](http://en.wikipedia.org/wiki/Big_O_notation), that would be `O(n^(k+1))`, where `k` is the number of descendant selectors (that's the space in the example above).
The far more efficient approach is to first look for `b` elements, then check if they have superior `a` elements: Using big O notation again, that would be `O(n)`. That's called right-to-left execution.
And that's what css-select does and why it's quite performant.
## How does it work?
By building a stack of functions.
_Wait, what?_
Okay, so let's suppose we want to compile the selector `a b` again, for right-to-left execution. We start by _parsing_ the selector, which means we turn the selector into an array of the building-blocks of the selector, so we can distinguish them easily. That's what the [`css-what`](https://github.com/fb55/css-what) module is for, if you want to have a look.
Anyway, after parsing, we end up with an array like this one:
```js
[
{ type: 'tag', name: 'a' },
{ type: 'descendant' },
{ type: 'tag', name: 'b' }
]
```
Actually, this array is wrapped in another array, but that's another story (involving commas in selectors).
Now that we know the meaning of every part of the selector, we can compile it. That's where it becomes interesting.
The basic idea is to turn every part of the selector into a function, which takes an element as its only argument. The function checks whether a passed element matches its part of the selector: If it does, the element is passed to the next turned-into-a-function part of the selector, which does the same. If an element is accepted by all parts of the selector, it _matches_ the selector and double rainbow ALL THE WAY.
As said before, we want to do right-to-left execution with all the big O improvements nonsense, so elements are passed from the rightmost part of the selector (`b` in our example) to the leftmost (~~which would be `c`~~ of course `a`).
_//TODO: More in-depth description. Implementation details. Build a spaceship._
## API
```js
var CSSselect = require("css-select");
```
#### `CSSselect(query, elems, options)`
Queries `elems`, returns an array containing all matches.
- `query` can be either a CSS selector or a function.
- `elems` can be either an array of elements, or a single element. If it is an element, its children will be queried.
- `options` is described below.
Aliases: `CSSselect.selectAll(query, elems)`, `CSSselect.iterate(query, elems)`.
#### `CSSselect.compile(query)`
Compiles the query, returns a function.
#### `CSSselect.is(elem, query, options)`
Tests whether or not an element is matched by `query`. `query` can be either a CSS selector or a function.
#### `CSSselect.selectOne(query, elems, options)`
Arguments are the same as for `CSSselect(query, elems)`. Only returns the first match, or `null` if there was no match.
### Options
- `xmlMode`: When enabled, tag names will be case-sensitive. Default: `false`.
- `strict`: Limits the module to only use CSS3 selectors. Default: `false`.
- `rootFunc`: The last function in the stack, will be called with the last element that's looked at. Should return `true`.
## Supported selectors
_As defined by CSS 4 and / or jQuery._
* Universal (`*`)
* Tag (`<tagname>`)
* Descendant (` `)
* Child (`>`)
* Parent (`<`) *
* Sibling (`+`)
* Adjacent (`~`)
* Attribute (`[attr=foo]`), with supported comparisons:
* `[attr]` (existential)
* `=`
* `~=`
* `|=`
* `*=`
* `^=`
* `$=`
* `!=` *
* Also, `i` can be added after the comparison to make the comparison case-insensitive (eg. `[attr=foo i]`) *
* Pseudos:
* `:not`
* `:contains` *
* `:icontains` * (case-insensitive version of `:contains`)
* `:has` *
* `:root`
* `:empty`
* `:parent` *
* `:[first|last]-child[-of-type]`
* `:only-of-type`, `:only-child`
* `:nth-[last-]child[-of-type]`
* `:link`, `:visited` (the latter doesn't match any elements)
* `:selected` *, `:checked`
* `:enabled`, `:disabled`
* `:required`, `:optional`
* `:header`, `:button`, `:input`, `:text`, `:checkbox`, `:file`, `:password`, `:reset`, `:radio` etc. *
* `:matches` *
__*__: Not part of CSS3
---
License: BSD-like

59
editor/node_modules/css-select/index.js generated vendored Normal file
View File

@@ -0,0 +1,59 @@
"use strict";
module.exports = CSSselect;
var Pseudos = require("./lib/pseudos.js"),
DomUtils = require("domutils"),
findOne = DomUtils.findOne,
findAll = DomUtils.findAll,
getChildren = DomUtils.getChildren,
removeSubsets = DomUtils.removeSubsets,
falseFunc = require("boolbase").falseFunc,
compile = require("./lib/compile.js"),
compileUnsafe = compile.compileUnsafe,
compileToken = compile.compileToken;
function getSelectorFunc(searchFunc){
return function select(query, elems, options){
if(typeof query !== "function") query = compileUnsafe(query, options, elems);
if(!Array.isArray(elems)) elems = getChildren(elems);
else elems = removeSubsets(elems);
return searchFunc(query, elems);
};
}
var selectAll = getSelectorFunc(function selectAll(query, elems){
return (query === falseFunc || !elems || elems.length === 0) ? [] : findAll(query, elems);
});
var selectOne = getSelectorFunc(function selectOne(query, elems){
return (query === falseFunc || !elems || elems.length === 0) ? null : findOne(query, elems);
});
function is(elem, query, options){
return (typeof query === "function" ? query : compile(query, options))(elem);
}
/*
the exported interface
*/
function CSSselect(query, elems, options){
return selectAll(query, elems, options);
}
CSSselect.compile = compile;
CSSselect.filters = Pseudos.filters;
CSSselect.pseudos = Pseudos.pseudos;
CSSselect.selectAll = selectAll;
CSSselect.selectOne = selectOne;
CSSselect.is = is;
//legacy methods (might be removed)
CSSselect.parse = compile;
CSSselect.iterate = selectAll;
//hooks
CSSselect._compileUnsafe = compileUnsafe;
CSSselect._compileToken = compileToken;

181
editor/node_modules/css-select/lib/attributes.js generated vendored Normal file
View File

@@ -0,0 +1,181 @@
var DomUtils = require("domutils"),
hasAttrib = DomUtils.hasAttrib,
getAttributeValue = DomUtils.getAttributeValue,
falseFunc = require("boolbase").falseFunc;
//https://github.com/slevithan/XRegExp/blob/master/src/xregexp.js#L469
var reChars = /[-[\]{}()*+?.,\\^$|#\s]/g;
/*
attribute selectors
*/
var attributeRules = {
__proto__: null,
equals: function(next, data){
var name = data.name,
value = data.value;
if(data.ignoreCase){
value = value.toLowerCase();
return function equalsIC(elem){
var attr = getAttributeValue(elem, name);
return attr != null && attr.toLowerCase() === value && next(elem);
};
}
return function equals(elem){
return getAttributeValue(elem, name) === value && next(elem);
};
},
hyphen: function(next, data){
var name = data.name,
value = data.value,
len = value.length;
if(data.ignoreCase){
value = value.toLowerCase();
return function hyphenIC(elem){
var attr = getAttributeValue(elem, name);
return attr != null &&
(attr.length === len || attr.charAt(len) === "-") &&
attr.substr(0, len).toLowerCase() === value &&
next(elem);
};
}
return function hyphen(elem){
var attr = getAttributeValue(elem, name);
return attr != null &&
attr.substr(0, len) === value &&
(attr.length === len || attr.charAt(len) === "-") &&
next(elem);
};
},
element: function(next, data){
var name = data.name,
value = data.value;
if(/\s/.test(value)){
return falseFunc;
}
value = value.replace(reChars, "\\$&");
var pattern = "(?:^|\\s)" + value + "(?:$|\\s)",
flags = data.ignoreCase ? "i" : "",
regex = new RegExp(pattern, flags);
return function element(elem){
var attr = getAttributeValue(elem, name);
return attr != null && regex.test(attr) && next(elem);
};
},
exists: function(next, data){
var name = data.name;
return function exists(elem){
return hasAttrib(elem, name) && next(elem);
};
},
start: function(next, data){
var name = data.name,
value = data.value,
len = value.length;
if(len === 0){
return falseFunc;
}
if(data.ignoreCase){
value = value.toLowerCase();
return function startIC(elem){
var attr = getAttributeValue(elem, name);
return attr != null && attr.substr(0, len).toLowerCase() === value && next(elem);
};
}
return function start(elem){
var attr = getAttributeValue(elem, name);
return attr != null && attr.substr(0, len) === value && next(elem);
};
},
end: function(next, data){
var name = data.name,
value = data.value,
len = -value.length;
if(len === 0){
return falseFunc;
}
if(data.ignoreCase){
value = value.toLowerCase();
return function endIC(elem){
var attr = getAttributeValue(elem, name);
return attr != null && attr.substr(len).toLowerCase() === value && next(elem);
};
}
return function end(elem){
var attr = getAttributeValue(elem, name);
return attr != null && attr.substr(len) === value && next(elem);
};
},
any: function(next, data){
var name = data.name,
value = data.value;
if(value === ""){
return falseFunc;
}
if(data.ignoreCase){
var regex = new RegExp(value.replace(reChars, "\\$&"), "i");
return function anyIC(elem){
var attr = getAttributeValue(elem, name);
return attr != null && regex.test(attr) && next(elem);
};
}
return function any(elem){
var attr = getAttributeValue(elem, name);
return attr != null && attr.indexOf(value) >= 0 && next(elem);
};
},
not: function(next, data){
var name = data.name,
value = data.value;
if(value === ""){
return function notEmpty(elem){
return !!getAttributeValue(elem, name) && next(elem);
};
} else if(data.ignoreCase){
value = value.toLowerCase();
return function notIC(elem){
var attr = getAttributeValue(elem, name);
return attr != null && attr.toLowerCase() !== value && next(elem);
};
}
return function not(elem){
return getAttributeValue(elem, name) !== value && next(elem);
};
}
};
module.exports = {
compile: function(next, data, options){
if(options && options.strict && (
data.ignoreCase || data.action === "not"
)) throw SyntaxError("Unsupported attribute selector");
return attributeRules[data.action](next, data);
},
rules: attributeRules
};

192
editor/node_modules/css-select/lib/compile.js generated vendored Normal file
View File

@@ -0,0 +1,192 @@
/*
compiles a selector to an executable function
*/
module.exports = compile;
module.exports.compileUnsafe = compileUnsafe;
module.exports.compileToken = compileToken;
var parse = require("css-what"),
DomUtils = require("domutils"),
isTag = DomUtils.isTag,
Rules = require("./general.js"),
sortRules = require("./sort.js"),
BaseFuncs = require("boolbase"),
trueFunc = BaseFuncs.trueFunc,
falseFunc = BaseFuncs.falseFunc,
procedure = require("./procedure.json");
function compile(selector, options, context){
var next = compileUnsafe(selector, options, context);
return wrap(next);
}
function wrap(next){
return function base(elem){
return isTag(elem) && next(elem);
};
}
function compileUnsafe(selector, options, context){
var token = parse(selector, options);
return compileToken(token, options, context);
}
function includesScopePseudo(t){
return t.type === "pseudo" && (
t.name === "scope" || (
Array.isArray(t.data) &&
t.data.some(function(data){
return data.some(includesScopePseudo);
})
)
);
}
var DESCENDANT_TOKEN = {type: "descendant"},
SCOPE_TOKEN = {type: "pseudo", name: "scope"},
PLACEHOLDER_ELEMENT = {},
getParent = DomUtils.getParent;
//CSS 4 Spec (Draft): 3.3.1. Absolutizing a Scope-relative Selector
//http://www.w3.org/TR/selectors4/#absolutizing
function absolutize(token, context){
//TODO better check if context is document
var hasContext = !!context && !!context.length && context.every(function(e){
return e === PLACEHOLDER_ELEMENT || !!getParent(e);
});
token.forEach(function(t){
if(t.length > 0 && isTraversal(t[0]) && t[0].type !== "descendant"){
//don't return in else branch
} else if(hasContext && !includesScopePseudo(t)){
t.unshift(DESCENDANT_TOKEN);
} else {
return;
}
t.unshift(SCOPE_TOKEN);
});
}
function compileToken(token, options, context){
token = token.filter(function(t){ return t.length > 0; });
token.forEach(sortRules);
var isArrayContext = Array.isArray(context);
context = (options && options.context) || context;
if(context && !isArrayContext) context = [context];
absolutize(token, context);
return token
.map(function(rules){ return compileRules(rules, options, context, isArrayContext); })
.reduce(reduceRules, falseFunc);
}
function isTraversal(t){
return procedure[t.type] < 0;
}
function compileRules(rules, options, context, isArrayContext){
var acceptSelf = (isArrayContext && rules[0].name === "scope" && rules[1].type === "descendant");
return rules.reduce(function(func, rule, index){
if(func === falseFunc) return func;
return Rules[rule.type](func, rule, options, context, acceptSelf && index === 1);
}, options && options.rootFunc || trueFunc);
}
function reduceRules(a, b){
if(b === falseFunc || a === trueFunc){
return a;
}
if(a === falseFunc || b === trueFunc){
return b;
}
return function combine(elem){
return a(elem) || b(elem);
};
}
//:not, :has and :matches have to compile selectors
//doing this in lib/pseudos.js would lead to circular dependencies,
//so we add them here
var Pseudos = require("./pseudos.js"),
filters = Pseudos.filters,
existsOne = DomUtils.existsOne,
isTag = DomUtils.isTag,
getChildren = DomUtils.getChildren;
function containsTraversal(t){
return t.some(isTraversal);
}
filters.not = function(next, token, options, context){
var opts = {
xmlMode: !!(options && options.xmlMode),
strict: !!(options && options.strict)
};
if(opts.strict){
if(token.length > 1 || token.some(containsTraversal)){
throw new SyntaxError("complex selectors in :not aren't allowed in strict mode");
}
}
var func = compileToken(token, opts, context);
if(func === falseFunc) return next;
if(func === trueFunc) return falseFunc;
return function(elem){
return !func(elem) && next(elem);
};
};
filters.has = function(next, token, options){
var opts = {
xmlMode: !!(options && options.xmlMode),
strict: !!(options && options.strict)
};
//FIXME: Uses an array as a pointer to the current element (side effects)
var context = token.some(containsTraversal) ? [PLACEHOLDER_ELEMENT] : null;
var func = compileToken(token, opts, context);
if(func === falseFunc) return falseFunc;
if(func === trueFunc) return function(elem){
return getChildren(elem).some(isTag) && next(elem);
};
func = wrap(func);
if(context){
return function has(elem){
return next(elem) && (
(context[0] = elem), existsOne(func, getChildren(elem))
);
};
}
return function has(elem){
return next(elem) && existsOne(func, getChildren(elem));
};
};
filters.matches = function(next, token, options, context){
var opts = {
xmlMode: !!(options && options.xmlMode),
strict: !!(options && options.strict),
rootFunc: next
};
return compileToken(token, opts, context);
};

89
editor/node_modules/css-select/lib/general.js generated vendored Normal file
View File

@@ -0,0 +1,89 @@
var DomUtils = require("domutils"),
isTag = DomUtils.isTag,
getParent = DomUtils.getParent,
getChildren = DomUtils.getChildren,
getSiblings = DomUtils.getSiblings,
getName = DomUtils.getName;
/*
all available rules
*/
module.exports = {
__proto__: null,
attribute: require("./attributes.js").compile,
pseudo: require("./pseudos.js").compile,
//tags
tag: function(next, data){
var name = data.name;
return function tag(elem){
return getName(elem) === name && next(elem);
};
},
//traversal
descendant: function(next, rule, options, context, acceptSelf){
return function descendant(elem){
if (acceptSelf && next(elem)) return true;
var found = false;
while(!found && (elem = getParent(elem))){
found = next(elem);
}
return found;
};
},
parent: function(next, data, options){
if(options && options.strict) throw SyntaxError("Parent selector isn't part of CSS3");
return function parent(elem){
return getChildren(elem).some(test);
};
function test(elem){
return isTag(elem) && next(elem);
}
},
child: function(next){
return function child(elem){
var parent = getParent(elem);
return !!parent && next(parent);
};
},
sibling: function(next){
return function sibling(elem){
var siblings = getSiblings(elem);
for(var i = 0; i < siblings.length; i++){
if(isTag(siblings[i])){
if(siblings[i] === elem) break;
if(next(siblings[i])) return true;
}
}
return false;
};
},
adjacent: function(next){
return function adjacent(elem){
var siblings = getSiblings(elem),
lastElement;
for(var i = 0; i < siblings.length; i++){
if(isTag(siblings[i])){
if(siblings[i] === elem) break;
lastElement = siblings[i];
}
}
return !!lastElement && next(lastElement);
};
},
universal: function(next){
return next;
}
};

11
editor/node_modules/css-select/lib/procedure.json generated vendored Normal file
View File

@@ -0,0 +1,11 @@
{
"universal": 50,
"tag": 30,
"attribute": 1,
"pseudo": 0,
"descendant": -1,
"child": -1,
"parent": -1,
"sibling": -1,
"adjacent": -1
}

393
editor/node_modules/css-select/lib/pseudos.js generated vendored Normal file
View File

@@ -0,0 +1,393 @@
/*
pseudo selectors
---
they are available in two forms:
* filters called when the selector
is compiled and return a function
that needs to return next()
* pseudos get called on execution
they need to return a boolean
*/
var DomUtils = require("domutils"),
isTag = DomUtils.isTag,
getText = DomUtils.getText,
getParent = DomUtils.getParent,
getChildren = DomUtils.getChildren,
getSiblings = DomUtils.getSiblings,
hasAttrib = DomUtils.hasAttrib,
getName = DomUtils.getName,
getAttribute= DomUtils.getAttributeValue,
getNCheck = require("nth-check"),
checkAttrib = require("./attributes.js").rules.equals,
BaseFuncs = require("boolbase"),
trueFunc = BaseFuncs.trueFunc,
falseFunc = BaseFuncs.falseFunc;
//helper methods
function getFirstElement(elems){
for(var i = 0; elems && i < elems.length; i++){
if(isTag(elems[i])) return elems[i];
}
}
function getAttribFunc(name, value){
var data = {name: name, value: value};
return function attribFunc(next){
return checkAttrib(next, data);
};
}
function getChildFunc(next){
return function(elem){
return !!getParent(elem) && next(elem);
};
}
var filters = {
contains: function(next, text){
return function contains(elem){
return next(elem) && getText(elem).indexOf(text) >= 0;
};
},
icontains: function(next, text){
var itext = text.toLowerCase();
return function icontains(elem){
return next(elem) &&
getText(elem).toLowerCase().indexOf(itext) >= 0;
};
},
//location specific methods
"nth-child": function(next, rule){
var func = getNCheck(rule);
if(func === falseFunc) return func;
if(func === trueFunc) return getChildFunc(next);
return function nthChild(elem){
var siblings = getSiblings(elem);
for(var i = 0, pos = 0; i < siblings.length; i++){
if(isTag(siblings[i])){
if(siblings[i] === elem) break;
else pos++;
}
}
return func(pos) && next(elem);
};
},
"nth-last-child": function(next, rule){
var func = getNCheck(rule);
if(func === falseFunc) return func;
if(func === trueFunc) return getChildFunc(next);
return function nthLastChild(elem){
var siblings = getSiblings(elem);
for(var pos = 0, i = siblings.length - 1; i >= 0; i--){
if(isTag(siblings[i])){
if(siblings[i] === elem) break;
else pos++;
}
}
return func(pos) && next(elem);
};
},
"nth-of-type": function(next, rule){
var func = getNCheck(rule);
if(func === falseFunc) return func;
if(func === trueFunc) return getChildFunc(next);
return function nthOfType(elem){
var siblings = getSiblings(elem);
for(var pos = 0, i = 0; i < siblings.length; i++){
if(isTag(siblings[i])){
if(siblings[i] === elem) break;
if(getName(siblings[i]) === getName(elem)) pos++;
}
}
return func(pos) && next(elem);
};
},
"nth-last-of-type": function(next, rule){
var func = getNCheck(rule);
if(func === falseFunc) return func;
if(func === trueFunc) return getChildFunc(next);
return function nthLastOfType(elem){
var siblings = getSiblings(elem);
for(var pos = 0, i = siblings.length - 1; i >= 0; i--){
if(isTag(siblings[i])){
if(siblings[i] === elem) break;
if(getName(siblings[i]) === getName(elem)) pos++;
}
}
return func(pos) && next(elem);
};
},
//TODO determine the actual root element
root: function(next){
return function(elem){
return !getParent(elem) && next(elem);
};
},
scope: function(next, rule, options, context){
if(!context || context.length === 0){
//equivalent to :root
return filters.root(next);
}
if(context.length === 1){
//NOTE: can't be unpacked, as :has uses this for side-effects
return function(elem){
return context[0] === elem && next(elem);
};
}
return function(elem){
return context.indexOf(elem) >= 0 && next(elem);
};
},
//jQuery extensions (others follow as pseudos)
checkbox: getAttribFunc("type", "checkbox"),
file: getAttribFunc("type", "file"),
password: getAttribFunc("type", "password"),
radio: getAttribFunc("type", "radio"),
reset: getAttribFunc("type", "reset"),
image: getAttribFunc("type", "image"),
submit: getAttribFunc("type", "submit")
};
//while filters are precompiled, pseudos get called when they are needed
var pseudos = {
empty: function(elem){
return !getChildren(elem).some(function(elem){
return isTag(elem) || elem.type === "text";
});
},
"first-child": function(elem){
return getFirstElement(getSiblings(elem)) === elem;
},
"last-child": function(elem){
var siblings = getSiblings(elem);
for(var i = siblings.length - 1; i >= 0; i--){
if(siblings[i] === elem) return true;
if(isTag(siblings[i])) break;
}
return false;
},
"first-of-type": function(elem){
var siblings = getSiblings(elem);
for(var i = 0; i < siblings.length; i++){
if(isTag(siblings[i])){
if(siblings[i] === elem) return true;
if(getName(siblings[i]) === getName(elem)) break;
}
}
return false;
},
"last-of-type": function(elem){
var siblings = getSiblings(elem);
for(var i = siblings.length-1; i >= 0; i--){
if(isTag(siblings[i])){
if(siblings[i] === elem) return true;
if(getName(siblings[i]) === getName(elem)) break;
}
}
return false;
},
"only-of-type": function(elem){
var siblings = getSiblings(elem);
for(var i = 0, j = siblings.length; i < j; i++){
if(isTag(siblings[i])){
if(siblings[i] === elem) continue;
if(getName(siblings[i]) === getName(elem)) return false;
}
}
return true;
},
"only-child": function(elem){
var siblings = getSiblings(elem);
for(var i = 0; i < siblings.length; i++){
if(isTag(siblings[i]) && siblings[i] !== elem) return false;
}
return true;
},
//:matches(a, area, link)[href]
link: function(elem){
return hasAttrib(elem, "href");
},
visited: falseFunc, //seems to be a valid implementation
//TODO: :any-link once the name is finalized (as an alias of :link)
//forms
//to consider: :target
//:matches([selected], select:not([multiple]):not(> option[selected]) > option:first-of-type)
selected: function(elem){
if(hasAttrib(elem, "selected")) return true;
else if(getName(elem) !== "option") return false;
//the first <option> in a <select> is also selected
var parent = getParent(elem);
if(
!parent ||
getName(parent) !== "select" ||
hasAttrib(parent, "multiple")
) return false;
var siblings = getChildren(parent),
sawElem = false;
for(var i = 0; i < siblings.length; i++){
if(isTag(siblings[i])){
if(siblings[i] === elem){
sawElem = true;
} else if(!sawElem){
return false;
} else if(hasAttrib(siblings[i], "selected")){
return false;
}
}
}
return sawElem;
},
//https://html.spec.whatwg.org/multipage/scripting.html#disabled-elements
//:matches(
// :matches(button, input, select, textarea, menuitem, optgroup, option)[disabled],
// optgroup[disabled] > option),
// fieldset[disabled] * //TODO not child of first <legend>
//)
disabled: function(elem){
return hasAttrib(elem, "disabled");
},
enabled: function(elem){
return !hasAttrib(elem, "disabled");
},
//:matches(:matches(:radio, :checkbox)[checked], :selected) (TODO menuitem)
checked: function(elem){
return hasAttrib(elem, "checked") || pseudos.selected(elem);
},
//:matches(input, select, textarea)[required]
required: function(elem){
return hasAttrib(elem, "required");
},
//:matches(input, select, textarea):not([required])
optional: function(elem){
return !hasAttrib(elem, "required");
},
//jQuery extensions
//:not(:empty)
parent: function(elem){
return !pseudos.empty(elem);
},
//:matches(h1, h2, h3, h4, h5, h6)
header: function(elem){
var name = getName(elem);
return name === "h1" ||
name === "h2" ||
name === "h3" ||
name === "h4" ||
name === "h5" ||
name === "h6";
},
//:matches(button, input[type=button])
button: function(elem){
var name = getName(elem);
return name === "button" ||
name === "input" &&
getAttribute(elem, "type") === "button";
},
//:matches(input, textarea, select, button)
input: function(elem){
var name = getName(elem);
return name === "input" ||
name === "textarea" ||
name === "select" ||
name === "button";
},
//input:matches(:not([type!='']), [type='text' i])
text: function(elem){
var attr;
return getName(elem) === "input" && (
!(attr = getAttribute(elem, "type")) ||
attr.toLowerCase() === "text"
);
}
};
function verifyArgs(func, name, subselect){
if(subselect === null){
if(func.length > 1 && name !== "scope"){
throw new SyntaxError("pseudo-selector :" + name + " requires an argument");
}
} else {
if(func.length === 1){
throw new SyntaxError("pseudo-selector :" + name + " doesn't have any arguments");
}
}
}
//FIXME this feels hacky
var re_CSS3 = /^(?:(?:nth|last|first|only)-(?:child|of-type)|root|empty|(?:en|dis)abled|checked|not)$/;
module.exports = {
compile: function(next, data, options, context){
var name = data.name,
subselect = data.data;
if(options && options.strict && !re_CSS3.test(name)){
throw SyntaxError(":" + name + " isn't part of CSS3");
}
if(typeof filters[name] === "function"){
verifyArgs(filters[name], name, subselect);
return filters[name](next, subselect, options, context);
} else if(typeof pseudos[name] === "function"){
var func = pseudos[name];
verifyArgs(func, name, subselect);
if(next === trueFunc) return func;
return function pseudoArgs(elem){
return func(elem, subselect) && next(elem);
};
} else {
throw new SyntaxError("unmatched pseudo-class :" + name);
}
},
filters: filters,
pseudos: pseudos
};

80
editor/node_modules/css-select/lib/sort.js generated vendored Normal file
View File

@@ -0,0 +1,80 @@
module.exports = sortByProcedure;
/*
sort the parts of the passed selector,
as there is potential for optimization
(some types of selectors are faster than others)
*/
var procedure = require("./procedure.json");
var attributes = {
__proto__: null,
exists: 10,
equals: 8,
not: 7,
start: 6,
end: 6,
any: 5,
hyphen: 4,
element: 4
};
function sortByProcedure(arr){
var procs = arr.map(getProcedure);
for(var i = 1; i < arr.length; i++){
var procNew = procs[i];
if(procNew < 0) continue;
for(var j = i - 1; j >= 0 && procNew < procs[j]; j--){
var token = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = token;
procs[j + 1] = procs[j];
procs[j] = procNew;
}
}
}
function getProcedure(token){
var proc = procedure[token.type];
if(proc === procedure.attribute){
proc = attributes[token.action];
if(proc === attributes.equals && token.name === "id"){
//prefer ID selectors (eg. #ID)
proc = 9;
}
if(token.ignoreCase){
//ignoreCase adds some overhead, prefer "normal" token
//this is a binary operation, to ensure it's still an int
proc >>= 1;
}
} else if(proc === procedure.pseudo){
if(!token.data){
proc = 3;
} else if(token.name === "has" || token.name === "contains"){
proc = 0; //expensive in any case
} else if(token.name === "matches" || token.name === "not"){
proc = 0;
for(var i = 0; i < token.data.length; i++){
//TODO better handling of complex selectors
if(token.data[i].length !== 1) continue;
var cur = getProcedure(token.data[i][0]);
//avoid executing :has or :contains
if(cur === 0){
proc = 0;
break;
}
if(cur > proc) proc = cur;
}
if(token.data.length > 1 && proc > 0) proc -= 1;
} else {
proc = 1;
}
}
return proc;
}

116
editor/node_modules/css-select/package.json generated vendored Normal file
View File

@@ -0,0 +1,116 @@
{
"_args": [
[
"css-select@~1.2.0",
"/home/osboxes/code/pentext/editor/node_modules/cheerio"
]
],
"_from": "css-select@>=1.2.0 <1.3.0",
"_id": "css-select@1.2.0",
"_inCache": true,
"_installable": true,
"_location": "/css-select",
"_nodeVersion": "5.0.0",
"_npmUser": {
"email": "me@feedic.com",
"name": "feedic"
},
"_npmVersion": "3.3.9",
"_phantomChildren": {},
"_requested": {
"name": "css-select",
"raw": "css-select@~1.2.0",
"rawSpec": "~1.2.0",
"scope": null,
"spec": ">=1.2.0 <1.3.0",
"type": "range"
},
"_requiredBy": [
"/cheerio"
],
"_resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
"_shasum": "2b3a110539c5355f1cd8d314623e870b121ec858",
"_shrinkwrap": null,
"_spec": "css-select@~1.2.0",
"_where": "/home/osboxes/code/pentext/editor/node_modules/cheerio",
"author": {
"email": "me@feedic.com",
"name": "Felix Boehm"
},
"bugs": {
"url": "https://github.com/fb55/css-select/issues"
},
"dependencies": {
"boolbase": "~1.0.0",
"css-what": "2.1",
"domutils": "1.5.1",
"nth-check": "~1.0.1"
},
"description": "a CSS selector compiler/engine",
"devDependencies": {
"cheerio-soupselect": "*",
"coveralls": "*",
"expect.js": "*",
"htmlparser2": "*",
"istanbul": "*",
"jshint": "2",
"mocha": "*",
"mocha-lcov-reporter": "*"
},
"directories": {},
"dist": {
"shasum": "2b3a110539c5355f1cd8d314623e870b121ec858",
"tarball": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz"
},
"files": [
"index.js",
"lib"
],
"gitHead": "09c405d8296bd97a660256604d8cdfb23fca47b6",
"homepage": "https://github.com/fb55/css-select#readme",
"jshintConfig": {
"eqeqeq": true,
"eqnull": true,
"freeze": true,
"globals": {
"describe": true,
"it": true
},
"latedef": "nofunc",
"noarg": true,
"node": true,
"nonbsp": true,
"proto": true,
"quotmark": "double",
"smarttabs": true,
"trailing": true,
"undef": true,
"unused": true
},
"keywords": [
"css",
"selector",
"sizzle"
],
"license": "BSD-like",
"maintainers": [
{
"name": "feedic",
"email": "me@feedic.com"
}
],
"name": "css-select",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git://github.com/fb55/css-select.git"
},
"scripts": {
"coveralls": "npm run lint && npm run lcov && (cat coverage/lcov.info | coveralls || exit 0)",
"lcov": "istanbul cover _mocha --report lcovonly -- -R spec",
"lint": "jshint index.js lib/*.js test/*.js",
"test": "mocha && npm run lint"
},
"version": "1.2.0"
}

1
editor/node_modules/css-what/.meteor-portable generated vendored Normal file
View File

@@ -0,0 +1 @@
true

11
editor/node_modules/css-what/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,11 @@
Copyright (c) Felix Böhm
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

267
editor/node_modules/css-what/index.js generated vendored Normal file
View File

@@ -0,0 +1,267 @@
"use strict";
module.exports = parse;
var re_name = /^(?:\\.|[\w\-\u00c0-\uFFFF])+/,
re_escape = /\\([\da-f]{1,6}\s?|(\s)|.)/ig,
//modified version of https://github.com/jquery/sizzle/blob/master/src/sizzle.js#L87
re_attr = /^\s*((?:\\.|[\w\u00c0-\uFFFF\-])+)\s*(?:(\S?)=\s*(?:(['"])(.*?)\3|(#?(?:\\.|[\w\u00c0-\uFFFF\-])*)|)|)\s*(i)?\]/;
var actionTypes = {
__proto__: null,
"undefined": "exists",
"": "equals",
"~": "element",
"^": "start",
"$": "end",
"*": "any",
"!": "not",
"|": "hyphen"
};
var simpleSelectors = {
__proto__: null,
">": "child",
"<": "parent",
"~": "sibling",
"+": "adjacent"
};
var attribSelectors = {
__proto__: null,
"#": ["id", "equals"],
".": ["class", "element"]
};
//pseudos, whose data-property is parsed as well
var unpackPseudos = {
__proto__: null,
"has": true,
"not": true,
"matches": true
};
var stripQuotesFromPseudos = {
__proto__: null,
"contains": true,
"icontains": true
};
var quotes = {
__proto__: null,
"\"": true,
"'": true
};
//unescape function taken from https://github.com/jquery/sizzle/blob/master/src/sizzle.js#L139
function funescape( _, escaped, escapedWhitespace ) {
var high = "0x" + escaped - 0x10000;
// NaN means non-codepoint
// Support: Firefox
// Workaround erroneous numeric interpretation of +"0x"
return high !== high || escapedWhitespace ?
escaped :
// BMP codepoint
high < 0 ?
String.fromCharCode( high + 0x10000 ) :
// Supplemental Plane codepoint (surrogate pair)
String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
}
function unescapeCSS(str){
return str.replace(re_escape, funescape);
}
function isWhitespace(c){
return c === " " || c === "\n" || c === "\t" || c === "\f" || c === "\r";
}
function parse(selector, options){
var subselects = [];
selector = parseSelector(subselects, selector + "", options);
if(selector !== ""){
throw new SyntaxError("Unmatched selector: " + selector);
}
return subselects;
}
function parseSelector(subselects, selector, options){
var tokens = [],
sawWS = false,
data, firstChar, name, quot;
function getName(){
var sub = selector.match(re_name)[0];
selector = selector.substr(sub.length);
return unescapeCSS(sub);
}
function stripWhitespace(start){
while(isWhitespace(selector.charAt(start))) start++;
selector = selector.substr(start);
}
stripWhitespace(0);
while(selector !== ""){
firstChar = selector.charAt(0);
if(isWhitespace(firstChar)){
sawWS = true;
stripWhitespace(1);
} else if(firstChar in simpleSelectors){
tokens.push({type: simpleSelectors[firstChar]});
sawWS = false;
stripWhitespace(1);
} else if(firstChar === ","){
if(tokens.length === 0){
throw new SyntaxError("empty sub-selector");
}
subselects.push(tokens);
tokens = [];
sawWS = false;
stripWhitespace(1);
} else {
if(sawWS){
if(tokens.length > 0){
tokens.push({type: "descendant"});
}
sawWS = false;
}
if(firstChar === "*"){
selector = selector.substr(1);
tokens.push({type: "universal"});
} else if(firstChar in attribSelectors){
selector = selector.substr(1);
tokens.push({
type: "attribute",
name: attribSelectors[firstChar][0],
action: attribSelectors[firstChar][1],
value: getName(),
ignoreCase: false
});
} else if(firstChar === "["){
selector = selector.substr(1);
data = selector.match(re_attr);
if(!data){
throw new SyntaxError("Malformed attribute selector: " + selector);
}
selector = selector.substr(data[0].length);
name = unescapeCSS(data[1]);
if(
!options || (
"lowerCaseAttributeNames" in options ?
options.lowerCaseAttributeNames :
!options.xmlMode
)
){
name = name.toLowerCase();
}
tokens.push({
type: "attribute",
name: name,
action: actionTypes[data[2]],
value: unescapeCSS(data[4] || data[5] || ""),
ignoreCase: !!data[6]
});
} else if(firstChar === ":"){
if(selector.charAt(1) === ":"){
selector = selector.substr(2);
tokens.push({type: "pseudo-element", name: getName().toLowerCase()});
continue;
}
selector = selector.substr(1);
name = getName().toLowerCase();
data = null;
if(selector.charAt(0) === "("){
if(name in unpackPseudos){
quot = selector.charAt(1);
var quoted = quot in quotes;
selector = selector.substr(quoted + 1);
data = [];
selector = parseSelector(data, selector, options);
if(quoted){
if(selector.charAt(0) !== quot){
throw new SyntaxError("unmatched quotes in :" + name);
} else {
selector = selector.substr(1);
}
}
if(selector.charAt(0) !== ")"){
throw new SyntaxError("missing closing parenthesis in :" + name + " " + selector);
}
selector = selector.substr(1);
} else {
var pos = 1, counter = 1;
for(; counter > 0 && pos < selector.length; pos++){
if(selector.charAt(pos) === "(") counter++;
else if(selector.charAt(pos) === ")") counter--;
}
if(counter){
throw new SyntaxError("parenthesis not matched");
}
data = selector.substr(1, pos - 2);
selector = selector.substr(pos);
if(name in stripQuotesFromPseudos){
quot = data.charAt(0);
if(quot === data.slice(-1) && quot in quotes){
data = data.slice(1, -1);
}
data = unescapeCSS(data);
}
}
}
tokens.push({type: "pseudo", name: name, data: data});
} else if(re_name.test(selector)){
name = getName();
if(!options || ("lowerCaseTags" in options ? options.lowerCaseTags : !options.xmlMode)){
name = name.toLowerCase();
}
tokens.push({type: "tag", name: name});
} else {
if(tokens.length && tokens[tokens.length - 1].type === "descendant"){
tokens.pop();
}
addToken(subselects, tokens);
return selector;
}
}
}
addToken(subselects, tokens);
return selector;
}
function addToken(subselects, tokens){
if(subselects.length > 0 && tokens.length === 0){
throw new SyntaxError("empty sub-selector");
}
subselects.push(tokens);
}

99
editor/node_modules/css-what/package.json generated vendored Normal file
View File

@@ -0,0 +1,99 @@
{
"_args": [
[
"css-what@2.1",
"/home/osboxes/code/pentext/editor/node_modules/css-select"
]
],
"_from": "css-what@>=2.1.0 <2.2.0",
"_id": "css-what@2.1.0",
"_inCache": true,
"_installable": true,
"_location": "/css-what",
"_nodeVersion": "5.0.0",
"_npmUser": {
"email": "me@feedic.com",
"name": "feedic"
},
"_npmVersion": "3.3.9",
"_phantomChildren": {},
"_requested": {
"name": "css-what",
"raw": "css-what@2.1",
"rawSpec": "2.1",
"scope": null,
"spec": ">=2.1.0 <2.2.0",
"type": "range"
},
"_requiredBy": [
"/css-select"
],
"_resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz",
"_shasum": "9467d032c38cfaefb9f2d79501253062f87fa1bd",
"_shrinkwrap": null,
"_spec": "css-what@2.1",
"_where": "/home/osboxes/code/pentext/editor/node_modules/css-select",
"author": {
"email": "me@feedic.com",
"name": "Felix Böhm",
"url": "http://feedic.com"
},
"bugs": {
"url": "https://github.com/fb55/css-what/issues"
},
"dependencies": {},
"description": "a CSS selector parser",
"devDependencies": {
"jshint": "2"
},
"directories": {},
"dist": {
"shasum": "9467d032c38cfaefb9f2d79501253062f87fa1bd",
"tarball": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz"
},
"engines": {
"node": "*"
},
"files": [
"index.js"
],
"gitHead": "fd6b9f62146efec8e17ee80ddaebdfb6ede21d7b",
"homepage": "https://github.com/fb55/css-what#readme",
"jshintConfig": {
"eqeqeq": true,
"eqnull": true,
"freeze": true,
"globals": {
"describe": true,
"it": true
},
"latedef": "nofunc",
"noarg": true,
"node": true,
"nonbsp": true,
"proto": true,
"quotmark": "double",
"smarttabs": true,
"trailing": true,
"undef": true,
"unused": true
},
"license": "BSD-like",
"main": "./index.js",
"maintainers": [
{
"name": "feedic",
"email": "me@feedic.com"
}
],
"name": "css-what",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"url": "git+https://github.com/fb55/css-what.git"
},
"scripts": {
"test": "node tests/test.js && jshint *.js"
},
"version": "2.1.0"
}

46
editor/node_modules/css-what/readme.md generated vendored Normal file
View File

@@ -0,0 +1,46 @@
# css-what [![Build Status](https://secure.travis-ci.org/fb55/css-what.svg?branch=master)](http://travis-ci.org/fb55/css-what)
a CSS selector parser
## Example
```js
require('css-what')('foo[bar]:baz')
~> [ [ { type: 'tag', name: 'foo' },
{ type: 'attribute',
name: 'bar',
action: 'exists',
value: '',
ignoreCase: false },
{ type: 'pseudo',
name: 'baz',
data: null } ] ]
```
## API
__`CSSwhat(selector, options)` - Parses `str`, with the passed `options`.__
The function returns a two-dimensional array. The first array represents selectors separated by commas (eg. `sub1, sub2`), the second contains the relevant tokens for that selector. Possible token types are:
name | attributes | example | output
---- | ---------- | ------- | ------
`tag`| `name` | `div` | `{ type: 'tag', name: 'div' }`
`universal`| - | `*` | `{ type: 'universal' }`
`pseudo`| `name`, `data`|`:name(data)`| `{ type: 'pseudo', name: 'name', data: 'data' }`
`pseudo`| `name`, `data`|`:name`| `{ type: 'pseudo', name: 'name', data: null }`
`attribute`|`name`, `action`, `value`, `ignoreCase`|`[attr]`|`{ type: 'attribute', name: 'attr', action: 'exists', value: '', ignoreCase: false }`
`attribute`|`name`, `action`, `value`, `ignoreCase`|`[attr=val]`|`{ type: 'attribute', name: 'attr', action: 'equals', value: 'val', ignoreCase: false }`
`attribute`|`name`, `action`, `value`, `ignoreCase`|`[attr^=val]`|`{ type: 'attribute', name: 'attr', action: 'start', value: 'val', ignoreCase: false }`
`attribute`|`name`, `action`, `value`, `ignoreCase`|`[attr$=val]`|`{ type: 'attribute', name: 'attr', action: 'end', value: 'val', ignoreCase: false }`
//TODO complete list
__Options:__
- `xmlMode`: When enabled, tag names will be case-sensitive (meaning they won't be lowercased).
---
License: BSD-like

1
editor/node_modules/dom-serializer/.meteor-portable generated vendored Normal file
View File

@@ -0,0 +1 @@
true

11
editor/node_modules/dom-serializer/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,11 @@
License
(The MIT License)
Copyright (c) 2014 The cheeriojs contributors
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.

178
editor/node_modules/dom-serializer/index.js generated vendored Normal file
View File

@@ -0,0 +1,178 @@
/*
Module dependencies
*/
var ElementType = require('domelementtype');
var entities = require('entities');
/*
Boolean Attributes
*/
var booleanAttributes = {
__proto__: null,
allowfullscreen: true,
async: true,
autofocus: true,
autoplay: true,
checked: true,
controls: true,
default: true,
defer: true,
disabled: true,
hidden: true,
ismap: true,
loop: true,
multiple: true,
muted: true,
open: true,
readonly: true,
required: true,
reversed: true,
scoped: true,
seamless: true,
selected: true,
typemustmatch: true
};
var unencodedElements = {
__proto__: null,
style: true,
script: true,
xmp: true,
iframe: true,
noembed: true,
noframes: true,
plaintext: true,
noscript: true
};
/*
Format attributes
*/
function formatAttrs(attributes, opts) {
if (!attributes) return;
var output = '',
value;
// Loop through the attributes
for (var key in attributes) {
value = attributes[key];
if (output) {
output += ' ';
}
if (!value && booleanAttributes[key]) {
output += key;
} else {
output += key + '="' + (opts.decodeEntities ? entities.encodeXML(value) : value) + '"';
}
}
return output;
}
/*
Self-enclosing tags (stolen from node-htmlparser)
*/
var singleTag = {
__proto__: null,
area: true,
base: true,
basefont: true,
br: true,
col: true,
command: true,
embed: true,
frame: true,
hr: true,
img: true,
input: true,
isindex: true,
keygen: true,
link: true,
meta: true,
param: true,
source: true,
track: true,
wbr: true,
};
var render = module.exports = function(dom, opts) {
if (!Array.isArray(dom) && !dom.cheerio) dom = [dom];
opts = opts || {};
var output = '';
for(var i = 0; i < dom.length; i++){
var elem = dom[i];
if (elem.type === 'root')
output += render(elem.children, opts);
else if (ElementType.isTag(elem))
output += renderTag(elem, opts);
else if (elem.type === ElementType.Directive)
output += renderDirective(elem);
else if (elem.type === ElementType.Comment)
output += renderComment(elem);
else if (elem.type === ElementType.CDATA)
output += renderCdata(elem);
else
output += renderText(elem, opts);
}
return output;
};
function renderTag(elem, opts) {
// Handle SVG
if (elem.name === "svg") opts = {decodeEntities: opts.decodeEntities, xmlMode: true};
var tag = '<' + elem.name,
attribs = formatAttrs(elem.attribs, opts);
if (attribs) {
tag += ' ' + attribs;
}
if (
opts.xmlMode
&& (!elem.children || elem.children.length === 0)
) {
tag += '/>';
} else {
tag += '>';
if (elem.children) {
tag += render(elem.children, opts);
}
if (!singleTag[elem.name] || opts.xmlMode) {
tag += '</' + elem.name + '>';
}
}
return tag;
}
function renderDirective(elem) {
return '<' + elem.data + '>';
}
function renderText(elem, opts) {
var data = elem.data || '';
// if entities weren't decoded, no need to encode them back
if (opts.decodeEntities && !(elem.parent && elem.parent.name in unencodedElements)) {
data = entities.encodeXML(data);
}
return data;
}
function renderCdata(elem) {
return '<![CDATA[' + elem.children[0].data + ']]>';
}
function renderComment(elem) {
return '<!--' + elem.data + '-->';
}

View File

@@ -0,0 +1 @@
true

View File

@@ -0,0 +1,11 @@
Copyright (c) Felix Böhm
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,14 @@
//Types of elements found in the DOM
module.exports = {
Text: "text", //Text
Directive: "directive", //<? ... ?>
Comment: "comment", //<!-- ... -->
Script: "script", //<script> tags
Style: "style", //<style> tags
Tag: "tag", //Any tag
CDATA: "cdata", //<![CDATA[ ... ]]>
isTag: function(elem){
return elem.type === "tag" || elem.type === "script" || elem.type === "style";
}
};

View File

@@ -0,0 +1,73 @@
{
"_args": [
[
"domelementtype@~1.1.1",
"/home/osboxes/code/pentext/editor/node_modules/dom-serializer"
]
],
"_from": "domelementtype@>=1.1.1 <1.2.0",
"_id": "domelementtype@1.1.3",
"_inCache": true,
"_installable": true,
"_location": "/dom-serializer/domelementtype",
"_nodeVersion": "0.10.32",
"_npmUser": {
"email": "me@feedic.com",
"name": "feedic"
},
"_npmVersion": "2.1.5",
"_phantomChildren": {},
"_requested": {
"name": "domelementtype",
"raw": "domelementtype@~1.1.1",
"rawSpec": "~1.1.1",
"scope": null,
"spec": ">=1.1.1 <1.2.0",
"type": "range"
},
"_requiredBy": [
"/dom-serializer"
],
"_resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
"_shasum": "bd28773e2642881aec51544924299c5cd822185b",
"_shrinkwrap": null,
"_spec": "domelementtype@~1.1.1",
"_where": "/home/osboxes/code/pentext/editor/node_modules/dom-serializer",
"author": {
"email": "me@feedic.com",
"name": "Felix Boehm"
},
"bugs": {
"url": "https://github.com/FB55/domelementtype/issues"
},
"dependencies": {},
"description": "all the types of nodes in htmlparser2's dom",
"devDependencies": {},
"directories": {},
"dist": {
"shasum": "bd28773e2642881aec51544924299c5cd822185b",
"tarball": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz"
},
"gitHead": "012a97a1d38737e096de2045b2b5f28768d8187e",
"homepage": "https://github.com/FB55/domelementtype",
"keywords": [
"dom",
"htmlparser2"
],
"main": "index.js",
"maintainers": [
{
"name": "feedic",
"email": "me@feedic.com"
}
],
"name": "domelementtype",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git://github.com/FB55/domelementtype.git"
},
"scripts": {},
"version": "1.1.3"
}

View File

@@ -0,0 +1 @@
all the types of nodes in htmlparser2's dom

99
editor/node_modules/dom-serializer/package.json generated vendored Normal file
View File

@@ -0,0 +1,99 @@
{
"_args": [
[
"dom-serializer@~0.1.0",
"/home/osboxes/code/pentext/editor/node_modules/cheerio"
]
],
"_from": "dom-serializer@>=0.1.0 <0.2.0",
"_id": "dom-serializer@0.1.0",
"_inCache": true,
"_installable": true,
"_location": "/dom-serializer",
"_nodeVersion": "1.2.0",
"_npmUser": {
"email": "me@feedic.com",
"name": "feedic"
},
"_npmVersion": "2.4.1",
"_phantomChildren": {},
"_requested": {
"name": "dom-serializer",
"raw": "dom-serializer@~0.1.0",
"rawSpec": "~0.1.0",
"scope": null,
"spec": ">=0.1.0 <0.2.0",
"type": "range"
},
"_requiredBy": [
"/cheerio",
"/domutils"
],
"_resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
"_shasum": "073c697546ce0780ce23be4a28e293e40bc30c82",
"_shrinkwrap": null,
"_spec": "dom-serializer@~0.1.0",
"_where": "/home/osboxes/code/pentext/editor/node_modules/cheerio",
"author": {
"email": "me@feedic.com",
"name": "Felix Boehm"
},
"bugs": {
"url": "https://github.com/cheeriojs/dom-renderer/issues"
},
"dependencies": {
"domelementtype": "~1.1.1",
"entities": "~1.1.1"
},
"description": "render dom nodes to string",
"devDependencies": {
"cheerio": "*",
"expect.js": "~0.3.1",
"jshint": "~2.3.0",
"lodash": "~2.4.1",
"mocha": "*",
"xyz": "0.4.x"
},
"directories": {},
"dist": {
"shasum": "073c697546ce0780ce23be4a28e293e40bc30c82",
"tarball": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz"
},
"files": [
"index.js"
],
"gitHead": "249b9a921e6ba318c52b87de21e8475bcb4050e5",
"homepage": "https://github.com/cheeriojs/dom-renderer",
"keywords": [
"html",
"render",
"xml"
],
"license": "MIT",
"main": "./index.js",
"maintainers": [
{
"name": "feedic",
"email": "me@feedic.com"
},
{
"name": "davidchambers",
"email": "dc@davidchambers.me"
},
{
"name": "mattmueller",
"email": "mattmuelle@gmail.com"
}
],
"name": "dom-serializer",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git://github.com/cheeriojs/dom-renderer.git"
},
"scripts": {
"test": "mocha test.js"
},
"version": "0.1.0"
}

1
editor/node_modules/domelementtype/.meteor-portable generated vendored Normal file
View File

@@ -0,0 +1 @@
true

11
editor/node_modules/domelementtype/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,11 @@
Copyright (c) Felix Böhm
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

15
editor/node_modules/domelementtype/index.js generated vendored Normal file
View File

@@ -0,0 +1,15 @@
//Types of elements found in the DOM
module.exports = {
Text: "text", //Text
Directive: "directive", //<? ... ?>
Comment: "comment", //<!-- ... -->
Script: "script", //<script> tags
Style: "style", //<style> tags
Tag: "tag", //Any tag
CDATA: "cdata", //<![CDATA[ ... ]]>
Doctype: "doctype",
isTag: function(elem){
return elem.type === "tag" || elem.type === "script" || elem.type === "style";
}
};

75
editor/node_modules/domelementtype/package.json generated vendored Normal file
View File

@@ -0,0 +1,75 @@
{
"_args": [
[
"domelementtype@1",
"/home/osboxes/code/pentext/editor/node_modules/domutils"
]
],
"_from": "domelementtype@>=1.0.0 <2.0.0",
"_id": "domelementtype@1.3.0",
"_inCache": true,
"_installable": true,
"_location": "/domelementtype",
"_nodeVersion": "1.4.2",
"_npmUser": {
"email": "me@feedic.com",
"name": "feedic"
},
"_npmVersion": "2.6.1",
"_phantomChildren": {},
"_requested": {
"name": "domelementtype",
"raw": "domelementtype@1",
"rawSpec": "1",
"scope": null,
"spec": ">=1.0.0 <2.0.0",
"type": "range"
},
"_requiredBy": [
"/domhandler",
"/domutils",
"/htmlparser2"
],
"_resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
"_shasum": "b17aed82e8ab59e52dd9c19b1756e0fc187204c2",
"_shrinkwrap": null,
"_spec": "domelementtype@1",
"_where": "/home/osboxes/code/pentext/editor/node_modules/domutils",
"author": {
"email": "me@feedic.com",
"name": "Felix Boehm"
},
"bugs": {
"url": "https://github.com/FB55/domelementtype/issues"
},
"dependencies": {},
"description": "all the types of nodes in htmlparser2's dom",
"devDependencies": {},
"directories": {},
"dist": {
"shasum": "b17aed82e8ab59e52dd9c19b1756e0fc187204c2",
"tarball": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz"
},
"gitHead": "2a95eed4c829ef479a88984d117cb5f4b379e6e8",
"homepage": "https://github.com/FB55/domelementtype",
"keywords": [
"dom",
"htmlparser2"
],
"main": "index.js",
"maintainers": [
{
"name": "feedic",
"email": "me@feedic.com"
}
],
"name": "domelementtype",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git://github.com/FB55/domelementtype.git"
},
"scripts": {},
"version": "1.3.0"
}

1
editor/node_modules/domelementtype/readme.md generated vendored Normal file
View File

@@ -0,0 +1 @@
all the types of nodes in htmlparser2's dom

1
editor/node_modules/domhandler/.meteor-portable generated vendored Normal file
View File

@@ -0,0 +1 @@
true

7
editor/node_modules/domhandler/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,7 @@
before_install:
- '[ "${TRAVIS_NODE_VERSION}" != "0.8" ] || npm install -g npm@1.4.28'
- npm install -g npm@latest
language: node_js
node_js:
- 0.8
- 0.10

11
editor/node_modules/domhandler/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,11 @@
Copyright (c) Felix Böhm
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

182
editor/node_modules/domhandler/index.js generated vendored Normal file
View File

@@ -0,0 +1,182 @@
var ElementType = require("domelementtype");
var re_whitespace = /\s+/g;
var NodePrototype = require("./lib/node");
var ElementPrototype = require("./lib/element");
function DomHandler(callback, options, elementCB){
if(typeof callback === "object"){
elementCB = options;
options = callback;
callback = null;
} else if(typeof options === "function"){
elementCB = options;
options = defaultOpts;
}
this._callback = callback;
this._options = options || defaultOpts;
this._elementCB = elementCB;
this.dom = [];
this._done = false;
this._tagStack = [];
this._parser = this._parser || null;
}
//default options
var defaultOpts = {
normalizeWhitespace: false, //Replace all whitespace with single spaces
withStartIndices: false, //Add startIndex properties to nodes
};
DomHandler.prototype.onparserinit = function(parser){
this._parser = parser;
};
//Resets the handler back to starting state
DomHandler.prototype.onreset = function(){
DomHandler.call(this, this._callback, this._options, this._elementCB);
};
//Signals the handler that parsing is done
DomHandler.prototype.onend = function(){
if(this._done) return;
this._done = true;
this._parser = null;
this._handleCallback(null);
};
DomHandler.prototype._handleCallback =
DomHandler.prototype.onerror = function(error){
if(typeof this._callback === "function"){
this._callback(error, this.dom);
} else {
if(error) throw error;
}
};
DomHandler.prototype.onclosetag = function(){
//if(this._tagStack.pop().name !== name) this._handleCallback(Error("Tagname didn't match!"));
var elem = this._tagStack.pop();
if(this._elementCB) this._elementCB(elem);
};
DomHandler.prototype._addDomElement = function(element){
var parent = this._tagStack[this._tagStack.length - 1];
var siblings = parent ? parent.children : this.dom;
var previousSibling = siblings[siblings.length - 1];
element.next = null;
if(this._options.withStartIndices){
element.startIndex = this._parser.startIndex;
}
if (this._options.withDomLvl1) {
element.__proto__ = element.type === "tag" ? ElementPrototype : NodePrototype;
}
if(previousSibling){
element.prev = previousSibling;
previousSibling.next = element;
} else {
element.prev = null;
}
siblings.push(element);
element.parent = parent || null;
};
DomHandler.prototype.onopentag = function(name, attribs){
var element = {
type: name === "script" ? ElementType.Script : name === "style" ? ElementType.Style : ElementType.Tag,
name: name,
attribs: attribs,
children: []
};
this._addDomElement(element);
this._tagStack.push(element);
};
DomHandler.prototype.ontext = function(data){
//the ignoreWhitespace is officially dropped, but for now,
//it's an alias for normalizeWhitespace
var normalize = this._options.normalizeWhitespace || this._options.ignoreWhitespace;
var lastTag;
if(!this._tagStack.length && this.dom.length && (lastTag = this.dom[this.dom.length-1]).type === ElementType.Text){
if(normalize){
lastTag.data = (lastTag.data + data).replace(re_whitespace, " ");
} else {
lastTag.data += data;
}
} else {
if(
this._tagStack.length &&
(lastTag = this._tagStack[this._tagStack.length - 1]) &&
(lastTag = lastTag.children[lastTag.children.length - 1]) &&
lastTag.type === ElementType.Text
){
if(normalize){
lastTag.data = (lastTag.data + data).replace(re_whitespace, " ");
} else {
lastTag.data += data;
}
} else {
if(normalize){
data = data.replace(re_whitespace, " ");
}
this._addDomElement({
data: data,
type: ElementType.Text
});
}
}
};
DomHandler.prototype.oncomment = function(data){
var lastTag = this._tagStack[this._tagStack.length - 1];
if(lastTag && lastTag.type === ElementType.Comment){
lastTag.data += data;
return;
}
var element = {
data: data,
type: ElementType.Comment
};
this._addDomElement(element);
this._tagStack.push(element);
};
DomHandler.prototype.oncdatastart = function(){
var element = {
children: [{
data: "",
type: ElementType.Text
}],
type: ElementType.CDATA
};
this._addDomElement(element);
this._tagStack.push(element);
};
DomHandler.prototype.oncommentend = DomHandler.prototype.oncdataend = function(){
this._tagStack.pop();
};
DomHandler.prototype.onprocessinginstruction = function(name, data){
this._addDomElement({
name: name,
data: data,
type: ElementType.Directive
});
};
module.exports = DomHandler;

20
editor/node_modules/domhandler/lib/element.js generated vendored Normal file
View File

@@ -0,0 +1,20 @@
// DOM-Level-1-compliant structure
var NodePrototype = require('./node');
var ElementPrototype = module.exports = Object.create(NodePrototype);
var domLvl1 = {
tagName: "name"
};
Object.keys(domLvl1).forEach(function(key) {
var shorthand = domLvl1[key];
Object.defineProperty(ElementPrototype, key, {
get: function() {
return this[shorthand] || null;
},
set: function(val) {
this[shorthand] = val;
return val;
}
});
});

44
editor/node_modules/domhandler/lib/node.js generated vendored Normal file
View File

@@ -0,0 +1,44 @@
// This object will be used as the prototype for Nodes when creating a
// DOM-Level-1-compliant structure.
var NodePrototype = module.exports = {
get firstChild() {
var children = this.children;
return children && children[0] || null;
},
get lastChild() {
var children = this.children;
return children && children[children.length - 1] || null;
},
get nodeType() {
return nodeTypes[this.type] || nodeTypes.element;
}
};
var domLvl1 = {
tagName: "name",
childNodes: "children",
parentNode: "parent",
previousSibling: "prev",
nextSibling: "next",
nodeValue: "data"
};
var nodeTypes = {
element: 1,
text: 3,
cdata: 4,
comment: 8
};
Object.keys(domLvl1).forEach(function(key) {
var shorthand = domLvl1[key];
Object.defineProperty(NodePrototype, key, {
get: function() {
return this[shorthand] || null;
},
set: function(val) {
this[shorthand] = val;
return val;
}
});
});

94
editor/node_modules/domhandler/package.json generated vendored Normal file
View File

@@ -0,0 +1,94 @@
{
"_args": [
[
"domhandler@^2.3.0",
"/home/osboxes/code/pentext/editor/node_modules/htmlparser2"
]
],
"_from": "domhandler@>=2.3.0 <3.0.0",
"_id": "domhandler@2.3.0",
"_inCache": true,
"_installable": true,
"_location": "/domhandler",
"_nodeVersion": "0.10.32",
"_npmUser": {
"email": "me@feedic.com",
"name": "feedic"
},
"_npmVersion": "2.1.5",
"_phantomChildren": {},
"_requested": {
"name": "domhandler",
"raw": "domhandler@^2.3.0",
"rawSpec": "^2.3.0",
"scope": null,
"spec": ">=2.3.0 <3.0.0",
"type": "range"
},
"_requiredBy": [
"/htmlparser2"
],
"_resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz",
"_shasum": "2de59a0822d5027fabff6f032c2b25a2a8abe738",
"_shrinkwrap": null,
"_spec": "domhandler@^2.3.0",
"_where": "/home/osboxes/code/pentext/editor/node_modules/htmlparser2",
"author": {
"email": "me@feedic.com",
"name": "Felix Boehm"
},
"bugs": {
"url": "https://github.com/fb55/DomHandler/issues"
},
"dependencies": {
"domelementtype": "1"
},
"description": "handler for htmlparser2 that turns pages into a dom",
"devDependencies": {
"htmlparser2": "3.8",
"jshint": "~2.3.0",
"mocha": "1"
},
"directories": {
"test": "tests"
},
"dist": {
"shasum": "2de59a0822d5027fabff6f032c2b25a2a8abe738",
"tarball": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz"
},
"gitHead": "9c224be43a43bc54ebfc2d2e47ab3b9f97836cb2",
"homepage": "https://github.com/fb55/DomHandler",
"jshintConfig": {
"globals": {
"it": true
},
"node": true,
"proto": true,
"quotmark": "double",
"trailing": true,
"undef": true,
"unused": true
},
"keywords": [
"dom",
"htmlparser2"
],
"main": "index.js",
"maintainers": [
{
"name": "feedic",
"email": "me@feedic.com"
}
],
"name": "domhandler",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git://github.com/fb55/DomHandler.git"
},
"scripts": {
"test": "mocha -R list && jshint index.js test/"
},
"version": "2.3.0"
}

105
editor/node_modules/domhandler/readme.md generated vendored Normal file
View File

@@ -0,0 +1,105 @@
#DOMHandler [![Build Status](https://secure.travis-ci.org/fb55/DomHandler.png)](http://travis-ci.org/fb55/DomHandler)
The DOM handler (formally known as DefaultHandler) creates a tree containing all nodes of a page. The tree may be manipulated using the DOMUtils library.
##Usage
```javascript
var handler = new DomHandler([ <func> callback(err, dom), ] [ <obj> options ]);
// var parser = new Parser(handler[, options]);
```
##Example
```javascript
var htmlparser = require("htmlparser2");
var rawHtml = "Xyz <script language= javascript>var foo = '<<bar>>';< / script><!--<!-- Waah! -- -->";
var handler = new htmlparser.DomHandler(function (error, dom) {
if (error)
[...do something for errors...]
else
[...parsing done, do something...]
console.log(dom);
});
var parser = new htmlparser.Parser(handler);
parser.write(rawHtml);
parser.done();
```
Output:
```javascript
[{
data: 'Xyz ',
type: 'text'
}, {
type: 'script',
name: 'script',
attribs: {
language: 'javascript'
},
children: [{
data: 'var foo = \'<bar>\';<',
type: 'text'
}]
}, {
data: '<!-- Waah! -- ',
type: 'comment'
}]
```
##Option: normalizeWhitespace
Indicates whether the whitespace in text nodes should be normalized (= all whitespace should be replaced with single spaces). The default value is "false".
The following HTML will be used:
```html
<font>
<br>this is the text
<font>
```
###Example: true
```javascript
[{
type: 'tag',
name: 'font',
children: [{
data: ' ',
type: 'text'
}, {
type: 'tag',
name: 'br'
}, {
data: 'this is the text ',
type: 'text'
}, {
type: 'tag',
name: 'font'
}]
}]
```
###Example: false
```javascript
[{
type: 'tag',
name: 'font',
children: [{
data: '\n\t',
type: 'text'
}, {
type: 'tag',
name: 'br'
}, {
data: 'this is the text\n',
type: 'text'
}, {
type: 'tag',
name: 'font'
}]
}]
```
##Option: withStartIndices
Indicates whether a `startIndex` property will be added to nodes. When the parser is used in a non-streaming fashion, `startIndex` is an integer indicating the position of the start of the node in the document. The default value is "false".

View File

@@ -0,0 +1,57 @@
{
"name": "Basic test",
"options": {},
"html": "<!DOCTYPE html><html><title>The Title</title><body>Hello world</body></html>",
"expected": [
{
"name": "!doctype",
"data": "!DOCTYPE html",
"type": "directive"
},
{
"type": "tag",
"name": "html",
"attribs": {},
"parent": null,
"children": [
{
"type": "tag",
"name": "title",
"attribs": {},
"parent": {
"type": "tag",
"name": "html",
"attribs": {}
},
"children": [
{
"data": "The Title",
"type": "text",
"parent": {
"type": "tag",
"name": "title",
"attribs": {}
}
}
]
},
{
"type": "tag",
"name": "body",
"attribs": {},
"children": [
{
"data": "Hello world",
"type": "text"
}
],
"prev": {
"type": "tag",
"name": "title",
"attribs": {}
}
}
]
}
]
}

View File

@@ -0,0 +1,21 @@
{
"name": "Single Tag 1",
"options": {},
"html": "<br>text</br>",
"expected": [
{
"type": "tag",
"name": "br",
"attribs": {}
},
{
"data": "text",
"type": "text"
},
{
"type": "tag",
"name": "br",
"attribs": {}
}
]
}

View File

@@ -0,0 +1,21 @@
{
"name": "Single Tag 2",
"options": {},
"html": "<br>text<br>",
"expected": [
{
"type": "tag",
"name": "br",
"attribs": {}
},
{
"data": "text",
"type": "text"
},
{
"type": "tag",
"name": "br",
"attribs": {}
}
]
}

View File

@@ -0,0 +1,27 @@
{
"name": "Unescaped chars in script",
"options": {},
"html": "<head><script language=\"Javascript\">var foo = \"<bar>\"; alert(2 > foo); var baz = 10 << 2; var zip = 10 >> 1; var yap = \"<<>>>><<\";</script></head>",
"expected": [
{
"type": "tag",
"name": "head",
"attribs": {},
"children": [
{
"type": "script",
"name": "script",
"attribs": {
"language": "Javascript"
},
"children": [
{
"data": "var foo = \"<bar>\"; alert(2 > foo); var baz = 10 << 2; var zip = 10 >> 1; var yap = \"<<>>>><<\";",
"type": "text"
}
]
}
]
}
]
}

View File

@@ -0,0 +1,18 @@
{
"name": "Special char in comment",
"options": {},
"html": "<head><!-- commented out tags <title>Test</title>--></head>",
"expected": [
{
"type": "tag",
"name": "head",
"attribs": {},
"children": [
{
"data": " commented out tags <title>Test</title>",
"type": "comment"
}
]
}
]
}

View File

@@ -0,0 +1,18 @@
{
"name": "Script source in comment",
"options": {},
"html": "<script><!--var foo = 1;--></script>",
"expected": [
{
"type": "script",
"name": "script",
"attribs": {},
"children": [
{
"data": "<!--var foo = 1;-->",
"type": "text"
}
]
}
]
}

Some files were not shown because too many files have changed in this diff Show More