HTML5全屏检测

前一段时间HTML5也算是定稿了,CSDN之类的网站也对全屏API进行了部分介绍。但是查了中文资料就没有全屏检测的。下面给出完整的全屏以及检测的方式

    function isFullSrc(){
        if((window.fullScreen) ||(window.innerWidth == screen.width && window.innerHeight == screen.height)) 
            return true;
        else 
            return false;
    }

    function requestFullScreen() {
        var de = document.documentElement;
        if (de.requestFullscreen) {
            de.requestFullscreen();
        } else if (de.mozRequestFullScreen) {
            de.mozRequestFullScreen();
        } else if (de.webkitRequestFullScreen) {
            de.webkitRequestFullScreen();
        }
    }

    function exitFullscreen() {
        var de = document;
        if (de.exitFullscreen) {
            de.exitFullscreen();
        } else if (de.mozCancelFullScreen) {
            de.mozCancelFullScreen();
        } else if (de.webkitCancelFullScreen) {
            de.webkitCancelFullScreen();
        }
    }

flex播放视频

消失了好久,一直在做数学建模比赛,终于抽出一些时间来了。来更新一下。大概下一段时间我应该能放出不少源代码吧(其实我是一直懒得上传Github……


 

现在U2B已经正式使用html5的视频播放器作为默认视频播放器,不过由于各种原因国内的视频源绝大多数视频都是flv作为容器的,没有办法被html5的video标签播放,最近的弹幕播放的项目逼得我去学习那过时的flex技术。什么都不说了,上代码好了。flex4不支持。



	
	
	
	
	
	
	
		
	

GFW这次升级的原理推测

面对着GFW的升级,相当多的梯子的作者也是纷纷表示和GfW进行斗争已经没有意义。我这里也花了一些时间稍微看了看GFW升级之后的情况。由于我在教育网,所以这个结果不一定是全国的普遍情况。
fqrouter的作者声称这次GFW的升级是进行全球范围的拔网线。这个一点都不假,这车升级之后GFW不会像以前以前一样在国际出口检测之后发送RST包进行阻塞了。GFW现在的行为直接是在骨干路由进行丢包。我这里对Google进行一次tracert的测试:
通过最多 30 个跃点跟踪
到 google.com [173.194.127.192] 的路由:

1 2 ms 2 ms 2 ms 180.201.128.1
……
6 8 ms 8 ms 9 ms 119.167.86.53
7 36 ms 36 ms 36 ms 219.158.10.81
8 * * * 请求超时。
显然,在骨干网就被丢包了。
现在一个能访问的google ip,一旦你进行访问,那么过上半分钟左右它就会被添加到黑名单里面。这个速度应该不是通过路由表扩散进行污染的应该是通过某种新的技术来进行可编程的拦截。经过测试发现这个设备确实就是出口路由了,它的下一跳就已经是国外的ip。
虽然说没有太多的实验,基本确定了这次升级之后GFW会尝试自动扩展黑名单并且在国际出口墙掉它们。

方滨兴教授祝您身体健康

2015新年大礼:GFW再次大升级,fqrouter已死,goagent已死

上个月低GFW屏蔽Gmail服务之后,今年GFW一上来就来了一个惊喜,该屏蔽的都屏蔽了。
fqrouter的作者昨天在twitter上表示项目停止维护。而GoAgent的作者也停止了GoAgent这个项目。也就是说原本大约40%的翻墙者不得不更换新的工具。
这一次的屏蔽似乎并不是简简单单的普通的屏蔽,而是带有回访功能的更加智能的骨干网丢包。我这里的以前通过hosts修改来访问google,而现在当我查找到能使用的google ip并且尝试访问之后的几分钟之内,这个ip地址就被阻断,然而该ip可以ping通,而80端口tcp包却没有任何应答,而443端口的tcp也是中途就会丢失。由于并不知道google的mac地址,所以不能实际确定这次是使用的路由表污染还是使用的选择性丢包完成的。至于更进一步的研究就要等着我有更多时间之后进行仔细的研究。
至于这次的GFW升级的影响肯定还是很大的。不管GFW怎么升级,VPN或者SS这种麻雀战以及XX门这种XX功的东西肯定是不会消亡的。如果中国阻断PPTP协议的话,那么许多外国企业就完全没有办法在中国办公了。而XX门那种工具有着政治对手的支持肯定也不会消亡。所以这次升级直接的后果肯定就会使现在翻墙工具变得更加单一化。
总之,方教授真是给了一个新年大礼啊。本来还想写一篇关于GFW的论文,结果GFW就升级了……你特么在逗我

php文件函数windows系统编码bug

最近在windows的php环境突然发现windows的php的文件函数文件名都是使用的GBK编码没有使用utf-8编码。于是需要手动转换一下编码。当然了linux系统都是使用的utf-8编码就没有这些问题啦。

我写了一些常用的函数的包装,供大家方便使用

$Server_System;
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
    $Server_System = 'windows';//filename will be changed into utf-8 in windows
} else {
    $Server_System = 'linux';
}

