tree crawl

crawl tree

目前為 2017-06-20 提交的版本,檢視 最新版本

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.cn-greasyfork.org/scripts/30801/201742/tree%20crawl.js

  1. // ==UserScript==
  2. // @name tree crawl
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1
  5. // @description crawl tree
  6. // @author Piotr S.
  7. // @require https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.24.2/babel.min.js
  8. // @require https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.23.0/polyfill.min.js
  9. // @match https://dynalist.io/d/*
  10. // ==/UserScript==
  11.  
  12. /* jshint ignore:start */
  13. var inline_src = (<><![CDATA[
  14.  
  15. (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  16. let crawl = require('tree-crawl')
  17. },{"tree-crawl":2}],2:[function(require,module,exports){
  18. (function (global, factory) {
  19. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  20. typeof define === 'function' && define.amd ? define(factory) :
  21. (global.crawl = factory());
  22. }(this, (function () { 'use strict';
  23.  
  24. function Context(flags, cursor) {
  25. this.flags = flags;
  26. this.cursor = cursor;
  27. }
  28. Context.prototype = {
  29. skip: function skip() {
  30. this.flags.skip = true;
  31. },
  32. break: function _break() {
  33. this.flags.break = true;
  34. },
  35. remove: function remove() {
  36. this.flags.remove = true;
  37. },
  38. replace: function replace(node) {
  39. this.flags.replace = node;
  40. },
  41. get parent() {
  42. return this.cursor.parent;
  43. },
  44. get depth() {
  45. return this.cursor.depth;
  46. },
  47. get level() {
  48. return this.cursor.depth + 1;
  49. },
  50. get index() {
  51. return this.cursor.index;
  52. }
  53. };
  54. function ContextFactory(flags, cursor) {
  55. return new Context(flags, cursor);
  56. }
  57.  
  58. function Stack(initial) {
  59. this.xs = [initial];
  60. this.top = 0;
  61. }
  62. Stack.prototype = {
  63. push: function push(x) {
  64. this.top++;
  65. if (this.top < this.xs.length) {
  66. this.xs[this.top] = x;
  67. } else {
  68. this.xs.push(x);
  69. }
  70. },
  71. pushArrayReverse: function pushArrayReverse(xs) {
  72. for (var i = xs.length - 1; i >= 0; i--) {
  73. this.push(xs[i]);
  74. }
  75. },
  76. pop: function pop() {
  77. var x = this.peek();
  78. this.top--;
  79. return x;
  80. },
  81. peek: function peek() {
  82. return this.xs[this.top];
  83. },
  84. isEmpty: function isEmpty() {
  85. return -1 === this.top;
  86. }
  87. };
  88. function QueueFactory(initial) {
  89. return new Stack(initial);
  90. }
  91.  
  92. function DfsCursor() {
  93. this.depth = 0;
  94. this.stack = QueueFactory({ node: null, index: -1 });
  95. }
  96. DfsCursor.prototype = {
  97. moveDown: function moveDown(node) {
  98. this.depth++;
  99. this.stack.push({ node: node, index: 0 });
  100. },
  101. moveUp: function moveUp() {
  102. this.depth--;
  103. this.stack.pop();
  104. },
  105. moveNext: function moveNext() {
  106. this.stack.peek().index++;
  107. },
  108. get parent() {
  109. return this.stack.peek().node;
  110. },
  111. get index() {
  112. return this.stack.peek().index;
  113. }
  114. };
  115. function CursorFactory() {
  116. return new DfsCursor();
  117. }
  118.  
  119. function Flags() {
  120. this.break = false;
  121. this.skip = false;
  122. this.remove = false;
  123. this.replace = null;
  124. }
  125. Flags.prototype = {
  126. reset: function reset() {
  127. this.break = false;
  128. this.skip = false;
  129. this.remove = false;
  130. this.replace = null;
  131. }
  132. };
  133. function FlagsFactory() {
  134. return new Flags();
  135. }
  136.  
  137. function isNotEmpty(xs) {
  138. return 0 !== xs.length;
  139. }
  140.  
  141. function dfsPre(root, iteratee, getChildren) {
  142. var flags = FlagsFactory();
  143. var cursor = CursorFactory();
  144. var context = ContextFactory(flags, cursor);
  145. var stack = QueueFactory(root);
  146. var dummy = Object.assign({}, root);
  147. while (!stack.isEmpty()) {
  148. var node = stack.pop();
  149. if (node === dummy) {
  150. cursor.moveUp();
  151. continue;
  152. }
  153. flags.reset();
  154. iteratee(node, context);
  155. if (flags.break) break;
  156. if (flags.remove) continue;
  157. cursor.moveNext();
  158. if (!flags.skip) {
  159. if (flags.replace) {
  160. node = flags.replace;
  161. }
  162. var children = getChildren(node);
  163. if (isNotEmpty(children)) {
  164. stack.push(dummy);
  165. stack.pushArrayReverse(children);
  166. cursor.moveDown(node);
  167. }
  168. }
  169. }
  170. }
  171.  
  172. function dfsPost(root, iteratee, getChildren) {
  173. var flags = FlagsFactory();
  174. var cursor = CursorFactory();
  175. var context = ContextFactory(flags, cursor);
  176. var stack = QueueFactory(root);
  177. var ancestors = QueueFactory(null);
  178. while (!stack.isEmpty()) {
  179. var node = stack.peek();
  180. var parent = ancestors.peek();
  181. var children = getChildren(node);
  182. flags.reset();
  183. if (node === parent || !isNotEmpty(children)) {
  184. if (node === parent) {
  185. ancestors.pop();
  186. cursor.moveUp();
  187. }
  188. stack.pop();
  189. iteratee(node, context);
  190. if (flags.break) break;
  191. if (flags.remove) continue;
  192. cursor.moveNext();
  193. } else {
  194. ancestors.push(node);
  195. cursor.moveDown(node);
  196. stack.pushArrayReverse(children);
  197. }
  198. }
  199. }
  200.  
  201. var THRESHOLD = 32768;
  202. function Queue(initial) {
  203. this.xs = [initial];
  204. this.top = 0;
  205. this.maxLength = 0;
  206. }
  207. Queue.prototype = {
  208. enqueue: function enqueue(x) {
  209. this.xs.push(x);
  210. },
  211. enqueueMultiple: function enqueueMultiple(xs) {
  212. for (var i = 0, len = xs.length; i < len; i++) {
  213. this.enqueue(xs[i]);
  214. }
  215. },
  216. dequeue: function dequeue() {
  217. var x = this.peek();
  218. this.top++;
  219. if (this.top === THRESHOLD) {
  220. this.xs = this.xs.slice(this.top);
  221. this.top = 0;
  222. }
  223. return x;
  224. },
  225. peek: function peek() {
  226. return this.xs[this.top];
  227. },
  228. isEmpty: function isEmpty() {
  229. return this.top === this.xs.length;
  230. }
  231. };
  232. function QueueFactory$1(initial) {
  233. return new Queue(initial);
  234. }
  235.  
  236. function BfsCursor() {
  237. this.depth = 0;
  238. this.index = -1;
  239. this.queue = QueueFactory$1({ node: null, arity: 1 });
  240. this.levelNodes = 1;
  241. this.nextLevelNodes = 0;
  242. }
  243. BfsCursor.prototype = {
  244. store: function store(node, arity) {
  245. this.queue.enqueue({ node: node, arity: arity });
  246. this.nextLevelNodes += arity;
  247. },
  248. moveNext: function moveNext() {
  249. this.index++;
  250. },
  251. moveForward: function moveForward() {
  252. this.queue.peek().arity--;
  253. this.levelNodes--;
  254. if (0 === this.queue.peek().arity) {
  255. this.index = 0;
  256. this.queue.dequeue();
  257. }
  258. if (0 === this.levelNodes) {
  259. this.depth++;
  260. this.levelNodes = this.nextLevelNodes;
  261. this.nextLevelNodes = 0;
  262. }
  263. },
  264. get parent() {
  265. return this.queue.peek().node;
  266. }
  267. };
  268. function CursorFactory$1() {
  269. return new BfsCursor();
  270. }
  271.  
  272. function bfs(root, iteratee, getChildren) {
  273. var flags = FlagsFactory();
  274. var cursor = CursorFactory$1();
  275. var context = ContextFactory(flags, cursor);
  276. var queue = QueueFactory$1(root);
  277. while (!queue.isEmpty()) {
  278. var node = queue.dequeue();
  279. flags.reset();
  280. iteratee(node, context);
  281. if (flags.break) break;
  282. if (!flags.remove) {
  283. cursor.moveNext();
  284. if (flags.replace) {
  285. node = flags.replace;
  286. }
  287. if (!flags.skip) {
  288. var children = getChildren(node);
  289. if (isNotEmpty(children)) {
  290. queue.enqueueMultiple(children);
  291. cursor.store(node, children.length);
  292. }
  293. }
  294. }
  295. cursor.moveForward();
  296. }
  297. }
  298.  
  299. var defaultGetChildren = function defaultGetChildren(node) {
  300. return node.children;
  301. };
  302. DYNALIST.crawl = function(root, iteratee, options) {
  303. if (null == root) return;
  304. var order = options.order || 'pre';
  305. var getChildren = options.getChildren || defaultGetChildren;
  306. if ('pre' === order) {
  307. dfsPre(root, iteratee, getChildren);
  308. } else if ('post' === order) {
  309. dfsPost(root, iteratee, getChildren);
  310. } else if ('bfs' === order) {
  311. bfs(root, iteratee, getChildren);
  312. }
  313. }
  314.  
  315. return DYNALIST.crawl;
  316.  
  317. })));
  318.  
  319. },{}]},{},[1]);
  320.  
  321. ]]></>).toString();
  322. var c = Babel.transform(inline_src, { presets: [ "es2015", "es2016", "es2017" ] });
  323. eval(c.code);