Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
executable file 201 lines (190 sloc) 6.66 KB
var ua = navigator.userAgent,
android = ua.match(/(Android);?[\s\/]+([\d.]+)?/),
ipad = ua.match(/(iPad).*OS\s([\d_]+)/),
ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/),
iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/),
os = {};
if (android) os.android = true, os.version = android[2];
if (iphone && !ipod) os.ios = os.iphone = true, os.version = iphone[2].replace(/_/g, '.')
if (ipad) os.ios = os.ipad = true, os.version = ipad[2].replace(/_/g, '.')
if (ipod) os.ios = os.ipod = true, os.version = ipod[3] ? ipod[3].replace(/_/g, '.') : null;
var MetaHandler = function () {
//MONOSTATE
if (MetaHandler.prototype.instance) {
return MetaHandler.prototype.instance;
}
var me = this;
var meta = {}, _els;
/**
* _els
* meta = {name:{content:String,seriation:Array,store:{property:String},...},...}
* @method init
*/
function init() {
_els = document.getElementsByTagName('meta');
for (var i = 0; i < _els.length; i++) {
var name = _els[i].name;
if (name) {
meta[name] = {};
meta[name].el = _els[i];
meta[name].content = _els[i].content;
meta[name].seriation = meta[name].content.split(',');
meta[name].store = getContentStore(name);
}
}
return me;
}
function getContentStore(name) {
var content = meta[name].seriation, store = {};
for (var i = 0; i < content.length; i++) {
if (content[i].length < 1) {
content[i] = null;
delete content[i];
content.length--;
} else {
var ct = content[i].split('='),
pp = ct[0];
if (pp) {
store[pp] = ct[1];
}
}
}
return store;
}
this.hasMeta = function (name) {
return meta[name] ? 1 : 0;
}
this.createMeta = function (name) {
if (!this.hasMeta(name)) {
var el = document.createElement('meta');
el.name = name;
document.head.appendChild(el);
meta[name] = {};
meta[name].el = el;
meta[name].content = '';
meta[name].seriation = [];
meta[name].store = {};
}
return me;
}
this.setContent = function (name, value) {
meta[name].content = value;
meta[name].el.content = value;
return me;
}
this.getContent = function (name) {
return meta[name] && meta[name].content;
}
function updateContent(name) {
meta[name].content = meta[name].seriation.join(',');
me.setContent(name, meta[name].content);
return me;
}
this.removeContentProperty = function (name, property) {
var _property = property;
if (meta[name]) {
if (meta[name].store[_property] != null) {
for (var i = 0; i < meta[name].seriation.length; i++) {
if (meta[name].seriation[i].indexOf(property + '=') != -1) {
meta[name].seriation[i] = null;
delete meta[name].seriation[i];
break;
}
}
}
updateContent(name);
}
return me;
}
this.getContentProperty = function (name, property) {
return meta[name] && meta[name].store[property];
}
this.setContentProperty = function (name, property, value) {
var _property = property,
pv = property + '=' + value;
if (meta[name]) {
if (meta[name].store[_property] != null) {
meta[name].store[_property] = value;
for (var i = 0; i < meta[name].seriation.length; i++) {
if (meta[name].seriation[i].indexOf(property + '=') != -1) {
meta[name].seriation[i] = pv;
break;
}
}
} else {
meta[name].store[_property] = value;
meta[name].seriation.push(pv);
}
updateContent(name);
}
return me;
}
/**
* Automatically adjusts according to a device’s screen size.
* Base on [theory](https://www.icloud.com/keynote/AwBWCAESEJd5uucfBPGt6KPotb3tNfsaKm-Q7fqs2-4ojmPoPJuWZCvjYgKl5jEf1URdRgdgNHe38BTzeF3DK7q1ewMCUCAQEEIJ85mw21ii_AwybOqxoF-V02v51Vdg855ED4qVA_8bXr)
*
* Note:
* For iOS it just works perfectly,if it's not,try to use "webView.scalesPageToFit = YES" in the webview.
* For android it works in all of build-in broswers,it might be break in some third-part ROM's build-in broswers(webview).
* That's because they don't do a good job for the webview,such as they should not use "webview.setBuiltInZoomControls(false)".
*
* This is a painless solution.For more extra work,checkout the [REM solution](http://gregrickaby.com/using-the-golden-ratio-and-rems/).
*
* e.g.
* <head>
* ....
* <!-- defind the viewport meta -->
* <meta content="target-densitydpi=device-dpi,width=640" name="viewport">
* <!-- set the body's width to be the same as the viewport's width -->
* <style type="text/css">
* body{width: 640px;}
* </style>
* <!-- magic happens here -->
* <script> (new MetaHandler()).fixViewportWidth(); </script>
* </head>
*
* Demo:
* [NetEase newsapp member club](http://c.3g.163.com/CreditMarket/default.html)
* [Deja Fashion topic](http://m.deja.me/topics/#/special/9)
*
* @param width {number} the size of the viewport
* @param fixBody {boolean} force to set body's width as same as the size of the viewport
*/
this.fixViewportWidth = function (width, fixBody) {
width = width || me.getContentProperty('viewport', 'width');
if (width != 'device-width') {
var iw = window.innerWidth || width,
ow = window.outerWidth || iw,
sw = window.screen.width || iw,
saw = window.screen.availWidth || iw,
ih = window.innerHeight || width,
oh = window.outerHeight || ih,
sh = window.screen.height || ih,
sah = window.screen.availHeight || ih,
w = Math.min(iw, ow, sw, saw, ih, oh, sh, sah),
ratio = w / width,
dpr = window.devicePixelRatio;
ratio = Math.min(ratio, dpr);
//fixBody may trigger a reflow,you should not use it if you could do it in your css
if (fixBody) {
document.body.style.width = width + 'px';
}
if (os.android) {
me.removeContentProperty('viewport', 'user-scalable')
.setContentProperty('viewport', 'target-densitydpi', 'device-dpi')
.setContentProperty('viewport', 'initial-scale', ratio)
.setContentProperty('viewport', 'maximum-scale', ratio);
} else if (os.ios && !os.android) {
me.setContentProperty('viewport', 'user-scalable', 'no');
//scale for UIWebview
if ( os.ios && parseInt(os.version) < 7 || !(window.indexedDB || window.webkitIndexedDB) ){
me.setContentProperty('viewport', 'initial-scale', ratio);
}
}
}
}
init();
//MONOSTATE
MetaHandler.prototype.instance = this;
};
module.exports = new MetaHandler;