function my_file_exists($path)
{
    global $Server_System;
    if($Server_System == 'windows')
    {
        $path = iconv('utf-8','gbk',$path);
    }
    return file_exists($path);
}

function my_file_get_contents($path)
{
    global $Server_System;
    if($Server_System == 'windows')
    {
        $path = iconv('utf-8','gbk',$path);
    }
    return file_get_contents($path);
}

function my_filemtime($path)
{
    global $Server_System;
    if($Server_System == 'windows')
    {
        $path = iconv('utf-8','gbk',$path);
    }
    return filemtime($path);
}

function my_file_put_contents($path,$data)
{
    global $Server_System;
    if($Server_System == 'windows')
    {
        $path = iconv('utf-8','gbk',$path);
    }
    return file_put_contents($path,$data);
}

function my_is_dir($path)
{
    global $Server_System;
    if($Server_System == 'windows')
    {
        $path = iconv('utf-8','gbk',$path);
    }

    return is_dir($path);
}

function my_md5_file($path)
{
    global $Server_System;
    if($Server_System == 'windows')
    {
        $path = iconv('utf-8','gbk',$path);
    }
    
    return md5_file($path);
}

function my_sha1_file($path)
{
    global $Server_System;
    if($Server_System == 'windows')
    {
        $path = iconv('utf-8','gbk',$path);
    }
    
    return sha1_file($path);
}

轻量级php文件同步:LIGHTphpCDN

嘛,很不要脸的来推广自己的项目了。一个开源的轻量级的PHP写的文件同步系统。当然目的是为了管理CDN的了,所以名字也就叫CDN了,至于是不是CDN嘛,看你怎么用啦。

为什么要写这个项目呢,主要是前一段时间被我的php空间恶心到了,由于是虚拟主机,只能使用ftp进行上传。由于想利用php免费空间建立下载镜像,所以就一怒之下写了这个软件。

软件的说明什么的在项目目录里面,不过是英文写的罢了。

项目主页:https://github.com/manageryzy/Light-php-CDN

 

CoffeeScript缺陷

没有任何疑问,CoffeeScript是一门优秀的编程语言,但是不管他再怎么优秀都有一些不尽如人意的地方。这里结合我使用这门语言几天的经验来说一下CoffeeScript的初体验一些缺陷

 


最大的问题:缺乏强有力的IDE

由于CoffeeScript是一门新生的语言,相当多的开发环境还没有完全的支持他。

  • 如果你使用Visual Studio编辑,你不得不建立一个.net网站工程才能在里面编辑CoffeeScript,否则你不能得到代码提示。
  • 如果你使用Notepad++编辑,你不会得到任何编码提示
  • 如果你使用eclipse进行编辑,目前的支持还是很有限的
  • http://fiddlesalad.com/coffeescript/ 这个在线IDE还是感觉很不错的,功能很强大,但是由于它只能在线使用,所以可能无法在没有网络的情况访问,另外它要求一定要联网,对于那些不开源的商业应用也是很大的挑战。

第二大问题:缩进来判断代码结束

