diff --git a/README.md b/README.md index 9322a3b..9bee778 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,22 @@ # README for Service Adapter Assignment on IF4050 2015 -##Instruction -1. Fork this repository https://github.com/if-itb/if4050-2015-ServiceAdapter.git -2. Work on your fork --> commit --> push [as many as you want] -3. [When you are done OR the deadline] create pull request +##Personal Data: + * NIM = 13512047 + * Name = Fahmi Dumadi + * GithubID = fahmidumadi -Each participnats should indicate clearly the following data: - * NIM = 1[35|82]+XXYYY - * Name = XXXXXXX - * GithubID = YYYY - -Requreiments: - * .... - * .... - * - -How to Deploy - 1. ..... - 2. ..... - 3. ..... - 4. +##Requirements: + * Node JS 4.0.0 -How to Run - 1. ..... - 2. ..... +##How to Deploy + 1. install dependencies using "npm install" command + 2. run adapter.js with command "node adapter.js" + 3. access through localhost:3000 +##How to Run + 1. The required parameter are + * 'ps': major code + * 'kode': course code + * 'kelas': class number + 2. Example of a full request: localhost:3000/?ps=101&kode=MA1101&kelas=01 + 3. The response from this adapter is JSON containing information with status code diff --git a/adapter.js b/adapter.js new file mode 100644 index 0000000..5de1530 --- /dev/null +++ b/adapter.js @@ -0,0 +1,92 @@ +var request = require("request"), + cheerio = require("cheerio"), + express = require("express"), + app = express(); + +app.get('/', function(req,resp){ + var prodi = req.query.ps, + kode_kuliah = req.query.kode, + kelas = req.query.kelas, + url = "https://six.akademik.itb.ac.id/publik/daftarkelas.php?ps="+prodi+"&semester=1&tahun=2015&th_kur=2013"; + //function getResponse(callback){ + if( prodi != null && kode_kuliah != null && kelas != null){ + request(url, function (error, response, body) { + if (!error) { + var $ = cheerio.load(body), + getURL = $('li:contains("'+kode_kuliah+'")').find('li:contains("'+kelas+'")').find('a').attr('href'); + newURL = 'https://six.akademik.itb.ac.id/publik/' + getURL; + + request(newURL, function (error, response, body) { + if (!error) { + if(getURL == null){ + var json = {}; + json.error = "Tidak ditemukan kelas dengan kode "+kode_kuliah; + console.log("Status Code: 404"); + resp.status(404).send(json); + //callback(json); + }else{ + var $ = cheerio.load(body), + data = $('pre').text().split('\n'), + json = {}; + json.fakultas = data[0]; + json.prodi = data[1].substr(17); + json.semester = data[2].substr(12,1); + json.tahun = "20" + data[2].substr(14); + json.kode = data[4].substr(19,6); + + var mata_kuliah = data[4].substr(28).split(','); + json.mata_kuliah = mata_kuliah[0]; + json.sks = mata_kuliah[1].substr(1,1); + + json.kelas = data[5].substr(19,2); + json.dosen = data[5].substr(24); + json.jumlah_peserta = data[data.length-2].substr(16); + + var peserta_kelas = []; + for(i = 0; i < json.jumlah_peserta; i++){ + jsonPK = {}; + jsonPK.nim = data[10+i].substr(4,8); + jsonPK.nama = data[10+i].substr(15); + peserta_kelas.push(jsonPK); + } + json.peserta = peserta_kelas; + console.log("Status Code: 200"); + resp.status(200).send(json); + //callback(json); + } + } else { + var json = {}; + json.error = "Terjadi kesalahan pada server"; + console.log("Status Code: 500"); + resp.status(500).send(json); + //callback(json); + } + }); + + } else { + var json = {}; + json.error = "Terjadi kesalahan pada server"; + console.log("Status Code: 500"); + resp.status(500).send(json); + //callback(json); + } + }); + } + else{ + var json = {}; + json.error = "Request tidak sesuai format"; + console.log("Status Code: 400"); + resp.status(400).send(json); + //callback(json); + } + //} + /*getResponse(function (hasil){ + resp.send(hasil); + });*/ +}); + +var server = app.listen(3000, function(){ + var host = server.address().address; + var port = server.address().port; + console.log("listening on port: " + port); +}); \ No newline at end of file diff --git a/node_modules/cheerio/.jshintrc b/node_modules/cheerio/.jshintrc new file mode 100644 index 0000000..1a078d4 --- /dev/null +++ b/node_modules/cheerio/.jshintrc @@ -0,0 +1,10 @@ +{ + "indent": 2, + "eqnull": true, + "laxbreak": true, + "proto": true, + "undef": true, + "unused": true, + "node": true, + "quotmark": "single" +} diff --git a/node_modules/cheerio/.npmignore b/node_modules/cheerio/.npmignore new file mode 100644 index 0000000..02ace9c --- /dev/null +++ b/node_modules/cheerio/.npmignore @@ -0,0 +1,9 @@ +benchmark/ +src/ +support/ +tests/ +examples/ +*.sock +*.tmproj +coverage.html +lib-cov diff --git a/node_modules/cheerio/.travis.yml b/node_modules/cheerio/.travis.yml new file mode 100644 index 0000000..57610c1 --- /dev/null +++ b/node_modules/cheerio/.travis.yml @@ -0,0 +1,9 @@ +language: node_js +node_js: + - "0.10" + - 0.11 +script: make travis-test +matrix: + fast_finish: true + allow_failures: + - node_js: 0.11 diff --git a/node_modules/cheerio/CONTRIBUTING.md b/node_modules/cheerio/CONTRIBUTING.md new file mode 100644 index 0000000..cc38bb8 --- /dev/null +++ b/node_modules/cheerio/CONTRIBUTING.md @@ -0,0 +1,47 @@ +# Contributing to Cheerio + +Thanks for your interest in contributing to the project! Here's a rundown of +how we'd like to work with you: + +1. File an issue on GitHub describing the contribution you'd like to make. This + will help us to get you started on the right foot. +2. Create a single commit that addresses the issue: + 1. Follow the project's code style (see below) + 2. Add enough unit tests to "prove" that your patch is correct + 3. Update the project documentation as needed (see below) + 4. Describe your approach with as much detail as necessary in the git + commit message +3. Open a pull request, and reference the initial issue in the pull request + message. + +# Documentation + +Any API change should be reflected in the project's README.md file. Reuse +[jQuery's documentation](http://api.jquery.com) wherever possible, but take +care to note aspects that make Cheerio distinct. + +# Code Style + +This section is by no means complete. For undocumented stylistic choices, +please try to maintain consistency with the code base. + +- Single quotes: `'` +- Whitespace + - Two-space "soft" tabs + - Once space following control flow statements (`if (condition) {` rather + than `if(condition) {`) + - Remove trailing spaces + - [End each file with a newline + character.](https://github.com/editorconfig/editorconfig/wiki/Newline-at-End-of-File-Support) +- Terminate every statement with a semicolon +- Private functionality (for re-using functionality that isn't part of the + jQuery API) + - *Static methods*: If the functionality does not require a reference to a + Cheerio instance, simply define a named function within the module it is + needed. + - *Instance methods*: If the functionality requires a reference to a Cheerio + instance, informally define the method as "private" using the following + conventions: + - Define the method as a function on the Cheerio prototype + - Prefix the method name with an underscore (`_`) character + - Include `@api private` in the code comment the documents the method diff --git a/node_modules/cheerio/History.md b/node_modules/cheerio/History.md new file mode 100644 index 0000000..6e946f8 --- /dev/null +++ b/node_modules/cheerio/History.md @@ -0,0 +1,515 @@ + +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('')`) 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 ` text " +); + +module.exports = makeDom(markup); diff --git a/node_modules/cheerio/node_modules/css-select/node_modules/domutils/test/tests/helpers.js b/node_modules/cheerio/node_modules/css-select/node_modules/domutils/test/tests/helpers.js new file mode 100644 index 0000000..c418dd4 --- /dev/null +++ b/node_modules/cheerio/node_modules/css-select/node_modules/domutils/test/tests/helpers.js @@ -0,0 +1,29 @@ +var makeDom = require("../utils").makeDom; +var assert = require("assert"); + +describe("helpers", function() { + describe("removeSubsets", function() { + var removeSubsets = require("../..").removeSubsets; + var dom = makeDom("

