/* eslint-env jquery, browser */ /* eslint-disable comma-dangle */ /* global PARAMS, signal, assert, log, debugPrint */ function preconfigureLESS(options) { assert(function assertion() { return options.selector && options.globalVars; }); options.globalVars = Object.assign(options.globalVars||{}, { hash: '' }); Object.assign(options, { errorReporting: Object.assign(function errorReporting(op, e, rootHref) { var type = 'Less-'+e.type+'-Error'; var lastResult = errorReporting.lastResult; delete errorReporting.lastResult; if (lastResult && lastResult['#line']) { e.line += lastResult['#line'] - 2; } e.stack = [type+':'+e.message+' at '+e.filename+':'+(e.line+1)] .concat((e.extract||[]).map(function(output, index) { return (index + e.line)+': '+output; })).join('\n\t'); _debug.handleUncaughtException(type+': ' + e.message, e.filename, e.line, e.column, { type: type, message: e.message, fileName: e.filename, lineNumber: e.line, stack: e.stack, }); }, { lastResult: null, lastSource: null, getLocation: null, $patch: function() { // when errors occur, stash the source and #line {offset} for better error dispay above assert(!this.getLocation); var originalGetLocation = less.utils.getLocation, self = this; less.utils.getLocation = customGetLocation; delete self.$patch; // only need to apply once function customGetLocation(index, stream) { self.lastSource = stream; var result = originalGetLocation.apply(this, arguments); result.source = stream; stream.replace(/#line (\d+)/, function(_, offset) { result['#line'] = parseInt(offset); }); return self.lastResult = result; } }, }), // poll: 1000, // watch: true, }); var lessManager = { options: options, onViewportUpdated: onViewportUpdated, elements: $(options.selector).remove() }; return lessManager; function onViewportUpdated(viewport) { var globalVars = options.globalVars, less = window.less; if (onViewportUpdated.to) { clearTimeout(onViewportUpdated.to); onViewportUpdated.to = 0; } else if (globalVars.hash) { onViewportUpdated.to = setTimeout(onViewportUpdated.bind(this, viewport), 500); // debounce return; } delete globalVars.hash; Object.assign(globalVars, { 'inner-width': viewport.inner.width, 'inner-height': viewport.inner.height, 'client-width': viewport.client.width, 'client-height': viewport.client.height, 'hash': '', }); globalVars.hash = JSON.stringify(JSON.stringify(globalVars,0,2)).replace(/\\n/g , '\\000a'); var hash = JSON.stringify(globalVars, 0, 2); debugPrint('onViewportUpdated', JSON.parse(onViewportUpdated.lastHash||'{}')['inner-width'], JSON.parse(hash)['inner-width']); if (onViewportUpdated.lastHash !== hash) { debugPrint('updating lessVars', 'less.modifyVars:' + typeof less.modifyVars, JSON.stringify(globalVars, 0, 2)); // dump less variables if lessDebug=true was in the url PARAMS.lessDebug && $('#errors').show().html("
").children(0).text(hash);

            // patch less with absolute line number reporting
            options.errorReporting && options.errorReporting.$patch && options.errorReporting.$patch();

            // to recompile inline styles (in response to onresize or when developing),
            // a fresh copy of the source nodes gets swapped-in
            var newNodes = lessManager.elements.clone().appendTo(document.body);
            // note: refresh(reload, modifyVars, clearFileCache)
            less.refresh(false, globalVars).then(function(result) {
                debugPrint('less.refresh completed OK', result);
            })['catch'](function(err) {
                log('less ERROR:', err);
            });
            var oldNodes = onViewportUpdated.lastNodes;
            oldNodes && oldNodes.remove();
            onViewportUpdated.lastNodes = newNodes;
        }
        onViewportUpdated.lastHash = hash;
    }
}