123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 |
- const Audio = require('./Audio'),
- tagsAndAttrs = require('./tagsAndAttrs');
- class ToJson {
- constructor(html,app){
- const _ts = this;
- let m = _ts.m = {};
- m.parse = require('./parse5');
- _ts.html = html;
- _ts.data = {};
- _ts.app = app;
- // 得到整体页面的数据
- _ts.data.document = m.parse.parse(_ts.html);
- // 得到body部分的数据
- _ts.data.body = _ts.getBodyData(_ts.data.document);
- // 生成当前的数据ID
- _ts.id = `dataId_${+new Date}_${(Math.random()+'').slice(2)}`;
- // 将数据保存到全局
- global.__towxmldata__ = global.__towxmldata__ || {};
- global.__towxmldata__[_ts.id] = global.__towxmldata__[_ts.id] || {};
- global.__towxmldata__[_ts.id].audio = {};
- }
- getData(){
- const _ts = this,
- m = _ts.m;
- let data = _ts.data,
- outData = _ts.sortOut(data.body);
- outData.node = 'root';
-
- // 为数据添加ID
- outData.id = _ts.id;
-
- global.__towxmldata__[_ts.id].article = outData;
- return global.__towxmldata__[_ts.id].article;
- }
- /**
- * 遍历页面数据整理成小程序想要的
- */
- sortOut(bodyData){
- const _ts = this,
- app = _ts.app,
- appData = app.data ;
- let result = {},
- arrange;
- (arrange = (data,result)=>{
- // 当有数据且有子元素时则遍历
- if(data && data.childNodes && data.childNodes.length){
- // 子元素数据不存在时,创建一个空的数组用以存储子元素数据
- if(!result.child){
- result.child = [];
- };
- // 遍历子节点,处理节点的数据
- for(let i=0,len=data.childNodes.length; i<len; i++){
- let node = data.childNodes[i], // 得到具体的节点
- attrs = node.attrs, // 得到节点的属性(一个数组)
- attrsLength = attrs && attrs.length ? attrs.length : 0, // 得到节点属性的长度
- current = { // 创建一个空对象,用于存储节点属性及处理之后的属性
- _e:{},
- attr:{} // html的原始数据
- };
- if(node){
- result.child.push(current);
- };
- // 如果有属性则处理其属性
- if (attrsLength) {
- if (current._e.attr === undefined) {
- //current.attr = {};
- current._e.attr = {};
- };
- for (let i = 0; i < attrsLength; i++) {
- let attrsItem = attrs[i],
- key = attrsItem.name,
- val = attrsItem.value;
-
- current.attr[key] = val;
- current._e.attr[key] = val;
- };
- };
- for(let key in node){
- // 保留最原始的html数据,父节点数据去掉(小程序会报错)
- if(typeof node[key] !== 'object'){
- current._e[key] = node[key];
- };
- switch (node.nodeName) {
- case 'body':
- current['node'] = 'root';
- break;
- case '#text':
- current['node'] = 'text';
- current['text'] = node.value;
- break;
- default:
- current['node'] = 'element';
- break;
- };
- };
- // 当前标签是audio的情况下
- if(node.tagName === 'audio'){
- current.tag = "view";
- current.attr = {};
- current.attr.class = 'audioForH2w';
- current._id = `audio_${+new Date()}_${(Math.random()+'').slice(2)}`;
- // // 用于保存播放器数据(小程序在setData完成之后,新的数据会重新占用内存空间,故此处保存没有必要)
- // if(appData){
- // appData.__audioData__ = appData.__audio__ || {};
- // appData.__audioData__[current._id] = current;
- // };
- // 创建播放器子元素
- current.child = [
- {
- node:"element",
- tag:"view",
- attr:{
- class:"h2w__view audioForH2w__icon"
- }
- },{
- node:"element",
- tag:"view",
- attr:{
- class:"h2w__view audioForH2w__cover"
- },
- child:[
- {
- node:"element",
- tag:"image",
- type:"audio",
- attr:{
- class:"h2w__img"
- }
- }
- ]
- },{
- node:"element",
- tag:"view",
- attr:{
- class:"h2w__view audioForH2w__info"
- },
- child:[
- {
- node:"element",
- tag:"view",
- attr:{
- class: "h2w__view audioForH2w__schedule",
- style: "width:0px;"
- }
- },{
- node:"element",
- tag:"view",
- attr:{
- class:"audioForH2w__title"
- },
- child:[
- {
- node:"text",
- text: "--",
- attr: {}
- }
- ]
- },{
- node:"element",
- tag:"view",
- attr:{
- class:"audioForH2w__author"
- },
- child:[
- {
- node:"text",
- text: "佚名",
- attr: {}
- }
- ]
- },{
- node:"element",
- tag:"view",
- attr:{
- class:"audioForH2w__time"
- },
- child:[
- {
- node:"text",
- text: "00:00:00 / 00:00:00",
- attr: {}
- }
- ]
- }
- ]
- }
- ];
- if(appData){
- // 得到音频选项
- let audioOption = ((node)=>{
- let option = {},
- nodeAttrs = node.attrs;
- for(let i=0,len=nodeAttrs.length; i<len; i++){
- let attrItem = nodeAttrs[i];
- option[attrItem.name] = attrItem.value;
- };
- return option;
- })(node);
- // 保存当前播放器数据
- global.__towxmldata__[_ts.id].audio[current._id] = current;
- //用于保存播放器对象
- appData.__audioObj__ = appData.__audioObj__ || {};
- appData.__audioObj__[current._id] = Audio({
- app:app, // 传入APP
- playerId:current._id, // 当前播放器ID
- dataId:_ts.id, // 数据ID
- option:audioOption // 传入音频选项
- });
- };
- }else if(node.tagName){
- current.tag = _ts.getTag(node.tagName);
- current.attr.class = current.attr.class ? `h2w__${node.tagName} ${current.attr.class}` : `h2w__${node.tagName}`;
- };
- arrange(node,current);
- };
- };
- })(bodyData,result);
- return result;
- }
- /**
- * 获取属于body那部分的数据
- */
- getBodyData(documentData){
- let data,
- getBody;
- (getBody = (list)=>{
- for(let i=0,len=list.length; i<len; i++){
- let item = list[i];
- if(item.nodeName === 'body' && item.tagName === 'body'){
- data = item;
- break;
- }else if (item.childNodes){
- getBody(item.childNodes);
- };
- }
- })(documentData.childNodes);
- return data;
- }
- /**
- * 得到转换对应的tag
- */
- getTag(tagName){
- let correspondTag = this.correspondTag(),
- wxmlTag = correspondTag[tagName] === undefined ? 'view' : correspondTag[tagName];
- return wxmlTag;
- }
- /**
- * 组织html与小程序的tag对应关系
- */
- correspondTag(){
- let data = {
- 'a':'navigator',
- 'img':'image',
- 'todogroup':'checkbox-group'
- };
- // 该系列的标签都转换为text
- ['span','b','strong','i','em','code','sub','sup','g-emoji','mark','ins'].forEach(item => {
- data[item] = 'text';
- });
- // 该系列是小程序原生tag,不需要转换
- tagsAndAttrs.wxml.forEach(item => {
- data[item] = item;
- });
- return data;
- }
- };
- module.exports = ToJson;
|