weekly release 3.2dev
[moodle.git] / lib / amd / src / loglevel.js
CommitLineData
3acc64e3
AN
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
24\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
ee519261 30// Delete the jshint validthis:true comments.\r
3acc64e3
AN
31\r
32/* jshint ignore:start */\r
ee519261 33/*! loglevel - v1.4.0 - https://github.com/pimterry/loglevel - (c) 2015 Tim Perry - licensed MIT */\r
3acc64e3 34(function (root, definition) {\r
ee519261 35 "use strict";\r
3acc64e3
AN
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
ee519261 44 "use strict";\r
3acc64e3
AN
45 var noop = function() {};\r
46 var undefinedType = "undefined";\r
47\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
59\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
75\r
ee519261
DW
76 // these private functions always need `this` to be set properly\r
77\r
78 function enableLoggingWhenConsoleArrives(methodName, level, loggerName) {\r
3acc64e3
AN
79 return function () {\r
80 if (typeof console !== undefinedType) {\r
ee519261
DW
81 replaceLoggingMethods.call(this, level, loggerName);\r
82 this[methodName].apply(this, arguments);\r
3acc64e3
AN
83 }\r
84 };\r
85 }\r
86\r
ee519261 87 function replaceLoggingMethods(level, loggerName) {\r
3acc64e3
AN
88 for (var i = 0; i < logMethods.length; i++) {\r
89 var methodName = logMethods[i];\r
ee519261
DW
90 this[methodName] = (i < level) ?\r
91 noop :\r
92 this.methodFactory(methodName, level, loggerName);\r
3acc64e3
AN
93 }\r
94 }\r
95\r
ee519261
DW
96 function defaultMethodFactory(methodName, level, loggerName) {\r
97 return realMethod(methodName) ||\r
98 enableLoggingWhenConsoleArrives.apply(this, arguments);\r
3acc64e3
AN
99 }\r
100\r
ee519261
DW
101 var logMethods = [\r
102 "trace",\r
103 "debug",\r
104 "info",\r
105 "warn",\r
106 "error"\r
107 ];\r
3acc64e3 108\r
ee519261
DW
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
116\r
117 function persistLevelIfPossible(levelNum) {\r
118 var levelName = (logMethods[levelNum] || 'silent').toUpperCase();\r
119\r
120 // Use localStorage if available\r
121 try {\r
122 window.localStorage[storageKey] = levelName;\r
123 return;\r
124 } catch (ignore) {}\r
125\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
132\r
133 function getPersistedLevel() {\r
134 var storedLevel;\r
135\r
136 try {\r
137 storedLevel = window.localStorage[storageKey];\r
138 } catch (ignore) {}\r
139\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
150\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
155\r
156 return storedLevel;\r
157 }\r
158\r
159 /*\r
160 *\r
161 * Public API\r
162 *\r
163 */\r
164\r
165 self.levels = { "TRACE": 0, "DEBUG": 1, "INFO": 2, "WARN": 3,\r
166 "ERROR": 4, "SILENT": 5};\r
167\r
168 self.methodFactory = factory || defaultMethodFactory;\r
169\r
170 self.getLevel = function () {\r
171 return currentLevel;\r
172 };\r
173\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
191\r
192 self.setDefaultLevel = function (level) {\r
193 if (!getPersistedLevel()) {\r
194 self.setLevel(level, false);\r
195 }\r
196 };\r
197\r
198 self.enableAll = function(persist) {\r
199 self.setLevel(self.levels.TRACE, persist);\r
200 };\r
201\r
202 self.disableAll = function(persist) {\r
203 self.setLevel(self.levels.SILENT, persist);\r
204 };\r
205\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
3acc64e3
AN
212 }\r
213\r
214 /*\r
215 *\r
ee519261 216 * Package-level API\r
3acc64e3
AN
217 *\r
218 */\r
219\r
ee519261 220 var defaultLogger = new Logger();\r
3acc64e3 221\r
ee519261
DW
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
3acc64e3 226 }\r
3acc64e3 227\r
ee519261
DW
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
3acc64e3
AN
234 };\r
235\r
236 // Grab the current global log variable in case of overwrite\r
237 var _log = (typeof window !== undefinedType) ? window.log : undefined;\r
ee519261 238 defaultLogger.noConflict = function() {\r
3acc64e3 239 if (typeof window !== undefinedType &&\r
ee519261 240 window.log === defaultLogger) {\r
3acc64e3
AN
241 window.log = _log;\r
242 }\r
243\r
ee519261 244 return defaultLogger;\r
3acc64e3
AN
245 };\r
246\r
ee519261 247 return defaultLogger;\r
3acc64e3
AN
248}));\r
249/* jshint ignore:end */\r