zoukankan      html  css  js  c++  java
  • less源码学习

    mass Framework决定用less作为自己的CSS重用工具,决定好好学习一下它的源码,说不定以后用mass Framework重写它。

    一上来是个经典结构:自动执行函数

    (function (window, undefined) {
    
    })(window)
    

    接着是加载器相关的内容

      function require(arg) {
            return window.less[arg.split('/')[1]];
        };
    
        // amd.js
        //如果引入AMD的加载器,则把它当成一个AMD模块
        if (typeof define === "function" && define.amd) {
            define("less", [], function () {
                return less;
            } );
        }
    

    再接着ecma262v5的语言补丁,我们总得支持IE6

    if (!Array.isArray) {
            Array.isArray = function(obj) {
                return Object.prototype.toString.call(obj) === "[object Array]" ||
                (obj instanceof Array);
            };
        }
        if (!Array.prototype.forEach) {
            Array.prototype.forEach =  function(block, thisObject) {
                var len = this.length >>> 0;
                for (var i = 0; i < len; i++) {
                    if (i in this) {
                        block.call(thisObject, this[i], i, this);
                    }
                }
            };
        }
        if (!Array.prototype.map) {
            Array.prototype.map = function(fun /*, thisp*/) {
                var len = this.length >>> 0;
                var res = new Array(len);
                var thisp = arguments[1];
    
                for (var i = 0; i < len; i++) {
                    if (i in this) {
                        res[i] = fun.call(thisp, this[i], i, this);
                    }
                }
                return res;
            };
        }
        if (!Array.prototype.filter) {
            Array.prototype.filter = function (block /*, thisp */) {
                var values = [];
                var thisp = arguments[1];
                for (var i = 0; i < this.length; i++) {
                    if (block.call(thisp, this[i])) {
                        values.push(this[i]);
                    }
                }
                return values;
            };
        }
        if (!Array.prototype.reduce) {
            Array.prototype.reduce = function(fun /*, initial*/) {
                var len = this.length >>> 0;
                var i = 0;
    
                // no value to return if no initial value and an empty array
                if (len === 0 && arguments.length === 1) throw new TypeError();
    
                if (arguments.length >= 2) {
                    var rv = arguments[1];
                } else {
                    do {
                        if (i in this) {
                            rv = this[i++];
                            break;
                        }
                        // if array contains no values, no initial value to return
                        if (++i >= len) throw new TypeError();
                    } while (true);
                }
                for (; i < len; i++) {
                    if (i in this) {
                        rv = fun.call(null, rv, this[i], i, this);
                    }
                }
                return rv;
            };
        }
        if (!Array.prototype.indexOf) {
            Array.prototype.indexOf = function (value /*, fromIndex */ ) {
                var length = this.length;
                var i = arguments[1] || 0;
    
                if (!length)     return -1;
                if (i >= length) return -1;
                if (i < 0)       i += length;
    
                for (; i < length; i++) {
                    if (!Object.prototype.hasOwnProperty.call(this, i)) {
                        continue
                    }
                    if (value === this[i]) return i;
                }
                return -1;
            };
        }
    
        if (!Object.keys) {
            Object.keys = function (object) {
                var keys = [];
                for (var name in object) {
                    if (Object.prototype.hasOwnProperty.call(object, name)) {
                        keys.push(name);
                    }
                }
                return keys;
            };
        }
    
        if (!String.prototype.trim) {
            String.prototype.trim = function () {
                return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
            };
        }
    

    接着是宿主环境检测与把命名空间放到全局变量下:

    
     var less, tree;
    
        if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
            //如果是在Rhino环境中
            // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
            if (typeof(window) === 'undefined') {
                less = {}
            } else                                {
                less = window.less = {}
            }
            tree = less.tree = {};
            less.mode = 'rhino';
        } else if (typeof(window) === 'undefined') {
            //如果是在node.js环境中
            less = exports,
            //我们可以把几个模块合并到一个JS文件中,因此如果是打包了,是调当前文件中的tree模块
            tree = require('./tree');
            less.mode = 'node';
        } else {
            //如果是在浏览器环境中
            if (typeof(window.less) === 'undefined') {
                window.less = {}
            }
            less = window.less,
            tree = window.less.tree = {};
            less.mode = 'browser';
        }
    

    下面就是正式的解析器的内容了最主要的用法是new(less.Parser)().parse,是没有传参,env可能是为了向前兼容。 由于方法间的连联太频繁,从原型上调来调去太低效,改成如下结构 // function (){ /*内部方法与对象*/ return parser = {} }

    待续!

  • 相关阅读:
    解决VUE刷新或者加载出现闪烁
    解决VUE<router-link>不能触发点击事件
    H5的本地存储web Storage
    格式化数字格式
    移动终端浏览器版本信息
    新的开始
    PHP用PHPExcel导入Excel表格的数据到MySQL(thinkPHP3.2.3)
    Layui的分页模块在网站中的应用
    PHPstorm连接ftp
    自定义PHPstorm快捷键
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/2682736.html
Copyright © 2011-2022 走看看