")[0]; + + it("removes identical trees", function() { + var matches = removeSubsets([dom, dom]); + assert.equal(matches.length, 1); + }); + + it("Removes subsets found first", function() { + var matches = removeSubsets([dom, dom.children[0].children[0]]); + assert.equal(matches.length, 1); + }); + + it("Removes subsets found last", function() { + var matches = removeSubsets([dom.children[0], dom]); + assert.equal(matches.length, 1); + }); + + it("Does not remove unique trees", function() { + var matches = removeSubsets([dom.children[0], dom.children[1]]); + assert.equal(matches.length, 2); + }); + }); +}); diff --git a/node_modules/cheerio/node_modules/css-select/node_modules/domutils/test/tests/legacy.js b/node_modules/cheerio/node_modules/css-select/node_modules/domutils/test/tests/legacy.js new file mode 100644 index 0000000..87fabfa --- /dev/null +++ b/node_modules/cheerio/node_modules/css-select/node_modules/domutils/test/tests/legacy.js @@ -0,0 +1,119 @@ +var DomUtils = require("../.."); +var fixture = require("../fixture"); +var assert = require("assert"); + +// Set up expected structures +var expected = { + idAsdf: fixture[1], + tag2: [], + typeScript: [] +}; +for (var idx = 0; idx < 20; ++idx) { + expected.tag2.push(fixture[idx*2 + 1].children[5]); + expected.typeScript.push(fixture[idx*2 + 1].children[1]); +} + +describe("legacy", function() { + describe("getElements", function() { + var getElements = DomUtils.getElements; + it("returns the node with the specified ID", function() { + assert.deepEqual( + getElements({ id: "asdf" }, fixture, true, 1), + [expected.idAsdf] + ); + }); + it("returns empty array for unknown IDs", function() { + assert.deepEqual(getElements({ id: "asdfs" }, fixture, true), []); + }); + it("returns the nodes with the specified tag name", function() { + assert.deepEqual( + getElements({ tag_name:"tag2" }, fixture, true), + expected.tag2 + ); + }); + it("returns empty array for unknown tag names", function() { + assert.deepEqual( + getElements({ tag_name : "asdfs" }, fixture, true), + [] + ); + }); + it("returns the nodes with the specified tag type", function() { + assert.deepEqual( + getElements({ tag_type: "script" }, fixture, true), + expected.typeScript + ); + }); + it("returns empty array for unknown tag types", function() { + assert.deepEqual( + getElements({ tag_type: "video" }, fixture, true), + [] + ); + }); + }); + + describe("getElementById", function() { + var getElementById = DomUtils.getElementById; + it("returns the specified node", function() { + assert.equal( + expected.idAsdf, + getElementById("asdf", fixture, true) + ); + }); + it("returns `null` for unknown IDs", function() { + assert.equal(null, getElementById("asdfs", fixture, true)); + }); + }); + + describe("getElementsByTagName", function() { + var getElementsByTagName = DomUtils.getElementsByTagName; + it("returns the specified nodes", function() { + assert.deepEqual( + getElementsByTagName("tag2", fixture, true), + expected.tag2 + ); + }); + it("returns empty array for unknown tag names", function() { + assert.deepEqual( + getElementsByTagName("tag23", fixture, true), + [] + ); + }); + }); + + describe("getElementsByTagType", function() { + var getElementsByTagType = DomUtils.getElementsByTagType; + it("returns the specified nodes", function() { + assert.deepEqual( + getElementsByTagType("script", fixture, true), + expected.typeScript + ); + }); + it("returns empty array for unknown tag types", function() { + assert.deepEqual( + getElementsByTagType("video", fixture, true), + [] + ); + }); + }); + + describe("getOuterHTML", function() { + var getOuterHTML = DomUtils.getOuterHTML; + it("Correctly renders the outer HTML", function() { + assert.equal( + getOuterHTML(fixture[1]), + " text " + ); + }); + }); + + describe("getInnerHTML", function() { + var getInnerHTML = DomUtils.getInnerHTML; + it("Correctly renders the inner HTML", function() { + assert.equal( + getInnerHTML(fixture[1]), + " text " + ); + }); + }); + +}); diff --git a/node_modules/cheerio/node_modules/css-select/node_modules/domutils/test/utils.js b/node_modules/cheerio/node_modules/css-select/node_modules/domutils/test/utils.js new file mode 100644 index 0000000..676e8f6 --- /dev/null +++ b/node_modules/cheerio/node_modules/css-select/node_modules/domutils/test/utils.js @@ -0,0 +1,9 @@ +var htmlparser = require("htmlparser2"); + +exports.makeDom = function(markup) { + var handler = new htmlparser.DomHandler(), + parser = new htmlparser.Parser(handler); + parser.write(markup); + parser.done(); + return handler.dom; +}; diff --git a/node_modules/cheerio/node_modules/css-select/node_modules/nth-check/.travis.yml b/node_modules/cheerio/node_modules/css-select/node_modules/nth-check/.travis.yml new file mode 100644 index 0000000..e20bedc --- /dev/null +++ b/node_modules/cheerio/node_modules/css-select/node_modules/nth-check/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - 0.8 + - "0.10" + - 0.11 diff --git a/node_modules/cheerio/node_modules/css-select/node_modules/nth-check/README.md b/node_modules/cheerio/node_modules/css-select/node_modules/nth-check/README.md new file mode 100644 index 0000000..fb80a1d --- /dev/null +++ b/node_modules/cheerio/node_modules/css-select/node_modules/nth-check/README.md @@ -0,0 +1,51 @@ +#nth-check [![Build Status](https://travis-ci.org/fb55/nth-check.png)](https://travis-ci.org/fb55/nth-check) + +A performant nth-check parser & compiler. + +###About + +This module can be used to parse & compile nth-checks, as they are found in CSS 3's `nth-child()` and `nth-last-of-type()`. + +`nth-check` focusses on speed, providing optimized functions for different kinds of nth-child formulas, while still following the [spec](http://www.w3.org/TR/css3-selectors/#nth-child-pseudo). + +###API + +```js +var nthCheck = require("nth-check"); +``` + +#####`nthCheck(formula)` + +First parses, then compiles the formula. + +#####`nthCheck.parse(formula)` + +Parses the expression, throws a `SyntaxError` if it fails, otherwise returns an array containing two elements. + +__Example:__ + +```js +nthCheck.parse("2n+3") //[2, 3] +``` + +#####`nthCheck.compile([a, b])` + +Takes an array with two elements (as returned by `.parse`) and returns a highly optimized function. + +If the formula doesn't match any elements, it returns [`boolbase`](https://github.com/fb55/boolbase)'s `falseFunc`, otherwise, a function accepting an _index_ is returned, which returns whether or not a passed _index_ matches the formula. (Note: The spec starts counting at `1`, the returned function at `0`). + +__Example:__ +```js +var check = nthCheck.compile([2, 3]); + +check(0) //false +check(1) //false +check(2) //true +check(3) //false +check(4) //true +check(5) //false +check(6) //true +``` + +--- +License: BSD diff --git a/node_modules/cheerio/node_modules/css-select/node_modules/nth-check/compile.js b/node_modules/cheerio/node_modules/css-select/node_modules/nth-check/compile.js new file mode 100644 index 0000000..77f2436 --- /dev/null +++ b/node_modules/cheerio/node_modules/css-select/node_modules/nth-check/compile.js @@ -0,0 +1,40 @@ +module.exports = compile; + +var BaseFuncs = require("boolbase"), + trueFunc = BaseFuncs.trueFunc, + falseFunc = BaseFuncs.falseFunc; + +/* + returns a function that checks if an elements index matches the given rule + highly optimized to return the fastest solution +*/ +function compile(parsed){ + var a = parsed[0], + b = parsed[1] - 1; + + //when b <= 0, a*n won't be possible for any matches when a < 0 + //besides, the specification says that no element is matched when a and b are 0 + if(b < 0 && a <= 0) return falseFunc; + + //when a is in the range -1..1, it matches any element (so only b is checked) + if(a ===-1) return function(pos){ return pos <= b; }; + if(a === 0) return function(pos){ return pos === b; }; + //when b <= 0 and a === 1, they match any element + if(a === 1) return b < 0 ? trueFunc : function(pos){ return pos >= b; }; + + //when a > 0, modulo can be used to check if there is a match + var bMod = b % a; + if(bMod < 0) bMod += a; + + if(a > 1){ + return function(pos){ + return pos >= b && pos % a === bMod; + }; + } + + a *= -1; //make `a` positive + + return function(pos){ + return pos <= b && pos % a === bMod; + }; +} \ No newline at end of file diff --git a/node_modules/cheerio/node_modules/css-select/node_modules/nth-check/index.js b/node_modules/cheerio/node_modules/css-select/node_modules/nth-check/index.js new file mode 100644 index 0000000..3253bbd --- /dev/null +++ b/node_modules/cheerio/node_modules/css-select/node_modules/nth-check/index.js @@ -0,0 +1,9 @@ +var parse = require("./parse.js"), + compile = require("./compile.js"); + +module.exports = function nthCheck(formula){ + return compile(parse(formula)); +}; + +module.exports.parse = parse; +module.exports.compile = compile; \ No newline at end of file diff --git a/node_modules/cheerio/node_modules/css-select/node_modules/nth-check/package.json b/node_modules/cheerio/node_modules/css-select/node_modules/nth-check/package.json new file mode 100644 index 0000000..da4f08e --- /dev/null +++ b/node_modules/cheerio/node_modules/css-select/node_modules/nth-check/package.json @@ -0,0 +1,52 @@ +{ + "name": "nth-check", + "version": "1.0.1", + "description": "performant nth-check parser & compiler", + "main": "index.js", + "scripts": { + "test": "node test" + }, + "repository": { + "type": "git", + "url": "https://github.com/fb55/nth-check" + }, + "keywords": [ + "nth-child", + "nth", + "css" + ], + "author": { + "name": "Felix Boehm", + "email": "me@feedic.com" + }, + "license": "BSD", + "bugs": { + "url": "https://github.com/fb55/nth-check/issues" + }, + "homepage": "https://github.com/fb55/nth-check", + "dependencies": { + "boolbase": "~1.0.0" + }, + "gitHead": "257338e5bbd53228236abd4cc09539b66b27dd11", + "_id": "nth-check@1.0.1", + "_shasum": "9929acdf628fc2c41098deab82ac580cf149aae4", + "_from": "nth-check@>=1.0.0 <1.1.0", + "_npmVersion": "2.6.1", + "_nodeVersion": "1.5.1", + "_npmUser": { + "name": "feedic", + "email": "me@feedic.com" + }, + "maintainers": [ + { + "name": "feedic", + "email": "me@feedic.com" + } + ], + "dist": { + "shasum": "9929acdf628fc2c41098deab82ac580cf149aae4", + "tarball": "http://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz" + }, + "directories": {}, + "_resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz" +} diff --git a/node_modules/cheerio/node_modules/css-select/node_modules/nth-check/parse.js b/node_modules/cheerio/node_modules/css-select/node_modules/nth-check/parse.js new file mode 100644 index 0000000..5302951 --- /dev/null +++ b/node_modules/cheerio/node_modules/css-select/node_modules/nth-check/parse.js @@ -0,0 +1,40 @@ +module.exports = parse; + +//following http://www.w3.org/TR/css3-selectors/#nth-child-pseudo + +//[ ['-'|'+']? INTEGER? {N} [ S* ['-'|'+'] S* INTEGER ]? +var re_nthElement = /^([+\-]?\d*n)?\s*(?:([+\-]?)\s*(\d+))?$/; + +/* + parses a nth-check formula, returns an array of two numbers +*/ +function parse(formula){ + formula = formula.trim().toLowerCase(); + + if(formula === "even"){ + return [2, 0]; + } else if(formula === "odd"){ + return [2, 1]; + } else { + var parsed = formula.match(re_nthElement); + + if(!parsed){ + throw new SyntaxError("n-th rule couldn't be parsed ('" + formula + "')"); + } + + var a; + + if(parsed[1]){ + a = parseInt(parsed[1], 10); + if(isNaN(a)){ + if(parsed[1].charAt(0) === "-") a = -1; + else a = 1; + } + } else a = 0; + + return [ + a, + parsed[3] ? parseInt((parsed[2] || "") + parsed[3], 10) : 0 + ]; + } +} diff --git a/node_modules/cheerio/node_modules/css-select/node_modules/nth-check/test.js b/node_modules/cheerio/node_modules/css-select/node_modules/nth-check/test.js new file mode 100644 index 0000000..0800701 --- /dev/null +++ b/node_modules/cheerio/node_modules/css-select/node_modules/nth-check/test.js @@ -0,0 +1,102 @@ +var nthCheck = require("./"), + assert = require("assert"); + +var invalid = ["-", "asdf", "2n+-0", "2+0", "- 1n", "-1 n"]; + +function parseInvalid(){ + invalid.forEach(function(formula){ + assert.throws(function(){ + nthCheck.parse(formula); + }, + SyntaxError, + formula + ); + }); +} + +var valid = { + "1": [ 0, 1 ], + "2": [ 0, 2 ], + "3": [ 0, 3 ], + "5": [ 0, 5 ], + " 1 ": [ 0, 1 ], + " 5 ": [ 0, 5 ], + "+2n + 1": [ 2, 1 ], + "-1": [ 0, -1 ], + "-1n + 3": [ -1, 3 ], + "-1n+3": [ -1, 3 ], + "-n+2": [ -1, 2 ], + "-n+3": [ -1, 3 ], + "0n+3": [ 0, 3 ], + "1n": [ 1, 0 ], + "1n+0": [ 1, 0 ], + "2n": [ 2, 0 ], + "2n + 1": [ 2, 1 ], + "2n+1": [ 2, 1 ], + "3n": [ 3, 0 ], + "3n+0": [ 3, 0 ], + "3n+1": [ 3, 1 ], + "3n+2": [ 3, 2 ], + "3n+3": [ 3, 3 ], + "3n-1": [ 3, -1 ], + "3n-2": [ 3, -2 ], + "3n-3": [ 3, -3 ], + even: [ 2, 0 ], + n: [ 1, 0 ], + "n+2": [ 1, 2 ], + odd: [ 2, 1 ], + + //surprisingly, neither sizzle, qwery or nwmatcher cover these cases + "-4n+13": [-4, 13], + "-2n + 12": [-2, 12] +}; + +function parseValid(){ + Object.keys(valid).forEach(function(formula){ + assert.deepEqual(nthCheck.parse(formula), valid[formula], formula); + }); +} + +function testValid(){ + Object.keys(valid).forEach(function(formula){ + testFormula(valid[formula], formula); + }); +} + +var valArray = Array.apply(null, Array(2e3)).map(function(_, i){return i;}); + +function testFormula(formula, name){ + var filtered = valArray.filter(nthCheck.compile(formula)), + iterated = stupidNth(formula); + + try { + assert.deepEqual(filtered, iterated, name); + } catch(e){ + e.expected = JSON.stringify(iterated) + " " + name; + e.actual = JSON.stringify(filtered) + " " + name; + throw e; + } +} + +function stupidNth(formula, limit){ + var a = formula[0], + b = formula[1]; + + if(a === 0 && b > 0) return [b - 1]; + + //taken from qwery + return valArray.filter(function(val){ + for(var i = b, l = valArray.length; ((a > 0) ? (i <= l) : (i >= 1)); i += a){ + if(val === valArray[i - 1]) return true; + } + }); +} + +process.stdout.write("- parser"); +process.stdout.write("\n - parse invalid:\t"); +parseInvalid(); +process.stdout.write("X\n - parse valid:\t"); +parseValid(); +process.stdout.write("X\n- check values: \t"); +testValid(); +process.stdout.write("X\n"); diff --git a/node_modules/cheerio/node_modules/css-select/package.json b/node_modules/cheerio/node_modules/css-select/package.json new file mode 100644 index 0000000..20f9212 --- /dev/null +++ b/node_modules/cheerio/node_modules/css-select/package.json @@ -0,0 +1,90 @@ +{ + "name": "css-select", + "version": "1.0.0", + "description": "a CSS selector compiler/engine", + "author": { + "name": "Felix Boehm", + "email": "me@feedic.com" + }, + "keywords": [ + "css", + "selector", + "sizzle" + ], + "repository": { + "type": "git", + "url": "git://github.com/fb55/css-select.git" + }, + "files": [ + "index.js", + "lib" + ], + "dependencies": { + "css-what": "1.0", + "domutils": "1.4", + "boolbase": "~1.0.0", + "nth-check": "~1.0.0" + }, + "devDependencies": { + "htmlparser2": "*", + "cheerio-soupselect": "*", + "mocha": "*", + "mocha-lcov-reporter": "*", + "coveralls": "*", + "istanbul": "*", + "expect.js": "*", + "jshint": "2" + }, + "scripts": { + "test": "mocha && npm run lint", + "lint": "jshint index.js lib/*.js test/*.js", + "lcov": "istanbul cover _mocha --report lcovonly -- -R spec", + "coveralls": "npm run lint && npm run lcov && (cat coverage/lcov.info | coveralls || exit 0)" + }, + "license": "BSD-like", + "jshintConfig": { + "eqeqeq": true, + "freeze": true, + "latedef": "nofunc", + "noarg": true, + "nonbsp": true, + "quotmark": "double", + "undef": true, + "unused": true, + "trailing": true, + "eqnull": true, + "proto": true, + "smarttabs": true, + "node": true, + "globals": { + "describe": true, + "it": true + } + }, + "gitHead": "c73512d9b5b4dc3f537702283143c9463b4f7d7d", + "bugs": { + "url": "https://github.com/fb55/css-select/issues" + }, + "homepage": "https://github.com/fb55/css-select", + "_id": "css-select@1.0.0", + "_shasum": "b1121ca51848dd264e2244d058cee254deeb44b0", + "_from": "css-select@>=1.0.0 <1.1.0", + "_npmVersion": "2.4.1", + "_nodeVersion": "1.0.4", + "_npmUser": { + "name": "feedic", + "email": "me@feedic.com" + }, + "maintainers": [ + { + "name": "feedic", + "email": "me@feedic.com" + } + ], + "dist": { + "shasum": "b1121ca51848dd264e2244d058cee254deeb44b0", + "tarball": "http://registry.npmjs.org/css-select/-/css-select-1.0.0.tgz" + }, + "directories": {}, + "_resolved": "https://registry.npmjs.org/css-select/-/css-select-1.0.0.tgz" +} diff --git a/node_modules/cheerio/node_modules/dom-serializer/LICENSE b/node_modules/cheerio/node_modules/dom-serializer/LICENSE new file mode 100644 index 0000000..3d241a8 --- /dev/null +++ b/node_modules/cheerio/node_modules/dom-serializer/LICENSE @@ -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. diff --git a/node_modules/cheerio/node_modules/dom-serializer/index.js b/node_modules/cheerio/node_modules/dom-serializer/index.js new file mode 100644 index 0000000..3316dfe --- /dev/null +++ b/node_modules/cheerio/node_modules/dom-serializer/index.js @@ -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 += ''; + } + } + + 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 ''; +} + +function renderComment(elem) { + return ''; +} diff --git a/node_modules/cheerio/node_modules/dom-serializer/node_modules/domelementtype/LICENSE b/node_modules/cheerio/node_modules/dom-serializer/node_modules/domelementtype/LICENSE new file mode 100644 index 0000000..c464f86 --- /dev/null +++ b/node_modules/cheerio/node_modules/dom-serializer/node_modules/domelementtype/LICENSE @@ -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. diff --git a/node_modules/cheerio/node_modules/dom-serializer/node_modules/domelementtype/index.js b/node_modules/cheerio/node_modules/dom-serializer/node_modules/domelementtype/index.js new file mode 100644 index 0000000..89e0b17 --- /dev/null +++ b/node_modules/cheerio/node_modules/dom-serializer/node_modules/domelementtype/index.js @@ -0,0 +1,14 @@ +//Types of elements found in the DOM +module.exports = { + Text: "text", //Text + Directive: "directive", // + Comment: "comment", // + Script: "script", //", + "expected": [ + { + "type": "script", + "name": "script", + "attribs": {}, + "children": [ + { + "data": "", + "type": "text" + } + ] + } + ] +} \ No newline at end of file diff --git a/node_modules/cheerio/node_modules/htmlparser2/node_modules/domhandler/test/cases/07-unescaped_in_style.json b/node_modules/cheerio/node_modules/htmlparser2/node_modules/domhandler/test/cases/07-unescaped_in_style.json new file mode 100644 index 0000000..77438fd --- /dev/null +++ b/node_modules/cheerio/node_modules/htmlparser2/node_modules/domhandler/test/cases/07-unescaped_in_style.json @@ -0,0 +1,20 @@ +{ + "name": "Unescaped chars in style", + "options": {}, + "html": "", + "expected": [ + { + "type": "style", + "name": "style", + "attribs": { + "type": "text/css" + }, + "children": [ + { + "data": "\n body > p\n\t{ font-weight: bold; }", + "type": "text" + } + ] + } + ] +} \ No newline at end of file diff --git a/node_modules/cheerio/node_modules/htmlparser2/node_modules/domhandler/test/cases/08-extra_spaces_in_tag.json b/node_modules/cheerio/node_modules/htmlparser2/node_modules/domhandler/test/cases/08-extra_spaces_in_tag.json new file mode 100644 index 0000000..5c2492e --- /dev/null +++ b/node_modules/cheerio/node_modules/htmlparser2/node_modules/domhandler/test/cases/08-extra_spaces_in_tag.json @@ -0,0 +1,20 @@ +{ + "name": "Extra spaces in tag", + "options": {}, + "html": "the text", + "expected": [ + { + "type": "tag", + "name": "font", + "attribs": { + "size": "14" + }, + "children": [ + { + "data": "the text", + "type": "text" + } + ] + } + ] +} \ No newline at end of file diff --git a/node_modules/cheerio/node_modules/htmlparser2/node_modules/domhandler/test/cases/09-unquoted_attrib.json b/node_modules/cheerio/node_modules/htmlparser2/node_modules/domhandler/test/cases/09-unquoted_attrib.json new file mode 100644 index 0000000..543ccee --- /dev/null +++ b/node_modules/cheerio/node_modules/htmlparser2/node_modules/domhandler/test/cases/09-unquoted_attrib.json @@ -0,0 +1,20 @@ +{ + "name": "Unquoted attributes", + "options": {}, + "html": "the text", + "expected": [ + { + "type": "tag", + "name": "font", + "attribs": { + "size": "14" + }, + "children": [ + { + "data": "the text", + "type": "text" + } + ] + } + ] +} \ No newline at end of file diff --git a/node_modules/cheerio/node_modules/htmlparser2/node_modules/domhandler/test/cases/10-singular_attribute.json b/node_modules/cheerio/node_modules/htmlparser2/node_modules/domhandler/test/cases/10-singular_attribute.json new file mode 100644 index 0000000..544636e --- /dev/null +++ b/node_modules/cheerio/node_modules/htmlparser2/node_modules/domhandler/test/cases/10-singular_attribute.json @@ -0,0 +1,15 @@ +{ + "name": "Singular attribute", + "options": {}, + "html": "