可能有人比较喜欢用缩进来结束代码,但是我非常不喜欢,尤其是当代码非常长的时候。当你的IDE不支持智能缩进的时候这更是一件非常辛苦的事情

第三大问题:不完全的OOP特性

CoffeeScript支持OOP无疑是非常方便的,但是很不幸的是这个支持是非常有限的。在这里一个没有办法通过CoffeeScript的成员自动添加定义一个类里面的私有成员,你只能通过一些技巧来实现手动的添加私有成员。在CoffeeScript里面,这里的私有成员只能是私有的,还不能实现保护成员。

所以记住:CoffeeScript只是JavaScript

第四大问题:糟糕的函数参数表设计

在CoffeeScript调用一个有参数函数你可以省略掉参数表的括号,但是这并不意味着你可以省略掉所有的括号:在无参数的时候你必须加上括号。这样的方式可能带来一个团队项目里面编码习惯的混乱。

第五大问题:变量自动声明导致的拼写错误

变量生存周期自动管理缺失不错,但是,这引来了一个问题:你可能因为一些失误错误的拼写了某些变量名,这样,在你的IDE没有办法给你足够的提示的时候,你不得不花费大量的时间去检查这样一个低级的错误


不管怎样,CoffeeScript都是一款优秀的语言,去尝试一下都是很好的,但是如果要实际的应用还是要一些勇气的

 

GruntJS配置实例

GruntJS配置还是比较耗时间的,这里放出一份我在h萌的一个项目的GruntJS的编译配置。这个编译配置参考了网络上的许多地方的配置文件整合的

 
JSON文件如下:

{
  "name": "",
  "version": "0.1.0",
  "dependencies": {
    "grunt": "0.x.x",
    "grunt-autoprefixer": "0.2.x",
    "grunt-contrib-clean": "0.5.x",
    "grunt-contrib-coffee": "0.7.x",
    "grunt-contrib-connect": "0.4.x",
    "grunt-contrib-copy": "0.4.x",
    "grunt-contrib-cssmin": "0.6.x",
    "grunt-contrib-jade": "0.8.x",
    "grunt-contrib-jshint": "0.6.x",
    "grunt-contrib-stylus": "0.8.x",
    "grunt-contrib-uglify": "0.2.x",
    "grunt-contrib-watch": "0.5.x",
	"grunt-html-build":"0.3.x",
	"grunt-contrib-htmlmin":"0.3.x",
	"grunt-cleanempty":"1.0.x"
  },
  "engine": "node >= 0.10"
}

下面是关键的JS

