MDL-51579 course: Bump version to update mobile service
[moodle.git] / lib / amd / src / loglevel.js
blob4d96ca161b69e497e40b7d2c06f003ae6a11579c
1 // The MIT License\r
2 //\r
3 // Copyright (c) 2014 Tom Perry\r
4 //\r
5 // Permission is hereby granted, free of charge, to any person obtaining\r
6 // a copy of this software and associated documentation files (the\r
7 // "Software"), to deal in the Software without restriction, including\r
8 // without limitation the rights to use, copy, modify, merge, publish,\r
9 // distribute, sublicense, and/or sell copies of the Software, and to\r
10 // permit persons to whom the Software is furnished to do so, subject to\r
11 // the following conditions:\r
12 //\r
13 // The above copyright notice and this permission notice shall be\r
14 // included in all copies or substantial portions of the Software.\r
15 //\r
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
18 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
19 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\r
20 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\r
21 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\r
22 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
23 //\r
25 // Description of import into Moodle:\r
26 // Download from https://github.com/pimterry/loglevel/releases\r
27 // Copy loglevel.js into lib/amd/src/ in Moodle folder.\r
28 // Add the license as a comment to the file and these instructions.\r
29 // Add the jshint ignore:start and ignore:end comments.\r
30 // Delete the jshint validthis:true comments.\r
32 /* jshint ignore:start */\r
33 /*! loglevel - v1.4.0 - https://github.com/pimterry/loglevel - (c) 2015 Tim Perry - licensed MIT */\r
34 (function (root, definition) {\r
35     "use strict";\r
36     if (typeof module === 'object' && module.exports && typeof require === 'function') {\r
37         module.exports = definition();\r
38     } else if (typeof define === 'function' && typeof define.amd === 'object') {\r
39         define(definition);\r
40     } else {\r
41         root.log = definition();\r
42     }\r
43 }(this, function () {\r
44     "use strict";\r
45     var noop = function() {};\r
46     var undefinedType = "undefined";\r
48     function realMethod(methodName) {\r
49         if (typeof console === undefinedType) {\r
50             return false; // We can't build a real method without a console to log to\r
51         } else if (console[methodName] !== undefined) {\r
52             return bindMethod(console, methodName);\r
53         } else if (console.log !== undefined) {\r
54             return bindMethod(console, 'log');\r
55         } else {\r
56             return noop;\r
57         }\r
58     }\r
60     function bindMethod(obj, methodName) {\r
61         var method = obj[methodName];\r
62         if (typeof method.bind === 'function') {\r
63             return method.bind(obj);\r
64         } else {\r
65             try {\r
66                 return Function.prototype.bind.call(method, obj);\r
67             } catch (e) {\r
68                 // Missing bind shim or IE8 + Modernizr, fallback to wrapping\r
69                 return function() {\r
70                     return Function.prototype.apply.apply(method, [obj, arguments]);\r
71                 };\r
72             }\r
73         }\r
74     }\r
76     // these private functions always need `this` to be set properly\r
78     function enableLoggingWhenConsoleArrives(methodName, level, loggerName) {\r
79         return function () {\r
80             if (typeof console !== undefinedType) {\r
81                 replaceLoggingMethods.call(this, level, loggerName);\r
82                 this[methodName].apply(this, arguments);\r
83             }\r
84         };\r
85     }\r
87     function replaceLoggingMethods(level, loggerName) {\r
88         for (var i = 0; i < logMethods.length; i++) {\r
89             var methodName = logMethods[i];\r
90             this[methodName] = (i < level) ?\r
91                 noop :\r
92                 this.methodFactory(methodName, level, loggerName);\r
93         }\r
94     }\r
96     function defaultMethodFactory(methodName, level, loggerName) {\r
97         return realMethod(methodName) ||\r
98                enableLoggingWhenConsoleArrives.apply(this, arguments);\r
99     }\r
101     var logMethods = [\r
102         "trace",\r
103         "debug",\r
104         "info",\r
105         "warn",\r
106         "error"\r
107     ];\r
109     function Logger(name, defaultLevel, factory) {\r
110       var self = this;\r
111       var currentLevel;\r
112       var storageKey = "loglevel";\r
113       if (name) {\r
114         storageKey += ":" + name;\r
115       }\r
117       function persistLevelIfPossible(levelNum) {\r
118           var levelName = (logMethods[levelNum] || 'silent').toUpperCase();\r
120           // Use localStorage if available\r
121           try {\r
122               window.localStorage[storageKey] = levelName;\r
123               return;\r
124           } catch (ignore) {}\r
126           // Use session cookie as fallback\r
127           try {\r
128               window.document.cookie =\r
129                 encodeURIComponent(storageKey) + "=" + levelName + ";";\r
130           } catch (ignore) {}\r
131       }\r
133       function getPersistedLevel() {\r
134           var storedLevel;\r
136           try {\r
137               storedLevel = window.localStorage[storageKey];\r
138           } catch (ignore) {}\r
140           if (typeof storedLevel === undefinedType) {\r
141               try {\r
142                   var cookie = window.document.cookie;\r
143                   var location = cookie.indexOf(\r
144                       encodeURIComponent(storageKey) + "=");\r
145                   if (location) {\r
146                       storedLevel = /^([^;]+)/.exec(cookie.slice(location))[1];\r
147                   }\r
148               } catch (ignore) {}\r
149           }\r
151           // If the stored level is not valid, treat it as if nothing was stored.\r
152           if (self.levels[storedLevel] === undefined) {\r
153               storedLevel = undefined;\r
154           }\r
156           return storedLevel;\r
157       }\r
159       /*\r
160        *\r
161        * Public API\r
162        *\r
163        */\r
165       self.levels = { "TRACE": 0, "DEBUG": 1, "INFO": 2, "WARN": 3,\r
166           "ERROR": 4, "SILENT": 5};\r
168       self.methodFactory = factory || defaultMethodFactory;\r
170       self.getLevel = function () {\r
171           return currentLevel;\r
172       };\r
174       self.setLevel = function (level, persist) {\r
175           if (typeof level === "string" && self.levels[level.toUpperCase()] !== undefined) {\r
176               level = self.levels[level.toUpperCase()];\r
177           }\r
178           if (typeof level === "number" && level >= 0 && level <= self.levels.SILENT) {\r
179               currentLevel = level;\r
180               if (persist !== false) {  // defaults to true\r
181                   persistLevelIfPossible(level);\r
182               }\r
183               replaceLoggingMethods.call(self, level, name);\r
184               if (typeof console === undefinedType && level < self.levels.SILENT) {\r
185                   return "No console available for logging";\r
186               }\r
187           } else {\r
188               throw "log.setLevel() called with invalid level: " + level;\r
189           }\r
190       };\r
192       self.setDefaultLevel = function (level) {\r
193           if (!getPersistedLevel()) {\r
194               self.setLevel(level, false);\r
195           }\r
196       };\r
198       self.enableAll = function(persist) {\r
199           self.setLevel(self.levels.TRACE, persist);\r
200       };\r
202       self.disableAll = function(persist) {\r
203           self.setLevel(self.levels.SILENT, persist);\r
204       };\r
206       // Initialize with the right level\r
207       var initialLevel = getPersistedLevel();\r
208       if (initialLevel == null) {\r
209           initialLevel = defaultLevel == null ? "WARN" : defaultLevel;\r
210       }\r
211       self.setLevel(initialLevel, false);\r
212     }\r
214     /*\r
215      *\r
216      * Package-level API\r
217      *\r
218      */\r
220     var defaultLogger = new Logger();\r
222     var _loggersByName = {};\r
223     defaultLogger.getLogger = function getLogger(name) {\r
224         if (typeof name !== "string" || name === "") {\r
225           throw new TypeError("You must supply a name when creating a logger.");\r
226         }\r
228         var logger = _loggersByName[name];\r
229         if (!logger) {\r
230           logger = _loggersByName[name] = new Logger(\r
231             name, defaultLogger.getLevel(), defaultLogger.methodFactory);\r
232         }\r
233         return logger;\r
234     };\r
236     // Grab the current global log variable in case of overwrite\r
237     var _log = (typeof window !== undefinedType) ? window.log : undefined;\r
238     defaultLogger.noConflict = function() {\r
239         if (typeof window !== undefinedType &&\r
240                window.log === defaultLogger) {\r
241             window.log = _log;\r
242         }\r
244         return defaultLogger;\r
245     };\r
247     return defaultLogger;\r
248 }));\r
249 /* jshint ignore:end */\r