Software zum Installieren eines Smart-Mirror Frameworks , zum Nutzen von hochschulrelevanten Informationen, auf einem Raspberry-Pi.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

jinja-compat.js 8.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. "use strict";
  2. function installCompat() {
  3. 'use strict';
  4. /* eslint-disable camelcase */
  5. // This must be called like `nunjucks.installCompat` so that `this`
  6. // references the nunjucks instance
  7. var runtime = this.runtime;
  8. var lib = this.lib; // Handle slim case where these 'modules' are excluded from the built source
  9. var Compiler = this.compiler.Compiler;
  10. var Parser = this.parser.Parser;
  11. var nodes = this.nodes;
  12. var lexer = this.lexer;
  13. var orig_contextOrFrameLookup = runtime.contextOrFrameLookup;
  14. var orig_memberLookup = runtime.memberLookup;
  15. var orig_Compiler_assertType;
  16. var orig_Parser_parseAggregate;
  17. if (Compiler) {
  18. orig_Compiler_assertType = Compiler.prototype.assertType;
  19. }
  20. if (Parser) {
  21. orig_Parser_parseAggregate = Parser.prototype.parseAggregate;
  22. }
  23. function uninstall() {
  24. runtime.contextOrFrameLookup = orig_contextOrFrameLookup;
  25. runtime.memberLookup = orig_memberLookup;
  26. if (Compiler) {
  27. Compiler.prototype.assertType = orig_Compiler_assertType;
  28. }
  29. if (Parser) {
  30. Parser.prototype.parseAggregate = orig_Parser_parseAggregate;
  31. }
  32. }
  33. runtime.contextOrFrameLookup = function contextOrFrameLookup(context, frame, key) {
  34. var val = orig_contextOrFrameLookup.apply(this, arguments);
  35. if (val !== undefined) {
  36. return val;
  37. }
  38. switch (key) {
  39. case 'True':
  40. return true;
  41. case 'False':
  42. return false;
  43. case 'None':
  44. return null;
  45. default:
  46. return undefined;
  47. }
  48. };
  49. function getTokensState(tokens) {
  50. return {
  51. index: tokens.index,
  52. lineno: tokens.lineno,
  53. colno: tokens.colno
  54. };
  55. }
  56. if (process.env.BUILD_TYPE !== 'SLIM' && nodes && Compiler && Parser) {
  57. // i.e., not slim mode
  58. var Slice = nodes.Node.extend('Slice', {
  59. fields: ['start', 'stop', 'step'],
  60. init: function init(lineno, colno, start, stop, step) {
  61. start = start || new nodes.Literal(lineno, colno, null);
  62. stop = stop || new nodes.Literal(lineno, colno, null);
  63. step = step || new nodes.Literal(lineno, colno, 1);
  64. this.parent(lineno, colno, start, stop, step);
  65. }
  66. });
  67. Compiler.prototype.assertType = function assertType(node) {
  68. if (node instanceof Slice) {
  69. return;
  70. }
  71. orig_Compiler_assertType.apply(this, arguments);
  72. };
  73. Compiler.prototype.compileSlice = function compileSlice(node, frame) {
  74. this._emit('(');
  75. this._compileExpression(node.start, frame);
  76. this._emit('),(');
  77. this._compileExpression(node.stop, frame);
  78. this._emit('),(');
  79. this._compileExpression(node.step, frame);
  80. this._emit(')');
  81. };
  82. Parser.prototype.parseAggregate = function parseAggregate() {
  83. var _this = this;
  84. var origState = getTokensState(this.tokens); // Set back one accounting for opening bracket/parens
  85. origState.colno--;
  86. origState.index--;
  87. try {
  88. return orig_Parser_parseAggregate.apply(this);
  89. } catch (e) {
  90. var errState = getTokensState(this.tokens);
  91. var rethrow = function rethrow() {
  92. lib._assign(_this.tokens, errState);
  93. return e;
  94. }; // Reset to state before original parseAggregate called
  95. lib._assign(this.tokens, origState);
  96. this.peeked = false;
  97. var tok = this.peekToken();
  98. if (tok.type !== lexer.TOKEN_LEFT_BRACKET) {
  99. throw rethrow();
  100. } else {
  101. this.nextToken();
  102. }
  103. var node = new Slice(tok.lineno, tok.colno); // If we don't encounter a colon while parsing, this is not a slice,
  104. // so re-raise the original exception.
  105. var isSlice = false;
  106. for (var i = 0; i <= node.fields.length; i++) {
  107. if (this.skip(lexer.TOKEN_RIGHT_BRACKET)) {
  108. break;
  109. }
  110. if (i === node.fields.length) {
  111. if (isSlice) {
  112. this.fail('parseSlice: too many slice components', tok.lineno, tok.colno);
  113. } else {
  114. break;
  115. }
  116. }
  117. if (this.skip(lexer.TOKEN_COLON)) {
  118. isSlice = true;
  119. } else {
  120. var field = node.fields[i];
  121. node[field] = this.parseExpression();
  122. isSlice = this.skip(lexer.TOKEN_COLON) || isSlice;
  123. }
  124. }
  125. if (!isSlice) {
  126. throw rethrow();
  127. }
  128. return new nodes.Array(tok.lineno, tok.colno, [node]);
  129. }
  130. };
  131. }
  132. function sliceLookup(obj, start, stop, step) {
  133. obj = obj || [];
  134. if (start === null) {
  135. start = step < 0 ? obj.length - 1 : 0;
  136. }
  137. if (stop === null) {
  138. stop = step < 0 ? -1 : obj.length;
  139. } else if (stop < 0) {
  140. stop += obj.length;
  141. }
  142. if (start < 0) {
  143. start += obj.length;
  144. }
  145. var results = [];
  146. for (var i = start;; i += step) {
  147. if (i < 0 || i > obj.length) {
  148. break;
  149. }
  150. if (step > 0 && i >= stop) {
  151. break;
  152. }
  153. if (step < 0 && i <= stop) {
  154. break;
  155. }
  156. results.push(runtime.memberLookup(obj, i));
  157. }
  158. return results;
  159. }
  160. function hasOwnProp(obj, key) {
  161. return Object.prototype.hasOwnProperty.call(obj, key);
  162. }
  163. var ARRAY_MEMBERS = {
  164. pop: function pop(index) {
  165. if (index === undefined) {
  166. return this.pop();
  167. }
  168. if (index >= this.length || index < 0) {
  169. throw new Error('KeyError');
  170. }
  171. return this.splice(index, 1);
  172. },
  173. append: function append(element) {
  174. return this.push(element);
  175. },
  176. remove: function remove(element) {
  177. for (var i = 0; i < this.length; i++) {
  178. if (this[i] === element) {
  179. return this.splice(i, 1);
  180. }
  181. }
  182. throw new Error('ValueError');
  183. },
  184. count: function count(element) {
  185. var count = 0;
  186. for (var i = 0; i < this.length; i++) {
  187. if (this[i] === element) {
  188. count++;
  189. }
  190. }
  191. return count;
  192. },
  193. index: function index(element) {
  194. var i;
  195. if ((i = this.indexOf(element)) === -1) {
  196. throw new Error('ValueError');
  197. }
  198. return i;
  199. },
  200. find: function find(element) {
  201. return this.indexOf(element);
  202. },
  203. insert: function insert(index, elem) {
  204. return this.splice(index, 0, elem);
  205. }
  206. };
  207. var OBJECT_MEMBERS = {
  208. items: function items() {
  209. return lib._entries(this);
  210. },
  211. values: function values() {
  212. return lib._values(this);
  213. },
  214. keys: function keys() {
  215. return lib.keys(this);
  216. },
  217. get: function get(key, def) {
  218. var output = this[key];
  219. if (output === undefined) {
  220. output = def;
  221. }
  222. return output;
  223. },
  224. has_key: function has_key(key) {
  225. return hasOwnProp(this, key);
  226. },
  227. pop: function pop(key, def) {
  228. var output = this[key];
  229. if (output === undefined && def !== undefined) {
  230. output = def;
  231. } else if (output === undefined) {
  232. throw new Error('KeyError');
  233. } else {
  234. delete this[key];
  235. }
  236. return output;
  237. },
  238. popitem: function popitem() {
  239. var keys = lib.keys(this);
  240. if (!keys.length) {
  241. throw new Error('KeyError');
  242. }
  243. var k = keys[0];
  244. var val = this[k];
  245. delete this[k];
  246. return [k, val];
  247. },
  248. setdefault: function setdefault(key, def) {
  249. if (def === void 0) {
  250. def = null;
  251. }
  252. if (!(key in this)) {
  253. this[key] = def;
  254. }
  255. return this[key];
  256. },
  257. update: function update(kwargs) {
  258. lib._assign(this, kwargs);
  259. return null; // Always returns None
  260. }
  261. };
  262. OBJECT_MEMBERS.iteritems = OBJECT_MEMBERS.items;
  263. OBJECT_MEMBERS.itervalues = OBJECT_MEMBERS.values;
  264. OBJECT_MEMBERS.iterkeys = OBJECT_MEMBERS.keys;
  265. runtime.memberLookup = function memberLookup(obj, val, autoescape) {
  266. if (arguments.length === 4) {
  267. return sliceLookup.apply(this, arguments);
  268. }
  269. obj = obj || {}; // If the object is an object, return any of the methods that Python would
  270. // otherwise provide.
  271. if (lib.isArray(obj) && hasOwnProp(ARRAY_MEMBERS, val)) {
  272. return ARRAY_MEMBERS[val].bind(obj);
  273. }
  274. if (lib.isObject(obj) && hasOwnProp(OBJECT_MEMBERS, val)) {
  275. return OBJECT_MEMBERS[val].bind(obj);
  276. }
  277. return orig_memberLookup.apply(this, arguments);
  278. };
  279. return uninstall;
  280. }
  281. module.exports = installCompat;