module.exports = function(grunt) {

	// configure the tasks
	grunt.initConfig({

		copy: {
			build: {
				cwd: 'static',
				src: [ '**', '!**/*.styl', '!**/*.coffee', '!**/*.jade' ,'!**.bak','!**.log','!**.html'],
				dest: 'build',
				expand: true
			},
		},
		clean: {
			build: {
				src: [ 'build' ]
			},
			stylesheets: {
				src: [ 'build/**/*.css', '!build/application.css' ]
			},
			scripts: {
				src: [ 'build/**/*.js', '!build/application.js' ]
			},
		},
		stylus: {
			build: {
				options: {
					linenos: true,
					compress: false
				},
				files: [{
					expand: true,
					cwd: 'static',
					src: [ '**/*.styl' ],
					dest: 'build',
					ext: '.css'
				}]
			}
		},
		autoprefixer: {
			build: {
				expand: true,
				cwd: 'build',
				src: [ '**/*.css' ],
				dest: 'build'
			}
		},
		cssmin: {
			build: {
				files: {
					'build/application.css': [ 'build/**/*.css' ]
				}
			}
		},
		coffee: {
			build: {
				expand: true,
				cwd: 'static',
				src: [ '**/*.coffee' ],
				dest: 'build',
				ext: '.js'
			}
		},
		uglify: {
			build: {
				options: {
					mangle: false
				},
				files: {
					'build/application.js': [ 'build/**/*.js' ]
				}
			}
		},
		jade: {
			compile: {
				options: {
					data: {}
				},
				files: [{
					expand: true,
					cwd: 'static',
					src: [ '**/*.jade' ],
					dest: 'build',
					ext: '.html'
				}]
			}
		},
		fixturesPath: "path",
		htmlbuild: {
			dist: {
				src: ['static/*.html'],
				dest: 'build/',
				options: {
					beautify: false,
					prefix: '//some-cdn',
					relative: true,
					scripts: {
					},
					styles: {
					},
					sections: {
					},
					data: {		
					},
				}
			}
		},
		htmlmin: {                                     // Task
			multiple: { 
				options: {                                 // Target options
					removeComments: true,
					collapseWhitespace: true
				},			// Target
				files: [{                                  // Dictionary of files
					expand: true,
					cwd: 'build/',                             // Project root
					src: '**/*.html',                        // Source
					dest: 'build/'                            // Destination
				}]
			}
		},
		cleanempty: {
			options: {
				force: true,
			},
			src: ['build/**/*', 'build/*'],
		},
	});

	// load the tasks
	grunt.loadNpmTasks('grunt-contrib-copy');
	grunt.loadNpmTasks('grunt-contrib-clean');
	grunt.loadNpmTasks('grunt-autoprefixer');
	grunt.loadNpmTasks('grunt-contrib-cssmin');
	grunt.loadNpmTasks('grunt-contrib-coffee');
	grunt.loadNpmTasks('grunt-contrib-uglify');
	grunt.loadNpmTasks('grunt-contrib-jade');
	grunt.loadNpmTasks('grunt-contrib-stylus');
	grunt.loadNpmTasks('grunt-html-build');
	grunt.loadNpmTasks('grunt-contrib-htmlmin');
	grunt.loadNpmTasks('grunt-cleanempty');

	// define the tasks

	grunt.registerTask(
		'stylesheets', 
		'Compiles the stylesheets.', 
		[ 'stylus', 'autoprefixer', 'cssmin', 'clean:stylesheets' ]
	);

	grunt.registerTask(
		'scripts', 
		'Compiles the JavaScript files.', 
		[ 'coffee', 'uglify', 'clean:scripts' ]
	);

	grunt.registerTask(
		'build', 
		'Compiles all of the assets and copies the files to the build directory.', 
		[ 'clean:build', 'copy', 'stylesheets', 'scripts', 'jade','htmlbuild' ,'htmlmin','cleanempty']
	);

	grunt.registerTask(
		'default', 
		'', 
		[ 'build']
	);

};

使用GruntJS优化你的网站

其实,一开始让我接触GruntJS我也是拒绝的,但是由于想要编译ABPlayerHtml5所以我不得不接触了一下GruntJS,结果发现——根本停不下来。GruntJS简直太好用了。

GruntJS是一个知名(为什么我以前没听说过……)的JavaScript构建工具,它就像“JavaScript世界的编译器”。它能够通过各种编译模块完成CoffeeScript、JadeScript的编译,JavaScript的合并以及压缩,CSS的合并以及压缩以及其他等许许多多的任务。

使用GruntJS进行构建的最大的好处就是能极大地减少你的网站请求次数,对于那些分散的JavaScript以及CSS你完全可以合并成一个文件并且以静态文件的方式放在内容分发网络(CDN)上。当然了,由于JS编译的过程局部变量是经过混淆的,所以文件的体积能进一步的减小。由于GruntJS是基于NodeJS的,所以你很容易就能在服务器上完成脚本的动态编译,如果你的服务器是基于NodeJS的话,你就可以轻松地写出一个能压缩Script以及CSS的静态缓存系统。

更多的可以参见GruntJS中文网:http://www.gruntjs.net/

CoffeeScript 像写诗一样写程序

昨天在编译ABPlayerHTML5的时候无意间发现了CoffeeScript这语言,以前虽然有过听说,但是都不屑的无视掉了这门语言。昨天在我看到这门语言的时候深深的被它吸引了,这种触动就和我第一次接触jQuery的时候一样,这给开发者的体验简直能用“感动”这个词来描述。

