first commit
This commit is contained in:
53
node_modules/less/lib/less-browser/add-default-options.js
generated
vendored
Normal file
53
node_modules/less/lib/less-browser/add-default-options.js
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
import {addDataAttr} from './utils.js';
|
||||
import browser from './browser.js';
|
||||
|
||||
/**
|
||||
* @param {Window} window
|
||||
* @param {Record<string, *>} options
|
||||
*/
|
||||
export default (window, options) => {
|
||||
|
||||
// use options from the current script tag data attribues
|
||||
addDataAttr(options, browser.currentScript(window));
|
||||
|
||||
if (options.isFileProtocol === undefined) {
|
||||
options.isFileProtocol = /^(file|(chrome|safari)(-extension)?|resource|qrc|app):/.test(window.location.protocol);
|
||||
}
|
||||
|
||||
// Load styles asynchronously (default: false)
|
||||
//
|
||||
// This is set to `false` by default, so that the body
|
||||
// doesn't start loading before the stylesheets are parsed.
|
||||
// Setting this to `true` can result in flickering.
|
||||
//
|
||||
options.async = options.async || false;
|
||||
options.fileAsync = options.fileAsync || false;
|
||||
|
||||
// Interval between watch polls
|
||||
options.poll = options.poll || (options.isFileProtocol ? 1000 : 1500);
|
||||
|
||||
options.env = options.env || (window.location.hostname == '127.0.0.1' ||
|
||||
window.location.hostname == '0.0.0.0' ||
|
||||
window.location.hostname == 'localhost' ||
|
||||
(window.location.port &&
|
||||
window.location.port.length > 0) ||
|
||||
options.isFileProtocol ? 'development'
|
||||
: 'production');
|
||||
|
||||
const dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(window.location.hash);
|
||||
if (dumpLineNumbers) {
|
||||
options.dumpLineNumbers = dumpLineNumbers[1];
|
||||
}
|
||||
|
||||
if (options.useFileCache === undefined) {
|
||||
options.useFileCache = true;
|
||||
}
|
||||
|
||||
if (options.onReady === undefined) {
|
||||
options.onReady = true;
|
||||
}
|
||||
|
||||
if (options.relativeUrls) {
|
||||
options.rewriteUrls = 'all';
|
||||
}
|
||||
};
|
||||
67
node_modules/less/lib/less-browser/bootstrap.js
generated
vendored
Normal file
67
node_modules/less/lib/less-browser/bootstrap.js
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Kicks off less and compiles any stylesheets
|
||||
* used in the browser distributed version of less
|
||||
* to kick-start less using the browser api
|
||||
*/
|
||||
import defaultOptions from '../less/default-options.js';
|
||||
import addDefaultOptions from './add-default-options.js';
|
||||
import root from './index.js';
|
||||
|
||||
const options = defaultOptions();
|
||||
|
||||
if (window.less) {
|
||||
for (const key in window.less) {
|
||||
if (Object.prototype.hasOwnProperty.call(window.less, key)) {
|
||||
options[key] = window.less[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
addDefaultOptions(window, options);
|
||||
|
||||
options.plugins = options.plugins || [];
|
||||
|
||||
if (window.LESS_PLUGINS) {
|
||||
options.plugins = options.plugins.concat(window.LESS_PLUGINS);
|
||||
}
|
||||
|
||||
const less = root(window, options);
|
||||
export default less;
|
||||
|
||||
window.less = less;
|
||||
|
||||
let css;
|
||||
let head;
|
||||
let style;
|
||||
|
||||
// Always restore page visibility
|
||||
function resolveOrReject(data) {
|
||||
if (data.filename) {
|
||||
console.warn(data);
|
||||
}
|
||||
if (!options.async) {
|
||||
head.removeChild(style);
|
||||
}
|
||||
}
|
||||
|
||||
if (options.onReady) {
|
||||
if (/!watch/.test(window.location.hash)) {
|
||||
less.watch();
|
||||
}
|
||||
// Simulate synchronous stylesheet loading by hiding page rendering
|
||||
if (!options.async) {
|
||||
css = 'body { display: none !important }';
|
||||
head = document.head || document.getElementsByTagName('head')[0];
|
||||
style = document.createElement('style');
|
||||
|
||||
style.type = 'text/css';
|
||||
if (style.styleSheet) {
|
||||
style.styleSheet.cssText = css;
|
||||
} else {
|
||||
style.appendChild(document.createTextNode(css));
|
||||
}
|
||||
|
||||
head.appendChild(style);
|
||||
}
|
||||
less.registerStylesheetsImmediately();
|
||||
less.pageLoadFinished = less.refresh(less.env === 'development').then(resolveOrReject, resolveOrReject);
|
||||
}
|
||||
65
node_modules/less/lib/less-browser/browser.js
generated
vendored
Normal file
65
node_modules/less/lib/less-browser/browser.js
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
import * as utils from './utils.js';
|
||||
|
||||
export default {
|
||||
createCSS: function (document, styles, sheet) {
|
||||
// Strip the query-string
|
||||
const href = sheet.href || '';
|
||||
|
||||
// If there is no title set, use the filename, minus the extension
|
||||
const id = `less:${sheet.title || utils.extractId(href)}`;
|
||||
|
||||
// If this has already been inserted into the DOM, we may need to replace it
|
||||
const oldStyleNode = document.getElementById(id);
|
||||
let keepOldStyleNode = false;
|
||||
|
||||
// Create a new stylesheet node for insertion or (if necessary) replacement
|
||||
const styleNode = document.createElement('style');
|
||||
styleNode.setAttribute('type', 'text/css');
|
||||
if (sheet.media) {
|
||||
styleNode.setAttribute('media', sheet.media);
|
||||
}
|
||||
styleNode.id = id;
|
||||
|
||||
if (!styleNode.styleSheet) {
|
||||
styleNode.appendChild(document.createTextNode(styles));
|
||||
|
||||
// If new contents match contents of oldStyleNode, don't replace oldStyleNode
|
||||
keepOldStyleNode = (oldStyleNode !== null && oldStyleNode.childNodes.length > 0 && styleNode.childNodes.length > 0 &&
|
||||
oldStyleNode.firstChild.nodeValue === styleNode.firstChild.nodeValue);
|
||||
}
|
||||
|
||||
const head = document.getElementsByTagName('head')[0];
|
||||
|
||||
// If there is no oldStyleNode, just append; otherwise, only append if we need
|
||||
// to replace oldStyleNode with an updated stylesheet
|
||||
if (oldStyleNode === null || keepOldStyleNode === false) {
|
||||
const nextEl = sheet && sheet.nextSibling || null;
|
||||
if (nextEl) {
|
||||
nextEl.parentNode.insertBefore(styleNode, nextEl);
|
||||
} else {
|
||||
head.appendChild(styleNode);
|
||||
}
|
||||
}
|
||||
if (oldStyleNode && keepOldStyleNode === false) {
|
||||
oldStyleNode.parentNode.removeChild(oldStyleNode);
|
||||
}
|
||||
|
||||
// For IE.
|
||||
// This needs to happen *after* the style element is added to the DOM, otherwise IE 7 and 8 may crash.
|
||||
// See http://social.msdn.microsoft.com/Forums/en-US/7e081b65-878a-4c22-8e68-c10d39c2ed32/internet-explorer-crashes-appending-style-element-to-head
|
||||
if (styleNode.styleSheet) {
|
||||
try {
|
||||
styleNode.styleSheet.cssText = styles;
|
||||
} catch (e) {
|
||||
throw new Error('Couldn\'t reassign styleSheet.cssText.');
|
||||
}
|
||||
}
|
||||
},
|
||||
currentScript: function(window) {
|
||||
const document = window.document;
|
||||
return document.currentScript || (() => {
|
||||
const scripts = document.getElementsByTagName('script');
|
||||
return scripts[scripts.length - 1];
|
||||
})();
|
||||
}
|
||||
};
|
||||
43
node_modules/less/lib/less-browser/cache.js
generated
vendored
Normal file
43
node_modules/less/lib/less-browser/cache.js
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
// Cache system is a bit outdated and could do with work
|
||||
|
||||
export default (window, options, logger) => {
|
||||
let cache = null;
|
||||
if (options.env !== 'development') {
|
||||
try {
|
||||
cache = (typeof window.localStorage === 'undefined') ? null : window.localStorage;
|
||||
} catch (_) {}
|
||||
}
|
||||
return {
|
||||
setCSS: function(path, lastModified, modifyVars, styles) {
|
||||
if (cache) {
|
||||
logger.info(`saving ${path} to cache.`);
|
||||
try {
|
||||
cache.setItem(path, styles);
|
||||
cache.setItem(`${path}:timestamp`, lastModified);
|
||||
if (modifyVars) {
|
||||
cache.setItem(`${path}:vars`, JSON.stringify(modifyVars));
|
||||
}
|
||||
} catch (e) {
|
||||
// TODO - could do with adding more robust error handling
|
||||
logger.error(`failed to save "${path}" to local storage for caching.`);
|
||||
}
|
||||
}
|
||||
},
|
||||
getCSS: function(path, webInfo, modifyVars) {
|
||||
const css = cache && cache.getItem(path);
|
||||
const timestamp = cache && cache.getItem(`${path}:timestamp`);
|
||||
let vars = cache && cache.getItem(`${path}:vars`);
|
||||
|
||||
modifyVars = modifyVars || {};
|
||||
vars = vars || '{}'; // if not set, treat as the JSON representation of an empty object
|
||||
|
||||
if (timestamp && webInfo.lastModified &&
|
||||
(new Date(webInfo.lastModified).valueOf() ===
|
||||
new Date(timestamp).valueOf()) &&
|
||||
JSON.stringify(modifyVars) === vars) {
|
||||
// Use local copy
|
||||
return css;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
170
node_modules/less/lib/less-browser/error-reporting.js
generated
vendored
Normal file
170
node_modules/less/lib/less-browser/error-reporting.js
generated
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
import * as utils from './utils.js';
|
||||
import browser from './browser.js';
|
||||
|
||||
export default (window, less, options) => {
|
||||
|
||||
function errorHTML(e, rootHref) {
|
||||
const id = `less-error-message:${utils.extractId(rootHref || '')}`;
|
||||
const template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>';
|
||||
const elem = window.document.createElement('div');
|
||||
let timer;
|
||||
let content;
|
||||
const errors = [];
|
||||
const filename = e.filename || rootHref;
|
||||
const filenameNoPath = filename.match(/([^/]+(\?.*)?)$/)[1];
|
||||
|
||||
elem.id = id;
|
||||
elem.className = 'less-error-message';
|
||||
|
||||
content = `<h3>${e.type || 'Syntax'}Error: ${e.message || 'There is an error in your .less file'}` +
|
||||
`</h3><p>in <a href="${filename}">${filenameNoPath}</a> `;
|
||||
|
||||
const errorline = (e, i, classname) => {
|
||||
if (e.extract[i] !== undefined) {
|
||||
errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1))
|
||||
.replace(/\{class\}/, classname)
|
||||
.replace(/\{content\}/, e.extract[i]));
|
||||
}
|
||||
};
|
||||
|
||||
if (e.line) {
|
||||
errorline(e, 0, '');
|
||||
errorline(e, 1, 'line');
|
||||
errorline(e, 2, '');
|
||||
content += `on line ${e.line}, column ${e.column + 1}:</p><ul>${errors.join('')}</ul>`;
|
||||
}
|
||||
if (e.stack && (e.extract || options.logLevel >= 4)) {
|
||||
content += `<br/>Stack Trace</br />${e.stack.split('\n').slice(1).join('<br/>')}`;
|
||||
}
|
||||
elem.innerHTML = content;
|
||||
|
||||
// CSS for error messages
|
||||
browser.createCSS(window.document, [
|
||||
'.less-error-message ul, .less-error-message li {',
|
||||
'list-style-type: none;',
|
||||
'margin-right: 15px;',
|
||||
'padding: 4px 0;',
|
||||
'margin: 0;',
|
||||
'}',
|
||||
'.less-error-message label {',
|
||||
'font-size: 12px;',
|
||||
'margin-right: 15px;',
|
||||
'padding: 4px 0;',
|
||||
'color: #cc7777;',
|
||||
'}',
|
||||
'.less-error-message pre {',
|
||||
'color: #dd6666;',
|
||||
'padding: 4px 0;',
|
||||
'margin: 0;',
|
||||
'display: inline-block;',
|
||||
'}',
|
||||
'.less-error-message pre.line {',
|
||||
'color: #ff0000;',
|
||||
'}',
|
||||
'.less-error-message h3 {',
|
||||
'font-size: 20px;',
|
||||
'font-weight: bold;',
|
||||
'padding: 15px 0 5px 0;',
|
||||
'margin: 0;',
|
||||
'}',
|
||||
'.less-error-message a {',
|
||||
'color: #10a',
|
||||
'}',
|
||||
'.less-error-message .error {',
|
||||
'color: red;',
|
||||
'font-weight: bold;',
|
||||
'padding-bottom: 2px;',
|
||||
'border-bottom: 1px dashed red;',
|
||||
'}'
|
||||
].join('\n'), { title: 'error-message' });
|
||||
|
||||
elem.style.cssText = [
|
||||
'font-family: Arial, sans-serif',
|
||||
'border: 1px solid #e00',
|
||||
'background-color: #eee',
|
||||
'border-radius: 5px',
|
||||
'-webkit-border-radius: 5px',
|
||||
'-moz-border-radius: 5px',
|
||||
'color: #e00',
|
||||
'padding: 15px',
|
||||
'margin-bottom: 15px'
|
||||
].join(';');
|
||||
|
||||
if (options.env === 'development') {
|
||||
timer = setInterval(() => {
|
||||
const document = window.document;
|
||||
const body = document.body;
|
||||
if (body) {
|
||||
if (document.getElementById(id)) {
|
||||
body.replaceChild(elem, document.getElementById(id));
|
||||
} else {
|
||||
body.insertBefore(elem, body.firstChild);
|
||||
}
|
||||
clearInterval(timer);
|
||||
}
|
||||
}, 10);
|
||||
}
|
||||
}
|
||||
|
||||
function removeErrorHTML(path) {
|
||||
const node = window.document.getElementById(`less-error-message:${utils.extractId(path)}`);
|
||||
if (node) {
|
||||
node.parentNode.removeChild(node);
|
||||
}
|
||||
}
|
||||
|
||||
function removeErrorConsole() {
|
||||
// no action
|
||||
}
|
||||
|
||||
function removeError(path) {
|
||||
if (!options.errorReporting || options.errorReporting === 'html') {
|
||||
removeErrorHTML(path);
|
||||
} else if (options.errorReporting === 'console') {
|
||||
removeErrorConsole(path);
|
||||
} else if (typeof options.errorReporting === 'function') {
|
||||
options.errorReporting('remove', path);
|
||||
}
|
||||
}
|
||||
|
||||
function errorConsole(e, rootHref) {
|
||||
const template = '{line} {content}';
|
||||
const filename = e.filename || rootHref;
|
||||
const errors = [];
|
||||
let content = `${e.type || 'Syntax'}Error: ${e.message || 'There is an error in your .less file'} in ${filename}`;
|
||||
|
||||
const errorline = (e, i, classname) => {
|
||||
if (e.extract[i] !== undefined) {
|
||||
errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1))
|
||||
.replace(/\{class\}/, classname)
|
||||
.replace(/\{content\}/, e.extract[i]));
|
||||
}
|
||||
};
|
||||
|
||||
if (e.line) {
|
||||
errorline(e, 0, '');
|
||||
errorline(e, 1, 'line');
|
||||
errorline(e, 2, '');
|
||||
content += ` on line ${e.line}, column ${e.column + 1}:\n${errors.join('\n')}`;
|
||||
}
|
||||
if (e.stack && (e.extract || options.logLevel >= 4)) {
|
||||
content += `\nStack Trace\n${e.stack}`;
|
||||
}
|
||||
less.logger.error(content);
|
||||
}
|
||||
|
||||
function error(e, rootHref) {
|
||||
if (!options.errorReporting || options.errorReporting === 'html') {
|
||||
errorHTML(e, rootHref);
|
||||
} else if (options.errorReporting === 'console') {
|
||||
errorConsole(e, rootHref);
|
||||
} else if (typeof options.errorReporting === 'function') {
|
||||
options.errorReporting('add', e, rootHref);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
add: error,
|
||||
remove: removeError
|
||||
};
|
||||
};
|
||||
112
node_modules/less/lib/less-browser/file-manager.js
generated
vendored
Normal file
112
node_modules/less/lib/less-browser/file-manager.js
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
import AbstractFileManager from '../less/environment/abstract-file-manager.js';
|
||||
|
||||
let options;
|
||||
let logger;
|
||||
let fileCache = {};
|
||||
|
||||
// TODOS - move log somewhere. pathDiff and doing something similar in node. use pathDiff in the other browser file for the initial load
|
||||
const FileManager = function() {}
|
||||
FileManager.prototype = Object.assign(new AbstractFileManager(), {
|
||||
alwaysMakePathsAbsolute() {
|
||||
return true;
|
||||
},
|
||||
|
||||
join(basePath, laterPath) {
|
||||
if (!basePath) {
|
||||
return laterPath;
|
||||
}
|
||||
return this.extractUrlParts(laterPath, basePath).path;
|
||||
},
|
||||
|
||||
doXHR(url, type, callback, errback) {
|
||||
const xhr = new XMLHttpRequest();
|
||||
const async = options.isFileProtocol ? options.fileAsync : true;
|
||||
|
||||
if (typeof xhr.overrideMimeType === 'function') {
|
||||
xhr.overrideMimeType('text/css');
|
||||
}
|
||||
logger.debug(`XHR: Getting '${url}'`);
|
||||
xhr.open('GET', url, async);
|
||||
xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
|
||||
xhr.send(null);
|
||||
|
||||
function handleResponse(xhr, callback, errback) {
|
||||
if (xhr.status >= 200 && xhr.status < 300) {
|
||||
callback(xhr.responseText,
|
||||
xhr.getResponseHeader('Last-Modified'));
|
||||
} else if (typeof errback === 'function') {
|
||||
errback(xhr.status, url);
|
||||
}
|
||||
}
|
||||
|
||||
if (options.isFileProtocol && !options.fileAsync) {
|
||||
if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
|
||||
callback(xhr.responseText);
|
||||
} else {
|
||||
errback(xhr.status, url);
|
||||
}
|
||||
} else if (async) {
|
||||
xhr.onreadystatechange = () => {
|
||||
if (xhr.readyState == 4) {
|
||||
handleResponse(xhr, callback, errback);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
handleResponse(xhr, callback, errback);
|
||||
}
|
||||
},
|
||||
|
||||
supports() {
|
||||
return true;
|
||||
},
|
||||
|
||||
clearFileCache() {
|
||||
fileCache = {};
|
||||
},
|
||||
|
||||
loadFile(filename, currentDirectory, options) {
|
||||
// TODO: Add prefix support like less-node?
|
||||
// What about multiple paths?
|
||||
|
||||
if (currentDirectory && !this.isPathAbsolute(filename)) {
|
||||
filename = currentDirectory + filename;
|
||||
}
|
||||
|
||||
filename = options.ext ? this.tryAppendExtension(filename, options.ext) : filename;
|
||||
|
||||
options = options || {};
|
||||
|
||||
// sheet may be set to the stylesheet for the initial load or a collection of properties including
|
||||
// some context variables for imports
|
||||
const hrefParts = this.extractUrlParts(filename, window.location.href);
|
||||
const href = hrefParts.url;
|
||||
const self = this;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (options.useFileCache && fileCache[href]) {
|
||||
try {
|
||||
const lessText = fileCache[href];
|
||||
return resolve({ contents: lessText, filename: href, webInfo: { lastModified: new Date() }});
|
||||
} catch (e) {
|
||||
return reject({ filename: href, message: `Error loading file ${href} error was ${e.message}` });
|
||||
}
|
||||
}
|
||||
|
||||
self.doXHR(href, options.mime, function doXHRCallback(data, lastModified) {
|
||||
// per file cache
|
||||
fileCache[href] = data;
|
||||
|
||||
// Use remote copy (re-parse)
|
||||
resolve({ contents: data, filename: href, webInfo: { lastModified }});
|
||||
}, function doXHRError(status, url) {
|
||||
reject({ type: 'File', message: `'${url}' wasn't found (${status})`, href });
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export default (opts, log) => {
|
||||
options = opts;
|
||||
logger = log;
|
||||
return FileManager;
|
||||
}
|
||||
28
node_modules/less/lib/less-browser/image-size.js
generated
vendored
Normal file
28
node_modules/less/lib/less-browser/image-size.js
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
import functionRegistry from './../less/functions/function-registry.js';
|
||||
|
||||
export default () => {
|
||||
function imageSize() {
|
||||
throw {
|
||||
type: 'Runtime',
|
||||
message: 'Image size functions are not supported in browser version of less'
|
||||
};
|
||||
}
|
||||
|
||||
const imageFunctions = {
|
||||
'image-size': function(filePathNode) {
|
||||
imageSize(this, filePathNode);
|
||||
return -1;
|
||||
},
|
||||
'image-width': function(filePathNode) {
|
||||
imageSize(this, filePathNode);
|
||||
return -1;
|
||||
},
|
||||
'image-height': function(filePathNode) {
|
||||
imageSize(this, filePathNode);
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
functionRegistry.addMultiple(imageFunctions);
|
||||
};
|
||||
284
node_modules/less/lib/less-browser/index.js
generated
vendored
Normal file
284
node_modules/less/lib/less-browser/index.js
generated
vendored
Normal file
@@ -0,0 +1,284 @@
|
||||
//
|
||||
// index.js
|
||||
// Should expose the additional browser functions on to the less object
|
||||
//
|
||||
import {addDataAttr} from './utils.js';
|
||||
import lessRoot from '../less/index.js';
|
||||
import browser from './browser.js';
|
||||
import FM from './file-manager.js';
|
||||
import PluginLoader from './plugin-loader.js';
|
||||
import LogListener from './log-listener.js';
|
||||
import ErrorReporting from './error-reporting.js';
|
||||
import Cache from './cache.js';
|
||||
import ImageSize from './image-size.js';
|
||||
import pkg from '../../package.json';
|
||||
|
||||
/**
|
||||
* @param {Window} window
|
||||
* @param {Object} options
|
||||
*/
|
||||
export default (window, options) => {
|
||||
const document = window.document;
|
||||
const less = lessRoot(undefined, undefined, pkg.version);
|
||||
|
||||
less.options = options;
|
||||
const environment = less.environment;
|
||||
const FileManager = FM(options, less.logger);
|
||||
const fileManager = new FileManager();
|
||||
environment.addFileManager(fileManager);
|
||||
less.FileManager = FileManager;
|
||||
less.PluginLoader = PluginLoader;
|
||||
|
||||
LogListener(less, options);
|
||||
const errors = ErrorReporting(window, less, options);
|
||||
const cache = less.cache = options.cache || Cache(window, options, less.logger);
|
||||
ImageSize(less.environment);
|
||||
|
||||
// Setup user functions - Deprecate?
|
||||
if (options.functions) {
|
||||
less.functions.functionRegistry.addMultiple(options.functions);
|
||||
}
|
||||
|
||||
const typePattern = /^text\/(x-)?less$/;
|
||||
|
||||
function clone(obj) {
|
||||
const cloned = {};
|
||||
for (const prop in obj) {
|
||||
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
|
||||
cloned[prop] = obj[prop];
|
||||
}
|
||||
}
|
||||
return cloned;
|
||||
}
|
||||
|
||||
function loadStyles(modifyVars) {
|
||||
const styles = document.getElementsByTagName('style');
|
||||
|
||||
for (let style of styles) {
|
||||
if (style.type.match(typePattern)) {
|
||||
const instanceOptions = {
|
||||
...clone(options),
|
||||
modifyVars,
|
||||
filename: document.location.href.replace(/#.*$/, '')
|
||||
}
|
||||
|
||||
const lessText = style.innerHTML || '';
|
||||
|
||||
/* jshint loopfunc:true */
|
||||
less.render(lessText, instanceOptions, (err, result) => {
|
||||
if (err) {
|
||||
errors.add(err, 'inline');
|
||||
} else {
|
||||
style.type = 'text/css';
|
||||
if (style.styleSheet) {
|
||||
style.styleSheet.cssText = result.css;
|
||||
} else {
|
||||
style.innerHTML = result.css;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function loadStyleSheet(sheet, callback, reload, remaining, modifyVars) {
|
||||
|
||||
const instanceOptions = clone(options);
|
||||
addDataAttr(instanceOptions, sheet);
|
||||
instanceOptions.mime = sheet.type;
|
||||
|
||||
if (modifyVars) {
|
||||
instanceOptions.modifyVars = modifyVars;
|
||||
}
|
||||
|
||||
function loadInitialFileCallback(loadedFile) {
|
||||
const data = loadedFile.contents;
|
||||
const path = loadedFile.filename;
|
||||
const webInfo = loadedFile.webInfo;
|
||||
|
||||
const newFileInfo = {
|
||||
currentDirectory: fileManager.getPath(path),
|
||||
filename: path,
|
||||
rootFilename: path,
|
||||
rewriteUrls: instanceOptions.rewriteUrls
|
||||
};
|
||||
|
||||
newFileInfo.entryPath = newFileInfo.currentDirectory;
|
||||
newFileInfo.rootpath = instanceOptions.rootpath || newFileInfo.currentDirectory;
|
||||
|
||||
if (webInfo) {
|
||||
webInfo.remaining = remaining;
|
||||
|
||||
const css = cache.getCSS(path, webInfo, instanceOptions.modifyVars);
|
||||
if (!reload && css) {
|
||||
webInfo.local = true;
|
||||
callback(null, css, data, sheet, webInfo, path);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TODO add tests around how this behaves when reloading
|
||||
errors.remove(path);
|
||||
|
||||
instanceOptions.rootFileInfo = newFileInfo;
|
||||
less.render(data, instanceOptions, (e, result) => {
|
||||
if (e) {
|
||||
e.href = path;
|
||||
callback(e);
|
||||
} else {
|
||||
cache.setCSS(sheet.href, webInfo.lastModified, instanceOptions.modifyVars, result.css);
|
||||
callback(null, result.css, data, sheet, webInfo, path);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fileManager.loadFile(sheet.href, null, instanceOptions, environment)
|
||||
.then(loadedFile => {
|
||||
loadInitialFileCallback(loadedFile);
|
||||
}).catch(err => {
|
||||
console.log(err);
|
||||
callback(err);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function loadStyleSheets(callback, reload, modifyVars) {
|
||||
for (let i = 0; i < less.sheets.length; i++) {
|
||||
loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1), modifyVars);
|
||||
}
|
||||
}
|
||||
|
||||
function initRunningMode() {
|
||||
if (less.env === 'development') {
|
||||
less.watchTimer = setInterval(() => {
|
||||
if (less.watchMode) {
|
||||
fileManager.clearFileCache();
|
||||
/**
|
||||
* @todo remove when this is typed with JSDoc
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
loadStyleSheets((e, css, _, sheet, webInfo) => {
|
||||
if (e) {
|
||||
errors.add(e, e.href || sheet.href);
|
||||
} else if (css) {
|
||||
browser.createCSS(window.document, css, sheet);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, options.poll);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Watch mode
|
||||
//
|
||||
less.watch = function () {
|
||||
if (!less.watchMode ) {
|
||||
less.env = 'development';
|
||||
initRunningMode();
|
||||
}
|
||||
this.watchMode = true;
|
||||
return true;
|
||||
};
|
||||
|
||||
less.unwatch = function () {clearInterval(less.watchTimer); this.watchMode = false; return false; };
|
||||
|
||||
//
|
||||
// Synchronously get all <link> tags with the 'rel' attribute set to
|
||||
// "stylesheet/less".
|
||||
//
|
||||
less.registerStylesheetsImmediately = () => {
|
||||
const links = document.getElementsByTagName('link');
|
||||
less.sheets = [];
|
||||
|
||||
for (let i = 0; i < links.length; i++) {
|
||||
if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
|
||||
(links[i].type.match(typePattern)))) {
|
||||
less.sheets.push(links[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Asynchronously get all <link> tags with the 'rel' attribute set to
|
||||
// "stylesheet/less", returning a Promise.
|
||||
//
|
||||
less.registerStylesheets = () => new Promise((resolve) => {
|
||||
less.registerStylesheetsImmediately();
|
||||
resolve();
|
||||
});
|
||||
|
||||
//
|
||||
// With this function, it's possible to alter variables and re-render
|
||||
// CSS without reloading less-files
|
||||
//
|
||||
less.modifyVars = record => less.refresh(true, record, false);
|
||||
|
||||
less.refresh = (reload, modifyVars, clearFileCache) => {
|
||||
if ((reload || clearFileCache) && clearFileCache !== false) {
|
||||
fileManager.clearFileCache();
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
let startTime;
|
||||
let endTime;
|
||||
let totalMilliseconds;
|
||||
let remainingSheets;
|
||||
startTime = endTime = new Date();
|
||||
|
||||
// Set counter for remaining unprocessed sheets
|
||||
remainingSheets = less.sheets.length;
|
||||
|
||||
if (remainingSheets === 0) {
|
||||
|
||||
endTime = new Date();
|
||||
totalMilliseconds = endTime - startTime;
|
||||
less.logger.info('Less has finished and no sheets were loaded.');
|
||||
resolve({
|
||||
startTime,
|
||||
endTime,
|
||||
totalMilliseconds,
|
||||
sheets: less.sheets.length
|
||||
});
|
||||
|
||||
} else {
|
||||
// Relies on less.sheets array, callback seems to be guaranteed to be called for every element of the array
|
||||
loadStyleSheets((e, css, _, sheet, webInfo) => {
|
||||
if (e) {
|
||||
errors.add(e, e.href || sheet.href);
|
||||
reject(e);
|
||||
return;
|
||||
}
|
||||
if (webInfo.local) {
|
||||
less.logger.info(`Loading ${sheet.href} from cache.`);
|
||||
} else {
|
||||
less.logger.info(`Rendered ${sheet.href} successfully.`);
|
||||
}
|
||||
browser.createCSS(window.document, css, sheet);
|
||||
less.logger.info(`CSS for ${sheet.href} generated in ${new Date() - endTime}ms`);
|
||||
|
||||
// Count completed sheet
|
||||
remainingSheets--;
|
||||
|
||||
// Check if the last remaining sheet was processed and then call the promise
|
||||
if (remainingSheets === 0) {
|
||||
totalMilliseconds = new Date() - startTime;
|
||||
less.logger.info(`Less has finished. CSS generated in ${totalMilliseconds}ms`);
|
||||
resolve({
|
||||
startTime,
|
||||
endTime,
|
||||
totalMilliseconds,
|
||||
sheets: less.sheets.length
|
||||
});
|
||||
}
|
||||
endTime = new Date();
|
||||
}, reload, modifyVars);
|
||||
}
|
||||
|
||||
loadStyles(modifyVars);
|
||||
});
|
||||
};
|
||||
|
||||
less.refreshStyles = loadStyles;
|
||||
return less;
|
||||
};
|
||||
42
node_modules/less/lib/less-browser/log-listener.js
generated
vendored
Normal file
42
node_modules/less/lib/less-browser/log-listener.js
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
export default (less, options) => {
|
||||
const logLevel_debug = 4;
|
||||
const logLevel_info = 3;
|
||||
const logLevel_warn = 2;
|
||||
const logLevel_error = 1;
|
||||
|
||||
// The amount of logging in the javascript console.
|
||||
// 3 - Debug, information and errors
|
||||
// 2 - Information and errors
|
||||
// 1 - Errors
|
||||
// 0 - None
|
||||
// Defaults to 2
|
||||
options.logLevel = typeof options.logLevel !== 'undefined' ? options.logLevel : (options.env === 'development' ? logLevel_info : logLevel_error);
|
||||
|
||||
if (!options.loggers) {
|
||||
options.loggers = [{
|
||||
debug: function(msg) {
|
||||
if (options.logLevel >= logLevel_debug) {
|
||||
console.log(msg);
|
||||
}
|
||||
},
|
||||
info: function(msg) {
|
||||
if (options.logLevel >= logLevel_info) {
|
||||
console.log(msg);
|
||||
}
|
||||
},
|
||||
warn: function(msg) {
|
||||
if (options.logLevel >= logLevel_warn) {
|
||||
console.warn(msg);
|
||||
}
|
||||
},
|
||||
error: function(msg) {
|
||||
if (options.logLevel >= logLevel_error) {
|
||||
console.error(msg);
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
for (let i = 0; i < options.loggers.length; i++) {
|
||||
less.logger.addListener(options.loggers[i]);
|
||||
}
|
||||
};
|
||||
24
node_modules/less/lib/less-browser/plugin-loader.js
generated
vendored
Normal file
24
node_modules/less/lib/less-browser/plugin-loader.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* @todo Add tests for browser `@plugin`
|
||||
*/
|
||||
import AbstractPluginLoader from '../less/environment/abstract-plugin-loader.js';
|
||||
|
||||
/**
|
||||
* Browser Plugin Loader
|
||||
*/
|
||||
const PluginLoader = function(less) {
|
||||
this.less = less;
|
||||
// Should we shim this.require for browser? Probably not?
|
||||
};
|
||||
|
||||
PluginLoader.prototype = Object.assign(new AbstractPluginLoader(), {
|
||||
loadPlugin(filename, basePath, context, environment, fileManager) {
|
||||
return new Promise((fulfill, reject) => {
|
||||
fileManager.loadFile(filename, basePath, context, environment)
|
||||
.then(fulfill).catch(reject);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export default PluginLoader;
|
||||
|
||||
30
node_modules/less/lib/less-browser/utils.js
generated
vendored
Normal file
30
node_modules/less/lib/less-browser/utils.js
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
/** @param {string} href */
|
||||
export function extractId(href) {
|
||||
return href.replace(/^[a-z-]+:\/+?[^/]+/, '') // Remove protocol & domain
|
||||
.replace(/[?&]livereload=\w+/, '') // Remove LiveReload cachebuster
|
||||
.replace(/^\//, '') // Remove root /
|
||||
.replace(/\.[a-zA-Z]+$/, '') // Remove simple extension
|
||||
.replace(/[^.\w-]+/g, '-') // Replace illegal characters
|
||||
.replace(/\./g, ':'); // Replace dots with colons(for valid id)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, *>} options
|
||||
* @param {HTMLElement | null} tag
|
||||
*/
|
||||
export function addDataAttr(options, tag) {
|
||||
if (!tag) {return;} // in case of tag is null or undefined
|
||||
for (const opt in tag.dataset) {
|
||||
if (Object.prototype.hasOwnProperty.call(tag.dataset, opt)) {
|
||||
if (opt === 'env' || opt === 'dumpLineNumbers' || opt === 'rootpath' || opt === 'errorReporting') {
|
||||
options[opt] = tag.dataset[opt];
|
||||
} else {
|
||||
try {
|
||||
options[opt] = JSON.parse(tag.dataset[opt]);
|
||||
}
|
||||
catch (_) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user