CoffeeScript是一种脚本语言没错,但是它还是需要编译的。它拥有一个javascript写的编译器用来把CoffeeScript编译到JavaScript。你可以在你的浏览器里面进行CoffeeScript的编译,但是更常见的做法是通过node.js来编译你的CoffeeScript。在node.js安装你的CoffeeScript是非常简单的一件事情:CoffeeScript已经可以直接通过npm获得你只需要下面一条指令就能获得最新稳定版的CoffeeScript

sudo npm install -g coffee-script

CoffeeScript里面你不需要特别的定义变量,一切变量的作用域都会自动的在最小的范围内。不像JavaScript,一切不声明var的变量都是全局变量。CoffeeScript会自动的声明变量。
# 赋值:
number   = 42
opposite = true

# 条件:
number = -42 if opposite

# 函数:
square = (x) -> x * x

# 数组:
list = [1, 2, 3, 4, 5]

# 对象:
math =
  root:   Math.sqrt
  square: square
  cube:   (x) -> x * square x

# Splats:
race = (winner, runners...) ->
  print winner, runners

# 存在性:
alert "I knew it!" if elvis?

# 数组 推导(comprehensions):
cubes = (math.cube num for num in list)

上面的这一段CoffeeScript编译之后就会变成下面的代码

var cubes, list, math, num, number, opposite, race, square,
  __slice = [].slice;

number = 42;

opposite = true;

if (opposite) {
  number = -42;
}

square = function(x) {
  return x * x;
};

list = [1, 2, 3, 4, 5];

math = {
  root: Math.sqrt,
  square: square,
  cube: function(x) {
    return x * square(x);
  }
};

race = function() {
  var runners, winner;
  winner = arguments[0], runners = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
  return print(winner, runners);
};

if (typeof elvis !== "undefined" && elvis !== null) {
  alert("I knew it!");
}

cubes = (function() {
  var _i, _len, _results;
  _results = [];
  for (_i = 0, _len = list.length; _i < _len; _i++) {
    num = list[_i];
    _results.push(math.cube(num));
  }
  return _results;
})();

CoffeeScript吸引人的特性除了这一点还有好多,比如CoffeeScript提供了类以及继承

class Animal
  constructor: (@name) ->

  move: (meters) ->
    alert @name + " moved #{meters}m."

class Snake extends Animal
  move: ->
    alert "Slithering..."
    super 5

class Horse extends Animal
  move: ->
    alert "Galloping..."
    super 45

sam = new Snake "Sammy the Python"
tom = new Horse "Tommy the Palomino"

sam.move()
tom.move()

编译之后的代码如下

var Animal, Horse, Snake, sam, tom,
  __hasProp = {}.hasOwnProperty,
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

Animal = (function() {
  function Animal(name) {
    this.name = name;
  }

  Animal.prototype.move = function(meters) {
    return alert(this.name + (" moved " + meters + "m."));
  };

  return Animal;

})();

Snake = (function(_super) {
  __extends(Snake, _super);

  function Snake() {
    return Snake.__super__.constructor.apply(this, arguments);
  }

  Snake.prototype.move = function() {
    alert("Slithering...");
    return Snake.__super__.move.call(this, 5);
  };

  return Snake;

})(Animal);

Horse = (function(_super) {
  __extends(Horse, _super);

  function Horse() {
    return Horse.__super__.constructor.apply(this, arguments);
  }

  Horse.prototype.move = function() {
    alert("Galloping...");
    return Horse.__super__.move.call(this, 45);
  };

  return Horse;

})(Animal);

sam = new Snake("Sammy the Python");

tom = new Horse("Tommy the Palomino");

sam.move();

tom.move();

CoffeeScript的函数绑定功能也是非常的方便

Account = (customer, cart) ->
  @customer = customer
  @cart = cart

  $('.shopping_cart').bind 'click', (event) =>
    @customer.purchase @cart

编译之后的代码是这样的

var Account;

Account = function(customer, cart) {
  this.customer = customer;
  this.cart = cart;
  return $('.shopping_cart').bind('click', (function(_this) {
    return function(event) {
      return _this.customer.purchase(_this.cart);
    };
  })(this));
};

更多的资料可以参考 http://coffee-script.org/