diff --git a/app.js b/app.js index f2ddfcc..6de4adf 100644 --- a/app.js +++ b/app.js @@ -15,7 +15,7 @@ App({ try { var res = tt.getSystemInfoSync(); that.statusBarHeight = res.statusBarHeight - console.log(`手机型号为 ${res.platform}`); + console.log(res,"型号"); this.globalData.platform = res.platform } catch (error) { console.log(`获取系统信息失败`); diff --git a/app.json b/app.json index c6b5b6d..8f6d7e4 100644 --- a/app.json +++ b/app.json @@ -13,7 +13,8 @@ "pages/mianCollect/mianCollect", "pages/UpHome/UpHome", "pages/publicity/publicity", - "pages/upEnter/upEnter" + "pages/upEnter/upEnter", + "pages/integral/integral" ], "usingComponents": {}, "window":{ diff --git a/config/config.js b/config/config.js index 78db652..ed773c0 100644 --- a/config/config.js +++ b/config/config.js @@ -15,6 +15,7 @@ let config = { getAuthor:"/merchant/listV1",//查询作者 checkUserInfo:"/user/checkWechatStatus",//用户是否授权 userInfo:"/user/getUserInfo",//用户授权 + getUserInfo:"/user/userinfo",//获取用户信息 mainCollet:"/ttCoupon/collectList",//我的收藏 getUpUser:"/merchant/findById",//up类容 getPublicity:"/wxCampaign/list",//轮播图 diff --git a/pages/UpHome/UpHome.js b/pages/UpHome/UpHome.js index 237026a..1d66ae5 100644 --- a/pages/UpHome/UpHome.js +++ b/pages/UpHome/UpHome.js @@ -14,6 +14,33 @@ Page({ classList:[],//课程列表 dNum:"",//但课程数 zNum:"",//专栏数 + addFlag: true, + }, + hieaddCheck() { + let animation = tt.createAnimation({ + duration: 1000, + timingFunction: "ease", + }); + animation.translateX(400).step() + this.setData({ + // extraClasses: 'addBox-transition', + showAddBox: animation.export(), + addFlag: true + }) + }, + showAddCheck: function () { + this.setData({ + addFlag: false + }) + let animation = tt.createAnimation({ + duration: 1000, + timingFunction: "ease", + }); + animation.translateX(0).step() + this.setData({ + showAddBox: animation.export(), + + }) }, getClass(){//课程list Http.get({ @@ -75,12 +102,25 @@ Page({ }) }, onLoad(options){ - this.setData({ - id:options.id, - name:options.name - }) - this.getUpData() - this.getClass() + if(app.globalData.token){ + this.setData({ + id:options.id, + name:options.name + }) + this.getUpData() + this.getClass() + + }else{ + app.tokenCallback = token =>{ + this.setData({ + id:options.id, + name:options.name + }) + this.getUpData() + this.getClass() + } + } + }, onReachBottom() { console.log("到底了"); @@ -89,5 +129,40 @@ Page({ }) this.getClass() - } + }, + onShow() { + let animation = tt.createAnimation({ + duration: 0, + // timingFunction: "ease", + }); + animation.translateX(400).step() + this.setData({ + showAddBox: animation.export(), + screenFlag:false,//初始化防录屏弹框 + }) + // this.itiRecording() + + }, + onShareAppMessage: function (shareOption) { + let that = this + if (shareOption.channel == 'video') { // 判断是是不是分享视频 + return { + channel: 'video', // 必写 video + //     templateId: '',   // 分享的模版 id (如果未设置就是默认,下面会说如何设置) + title: `知播堂-${that.data.upData.name}`,     // 分享的标题 + //     desc: '我是简介',     // 分享的内容介绍目前没有用 +     path: `/pages/UpHome/UpHome?id=${that.data.id}&name=${that.data.name}`,  // 分享的路径 + extra: { + videoTopics: ["知播堂",] // 只有抖音才会有的属性 + }, + } + } else { // 右上角分享 + return { + templateId: '',         //分享的模版 id + title: '',            //分享的标题 + desc: '',           // 分享的内容 + //      path: ``, // 分享的路径 + } + } + }, }) \ No newline at end of file diff --git a/pages/UpHome/UpHome.ttml b/pages/UpHome/UpHome.ttml index 0c2f548..92614a3 100644 --- a/pages/UpHome/UpHome.ttml +++ b/pages/UpHome/UpHome.ttml @@ -1,4 +1,4 @@ - + @@ -21,7 +21,7 @@ - + {{item.title}} @@ -45,6 +45,22 @@ + + + + + + + + + + + 申请入驻 + + \ No newline at end of file diff --git a/pages/UpHome/UpHome.ttss b/pages/UpHome/UpHome.ttss index c32f069..e40b1ea 100644 --- a/pages/UpHome/UpHome.ttss +++ b/pages/UpHome/UpHome.ttss @@ -150,6 +150,11 @@ font-weight: 500; font-size: 26rpx; color: #8790A8; + overflow:hidden; + text-overflow:ellipsis; + display:-webkit-box; + -webkit-box-orient:vertical; + -webkit-line-clamp:1 } .incomeBox{ margin-top: 10rpx; @@ -181,4 +186,78 @@ .moodsNum{ float: right; color: #00cc99; +} +.add{ + width: 140rpx; + height: 140rpx; + position: fixed; + right: 0; + bottom: 274rpx; + z-index: 10000; +} +.addBox{ + padding: 0 40rpx; + height: 100rpx; + background: linear-gradient(0deg, #2A3042, #464D61); + background-color: #2A3042; + box-shadow: 0px 6px 20px 0px rgba(0, 0, 0, 0.93); + border-radius: 49rpx; + position: fixed; + left: 5%; + bottom: 300rpx; +} + .goruzu{ + float: left; + } + +.video{ + width: 70rpx; + height: 70rpx; + float: left; + margin-left: 40rpx; + margin-top: 15rpx; +} +.checkImg{ + width: 70rpx; + height: 70rpx; + float: left; + margin-left: 80rpx; + margin-top: 10rpx; +} +.issue{ + float: left; + font-size: 30rpx; + font-family: OPPOSans; + font-weight: bold; + color: #FFFFFF; + line-height: 100rpx; + margin-left: 10rpx; +} +.xian{ + height: 70rpx; + width: 2rpx; + background-color: rgba(255, 255, 255, 0.3); + border-radius: 1px; + float: left; + margin-left: 80rpx; + margin-top: 15rpx; +} +button::after { + border: none; + + } + +button { + background-color: transparent; + + padding-left: 0; + + padding-right: 0; + + line-height:inherit; + +} + +button { + border-radius:0; } \ No newline at end of file diff --git a/pages/category/category.js b/pages/category/category.js index b16e13c..7682cbf 100644 --- a/pages/category/category.js +++ b/pages/category/category.js @@ -5,6 +5,7 @@ const config = require("../../config/config.js"); const Http = require("../../utils/HttpBasics") Page({ data: { + imgHttps:app.globalData.imgHttps, navigationBarHeight, navigationBarHeight2, activityFlag: 0, @@ -13,6 +14,7 @@ Page({ pageNum:1, dataLsit:[],//数据列表 inputValue:'',//搜索框值 + noDAtaFlag:false,// }, setActiviy(e){ let index = e.currentTarget.dataset.index @@ -60,7 +62,9 @@ Page({ }) }, getLsit(){ - console.log(666); + tt.showLoading({ + title: '加载中...', // 内容 + }); Http.get({ url:config.api.columnLsit, data:{ @@ -77,13 +81,25 @@ Page({ }else{ list = res.data.list } + if(list.length==0){ + this.setData({ + noDAtaFlag:true + }) + }else{ + this.setData({ + noDAtaFlag:false + }) + } this.setData({ dataLsit:list }) + tt.hideLoading(); }).catch(err=>{ + tt.hideLoading(); tt.showToast({ - title: err.message, // 内容 - }); + title: err.message?err.message:err.data, // 内容 + icon:"none" + }); }) }, onLoad(options){ diff --git a/pages/category/category.ttml b/pages/category/category.ttml index d4fbd80..8835b70 100644 --- a/pages/category/category.ttml +++ b/pages/category/category.ttml @@ -1,67 +1,50 @@ - - - - - - - - - - + + + + + + + + + + + + + {{item.title}} + - - - - - {{item.title}} - - - - + + + + + + + + {{item.title}} - - - - - - - {{item.title}} - - - - {{item.countClass?item.countClass+'课时':'单课程'}} - - - {{item.salePriceStr}} - - - ¥ - - - {{"免费"}} - - - - - - - - - - - - - - + + + {{item.countClass?item.countClass+'课时':'单课程'}} + + + {{item.salePriceStr}} + + + ¥ + + + {{"免费"}} + - - + - + + + + + - - \ No newline at end of file + + diff --git a/pages/category/category.ttss b/pages/category/category.ttss index 96580d9..576059c 100644 --- a/pages/category/category.ttss +++ b/pages/category/category.ttss @@ -27,7 +27,7 @@ /* float: left; */ position: fixed; top: 270rpx; - height: 1200rpx; + height: 1000rpx; overflow: scroll; } .columnBox::-webkit-scrollbar { diff --git a/pages/classDetails/classDetails.js b/pages/classDetails/classDetails.js index ac8e2fc..d184e7d 100644 --- a/pages/classDetails/classDetails.js +++ b/pages/classDetails/classDetails.js @@ -2,10 +2,13 @@ const app = getApp() const navigationBarHeight = (getApp().statusBarHeight + 44) + "px" const config = require("../../config/config") const Http = require("../../utils/HttpBasics.js") + Page({ data: { - showAddBox:{}, - ifPay: app.globalData.platform, + direction:-90, + screenFlag: false, + showAddBox: {}, + signal: app.globalData.platform, classTitle: "",//课程标题 showIos: false,//ios字符提示 showHie: false,//提示框 @@ -54,6 +57,42 @@ Page({ // goIndent(e){ // console.log(e.dataset.url); // }, + itiRecording(){//防止录屏初始化函数 + if(this.data.signal=='ios'){ + this.onRecord() + }else{ + this.disable() + } + }, + disable: function() {// 防止录屏录制 安卓 + tt.disableUserScreenRecord({ + success(res) { + console.log("disableUserScreenRecord 调用成功", res) + }, + fail(res) { + console.log("disableUserScreenRecord 调用失败", res); + }, + }) + }, + onRecord: function () { // 防止录屏录制 ios + const callback = (res) => { + if (res.state === 'start') { + this.data.videoContext.pause()//暂停 + this.data.videoContext.exitFullScreen()//退出全屏 + this.setData({ + screenFlag: true, + btnSuspend: false,//禁止播放 + }) + } else if (res.state === 'stop') { + this.data.videoContext.play(); + this.setData({ + screenFlag: false, + btnSuspend: true,//禁止播放 + }) + } + } + tt.onUserScreenRecord(callback) + }, showIos() { this.setData({ showIos: true @@ -122,14 +161,14 @@ Page({ duration: 1000, timingFunction: "ease", }); - animation.opacity(0).step() + animation.translateX(400).step() this.setData({ // extraClasses: 'addBox-transition', - showAddBox:animation.export(), + showAddBox: animation.export(), addFlag: true }) }, - showAddCheck:function(){ + showAddCheck: function () { this.setData({ addFlag: false }) @@ -137,27 +176,12 @@ Page({ duration: 1000, timingFunction: "ease", }); - animation.opacity(1).step() + animation.translateX(0).step() this.setData({ - showAddBox:animation.export(), - + showAddBox: animation.export(), + }) }, - // addCheck() {//动画 - // this.setData({ - // addFlag: false - // }) - // if (this.data.extraClasses == 'addBox-transition addBox-moved') { - // this.setData({ - // extraClasses: 'addBox-transition', - - // }) - // } else { - // this.setData({ - // extraClasses: 'addBox-transition addBox-moved' - // }) - // } - // }, setColumnIndex(e) { let index = e.currentTarget.dataset.index this.setData({ @@ -259,7 +283,7 @@ Page({ }) }).catch(err => { tt.showToast({ - title: '唤起支付失败', // 内容 + title: err.message ? err.message : err.data, // 内容 icon: "none" }); }) @@ -321,6 +345,7 @@ Page({ } }, + setCollect() {//设置收藏 if (this.data.iscollect) {//已收藏 Http.get({ @@ -394,7 +419,20 @@ Page({ videoId: id } }).then(res => { - + console.log(res.data.width,res.data.height); + if((res.data.width)*1>=(res.data.height)*1){ + //横屏 + console.log("横屏"); + this.setData({ + direction:-90 + }) + }else{ + //竖屏 + console.log("竖屏"); + this.setData({ + direction:0 + }) + } this.setData({ mp4Url: res.data.videoUrl }) @@ -407,11 +445,12 @@ Page({ }); }) }, - + onReady() { this.setData({ videoContext: wx.createVideoContext('myVideo') }) + this.itiRecording() }, onLoad(options) { if (app.globalData.token) { @@ -443,10 +482,13 @@ Page({ duration: 0, // timingFunction: "ease", }); - animation.opacity(0).step() + animation.translateX(400).step() this.setData({ - showAddBox:animation.export(), + showAddBox: animation.export(), + screenFlag:false,//初始化防录屏弹框 }) + // this.itiRecording() + }, onShareAppMessage: function (shareOption) { console.log(this.data.data.dyTitle); diff --git a/pages/classDetails/classDetails.ttml b/pages/classDetails/classDetails.ttml index 71d698a..5de541f 100644 --- a/pages/classDetails/classDetails.ttml +++ b/pages/classDetails/classDetails.ttml @@ -3,9 +3,9 @@ - - ¥ {{data.salePriceStr}} 购买 - 暂不支持购买 + + ¥ {{data.salePriceStr}} 购买 + 暂不支持购买 {{data.title}} @@ -178,11 +178,14 @@ - ¥{{data.salePriceStr}} - ¥{{data.salePriceStr}} + ¥{{data.salePriceStr}} + ¥{{data.salePriceStr}} + + 由于版权原因,此内容不支持iOS录屏 + \ No newline at end of file diff --git a/pages/classDetails/classDetails.ttss b/pages/classDetails/classDetails.ttss index de880df..48990e2 100644 --- a/pages/classDetails/classDetails.ttss +++ b/pages/classDetails/classDetails.ttss @@ -219,7 +219,7 @@ position: fixed; right: 0; bottom: 274rpx; - z-index: 100000000000000000; + z-index: 10000; } .addBox{ padding: 0 40rpx; @@ -674,3 +674,30 @@ button { top: 200px; left: 0; } +.screenBox{ + width: 100%; + height: 100vh; + background-color: rgba( 0, 0, 0, 0.4); + position: fixed; + top: 0; + left: 0; + font-size: 1000000000000; +} + +.screenText{ + width: 40%; + padding: 30rpx 10px; + border-radius: 10rpx; + text-align: center; + line-height: 40rpx; + font-size: 30rpx; + background-color: #ffffff; + color: #535E75; + font-size: 24rpx; + margin: 50% auto; +} +rich-text img{ + /* width: 100%; */ + max-width: 100%; + /* max-height: 400rpx; */ +} \ No newline at end of file diff --git a/pages/course/course.js b/pages/course/course.js index 38bb115..6801569 100644 --- a/pages/course/course.js +++ b/pages/course/course.js @@ -46,7 +46,7 @@ Page({ }); }}).catch(err=>{ tt.showToast({ - title: err.message, // 内容 + title: err.message?err.message:err.data, icon:"none" }); }) @@ -64,6 +64,9 @@ Page({ }) }, search() { + tt.showLoading({ + title: '加载中...', // 内容 + }); Http.get({ url: config.api.getOrderLsit, data: { @@ -85,6 +88,13 @@ Page({ list: res.data.list }) } + tt.hideLoading(); + }).catch(err=>{ + tt.hideLoading(); + tt.showToast({ + title: err.message?err.message:err.data, // 内容 + icon:"none" + }); }) }, onLoad() { diff --git a/pages/course/course.ttml b/pages/course/course.ttml index 58556ed..b329287 100644 --- a/pages/course/course.ttml +++ b/pages/course/course.ttml @@ -124,6 +124,7 @@ + 您暂未购买此课程! diff --git a/pages/course/course.ttss b/pages/course/course.ttss index f1ba536..1430ef7 100644 --- a/pages/course/course.ttss +++ b/pages/course/course.ttss @@ -168,7 +168,7 @@ width: 350rpx; height: 40rpx; line-height: 40rpx; - font-size: 36rpx; + font-size: 32rpx; font-family: PingFang SC; font-weight: 500; color: #FEFEFE; @@ -195,27 +195,34 @@ -webkit-line-clamp:1; } .moreBox{ + width: 340rpx; margin-top: 30rpx; position: relative; } .user{ - float: left; - width: 60rpx; - height: 60rpx; + position: absolute; + + width: 50rpx; + height: 50rpx; border-radius: 50%; - background-color: beige; + top: 0; + left: 0; } .userText{ - width: 200rpx; - text-align: center; - height: 60rpx; - line-height: 60rpx; - background: #222735; + padding-left:70rpx ; + padding-right:50rpx ; + float: left; border-radius: 50rpx; - font-family: PingFang SC; - font-weight: 500; - font-size: 26rpx; - color: #8790A8; + height: 50rpx; + background-color: #333; + text-align: center; + line-height: 50rpx; + color: #9999cc; + overflow:hidden; + text-overflow:ellipsis; + display:-webkit-box; + -webkit-box-orient:vertical; + -webkit-line-clamp:1 } .show{ position: absolute; @@ -242,6 +249,12 @@ height: 400rpx; margin-top: 200rpx; } +.noDataText{ + position: absolute; + color: #9999cc; + top: 730rpx; + left: 35%; +} .instrumentBox{ width: 100%; background: #1F232E; diff --git a/pages/index/index.js b/pages/index/index.js index 73089a4..be3cfa9 100644 --- a/pages/index/index.js +++ b/pages/index/index.js @@ -1,5 +1,6 @@ const app = getApp() const config = require("../../config/config") +const { log } = require("../../utils/HttpBasics.js") const Http = require("../../utils/HttpBasics.js") const navigationBarHeight = (getApp().statusBarHeight + 44) + "px" const convert = require("../../utils/util.js") @@ -29,11 +30,18 @@ Page({ }); }, goPublicity(e) { + let id = e.currentTarget.dataset.id let type = e.currentTarget.dataset.type - tt.navigateTo({ - url: `/pages/publicity/publicity?id=${id}&type=${type}` // 指定页面的url - }); + if(type==4){ + tt.navigateTo({ + url: `/pages/upEnter/upEnter` // 指定页面的url + }); + }else{ + tt.navigateTo({ + url: `/pages/publicity/publicity?id=${id}&type=${type}` // 指定页面的url + }); + } }, getNweDataLsit() {//今天推荐 Http.get({ @@ -150,7 +158,7 @@ Page({ url: config.api.getAuthor, data: { pageNum: this.data.authoPageNum, - pageSize: 4, + pageSize: 7, mark: 1, sortColumn: "markTime", sortOrder: "desc" diff --git a/pages/index/index.ttml b/pages/index/index.ttml index 2bbcaaa..1c9ba3d 100644 --- a/pages/index/index.ttml +++ b/pages/index/index.ttml @@ -1,95 +1,79 @@ - - - - - - - 搜索 - - - + + + + + + + 搜索 + + - - - - {{item.title}} - - - - + + + + {{item.title}} + + + + - - - - - - - + + + + + + + + + + + + 最新上架 - - - - - - 最新上架 - - - - - - - 精选课程 - - - - - - - 排行榜 - - - - - - - 全部分类 - - + + + + + 精选课程 - - - - - - 今日推荐 - - - - - - - - {{item.businessName}} - - - - - - {{item.title}} - - - - + + + + + 排行榜 + + + + + + 全部分类 + + + + + + + + + 今日推荐 + + + + + + + + {{item.businessName}} - + + + + + + + 精选内容 - - - - - - - 精选内容 - + + + + + + + + 最近人气 - - - - - - - 最近人气 - - - {{item.popularity}} - - - - - - - {{item.title}} - - - - - - {{item.merchantName}} - - - - - - - ¥ - - - {{item.salePriceStr}} - - - 免费 - - - - - - - - + + {{item.popularity}} + + + + + + {{item.title}} + + + + + + {{item.merchantName}} + + + + + ¥ + + + {{item.salePriceStr}} + + + 免费 + + + + - - - - - 查看更多 - - - - - - - + + + + + + + + 推荐作者 - - - - - - 推荐作者 - + + + + + + + + {{item.name}} + + {{item.authoRemark}} + + + + + - - - - - - - - {{item.name}} - - - {{item.authoRemark}} - - - - - - - - + + + + + 热门排行 - - - - - - - 热门排行 - + + + + + + + {{index+1}} - - - - - - {{index+1}} - - - - - - {{item.title}} - - - - - - 人 气 - - - {{item.popularity}} - - - - - - - - - + + + {{item.title}} + + + + + + 人 气 - - - - - + - - - - - 最新内容 - + + + + + 最新内容 + + + + + + + + + + 最近人气 - - - - - - - - 最近人气 - - - {{item.popularity}} - - - - - - - {{item.title}} - - - - - - {{item.merchantName}} - - - - - - ¥ - - - {{item.salePriceStr}} - - - 免费 - - - - - - - - + + {{item.popularity}} + + + + + + {{item.title}} + + + + + + {{item.merchantName}} + + + + + ¥ + + + {{item.salePriceStr}} + + + 免费 + - - - - - 查看更多 - - - - - - - - + - - - - \ No newline at end of file + + diff --git a/pages/index/index.ttss b/pages/index/index.ttss index f5b2f5a..46d5e50 100644 --- a/pages/index/index.ttss +++ b/pages/index/index.ttss @@ -10,6 +10,7 @@ } .topBox{ height: 70rpx; + line-height: 20rpx; color: #666666; margin-top: 10rpx; } @@ -34,7 +35,9 @@ margin-left: 12rpx; } .item{ - width: 80rpx; + /* width: 80rpx; */ + height: 60rpx; + height: 60rpx; margin: 0 20rpx; position: relative; display: inline-block; @@ -43,8 +46,10 @@ .title_a{ font-size: 34rpx; color: #00cc99; + padding-bottom: 10rpx; } .title{ + line-height: 60rpx; color: #666666; } .wire{ @@ -367,6 +372,11 @@ overflow: hidden; text-align: center; line-height: 50rpx; color: #9999cc; + overflow:hidden; + text-overflow:ellipsis; + display:-webkit-box; + -webkit-box-orient:vertical; + -webkit-line-clamp:1 } .introduce{ width: 96%; @@ -455,6 +465,11 @@ overflow: hidden; font-family: OPPOSans; font-weight: 500; color: #FFFFFF; + overflow:hidden; + text-overflow:ellipsis; + display:-webkit-box; + -webkit-box-orient:vertical; + -webkit-line-clamp:1; } .authorText{ width: 90%; diff --git a/pages/integral/integral.js b/pages/integral/integral.js new file mode 100644 index 0000000..5b7ffd9 --- /dev/null +++ b/pages/integral/integral.js @@ -0,0 +1,41 @@ +const app = getApp() +const config = require("../../config/config") +const Http = require("../../utils/HttpBasics.js") +const navigationBarHeight = (getApp().statusBarHeight + 44)+"px" +Page({ + data:{ + imgHttps:app.globalData.imgHttps, + navigationBarHeight, + list:[ + { + title:"积分充值", + type: 1, + id:123102410, + tiem:"2020-11-03", + num:2354121551, + }, + { + title:"积分消费", + type: 2, + id:1231023234, + tiem:"2020-10-03", + num:23545, + }, + { + title:"积分充值", + type: 1, + id:123104432, + tiem:"2020-11-03", + num:111, + }, + { + title:"积分充值", + type: 1, + id:1231422342, + tiem:"2020-11-03", + num:23, + }, + + ] + } +}) \ No newline at end of file diff --git a/pages/integral/integral.json b/pages/integral/integral.json new file mode 100644 index 0000000..c225e52 --- /dev/null +++ b/pages/integral/integral.json @@ -0,0 +1,6 @@ +{ + "navigationBarTitleText": "我的积分", + "usingComponents": { + "navbar": "../../components/navbar/navbar" + } +} \ No newline at end of file diff --git a/pages/integral/integral.ttml b/pages/integral/integral.ttml new file mode 100644 index 0000000..d64c432 --- /dev/null +++ b/pages/integral/integral.ttml @@ -0,0 +1,29 @@ + + + + + 积分余额 + 20151111.20 + 积分收支明细 + + + + + {{item.title}} + 订单编号:{{item.id}} + {{item.tiem}} + + + + +{{item.num}} + + + -{{item.num}} + + + + + + + + diff --git a/pages/integral/integral.ttss b/pages/integral/integral.ttss new file mode 100644 index 0000000..944d5a8 --- /dev/null +++ b/pages/integral/integral.ttss @@ -0,0 +1,61 @@ +.Box{ + /* overflow: hidden; */ +} +.limit{ + font-size: 32rpx; + text-align: center; + font-weight: 600; + color: #ffffff; + margin-top: 20rpx; +} +.balance{ + font-size: 38rpx; + text-align: center; + color: #07E881; + font-weight: 600; + margin-top: 20rpx; +} +.detail{ + width: 90%; + text-align: center; + padding: 6rpx 0; + color: #ffffff; + margin: 10rpx auto; + border-bottom: solid 1rpx #ffffff; + font-size: 26rpx; +} +.itemBox{ + width: 96%; + margin: 20rpx 2%; + color: #ffffff; + overflow: hidden; +} +.leftBox{ + float: left; + height: 120rpx; +} +.order{ + font-size: 26rpx; +} +.orderTiem{ + font-size: 26rpx; +} + +.rightBox{ + line-height: 120rpx; + float: right; + color: #07E881; + font-size: 34rpx; +} +.addright{ + line-height: 120rpx; + float: right; + color: red; + font-size: 34rpx; +} +.segmentation{ + width: 80%; + background-color: rgba(255,255,255,0.3); + height: 1rpx; + margin: 10rpx auto; +} diff --git a/pages/mianCollect/mianCollect.js b/pages/mianCollect/mianCollect.js index 61d4997..79f40d5 100644 --- a/pages/mianCollect/mianCollect.js +++ b/pages/mianCollect/mianCollect.js @@ -58,6 +58,9 @@ Page({ }) }, search() { + tt.showLoading({ + title: '加载中...', // 内容 + }); Http.get({ url: config.api.mainCollet, data: { @@ -78,6 +81,13 @@ Page({ list: res.data.list }) } + tt.hideLoading(); + }).catch(err=>{ + tt.hideLoading(); + tt.showToast({ + title: err.message?err.message:err.data, // 内容 + icon:"none" + }); }) }, onLoad() { diff --git a/pages/mianCollect/mianCollect.ttss b/pages/mianCollect/mianCollect.ttss index bd7f78a..e9bec20 100644 --- a/pages/mianCollect/mianCollect.ttss +++ b/pages/mianCollect/mianCollect.ttss @@ -77,13 +77,17 @@ position: relative; } .user{ - float: left; + position: absolute; + width: 50rpx; height: 50rpx; border-radius: 50%; - background-color: beige; + top: 0; + left: 0; } .userText{ + padding-left:50rpx ; + padding-right:20rpx ; width: 200rpx; text-align: center; height: 50rpx; @@ -94,6 +98,11 @@ font-weight: 500; font-size: 26rpx; color: #8790A8; + overflow:hidden; + text-overflow:ellipsis; + display:-webkit-box; + -webkit-box-orient:vertical; + -webkit-line-clamp:1 } .show{ position: absolute; diff --git a/pages/order/order.js b/pages/order/order.js index fd66497..f4cae2d 100644 --- a/pages/order/order.js +++ b/pages/order/order.js @@ -2,7 +2,8 @@ const app = getApp() const navigationBarHeight = (getApp().statusBarHeight + 44) + "px" const config = require("../../config/config") const util = require("../../utils/util"); -const Http = require("../../utils/HttpBasics.js") +const Http = require("../../utils/HttpBasics.js"); + Page({ data: { navigationBarHeight, @@ -115,7 +116,7 @@ Page({ }) }).catch(err => { tt.showToast({ - title: '唤起支付失败', // 内容 + title: err.message?err.message:err.data, // 内容 icon: "none" }); }) @@ -135,7 +136,6 @@ Page({ } else {//已支付 tempArr.push(...[2, 4, 5, 6]) } - console.log(tempArr); Http.get({ url: config.api.getOrderLsit, data: { @@ -149,13 +149,11 @@ Page({ item.createDate = util.formatTime(item.createDate, "yyyy-MM-dd hh:mm:ss") }) if(this.data.pageNum>1){ - let tempLsit = this.data.orderLsit - let tempArr = tempLsit.push(...arr) - + let tempArrLsit = [...tempLsit,...arr] this.setData({ - orderLsit:tempArr, - noDAtaFlag:tempArr.length==0?true: false, + orderLsit:tempArrLsit, + noDAtaFlag:tempArrLsit.length==0?true: false, }) }else{ this.setData({ diff --git a/pages/order/order.ttss b/pages/order/order.ttss index 3af6e25..8ea27d0 100644 --- a/pages/order/order.ttss +++ b/pages/order/order.ttss @@ -101,6 +101,11 @@ text-align: center; text-align: center; line-height: 50rpx; color: #9999cc; + overflow:hidden; + text-overflow:ellipsis; + display:-webkit-box; + -webkit-box-orient:vertical; + -webkit-line-clamp:1 } .name{ width: 220rpx; diff --git a/pages/publicity/publicity.js b/pages/publicity/publicity.js index 0548eda..fa59e0f 100644 --- a/pages/publicity/publicity.js +++ b/pages/publicity/publicity.js @@ -2,7 +2,7 @@ const app = getApp() const config = require("../../config/config") const Http = require("../../utils/HttpBasics.js") const navigationBarHeight = (getApp().statusBarHeight + 44)+"px" -var WxParse = require('../../wxParse/wxParse.js'); +// var WxParse = require('../../wxParse/wxParse.js'); const convert = require("../../utils/util.js") Page({ data:{ @@ -33,22 +33,6 @@ Page({ }); }) }, - getHtml(id ,that){ - tt.request({ - url: 'https://ttctest.malls.iformall.com/tt/api/wxCampaign/printHtmlById', // 目标服务器url - data:{ - token: app.globalData.token, - id:id, - date: new Date() - }, - header: { - 'content-type': 'application/html' - }, - success: (res) => { - var temp = WxParse.wxParse('article', 'html', res.data, that, 5); - } - }); - }, goXq(e){//跳转详情 let id = e.currentTarget.dataset.id let title = e.currentTarget.dataset.title @@ -58,20 +42,18 @@ Page({ }); }, onLoad:function (params) { - const that = this; - console.log(params.id); if(params.id &¶ms.type==1){//宣传页 - that.setData({ + this.setData({ id:params.id, type:params.type }) - that.getData() + this.getData() }else if(params.id &¶ms.type==2){//图文 - that.setData({ + this.setData({ id:params.id, type:params.type }) - that.getHtml(params.id,that) + this.getData() } }, }) \ No newline at end of file diff --git a/pages/publicity/publicity.ttml b/pages/publicity/publicity.ttml index 8ee3055..e8c2480 100644 --- a/pages/publicity/publicity.ttml +++ b/pages/publicity/publicity.ttml @@ -41,9 +41,12 @@ - + + + + \ No newline at end of file diff --git a/pages/publicity/publicity.ttss b/pages/publicity/publicity.ttss index 88512a5..dc0a452 100644 --- a/pages/publicity/publicity.ttss +++ b/pages/publicity/publicity.ttss @@ -95,6 +95,11 @@ text-align: center; line-height: 50rpx; color: #9999cc; + overflow:hidden; + text-overflow:ellipsis; + display:-webkit-box; + -webkit-box-orient:vertical; + -webkit-line-clamp:1 } .incomeBox{ margin-top: 20rpx; @@ -176,4 +181,19 @@ line-height: 46rpx; top: 0rpx; left: 20rpx; +} +.richtextBox{ + margin-top: 40rpx; + min-height: 120rpx; +} +.rich_text{ + width: 100%; + height: 100%; +} +.rich_text p{ + width: 100%; +} +rich-text img{ + width: 100%; + /* max-height: 400rpx; */ } \ No newline at end of file diff --git a/pages/ranking/ranking.ttss b/pages/ranking/ranking.ttss index c3b5a34..05f857c 100644 --- a/pages/ranking/ranking.ttss +++ b/pages/ranking/ranking.ttss @@ -91,6 +91,10 @@ text-align: center; line-height: 50rpx; color: #9999cc; + text-overflow:ellipsis; + display:-webkit-box; + -webkit-box-orient:vertical; + -webkit-line-clamp:1 } .incomeBox{ margin-top: 10rpx; diff --git a/pages/search/search.js b/pages/search/search.js index c37ddb0..3a664a6 100644 --- a/pages/search/search.js +++ b/pages/search/search.js @@ -23,7 +23,6 @@ Page({ this.setData({ activityFlag:index, pageNum:1, - inputValue:"", noDAtaFlag:false, list:[] }) @@ -44,6 +43,9 @@ Page({ this.search() }, search(){//查询 + tt.showLoading({ + title: '加载中...', // 内容 + }); let url = "" let data="" if(this.data.activityFlag==0){//课程 @@ -66,7 +68,6 @@ Page({ data:data }).then(res=>{ let arr = [] - if(res.data.list!=0&&res.data.list[0].businessTypes){ arr = res.data.list let sting = "" @@ -82,45 +83,70 @@ Page({ }) let tempArr = this.data.list if(this.data.pageNum>1){ - let contArr= tempArr.push(...arr) + // let contArr= tempArr.push(...arr) this.setData({ - list:arr, - noDAtaFlag:contArr.length==0?true:false + list:[...tempArr,...res.data.list], }) + if(this.data.list.length==0){ + this.setData({ + noDAtaFlag:true + }) + }else{ + this.setData({ + noDAtaFlag:false + }) + } }else{ this.setData({ list:arr, noDAtaFlag:arr.length==0?true:false }) } - + tt.hideLoading(); }else{ - if(this.pageNum>1){ + if(this.data.pageNum>1){ let tempArr = this.data.list - let contArr= tempArr.push(...res.data.list) - + // let contArr= tempArr.push(...res.data.list) + // console.log(contArr,"contArr"); this.setData({ - list:tempArr, - noDAtaFlag:contArr.length==0?true:false + list:[...tempArr,...res.data.list], }) + if(this.data.list.length==0){ + this.setData({ + noDAtaFlag:true + }) + }else{ + this.setData({ + noDAtaFlag:false + }) + } + }else{ this.setData({ list:res.data.list, noDAtaFlag:res.data.list==0?true:false }) } - + tt.hideLoading(); } + }).catch(err=>{ + tt.hideLoading(); + tt.showToast({ + title: err.message?err.message:err.data, // 内容 + icon:"none" + }); }) - console.log(this.data.list); + // console.log(this.data.list); }, onLoad(){ this.search() }, onReachBottom:function(){ + console.log("到底了"); this.setData({ pageNum:this.data.pageNum+1 }) + this.search() } }) \ No newline at end of file diff --git a/pages/search/search.ttml b/pages/search/search.ttml index a617dc9..3c8a920 100644 --- a/pages/search/search.ttml +++ b/pages/search/search.ttml @@ -1,43 +1,43 @@ - + - - - - - - - - - 搜索 - - - - - - - 推荐搜索 - - - - 锻炼的协调,炼的协调炼的协调炼的协调 - - - - + + + + + + + + 搜索 + + + + + + 推荐搜索 + + + + 锻炼的协调,炼的协调炼的协调炼的协调 + + + + + + + + + + 课程 + + + + + + 作者 + + + - - - - - 课程 - - - - - - - - - 作者 - - - - - - - - - + + + + + + + + {{item.title}} + + + + + {{item.merchantName}} + - - - - - - - - {{item.title}} - - - - {{item.merchantName}} - - - - - ¥ - - - {{item.salePriceStr}} - - - - - - - - - - {{item.name}} - - - - {{item.authoRemark}} - - - - - - - - + - - - - - - - - - - - - - - - + + + + + + + + - \ No newline at end of file diff --git a/pages/search/search.ttss b/pages/search/search.ttss index 88ebbdd..338208d 100644 --- a/pages/search/search.ttss +++ b/pages/search/search.ttss @@ -1,5 +1,5 @@ .Box{ - height: 100vh; + /* height: 100vh; */ overflow: scroll; min-height: 100vh; } @@ -92,13 +92,7 @@ border-radius: 50%; margin: 20rpx auto; } -.name{ - line-height: 72rpx; - text-align: center; - color: #ffffff; - font-size: 36rpx; - text-align: center; -} + .categoryBox{ display: flex; justify-content: center; @@ -183,21 +177,30 @@ -webkit-line-clamp:1; } .headImg{ + position: absolute; + width: 50rpx; height: 50rpx; border-radius: 50%; - float: left; + top: 0; + left: 0; } .name{ - width: 220rpx; - line-height: 50rpx; - height: 50rpx; + padding-left:70rpx ; + padding-right:50rpx ; + float: left; border-radius: 50rpx; - color: #8790A8; + height: 50rpx; + background-color: #333; text-align: center; - background-color: #222735; - font-size: 28rpx; + line-height: 50rpx; + color: #9999cc; + overflow:hidden; + text-overflow:ellipsis; + display:-webkit-box; + -webkit-box-orient:vertical; + -webkit-line-clamp:1 } .priceBox{ /* margin-top: 20rpx; */ diff --git a/pages/user/user.js b/pages/user/user.js index 9e533dc..3251a91 100644 --- a/pages/user/user.js +++ b/pages/user/user.js @@ -4,84 +4,172 @@ const config = require("../../config/config") const Http = require("../../utils/HttpBasics.js") const navigationBarHeight = (getApp().statusBarHeight + 44) + "px" Page({ - data: { - navigationBarHeight, - imgHttps: app.globalData.imgHttps, - userData: "", - }, + data: { + navigationBarHeight, + imgHttps: app.globalData.imgHttps, + userData: "", + userPhone: "", + showBindPhone: false,//绑定手机号边框 + Num: 60, + NumFlag: false, + code: ""//验证码 + }, + showBox() { + this.setData({ + showBindPhone: true + }) + }, + hideBox() { + this.setData({ + showBindPhone: false + }) + }, + setUserPhone(e) { + let value = e.detail.value + this.setData({ + userPhone: value + }) + }, + setCodePhone(e) { + let value = e.detail.value + this.setData({ + code: value + }) + }, + getCode() {//获取验证码 + console.log(this.data.userPhone); + let myreg = /^[1][3,4,5,7,8,9][0-9]{9}$/; + if (!myreg.test(this.data.userPhone)) { + tt.showToast({ + title: '请输入正确的手机号', + icon: "none" + }); + return + } + Http.get({ + url: config.api.getCodePhone, + data: { + phone: this.data.userPhone + } + }).then(res => { + this.setData({ + NumFlag: true + }) + let tiem = setInterval(() => { + console.log(this.data.Num) + this.setData({ + Num: this.data.Num - 1 + }) + if (this.data.Num <= 1) { + clearInterval(tiem) + this.setData({ + NumFlag: false + }) + } + }, 1000) - onLoad: function () { - console.log(123); - let _this = this - tt.login({ - success(_res) { - let {code} = _res - Http.post({ - url:config.api.login, - data:{ - code:code, - appId:'tt8183f73e1ebb053701' - } - }).then(res=>{ - Http.setToken(res.data.token); - app.globalData.token = res.data.token - tt.getUserInfo({// 获取用户信息 - withCredentials: true, - // withRealNameAuthenticationInfo: true, - success(res) { - console.log(res); - _this.setData({ - userData: res.userInfo - }) - - Http.get({ - url: config.api.checkUserInfo - }).then(res => { - }).catch(err=>{ - console.log("我没提交授权",err.code); - if(err.code == 11004){ - Http.post({ - url:config.api.userInfo, - data:{ - iv:res.iv, - encryptedData:res.encryptedData - } - }).then(res=>{ - console.log(res); - }) - } - }) - - }, - fail(res) { - tt.navigateTo({ - url: 'pages/index/index' // 指定页面的url - }); - }, - }); + tt.showToast({ + title: '发送成功', + icon: "none" + }); + }).catch(err => { + tt.showToast({ + title: err.message ? err.message : err.data, + icon: "none" + }); + }) + }, + + getUserData() {//获取用户信息 + Http.get({ + url:config.api.getUserInfo + }).then(res=>{ + if(res.data.phone){ + this.setData({ + userPhone:res.data.phone + }) + } + }).catch(err=>{ + tt.showToast({ + title: err.message ? err.message : err.data, + icon: "none" + }); + }) + }, - }).catch(err=>{ - console.log(err); - tt.showModal({ - title: '提示', - showCancel: false, - content: '登录失败,请重新尝试', - success: (res) => { - if (res.cancel) { - //点击取消,默认隐藏弹框 - } else { - //点击确定 - wx.reLaunch({ - url: '/pages/index/index', - }) - } - } - }); + onLoad: function () { + console.log(123); + this.getUserData() + let _this = this + tt.login({ + success(_res) { + let { code } = _res + Http.post({ + url: config.api.login, + data: { + code: code, + appId: 'tt8183f73e1ebb053701' + } + }).then(res => { + Http.setToken(res.data.token); + app.globalData.token = res.data.token + tt.getUserInfo({// 获取用户信息 + withCredentials: true, + // withRealNameAuthenticationInfo: true, + success(res) { + console.log(res); + _this.setData({ + userData: res.userInfo + }) + + Http.get({ + url: config.api.checkUserInfo + }).then(res => { + }).catch(err => { + console.log("我没提交授权", err.code); + if (err.code == 11004) { + Http.post({ + url: config.api.userInfo, + data: { + iv: res.iv, + encryptedData: res.encryptedData + } + }).then(res => { + console.log(res); }) - - - + } + }) + }, - }); - } + fail(res) { + tt.navigateTo({ + url: 'pages/index/index' // 指定页面的url + }); + }, + }); + + }).catch(err => { + console.log(err); + tt.showModal({ + title: '提示', + showCancel: false, + content: '登录失败,请重新尝试', + success: (res) => { + if (res.cancel) { + //点击取消,默认隐藏弹框 + } else { + //点击确定 + wx.reLaunch({ + url: '/pages/index/index', + }) + } + } + }); + }) + + + + }, + }); + } }) \ No newline at end of file diff --git a/pages/user/user.ttml b/pages/user/user.ttml index 3eac9e3..c217e72 100644 --- a/pages/user/user.ttml +++ b/pages/user/user.ttml @@ -16,11 +16,12 @@ - - + + + {{phoneNum}} + {{phoneNum?'更改绑定手机号':'绑定手机号'}} + /ig, '') - .replace(/\/\*.*?\*\//ig, '') - .replace(/[ ]+{ - if(item.name == 'src'){ - embUrl = item.value - } - }) - // if (node.attr.src.indexOf('http:')==-1){ - // embUrl = "http://xxxx.com" + node.attr.src; - // } - node.attr.src = embUrl; - node.tag='video'; - } - if (bufArray.length === 0) { - node.index = index.toString() - index += 1 - } else { - var parent = bufArray[0]; - if (parent.nodes === undefined) { - parent.nodes = []; - } - node.index = parent.index + '.' + parent.nodes.length - } - - if (block[tag]) { - node.tagType = "block"; - } else if (inline[tag]) { - node.tagType = "inline"; - } else if (closeSelf[tag]) { - node.tagType = "closeSelf"; - } - - if (attrs.length !== 0) { - node.attr = attrs.reduce(function (pre, attr) { - var name = attr.name; - var value = attr.value; - if (name == 'class') { - console.dir(value); - // value = value.join("") - node.classStr = value; - } - // has multi attibutes - // make it array of attribute - if (name == 'style') { - console.dir(value); - // value = value.join("") - node.styleStr = value; - } - if (value.match(/ /)) { - value = value.split(' '); - } - - - // if attr already exists - // merge it - if (pre[name]) { - if (Array.isArray(pre[name])) { - // already array, push to last - pre[name].push(value); - } else { - // single value, make it array - pre[name] = [pre[name], value]; - } - } else { - // not exist, put it - pre[name] = value; - } - - return pre; - }, {}); - } - - //对img添加额外数据 - if (node.tag === 'img') { - node.imgIndex = results.images.length; - var imgUrl = node.attr.src; - if (imgUrl[0] == '') { - imgUrl.splice(0, 1); - } - imgUrl = wxDiscode.urlToHttpUrl(imgUrl, __placeImgeUrlHttps); - node.attr.src = imgUrl; - node.from = bindName; - results.images.push(node); - results.imageUrls.push(imgUrl); - } - - // 处理font标签样式属性 - if (node.tag === 'font') { - var fontSize = ['x-small', 'small', 'medium', 'large', 'x-large', 'xx-large', '-webkit-xxx-large']; - var styleAttrs = { - 'color': 'color', - 'face': 'font-family', - 'size': 'font-size' - }; - if (!node.attr.style) node.attr.style = []; - if (!node.styleStr) node.styleStr = ''; - for (var key in styleAttrs) { - if (node.attr[key]) { - var value = key === 'size' ? fontSize[node.attr[key]-1] : node.attr[key]; - node.attr.style.push(styleAttrs[key]); - node.attr.style.push(value); - node.styleStr += styleAttrs[key] + ': ' + value + ';'; - } - } - } - - //临时记录source资源 - if(node.tag === 'source'){ - results.source = node.attr.src; - } - - if (unary) { - // if this tag doesn't have end tag - // like - // add to parents - var parent = bufArray[0] || results; - if (parent.nodes === undefined) { - parent.nodes = []; - } - parent.nodes.push(node); - } else { - bufArray.unshift(node); - } - }, - end: function (tag) { - //debug(tag); - // merge into parent tag - var node = bufArray.shift(); - if (node.tag !== tag) console.error('invalid state: mismatch end tag'); - - //当有缓存source资源时于于video补上src资源 - if(node.tag === 'video' && results.source){ - node.attr.src = results.source; - delete results.source; - } - - if (bufArray.length === 0) { - results.nodes.push(node); - } else { - var parent = bufArray[0]; - if (parent.nodes === undefined) { - parent.nodes = []; - } - parent.nodes.push(node); - } - }, - chars: function (text) { - //debug(text); - var node = { - node: 'text', - text: text, - textArray:transEmojiStr(text) - }; - - if (bufArray.length === 0) { - node.index = index.toString() - index += 1 - results.nodes.push(node); - } else { - var parent = bufArray[0]; - if (parent.nodes === undefined) { - parent.nodes = []; - } - node.index = parent.index + '.' + parent.nodes.length - parent.nodes.push(node); - } - }, - comment: function (text) { - //debug(text); - // var node = { - // node: 'comment', - // text: text, - // }; - // var parent = bufArray[0]; - // if (parent.nodes === undefined) { - // parent.nodes = []; - // } - // parent.nodes.push(node); - }, - }); - return results; -}; - -function transEmojiStr(str){ - // var eReg = new RegExp("["+__reg+' '+"]"); -// str = str.replace(/\[([^\[\]]+)\]/g,':$1:') - - var emojiObjs = []; - //如果正则表达式为空 - if(__emojisReg.length == 0 || !__emojis){ - var emojiObj = {} - emojiObj.node = "text"; - emojiObj.text = str; - array = [emojiObj]; - return array; - } - //这个地方需要调整 - str = str.replace(/\[([^\[\]]+)\]/g,':$1:') - var eReg = new RegExp("[:]"); - var array = str.split(eReg); - for(var i = 0; i < array.length; i++){ - var ele = array[i]; - var emojiObj = {}; - if(__emojis[ele]){ - emojiObj.node = "element"; - emojiObj.tag = "emoji"; - emojiObj.text = __emojis[ele]; - emojiObj.baseSrc= __emojisBaseSrc; - }else{ - emojiObj.node = "text"; - emojiObj.text = ele; - } - emojiObjs.push(emojiObj); - } - - return emojiObjs; -} - -function emojisInit(reg='',baseSrc="/wxParse/emojis/",emojis){ - __emojisReg = reg; - __emojisBaseSrc=baseSrc; - __emojis=emojis; -} - -module.exports = { - html2json: html2json, - emojisInit:emojisInit -}; - diff --git a/wxParse/htmlparser.js b/wxParse/htmlparser.js deleted file mode 100644 index 811ddac..0000000 --- a/wxParse/htmlparser.js +++ /dev/null @@ -1,192 +0,0 @@ -/** - * - * htmlParser改造自: https://github.com/blowsie/Pure-JavaScript-HTML5-Parser - * - * author: Di (微信小程序开发工程师) - * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) - * 垂直微信小程序开发交流社区 - * - * github地址: https://github.com/icindy/wxParse - * - * for: 微信小程序富文本解析 - * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 - */ -// Regular Expressions for parsing tags and attributes -var startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/, - endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/, - attr = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; - -// Empty Elements - HTML 5 -var empty = makeMap("area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr"); - -// Block Elements - HTML 5 -var block = makeMap("a,address,code,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video"); - -// Inline Elements - HTML 5 -var inline = makeMap("abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var"); - -// Elements that you can, intentionally, leave open -// (and which close themselves) -var closeSelf = makeMap("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr"); - -// Attributes that have their values filled in disabled="disabled" -var fillAttrs = makeMap("checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected"); - -// Special Elements (can contain anything) -var special = makeMap("wxxxcode-style,script,style,view,scroll-view,block"); - -function HTMLParser(html, handler) { - var index, chars, match, stack = [], last = html; - stack.last = function () { - return this[this.length - 1]; - }; - - while (html) { - chars = true; - - // Make sure we're not in a script or style element - if (!stack.last() || !special[stack.last()]) { - - // Comment - if (html.indexOf(""); - - if (index >= 0) { - if (handler.comment) - handler.comment(html.substring(4, index)); - html = html.substring(index + 3); - chars = false; - } - - // end tag - } else if (html.indexOf("]*>"), function (all, text) { - text = text.replace(/|/g, "$1$2"); - if (handler.chars) - handler.chars(text); - - return ""; - }); - - - parseEndTag("", stack.last()); - } - - if (html == last) - throw "Parse Error: " + html; - last = html; - } - - // Clean up any remaining tags - parseEndTag(); - - function parseStartTag(tag, tagName, rest, unary) { - tagName = tagName.toLowerCase(); - - if (block[tagName]) { - while (stack.last() && inline[stack.last()]) { - parseEndTag("", stack.last()); - } - } - - if (closeSelf[tagName] && stack.last() == tagName) { - parseEndTag("", tagName); - } - - unary = empty[tagName] || !!unary; - - if (!unary) - stack.push(tagName); - - if (handler.start) { - var attrs = []; - - rest.replace(attr, function (match, name) { - var value = arguments[2] ? arguments[2] : - arguments[3] ? arguments[3] : - arguments[4] ? arguments[4] : - fillAttrs[name] ? name : ""; - - attrs.push({ - name: name, - value: value, - escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') //" - }); - }); - - if (handler.start) { - handler.start(tagName, attrs, unary); - } - - } - } - - function parseEndTag(tag, tagName) { - // If no tag name is provided, clean shop - if (!tagName) - var pos = 0; - - // Find the closest opened tag of the same type - else { - tagName = tagName.toLowerCase(); - for (var pos = stack.length - 1; pos >= 0; pos--) - if (stack[pos] == tagName) - break; - } - if (pos >= 0) { - // Close all the open elements, up the stack - for (var i = stack.length - 1; i >= pos; i--) - if (handler.end) - handler.end(stack[i]); - - // Remove the open elements from the stack - stack.length = pos; - } - } -}; - - -function makeMap(str) { - var obj = {}, items = str.split(","); - for (var i = 0; i < items.length; i++) - obj[items[i]] = true; - return obj; -} - -module.exports = HTMLParser; diff --git a/wxParse/showdown.js b/wxParse/showdown.js deleted file mode 100644 index d29206d..0000000 --- a/wxParse/showdown.js +++ /dev/null @@ -1,2532 +0,0 @@ -/** - * - * showdown: https://github.com/showdownjs/showdown - * - * author: Di (微信小程序开发工程师) - * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) - * 垂直微信小程序开发交流社区 - * - * github地址: https://github.com/icindy/wxParse - * - * for: 微信小程序富文本解析 - * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 - */ - -function getDefaultOpts(simple) { - 'use strict'; - - var defaultOptions = { - omitExtraWLInCodeBlocks: { - defaultValue: false, - describe: 'Omit the default extra whiteline added to code blocks', - type: 'boolean' - }, - noHeaderId: { - defaultValue: false, - describe: 'Turn on/off generated header id', - type: 'boolean' - }, - prefixHeaderId: { - defaultValue: false, - describe: 'Specify a prefix to generated header ids', - type: 'string' - }, - headerLevelStart: { - defaultValue: false, - describe: 'The header blocks level start', - type: 'integer' - }, - parseImgDimensions: { - defaultValue: false, - describe: 'Turn on/off image dimension parsing', - type: 'boolean' - }, - simplifiedAutoLink: { - defaultValue: false, - describe: 'Turn on/off GFM autolink style', - type: 'boolean' - }, - literalMidWordUnderscores: { - defaultValue: false, - describe: 'Parse midword underscores as literal underscores', - type: 'boolean' - }, - strikethrough: { - defaultValue: false, - describe: 'Turn on/off strikethrough support', - type: 'boolean' - }, - tables: { - defaultValue: false, - describe: 'Turn on/off tables support', - type: 'boolean' - }, - tablesHeaderId: { - defaultValue: false, - describe: 'Add an id to table headers', - type: 'boolean' - }, - ghCodeBlocks: { - defaultValue: true, - describe: 'Turn on/off GFM fenced code blocks support', - type: 'boolean' - }, - tasklists: { - defaultValue: false, - describe: 'Turn on/off GFM tasklist support', - type: 'boolean' - }, - smoothLivePreview: { - defaultValue: false, - describe: 'Prevents weird effects in live previews due to incomplete input', - type: 'boolean' - }, - smartIndentationFix: { - defaultValue: false, - description: 'Tries to smartly fix identation in es6 strings', - type: 'boolean' - } - }; - if (simple === false) { - return JSON.parse(JSON.stringify(defaultOptions)); - } - var ret = {}; - for (var opt in defaultOptions) { - if (defaultOptions.hasOwnProperty(opt)) { - ret[opt] = defaultOptions[opt].defaultValue; - } - } - return ret; -} - -/** - * Created by Tivie on 06-01-2015. - */ - -// Private properties -var showdown = {}, - parsers = {}, - extensions = {}, - globalOptions = getDefaultOpts(true), - flavor = { - github: { - omitExtraWLInCodeBlocks: true, - prefixHeaderId: 'user-content-', - simplifiedAutoLink: true, - literalMidWordUnderscores: true, - strikethrough: true, - tables: true, - tablesHeaderId: true, - ghCodeBlocks: true, - tasklists: true - }, - vanilla: getDefaultOpts(true) - }; - -/** - * helper namespace - * @type {{}} - */ -showdown.helper = {}; - -/** - * TODO LEGACY SUPPORT CODE - * @type {{}} - */ -showdown.extensions = {}; - -/** - * Set a global option - * @static - * @param {string} key - * @param {*} value - * @returns {showdown} - */ -showdown.setOption = function (key, value) { - 'use strict'; - globalOptions[key] = value; - return this; -}; - -/** - * Get a global option - * @static - * @param {string} key - * @returns {*} - */ -showdown.getOption = function (key) { - 'use strict'; - return globalOptions[key]; -}; - -/** - * Get the global options - * @static - * @returns {{}} - */ -showdown.getOptions = function () { - 'use strict'; - return globalOptions; -}; - -/** - * Reset global options to the default values - * @static - */ -showdown.resetOptions = function () { - 'use strict'; - globalOptions = getDefaultOpts(true); -}; - -/** - * Set the flavor showdown should use as default - * @param {string} name - */ -showdown.setFlavor = function (name) { - 'use strict'; - if (flavor.hasOwnProperty(name)) { - var preset = flavor[name]; - for (var option in preset) { - if (preset.hasOwnProperty(option)) { - globalOptions[option] = preset[option]; - } - } - } -}; - -/** - * Get the default options - * @static - * @param {boolean} [simple=true] - * @returns {{}} - */ -showdown.getDefaultOptions = function (simple) { - 'use strict'; - return getDefaultOpts(simple); -}; - -/** - * Get or set a subParser - * - * subParser(name) - Get a registered subParser - * subParser(name, func) - Register a subParser - * @static - * @param {string} name - * @param {function} [func] - * @returns {*} - */ -showdown.subParser = function (name, func) { - 'use strict'; - if (showdown.helper.isString(name)) { - if (typeof func !== 'undefined') { - parsers[name] = func; - } else { - if (parsers.hasOwnProperty(name)) { - return parsers[name]; - } else { - throw Error('SubParser named ' + name + ' not registered!'); - } - } - } -}; - -/** - * Gets or registers an extension - * @static - * @param {string} name - * @param {object|function=} ext - * @returns {*} - */ -showdown.extension = function (name, ext) { - 'use strict'; - - if (!showdown.helper.isString(name)) { - throw Error('Extension \'name\' must be a string'); - } - - name = showdown.helper.stdExtName(name); - - // Getter - if (showdown.helper.isUndefined(ext)) { - if (!extensions.hasOwnProperty(name)) { - throw Error('Extension named ' + name + ' is not registered!'); - } - return extensions[name]; - - // Setter - } else { - // Expand extension if it's wrapped in a function - if (typeof ext === 'function') { - ext = ext(); - } - - // Ensure extension is an array - if (!showdown.helper.isArray(ext)) { - ext = [ext]; - } - - var validExtension = validate(ext, name); - - if (validExtension.valid) { - extensions[name] = ext; - } else { - throw Error(validExtension.error); - } - } -}; - -/** - * Gets all extensions registered - * @returns {{}} - */ -showdown.getAllExtensions = function () { - 'use strict'; - return extensions; -}; - -/** - * Remove an extension - * @param {string} name - */ -showdown.removeExtension = function (name) { - 'use strict'; - delete extensions[name]; -}; - -/** - * Removes all extensions - */ -showdown.resetExtensions = function () { - 'use strict'; - extensions = {}; -}; - -/** - * Validate extension - * @param {array} extension - * @param {string} name - * @returns {{valid: boolean, error: string}} - */ -function validate(extension, name) { - 'use strict'; - - var errMsg = (name) ? 'Error in ' + name + ' extension->' : 'Error in unnamed extension', - ret = { - valid: true, - error: '' - }; - - if (!showdown.helper.isArray(extension)) { - extension = [extension]; - } - - for (var i = 0; i < extension.length; ++i) { - var baseMsg = errMsg + ' sub-extension ' + i + ': ', - ext = extension[i]; - if (typeof ext !== 'object') { - ret.valid = false; - ret.error = baseMsg + 'must be an object, but ' + typeof ext + ' given'; - return ret; - } - - if (!showdown.helper.isString(ext.type)) { - ret.valid = false; - ret.error = baseMsg + 'property "type" must be a string, but ' + typeof ext.type + ' given'; - return ret; - } - - var type = ext.type = ext.type.toLowerCase(); - - // normalize extension type - if (type === 'language') { - type = ext.type = 'lang'; - } - - if (type === 'html') { - type = ext.type = 'output'; - } - - if (type !== 'lang' && type !== 'output' && type !== 'listener') { - ret.valid = false; - ret.error = baseMsg + 'type ' + type + ' is not recognized. Valid values: "lang/language", "output/html" or "listener"'; - return ret; - } - - if (type === 'listener') { - if (showdown.helper.isUndefined(ext.listeners)) { - ret.valid = false; - ret.error = baseMsg + '. Extensions of type "listener" must have a property called "listeners"'; - return ret; - } - } else { - if (showdown.helper.isUndefined(ext.filter) && showdown.helper.isUndefined(ext.regex)) { - ret.valid = false; - ret.error = baseMsg + type + ' extensions must define either a "regex" property or a "filter" method'; - return ret; - } - } - - if (ext.listeners) { - if (typeof ext.listeners !== 'object') { - ret.valid = false; - ret.error = baseMsg + '"listeners" property must be an object but ' + typeof ext.listeners + ' given'; - return ret; - } - for (var ln in ext.listeners) { - if (ext.listeners.hasOwnProperty(ln)) { - if (typeof ext.listeners[ln] !== 'function') { - ret.valid = false; - ret.error = baseMsg + '"listeners" property must be an hash of [event name]: [callback]. listeners.' + ln + - ' must be a function but ' + typeof ext.listeners[ln] + ' given'; - return ret; - } - } - } - } - - if (ext.filter) { - if (typeof ext.filter !== 'function') { - ret.valid = false; - ret.error = baseMsg + '"filter" must be a function, but ' + typeof ext.filter + ' given'; - return ret; - } - } else if (ext.regex) { - if (showdown.helper.isString(ext.regex)) { - ext.regex = new RegExp(ext.regex, 'g'); - } - if (!ext.regex instanceof RegExp) { - ret.valid = false; - ret.error = baseMsg + '"regex" property must either be a string or a RegExp object, but ' + typeof ext.regex + ' given'; - return ret; - } - if (showdown.helper.isUndefined(ext.replace)) { - ret.valid = false; - ret.error = baseMsg + '"regex" extensions must implement a replace string or function'; - return ret; - } - } - } - return ret; -} - -/** - * Validate extension - * @param {object} ext - * @returns {boolean} - */ -showdown.validateExtension = function (ext) { - 'use strict'; - - var validateExtension = validate(ext, null); - if (!validateExtension.valid) { - console.warn(validateExtension.error); - return false; - } - return true; -}; - -/** - * showdownjs helper functions - */ - -if (!showdown.hasOwnProperty('helper')) { - showdown.helper = {}; -} - -/** - * Check if var is string - * @static - * @param {string} a - * @returns {boolean} - */ -showdown.helper.isString = function isString(a) { - 'use strict'; - return (typeof a === 'string' || a instanceof String); -}; - -/** - * Check if var is a function - * @static - * @param {string} a - * @returns {boolean} - */ -showdown.helper.isFunction = function isFunction(a) { - 'use strict'; - var getType = {}; - return a && getType.toString.call(a) === '[object Function]'; -}; - -/** - * ForEach helper function - * @static - * @param {*} obj - * @param {function} callback - */ -showdown.helper.forEach = function forEach(obj, callback) { - 'use strict'; - if (typeof obj.forEach === 'function') { - obj.forEach(callback); - } else { - for (var i = 0; i < obj.length; i++) { - callback(obj[i], i, obj); - } - } -}; - -/** - * isArray helper function - * @static - * @param {*} a - * @returns {boolean} - */ -showdown.helper.isArray = function isArray(a) { - 'use strict'; - return a.constructor === Array; -}; - -/** - * Check if value is undefined - * @static - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. - */ -showdown.helper.isUndefined = function isUndefined(value) { - 'use strict'; - return typeof value === 'undefined'; -}; - -/** - * Standardidize extension name - * @static - * @param {string} s extension name - * @returns {string} - */ -showdown.helper.stdExtName = function (s) { - 'use strict'; - return s.replace(/[_-]||\s/g, '').toLowerCase(); -}; - -function escapeCharactersCallback(wholeMatch, m1) { - 'use strict'; - var charCodeToEscape = m1.charCodeAt(0); - return '~E' + charCodeToEscape + 'E'; -} - -/** - * Callback used to escape characters when passing through String.replace - * @static - * @param {string} wholeMatch - * @param {string} m1 - * @returns {string} - */ -showdown.helper.escapeCharactersCallback = escapeCharactersCallback; - -/** - * Escape characters in a string - * @static - * @param {string} text - * @param {string} charsToEscape - * @param {boolean} afterBackslash - * @returns {XML|string|void|*} - */ -showdown.helper.escapeCharacters = function escapeCharacters(text, charsToEscape, afterBackslash) { - 'use strict'; - // First we have to escape the escape characters so that - // we can build a character class out of them - var regexString = '([' + charsToEscape.replace(/([\[\]\\])/g, '\\$1') + '])'; - - if (afterBackslash) { - regexString = '\\\\' + regexString; - } - - var regex = new RegExp(regexString, 'g'); - text = text.replace(regex, escapeCharactersCallback); - - return text; -}; - -var rgxFindMatchPos = function (str, left, right, flags) { - 'use strict'; - var f = flags || '', - g = f.indexOf('g') > -1, - x = new RegExp(left + '|' + right, 'g' + f.replace(/g/g, '')), - l = new RegExp(left, f.replace(/g/g, '')), - pos = [], - t, s, m, start, end; - - do { - t = 0; - while ((m = x.exec(str))) { - if (l.test(m[0])) { - if (!(t++)) { - s = x.lastIndex; - start = s - m[0].length; - } - } else if (t) { - if (!--t) { - end = m.index + m[0].length; - var obj = { - left: {start: start, end: s}, - match: {start: s, end: m.index}, - right: {start: m.index, end: end}, - wholeMatch: {start: start, end: end} - }; - pos.push(obj); - if (!g) { - return pos; - } - } - } - } - } while (t && (x.lastIndex = s)); - - return pos; -}; - -/** - * matchRecursiveRegExp - * - * (c) 2007 Steven Levithan - * MIT License - * - * Accepts a string to search, a left and right format delimiter - * as regex patterns, and optional regex flags. Returns an array - * of matches, allowing nested instances of left/right delimiters. - * Use the "g" flag to return all matches, otherwise only the - * first is returned. Be careful to ensure that the left and - * right format delimiters produce mutually exclusive matches. - * Backreferences are not supported within the right delimiter - * due to how it is internally combined with the left delimiter. - * When matching strings whose format delimiters are unbalanced - * to the left or right, the output is intentionally as a - * conventional regex library with recursion support would - * produce, e.g. "<" and ">" both produce ["x"] when using - * "<" and ">" as the delimiters (both strings contain a single, - * balanced instance of ""). - * - * examples: - * matchRecursiveRegExp("test", "\\(", "\\)") - * returns: [] - * matchRecursiveRegExp(">>t<>", "<", ">", "g") - * returns: ["t<>", ""] - * matchRecursiveRegExp("
test
", "]*>", "", "gi") - * returns: ["test"] - */ -showdown.helper.matchRecursiveRegExp = function (str, left, right, flags) { - 'use strict'; - - var matchPos = rgxFindMatchPos (str, left, right, flags), - results = []; - - for (var i = 0; i < matchPos.length; ++i) { - results.push([ - str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end), - str.slice(matchPos[i].match.start, matchPos[i].match.end), - str.slice(matchPos[i].left.start, matchPos[i].left.end), - str.slice(matchPos[i].right.start, matchPos[i].right.end) - ]); - } - return results; -}; - -/** - * - * @param {string} str - * @param {string|function} replacement - * @param {string} left - * @param {string} right - * @param {string} flags - * @returns {string} - */ -showdown.helper.replaceRecursiveRegExp = function (str, replacement, left, right, flags) { - 'use strict'; - - if (!showdown.helper.isFunction(replacement)) { - var repStr = replacement; - replacement = function () { - return repStr; - }; - } - - var matchPos = rgxFindMatchPos(str, left, right, flags), - finalStr = str, - lng = matchPos.length; - - if (lng > 0) { - var bits = []; - if (matchPos[0].wholeMatch.start !== 0) { - bits.push(str.slice(0, matchPos[0].wholeMatch.start)); - } - for (var i = 0; i < lng; ++i) { - bits.push( - replacement( - str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end), - str.slice(matchPos[i].match.start, matchPos[i].match.end), - str.slice(matchPos[i].left.start, matchPos[i].left.end), - str.slice(matchPos[i].right.start, matchPos[i].right.end) - ) - ); - if (i < lng - 1) { - bits.push(str.slice(matchPos[i].wholeMatch.end, matchPos[i + 1].wholeMatch.start)); - } - } - if (matchPos[lng - 1].wholeMatch.end < str.length) { - bits.push(str.slice(matchPos[lng - 1].wholeMatch.end)); - } - finalStr = bits.join(''); - } - return finalStr; -}; - -/** - * POLYFILLS - */ -if (showdown.helper.isUndefined(console)) { - console = { - warn: function (msg) { - 'use strict'; - alert(msg); - }, - log: function (msg) { - 'use strict'; - alert(msg); - }, - error: function (msg) { - 'use strict'; - throw msg; - } - }; -} - -/** - * Created by Estevao on 31-05-2015. - */ - -/** - * Showdown Converter class - * @class - * @param {object} [converterOptions] - * @returns {Converter} - */ -showdown.Converter = function (converterOptions) { - 'use strict'; - - var - /** - * Options used by this converter - * @private - * @type {{}} - */ - options = {}, - - /** - * Language extensions used by this converter - * @private - * @type {Array} - */ - langExtensions = [], - - /** - * Output modifiers extensions used by this converter - * @private - * @type {Array} - */ - outputModifiers = [], - - /** - * Event listeners - * @private - * @type {{}} - */ - listeners = {}; - - _constructor(); - - /** - * Converter constructor - * @private - */ - function _constructor() { - converterOptions = converterOptions || {}; - - for (var gOpt in globalOptions) { - if (globalOptions.hasOwnProperty(gOpt)) { - options[gOpt] = globalOptions[gOpt]; - } - } - - // Merge options - if (typeof converterOptions === 'object') { - for (var opt in converterOptions) { - if (converterOptions.hasOwnProperty(opt)) { - options[opt] = converterOptions[opt]; - } - } - } else { - throw Error('Converter expects the passed parameter to be an object, but ' + typeof converterOptions + - ' was passed instead.'); - } - - if (options.extensions) { - showdown.helper.forEach(options.extensions, _parseExtension); - } - } - - /** - * Parse extension - * @param {*} ext - * @param {string} [name=''] - * @private - */ - function _parseExtension(ext, name) { - - name = name || null; - // If it's a string, the extension was previously loaded - if (showdown.helper.isString(ext)) { - ext = showdown.helper.stdExtName(ext); - name = ext; - - // LEGACY_SUPPORT CODE - if (showdown.extensions[ext]) { - console.warn('DEPRECATION WARNING: ' + ext + ' is an old extension that uses a deprecated loading method.' + - 'Please inform the developer that the extension should be updated!'); - legacyExtensionLoading(showdown.extensions[ext], ext); - return; - // END LEGACY SUPPORT CODE - - } else if (!showdown.helper.isUndefined(extensions[ext])) { - ext = extensions[ext]; - - } else { - throw Error('Extension "' + ext + '" could not be loaded. It was either not found or is not a valid extension.'); - } - } - - if (typeof ext === 'function') { - ext = ext(); - } - - if (!showdown.helper.isArray(ext)) { - ext = [ext]; - } - - var validExt = validate(ext, name); - if (!validExt.valid) { - throw Error(validExt.error); - } - - for (var i = 0; i < ext.length; ++i) { - switch (ext[i].type) { - - case 'lang': - langExtensions.push(ext[i]); - break; - - case 'output': - outputModifiers.push(ext[i]); - break; - } - if (ext[i].hasOwnProperty(listeners)) { - for (var ln in ext[i].listeners) { - if (ext[i].listeners.hasOwnProperty(ln)) { - listen(ln, ext[i].listeners[ln]); - } - } - } - } - - } - - /** - * LEGACY_SUPPORT - * @param {*} ext - * @param {string} name - */ - function legacyExtensionLoading(ext, name) { - if (typeof ext === 'function') { - ext = ext(new showdown.Converter()); - } - if (!showdown.helper.isArray(ext)) { - ext = [ext]; - } - var valid = validate(ext, name); - - if (!valid.valid) { - throw Error(valid.error); - } - - for (var i = 0; i < ext.length; ++i) { - switch (ext[i].type) { - case 'lang': - langExtensions.push(ext[i]); - break; - case 'output': - outputModifiers.push(ext[i]); - break; - default:// should never reach here - throw Error('Extension loader error: Type unrecognized!!!'); - } - } - } - - /** - * Listen to an event - * @param {string} name - * @param {function} callback - */ - function listen(name, callback) { - if (!showdown.helper.isString(name)) { - throw Error('Invalid argument in converter.listen() method: name must be a string, but ' + typeof name + ' given'); - } - - if (typeof callback !== 'function') { - throw Error('Invalid argument in converter.listen() method: callback must be a function, but ' + typeof callback + ' given'); - } - - if (!listeners.hasOwnProperty(name)) { - listeners[name] = []; - } - listeners[name].push(callback); - } - - function rTrimInputText(text) { - var rsp = text.match(/^\s*/)[0].length, - rgx = new RegExp('^\\s{0,' + rsp + '}', 'gm'); - return text.replace(rgx, ''); - } - - /** - * Dispatch an event - * @private - * @param {string} evtName Event name - * @param {string} text Text - * @param {{}} options Converter Options - * @param {{}} globals - * @returns {string} - */ - this._dispatch = function dispatch (evtName, text, options, globals) { - if (listeners.hasOwnProperty(evtName)) { - for (var ei = 0; ei < listeners[evtName].length; ++ei) { - var nText = listeners[evtName][ei](evtName, text, this, options, globals); - if (nText && typeof nText !== 'undefined') { - text = nText; - } - } - } - return text; - }; - - /** - * Listen to an event - * @param {string} name - * @param {function} callback - * @returns {showdown.Converter} - */ - this.listen = function (name, callback) { - listen(name, callback); - return this; - }; - - /** - * Converts a markdown string into HTML - * @param {string} text - * @returns {*} - */ - this.makeHtml = function (text) { - //check if text is not falsy - if (!text) { - return text; - } - - var globals = { - gHtmlBlocks: [], - gHtmlMdBlocks: [], - gHtmlSpans: [], - gUrls: {}, - gTitles: {}, - gDimensions: {}, - gListLevel: 0, - hashLinkCounts: {}, - langExtensions: langExtensions, - outputModifiers: outputModifiers, - converter: this, - ghCodeBlocks: [] - }; - - // attacklab: Replace ~ with ~T - // This lets us use tilde as an escape char to avoid md5 hashes - // The choice of character is arbitrary; anything that isn't - // magic in Markdown will work. - text = text.replace(/~/g, '~T'); - - // attacklab: Replace $ with ~D - // RegExp interprets $ as a special character - // when it's in a replacement string - text = text.replace(/\$/g, '~D'); - - // Standardize line endings - text = text.replace(/\r\n/g, '\n'); // DOS to Unix - text = text.replace(/\r/g, '\n'); // Mac to Unix - - if (options.smartIndentationFix) { - text = rTrimInputText(text); - } - - // Make sure text begins and ends with a couple of newlines: - //text = '\n\n' + text + '\n\n'; - text = text; - // detab - text = showdown.subParser('detab')(text, options, globals); - - // stripBlankLines - text = showdown.subParser('stripBlankLines')(text, options, globals); - - //run languageExtensions - showdown.helper.forEach(langExtensions, function (ext) { - text = showdown.subParser('runExtension')(ext, text, options, globals); - }); - - // run the sub parsers - text = showdown.subParser('hashPreCodeTags')(text, options, globals); - text = showdown.subParser('githubCodeBlocks')(text, options, globals); - text = showdown.subParser('hashHTMLBlocks')(text, options, globals); - text = showdown.subParser('hashHTMLSpans')(text, options, globals); - text = showdown.subParser('stripLinkDefinitions')(text, options, globals); - text = showdown.subParser('blockGamut')(text, options, globals); - text = showdown.subParser('unhashHTMLSpans')(text, options, globals); - text = showdown.subParser('unescapeSpecialChars')(text, options, globals); - - // attacklab: Restore dollar signs - text = text.replace(/~D/g, '$$'); - - // attacklab: Restore tildes - text = text.replace(/~T/g, '~'); - - // Run output modifiers - showdown.helper.forEach(outputModifiers, function (ext) { - text = showdown.subParser('runExtension')(ext, text, options, globals); - }); - return text; - }; - - /** - * Set an option of this Converter instance - * @param {string} key - * @param {*} value - */ - this.setOption = function (key, value) { - options[key] = value; - }; - - /** - * Get the option of this Converter instance - * @param {string} key - * @returns {*} - */ - this.getOption = function (key) { - return options[key]; - }; - - /** - * Get the options of this Converter instance - * @returns {{}} - */ - this.getOptions = function () { - return options; - }; - - /** - * Add extension to THIS converter - * @param {{}} extension - * @param {string} [name=null] - */ - this.addExtension = function (extension, name) { - name = name || null; - _parseExtension(extension, name); - }; - - /** - * Use a global registered extension with THIS converter - * @param {string} extensionName Name of the previously registered extension - */ - this.useExtension = function (extensionName) { - _parseExtension(extensionName); - }; - - /** - * Set the flavor THIS converter should use - * @param {string} name - */ - this.setFlavor = function (name) { - if (flavor.hasOwnProperty(name)) { - var preset = flavor[name]; - for (var option in preset) { - if (preset.hasOwnProperty(option)) { - options[option] = preset[option]; - } - } - } - }; - - /** - * Remove an extension from THIS converter. - * Note: This is a costly operation. It's better to initialize a new converter - * and specify the extensions you wish to use - * @param {Array} extension - */ - this.removeExtension = function (extension) { - if (!showdown.helper.isArray(extension)) { - extension = [extension]; - } - for (var a = 0; a < extension.length; ++a) { - var ext = extension[a]; - for (var i = 0; i < langExtensions.length; ++i) { - if (langExtensions[i] === ext) { - langExtensions[i].splice(i, 1); - } - } - for (var ii = 0; ii < outputModifiers.length; ++i) { - if (outputModifiers[ii] === ext) { - outputModifiers[ii].splice(i, 1); - } - } - } - }; - - /** - * Get all extension of THIS converter - * @returns {{language: Array, output: Array}} - */ - this.getAllExtensions = function () { - return { - language: langExtensions, - output: outputModifiers - }; - }; -}; - -/** - * Turn Markdown link shortcuts into XHTML tags. - */ -showdown.subParser('anchors', function (text, options, globals) { - 'use strict'; - - text = globals.converter._dispatch('anchors.before', text, options, globals); - - var writeAnchorTag = function (wholeMatch, m1, m2, m3, m4, m5, m6, m7) { - if (showdown.helper.isUndefined(m7)) { - m7 = ''; - } - wholeMatch = m1; - var linkText = m2, - linkId = m3.toLowerCase(), - url = m4, - title = m7; - - if (!url) { - if (!linkId) { - // lower-case and turn embedded newlines into spaces - linkId = linkText.toLowerCase().replace(/ ?\n/g, ' '); - } - url = '#' + linkId; - - if (!showdown.helper.isUndefined(globals.gUrls[linkId])) { - url = globals.gUrls[linkId]; - if (!showdown.helper.isUndefined(globals.gTitles[linkId])) { - title = globals.gTitles[linkId]; - } - } else { - if (wholeMatch.search(/\(\s*\)$/m) > -1) { - // Special case for explicit empty url - url = ''; - } else { - return wholeMatch; - } - } - } - - url = showdown.helper.escapeCharacters(url, '*_', false); - var result = ''; - - return result; - }; - - // First, handle reference-style links: [link text] [id] - /* - text = text.replace(/ - ( // wrap whole match in $1 - \[ - ( - (?: - \[[^\]]*\] // allow brackets nested one level - | - [^\[] // or anything else - )* - ) - \] - - [ ]? // one optional space - (?:\n[ ]*)? // one optional newline followed by spaces - - \[ - (.*?) // id = $3 - \] - )()()()() // pad remaining backreferences - /g,_DoAnchors_callback); - */ - text = text.replace(/(\[((?:\[[^\]]*]|[^\[\]])*)][ ]?(?:\n[ ]*)?\[(.*?)])()()()()/g, writeAnchorTag); - - // - // Next, inline-style links: [link text](url "optional title") - // - - /* - text = text.replace(/ - ( // wrap whole match in $1 - \[ - ( - (?: - \[[^\]]*\] // allow brackets nested one level - | - [^\[\]] // or anything else - ) - ) - \] - \( // literal paren - [ \t]* - () // no id, so leave $3 empty - ? // href = $4 - [ \t]* - ( // $5 - (['"]) // quote char = $6 - (.*?) // Title = $7 - \6 // matching quote - [ \t]* // ignore any spaces/tabs between closing quote and ) - )? // title is optional - \) - ) - /g,writeAnchorTag); - */ - text = text.replace(/(\[((?:\[[^\]]*]|[^\[\]])*)]\([ \t]*()?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g, - writeAnchorTag); - - // - // Last, handle reference-style shortcuts: [link text] - // These must come last in case you've also got [link test][1] - // or [link test](/foo) - // - - /* - text = text.replace(/ - ( // wrap whole match in $1 - \[ - ([^\[\]]+) // link text = $2; can't contain '[' or ']' - \] - )()()()()() // pad rest of backreferences - /g, writeAnchorTag); - */ - text = text.replace(/(\[([^\[\]]+)])()()()()()/g, writeAnchorTag); - - text = globals.converter._dispatch('anchors.after', text, options, globals); - return text; -}); - -showdown.subParser('autoLinks', function (text, options, globals) { - 'use strict'; - - text = globals.converter._dispatch('autoLinks.before', text, options, globals); - - var simpleURLRegex = /\b(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+)(?=\s|$)(?!["<>])/gi, - delimUrlRegex = /<(((https?|ftp|dict):\/\/|www\.)[^'">\s]+)>/gi, - simpleMailRegex = /(?:^|[ \n\t])([A-Za-z0-9!#$%&'*+-/=?^_`\{|}~\.]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(?:$|[ \n\t])/gi, - delimMailRegex = /<(?:mailto:)?([-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi; - - text = text.replace(delimUrlRegex, replaceLink); - text = text.replace(delimMailRegex, replaceMail); - // simpleURLRegex = /\b(((https?|ftp|dict):\/\/|www\.)[-.+~:?#@!$&'()*,;=[\]\w]+)\b/gi, - // Email addresses: - - if (options.simplifiedAutoLink) { - text = text.replace(simpleURLRegex, replaceLink); - text = text.replace(simpleMailRegex, replaceMail); - } - - function replaceLink(wm, link) { - var lnkTxt = link; - if (/^www\./i.test(link)) { - link = link.replace(/^www\./i, 'http://www.'); - } - return '' + lnkTxt + ''; - } - - function replaceMail(wholeMatch, m1) { - var unescapedStr = showdown.subParser('unescapeSpecialChars')(m1); - return showdown.subParser('encodeEmailAddress')(unescapedStr); - } - - text = globals.converter._dispatch('autoLinks.after', text, options, globals); - - return text; -}); - -/** - * These are all the transformations that form block-level - * tags like paragraphs, headers, and list items. - */ -showdown.subParser('blockGamut', function (text, options, globals) { - 'use strict'; - - text = globals.converter._dispatch('blockGamut.before', text, options, globals); - - // we parse blockquotes first so that we can have headings and hrs - // inside blockquotes - text = showdown.subParser('blockQuotes')(text, options, globals); - text = showdown.subParser('headers')(text, options, globals); - - // Do Horizontal Rules: - var key = showdown.subParser('hashBlock')('
', options, globals); - text = text.replace(/^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$/gm, key); - text = text.replace(/^[ ]{0,2}([ ]?\-[ ]?){3,}[ \t]*$/gm, key); - text = text.replace(/^[ ]{0,2}([ ]?_[ ]?){3,}[ \t]*$/gm, key); - - text = showdown.subParser('lists')(text, options, globals); - text = showdown.subParser('codeBlocks')(text, options, globals); - text = showdown.subParser('tables')(text, options, globals); - - // We already ran _HashHTMLBlocks() before, in Markdown(), but that - // was to escape raw HTML in the original Markdown source. This time, - // we're escaping the markup we've just created, so that we don't wrap - //

tags around block-level tags. - text = showdown.subParser('hashHTMLBlocks')(text, options, globals); - text = showdown.subParser('paragraphs')(text, options, globals); - - text = globals.converter._dispatch('blockGamut.after', text, options, globals); - - return text; -}); - -showdown.subParser('blockQuotes', function (text, options, globals) { - 'use strict'; - - text = globals.converter._dispatch('blockQuotes.before', text, options, globals); - /* - text = text.replace(/ - ( // Wrap whole match in $1 - ( - ^[ \t]*>[ \t]? // '>' at the start of a line - .+\n // rest of the first line - (.+\n)* // subsequent consecutive lines - \n* // blanks - )+ - ) - /gm, function(){...}); - */ - - text = text.replace(/((^[ \t]{0,3}>[ \t]?.+\n(.+\n)*\n*)+)/gm, function (wholeMatch, m1) { - var bq = m1; - - // attacklab: hack around Konqueror 3.5.4 bug: - // "----------bug".replace(/^-/g,"") == "bug" - bq = bq.replace(/^[ \t]*>[ \t]?/gm, '~0'); // trim one level of quoting - - // attacklab: clean up hack - bq = bq.replace(/~0/g, ''); - - bq = bq.replace(/^[ \t]+$/gm, ''); // trim whitespace-only lines - bq = showdown.subParser('githubCodeBlocks')(bq, options, globals); - bq = showdown.subParser('blockGamut')(bq, options, globals); // recurse - - bq = bq.replace(/(^|\n)/g, '$1 '); - // These leading spaces screw with

 content, so we need to fix that:
-    bq = bq.replace(/(\s*
[^\r]+?<\/pre>)/gm, function (wholeMatch, m1) {
-      var pre = m1;
-      // attacklab: hack around Konqueror 3.5.4 bug:
-      pre = pre.replace(/^  /mg, '~0');
-      pre = pre.replace(/~0/g, '');
-      return pre;
-    });
-
-    return showdown.subParser('hashBlock')('
\n' + bq + '\n
', options, globals); - }); - - text = globals.converter._dispatch('blockQuotes.after', text, options, globals); - return text; -}); - -/** - * Process Markdown `
` blocks.
- */
-showdown.subParser('codeBlocks', function (text, options, globals) {
-  'use strict';
-
-  text = globals.converter._dispatch('codeBlocks.before', text, options, globals);
-  /*
-   text = text.replace(text,
-   /(?:\n\n|^)
-   (								// $1 = the code block -- one or more lines, starting with a space/tab
-   (?:
-   (?:[ ]{4}|\t)			// Lines must start with a tab or a tab-width of spaces - attacklab: g_tab_width
-   .*\n+
-   )+
-   )
-   (\n*[ ]{0,3}[^ \t\n]|(?=~0))	// attacklab: g_tab_width
-   /g,function(){...});
-   */
-
-  // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
-  text += '~0';
-
-  var pattern = /(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=~0))/g;
-  text = text.replace(pattern, function (wholeMatch, m1, m2) {
-    var codeblock = m1,
-        nextChar = m2,
-        end = '\n';
-
-    codeblock = showdown.subParser('outdent')(codeblock);
-    codeblock = showdown.subParser('encodeCode')(codeblock);
-    codeblock = showdown.subParser('detab')(codeblock);
-    codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines
-    codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing newlines
-
-    if (options.omitExtraWLInCodeBlocks) {
-      end = '';
-    }
-
-    codeblock = '
' + codeblock + end + '
'; - - return showdown.subParser('hashBlock')(codeblock, options, globals) + nextChar; - }); - - // attacklab: strip sentinel - text = text.replace(/~0/, ''); - - text = globals.converter._dispatch('codeBlocks.after', text, options, globals); - return text; -}); - -/** - * - * * Backtick quotes are used for spans. - * - * * You can use multiple backticks as the delimiters if you want to - * include literal backticks in the code span. So, this input: - * - * Just type ``foo `bar` baz`` at the prompt. - * - * Will translate to: - * - *

Just type foo `bar` baz at the prompt.

- * - * There's no arbitrary limit to the number of backticks you - * can use as delimters. If you need three consecutive backticks - * in your code, use four for delimiters, etc. - * - * * You can use spaces to get literal backticks at the edges: - * - * ... type `` `bar` `` ... - * - * Turns to: - * - * ... type `bar` ... - */ -showdown.subParser('codeSpans', function (text, options, globals) { - 'use strict'; - - text = globals.converter._dispatch('codeSpans.before', text, options, globals); - - /* - text = text.replace(/ - (^|[^\\]) // Character before opening ` can't be a backslash - (`+) // $2 = Opening run of ` - ( // $3 = The code block - [^\r]*? - [^`] // attacklab: work around lack of lookbehind - ) - \2 // Matching closer - (?!`) - /gm, function(){...}); - */ - - if (typeof(text) === 'undefined') { - text = ''; - } - text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm, - function (wholeMatch, m1, m2, m3) { - var c = m3; - c = c.replace(/^([ \t]*)/g, ''); // leading whitespace - c = c.replace(/[ \t]*$/g, ''); // trailing whitespace - c = showdown.subParser('encodeCode')(c); - return m1 + '' + c + ''; - } - ); - - text = globals.converter._dispatch('codeSpans.after', text, options, globals); - return text; -}); - -/** - * Convert all tabs to spaces - */ -showdown.subParser('detab', function (text) { - 'use strict'; - - // expand first n-1 tabs - text = text.replace(/\t(?=\t)/g, ' '); // g_tab_width - - // replace the nth with two sentinels - text = text.replace(/\t/g, '~A~B'); - - // use the sentinel to anchor our regex so it doesn't explode - text = text.replace(/~B(.+?)~A/g, function (wholeMatch, m1) { - var leadingText = m1, - numSpaces = 4 - leadingText.length % 4; // g_tab_width - - // there *must* be a better way to do this: - for (var i = 0; i < numSpaces; i++) { - leadingText += ' '; - } - - return leadingText; - }); - - // clean up sentinels - text = text.replace(/~A/g, ' '); // g_tab_width - text = text.replace(/~B/g, ''); - - return text; - -}); - -/** - * Smart processing for ampersands and angle brackets that need to be encoded. - */ -showdown.subParser('encodeAmpsAndAngles', function (text) { - 'use strict'; - // Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin: - // http://bumppo.net/projects/amputator/ - text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g, '&'); - - // Encode naked <'s - text = text.replace(/<(?![a-z\/?\$!])/gi, '<'); - - return text; -}); - -/** - * Returns the string, with after processing the following backslash escape sequences. - * - * attacklab: The polite way to do this is with the new escapeCharacters() function: - * - * text = escapeCharacters(text,"\\",true); - * text = escapeCharacters(text,"`*_{}[]()>#+-.!",true); - * - * ...but we're sidestepping its use of the (slow) RegExp constructor - * as an optimization for Firefox. This function gets called a LOT. - */ -showdown.subParser('encodeBackslashEscapes', function (text) { - 'use strict'; - text = text.replace(/\\(\\)/g, showdown.helper.escapeCharactersCallback); - text = text.replace(/\\([`*_{}\[\]()>#+-.!])/g, showdown.helper.escapeCharactersCallback); - return text; -}); - -/** - * Encode/escape certain characters inside Markdown code runs. - * The point is that in code, these characters are literals, - * and lose their special Markdown meanings. - */ -showdown.subParser('encodeCode', function (text) { - 'use strict'; - - // Encode all ampersands; HTML entities are not - // entities within a Markdown code span. - text = text.replace(/&/g, '&'); - - // Do the angle bracket song and dance: - text = text.replace(//g, '>'); - - // Now, escape characters that are magic in Markdown: - text = showdown.helper.escapeCharacters(text, '*_{}[]\\', false); - - // jj the line above breaks this: - //--- - //* Item - // 1. Subitem - // special char: * - // --- - - return text; -}); - -/** - * Input: an email address, e.g. "foo@example.com" - * - * Output: the email address as a mailto link, with each character - * of the address encoded as either a decimal or hex entity, in - * the hopes of foiling most address harvesting spam bots. E.g.: - * - * foo - * @example.com - * - * Based on a filter by Matthew Wickline, posted to the BBEdit-Talk - * mailing list: - * - */ -showdown.subParser('encodeEmailAddress', function (addr) { - 'use strict'; - - var encode = [ - function (ch) { - return '&#' + ch.charCodeAt(0) + ';'; - }, - function (ch) { - return '&#x' + ch.charCodeAt(0).toString(16) + ';'; - }, - function (ch) { - return ch; - } - ]; - - addr = 'mailto:' + addr; - - addr = addr.replace(/./g, function (ch) { - if (ch === '@') { - // this *must* be encoded. I insist. - ch = encode[Math.floor(Math.random() * 2)](ch); - } else if (ch !== ':') { - // leave ':' alone (to spot mailto: later) - var r = Math.random(); - // roughly 10% raw, 45% hex, 45% dec - ch = ( - r > 0.9 ? encode[2](ch) : r > 0.45 ? encode[1](ch) : encode[0](ch) - ); - } - return ch; - }); - - addr = '' + addr + ''; - addr = addr.replace(/">.+:/g, '">'); // strip the mailto: from the visible part - - return addr; -}); - -/** - * Within tags -- meaning between < and > -- encode [\ ` * _] so they - * don't conflict with their use in Markdown for code, italics and strong. - */ -showdown.subParser('escapeSpecialCharsWithinTagAttributes', function (text) { - 'use strict'; - - // Build a regex to find HTML tags and comments. See Friedl's - // "Mastering Regular Expressions", 2nd Ed., pp. 200-201. - var regex = /(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|)/gi; - - text = text.replace(regex, function (wholeMatch) { - var tag = wholeMatch.replace(/(.)<\/?code>(?=.)/g, '$1`'); - tag = showdown.helper.escapeCharacters(tag, '\\`*_', false); - return tag; - }); - - return text; -}); - -/** - * Handle github codeblocks prior to running HashHTML so that - * HTML contained within the codeblock gets escaped properly - * Example: - * ```ruby - * def hello_world(x) - * puts "Hello, #{x}" - * end - * ``` - */ -showdown.subParser('githubCodeBlocks', function (text, options, globals) { - 'use strict'; - - // early exit if option is not enabled - if (!options.ghCodeBlocks) { - return text; - } - - text = globals.converter._dispatch('githubCodeBlocks.before', text, options, globals); - - text += '~0'; - - text = text.replace(/(?:^|\n)```(.*)\n([\s\S]*?)\n```/g, function (wholeMatch, language, codeblock) { - var end = (options.omitExtraWLInCodeBlocks) ? '' : '\n'; - - // First parse the github code block - codeblock = showdown.subParser('encodeCode')(codeblock); - codeblock = showdown.subParser('detab')(codeblock); - codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines - codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing whitespace - - codeblock = '
' + codeblock + end + '
'; - - codeblock = showdown.subParser('hashBlock')(codeblock, options, globals); - - // Since GHCodeblocks can be false positives, we need to - // store the primitive text and the parsed text in a global var, - // and then return a token - return '\n\n~G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n'; - }); - - // attacklab: strip sentinel - text = text.replace(/~0/, ''); - - return globals.converter._dispatch('githubCodeBlocks.after', text, options, globals); -}); - -showdown.subParser('hashBlock', function (text, options, globals) { - 'use strict'; - text = text.replace(/(^\n+|\n+$)/g, ''); - return '\n\n~K' + (globals.gHtmlBlocks.push(text) - 1) + 'K\n\n'; -}); - -showdown.subParser('hashElement', function (text, options, globals) { - 'use strict'; - - return function (wholeMatch, m1) { - var blockText = m1; - - // Undo double lines - blockText = blockText.replace(/\n\n/g, '\n'); - blockText = blockText.replace(/^\n/, ''); - - // strip trailing blank lines - blockText = blockText.replace(/\n+$/g, ''); - - // Replace the element text with a marker ("~KxK" where x is its key) - blockText = '\n\n~K' + (globals.gHtmlBlocks.push(blockText) - 1) + 'K\n\n'; - - return blockText; - }; -}); - -showdown.subParser('hashHTMLBlocks', function (text, options, globals) { - 'use strict'; - - var blockTags = [ - 'pre', - 'div', - 'h1', - 'h2', - 'h3', - 'h4', - 'h5', - 'h6', - 'blockquote', - 'table', - 'dl', - 'ol', - 'ul', - 'script', - 'noscript', - 'form', - 'fieldset', - 'iframe', - 'math', - 'style', - 'section', - 'header', - 'footer', - 'nav', - 'article', - 'aside', - 'address', - 'audio', - 'canvas', - 'figure', - 'hgroup', - 'output', - 'video', - 'p' - ], - repFunc = function (wholeMatch, match, left, right) { - var txt = wholeMatch; - // check if this html element is marked as markdown - // if so, it's contents should be parsed as markdown - if (left.search(/\bmarkdown\b/) !== -1) { - txt = left + globals.converter.makeHtml(match) + right; - } - return '\n\n~K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n'; - }; - - for (var i = 0; i < blockTags.length; ++i) { - text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '^(?: |\\t){0,3}<' + blockTags[i] + '\\b[^>]*>', '', 'gim'); - } - - // HR SPECIAL CASE - text = text.replace(/(\n[ ]{0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g, - showdown.subParser('hashElement')(text, options, globals)); - - // Special case for standalone HTML comments: - text = text.replace(/()/g, - showdown.subParser('hashElement')(text, options, globals)); - - // PHP and ASP-style processor instructions ( and <%...%>) - text = text.replace(/(?:\n\n)([ ]{0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g, - showdown.subParser('hashElement')(text, options, globals)); - return text; -}); - -/** - * Hash span elements that should not be parsed as markdown - */ -showdown.subParser('hashHTMLSpans', function (text, config, globals) { - 'use strict'; - - var matches = showdown.helper.matchRecursiveRegExp(text, ']*>', '', 'gi'); - - for (var i = 0; i < matches.length; ++i) { - text = text.replace(matches[i][0], '~L' + (globals.gHtmlSpans.push(matches[i][0]) - 1) + 'L'); - } - return text; -}); - -/** - * Unhash HTML spans - */ -showdown.subParser('unhashHTMLSpans', function (text, config, globals) { - 'use strict'; - - for (var i = 0; i < globals.gHtmlSpans.length; ++i) { - text = text.replace('~L' + i + 'L', globals.gHtmlSpans[i]); - } - - return text; -}); - -/** - * Hash span elements that should not be parsed as markdown - */ -showdown.subParser('hashPreCodeTags', function (text, config, globals) { - 'use strict'; - - var repFunc = function (wholeMatch, match, left, right) { - // encode html entities - var codeblock = left + showdown.subParser('encodeCode')(match) + right; - return '\n\n~G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n'; - }; - - text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '^(?: |\\t){0,3}]*>\\s*]*>', '^(?: |\\t){0,3}\\s*
', 'gim'); - return text; -}); - -showdown.subParser('headers', function (text, options, globals) { - 'use strict'; - - text = globals.converter._dispatch('headers.before', text, options, globals); - - var prefixHeader = options.prefixHeaderId, - headerLevelStart = (isNaN(parseInt(options.headerLevelStart))) ? 1 : parseInt(options.headerLevelStart), - - // Set text-style headers: - // Header 1 - // ======== - // - // Header 2 - // -------- - // - setextRegexH1 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n={2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n=+[ \t]*\n+/gm, - setextRegexH2 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n-{2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n-+[ \t]*\n+/gm; - - text = text.replace(setextRegexH1, function (wholeMatch, m1) { - - var spanGamut = showdown.subParser('spanGamut')(m1, options, globals), - hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"', - hLevel = headerLevelStart, - hashBlock = '' + spanGamut + ''; - return showdown.subParser('hashBlock')(hashBlock, options, globals); - }); - - text = text.replace(setextRegexH2, function (matchFound, m1) { - var spanGamut = showdown.subParser('spanGamut')(m1, options, globals), - hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"', - hLevel = headerLevelStart + 1, - hashBlock = '' + spanGamut + ''; - return showdown.subParser('hashBlock')(hashBlock, options, globals); - }); - - // atx-style headers: - // # Header 1 - // ## Header 2 - // ## Header 2 with closing hashes ## - // ... - // ###### Header 6 - // - text = text.replace(/^(#{1,6})[ \t]*(.+?)[ \t]*#*\n+/gm, function (wholeMatch, m1, m2) { - var span = showdown.subParser('spanGamut')(m2, options, globals), - hID = (options.noHeaderId) ? '' : ' id="' + headerId(m2) + '"', - hLevel = headerLevelStart - 1 + m1.length, - header = '' + span + ''; - - return showdown.subParser('hashBlock')(header, options, globals); - }); - - function headerId(m) { - var title, escapedId = m.replace(/[^\w]/g, '').toLowerCase(); - - if (globals.hashLinkCounts[escapedId]) { - title = escapedId + '-' + (globals.hashLinkCounts[escapedId]++); - } else { - title = escapedId; - globals.hashLinkCounts[escapedId] = 1; - } - - // Prefix id to prevent causing inadvertent pre-existing style matches. - if (prefixHeader === true) { - prefixHeader = 'section'; - } - - if (showdown.helper.isString(prefixHeader)) { - return prefixHeader + title; - } - return title; - } - - text = globals.converter._dispatch('headers.after', text, options, globals); - return text; -}); - -/** - * Turn Markdown image shortcuts into tags. - */ -showdown.subParser('images', function (text, options, globals) { - 'use strict'; - - text = globals.converter._dispatch('images.before', text, options, globals); - - var inlineRegExp = /!\[(.*?)]\s?\([ \t]*()?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(['"])(.*?)\6[ \t]*)?\)/g, - referenceRegExp = /!\[([^\]]*?)] ?(?:\n *)?\[(.*?)]()()()()()/g; - - function writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title) { - - var gUrls = globals.gUrls, - gTitles = globals.gTitles, - gDims = globals.gDimensions; - - linkId = linkId.toLowerCase(); - - if (!title) { - title = ''; - } - - if (url === '' || url === null) { - if (linkId === '' || linkId === null) { - // lower-case and turn embedded newlines into spaces - linkId = altText.toLowerCase().replace(/ ?\n/g, ' '); - } - url = '#' + linkId; - - if (!showdown.helper.isUndefined(gUrls[linkId])) { - url = gUrls[linkId]; - if (!showdown.helper.isUndefined(gTitles[linkId])) { - title = gTitles[linkId]; - } - if (!showdown.helper.isUndefined(gDims[linkId])) { - width = gDims[linkId].width; - height = gDims[linkId].height; - } - } else { - return wholeMatch; - } - } - - altText = altText.replace(/"/g, '"'); - altText = showdown.helper.escapeCharacters(altText, '*_', false); - url = showdown.helper.escapeCharacters(url, '*_', false); - var result = '' + altText + 'x "optional title") - text = text.replace(inlineRegExp, writeImageTag); - - text = globals.converter._dispatch('images.after', text, options, globals); - return text; -}); - -showdown.subParser('italicsAndBold', function (text, options, globals) { - 'use strict'; - - text = globals.converter._dispatch('italicsAndBold.before', text, options, globals); - - if (options.literalMidWordUnderscores) { - //underscores - // Since we are consuming a \s character, we need to add it - text = text.replace(/(^|\s|>|\b)__(?=\S)([\s\S]+?)__(?=\b|<|\s|$)/gm, '$1$2'); - text = text.replace(/(^|\s|>|\b)_(?=\S)([\s\S]+?)_(?=\b|<|\s|$)/gm, '$1$2'); - //asterisks - text = text.replace(/(\*\*)(?=\S)([^\r]*?\S[*]*)\1/g, '$2'); - text = text.replace(/(\*)(?=\S)([^\r]*?\S)\1/g, '$2'); - - } else { - // must go first: - text = text.replace(/(\*\*|__)(?=\S)([^\r]*?\S[*_]*)\1/g, '$2'); - text = text.replace(/(\*|_)(?=\S)([^\r]*?\S)\1/g, '$2'); - } - - text = globals.converter._dispatch('italicsAndBold.after', text, options, globals); - return text; -}); - -/** - * Form HTML ordered (numbered) and unordered (bulleted) lists. - */ -showdown.subParser('lists', function (text, options, globals) { - 'use strict'; - - text = globals.converter._dispatch('lists.before', text, options, globals); - /** - * Process the contents of a single ordered or unordered list, splitting it - * into individual list items. - * @param {string} listStr - * @param {boolean} trimTrailing - * @returns {string} - */ - function processListItems (listStr, trimTrailing) { - // The $g_list_level global keeps track of when we're inside a list. - // Each time we enter a list, we increment it; when we leave a list, - // we decrement. If it's zero, we're not in a list anymore. - // - // We do this because when we're not inside a list, we want to treat - // something like this: - // - // I recommend upgrading to version - // 8. Oops, now this line is treated - // as a sub-list. - // - // As a single paragraph, despite the fact that the second line starts - // with a digit-period-space sequence. - // - // Whereas when we're inside a list (or sub-list), that line will be - // treated as the start of a sub-list. What a kludge, huh? This is - // an aspect of Markdown's syntax that's hard to parse perfectly - // without resorting to mind-reading. Perhaps the solution is to - // change the syntax rules such that sub-lists must start with a - // starting cardinal number; e.g. "1." or "a.". - globals.gListLevel++; - - // trim trailing blank lines: - listStr = listStr.replace(/\n{2,}$/, '\n'); - - // attacklab: add sentinel to emulate \z - listStr += '~0'; - - var rgx = /(\n)?(^[ \t]*)([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(~0|\2([*+-]|\d+[.])[ \t]+))/gm, - isParagraphed = (/\n[ \t]*\n(?!~0)/.test(listStr)); - - listStr = listStr.replace(rgx, function (wholeMatch, m1, m2, m3, m4, taskbtn, checked) { - checked = (checked && checked.trim() !== ''); - var item = showdown.subParser('outdent')(m4, options, globals), - bulletStyle = ''; - - // Support for github tasklists - if (taskbtn && options.tasklists) { - bulletStyle = ' class="task-list-item" style="list-style-type: none;"'; - item = item.replace(/^[ \t]*\[(x|X| )?]/m, function () { - var otp = ' -1)) { - item = showdown.subParser('githubCodeBlocks')(item, options, globals); - item = showdown.subParser('blockGamut')(item, options, globals); - } else { - // Recursion for sub-lists: - item = showdown.subParser('lists')(item, options, globals); - item = item.replace(/\n$/, ''); // chomp(item) - if (isParagraphed) { - item = showdown.subParser('paragraphs')(item, options, globals); - } else { - item = showdown.subParser('spanGamut')(item, options, globals); - } - } - item = '\n' + item + '\n'; - return item; - }); - - // attacklab: strip sentinel - listStr = listStr.replace(/~0/g, ''); - - globals.gListLevel--; - - if (trimTrailing) { - listStr = listStr.replace(/\s+$/, ''); - } - - return listStr; - } - - /** - * Check and parse consecutive lists (better fix for issue #142) - * @param {string} list - * @param {string} listType - * @param {boolean} trimTrailing - * @returns {string} - */ - function parseConsecutiveLists(list, listType, trimTrailing) { - // check if we caught 2 or more consecutive lists by mistake - // we use the counterRgx, meaning if listType is UL we look for UL and vice versa - var counterRxg = (listType === 'ul') ? /^ {0,2}\d+\.[ \t]/gm : /^ {0,2}[*+-][ \t]/gm, - subLists = [], - result = ''; - - if (list.search(counterRxg) !== -1) { - (function parseCL(txt) { - var pos = txt.search(counterRxg); - if (pos !== -1) { - // slice - result += '\n\n<' + listType + '>' + processListItems(txt.slice(0, pos), !!trimTrailing) + '\n\n'; - - // invert counterType and listType - listType = (listType === 'ul') ? 'ol' : 'ul'; - counterRxg = (listType === 'ul') ? /^ {0,2}\d+\.[ \t]/gm : /^ {0,2}[*+-][ \t]/gm; - - //recurse - parseCL(txt.slice(pos)); - } else { - result += '\n\n<' + listType + '>' + processListItems(txt, !!trimTrailing) + '\n\n'; - } - })(list); - for (var i = 0; i < subLists.length; ++i) { - - } - } else { - result = '\n\n<' + listType + '>' + processListItems(list, !!trimTrailing) + '\n\n'; - } - - return result; - } - - // attacklab: add sentinel to hack around khtml/safari bug: - // http://bugs.webkit.org/show_bug.cgi?id=11231 - text += '~0'; - - // Re-usable pattern to match any entire ul or ol list: - var wholeList = /^(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm; - - if (globals.gListLevel) { - text = text.replace(wholeList, function (wholeMatch, list, m2) { - var listType = (m2.search(/[*+-]/g) > -1) ? 'ul' : 'ol'; - return parseConsecutiveLists(list, listType, true); - }); - } else { - wholeList = /(\n\n|^\n?)(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm; - //wholeList = /(\n\n|^\n?)( {0,3}([*+-]|\d+\.)[ \t]+[\s\S]+?)(?=(~0)|(\n\n(?!\t| {2,}| {0,3}([*+-]|\d+\.)[ \t])))/g; - text = text.replace(wholeList, function (wholeMatch, m1, list, m3) { - - var listType = (m3.search(/[*+-]/g) > -1) ? 'ul' : 'ol'; - return parseConsecutiveLists(list, listType); - }); - } - - // attacklab: strip sentinel - text = text.replace(/~0/, ''); - - text = globals.converter._dispatch('lists.after', text, options, globals); - return text; -}); - -/** - * Remove one level of line-leading tabs or spaces - */ -showdown.subParser('outdent', function (text) { - 'use strict'; - - // attacklab: hack around Konqueror 3.5.4 bug: - // "----------bug".replace(/^-/g,"") == "bug" - text = text.replace(/^(\t|[ ]{1,4})/gm, '~0'); // attacklab: g_tab_width - - // attacklab: clean up hack - text = text.replace(/~0/g, ''); - - return text; -}); - -/** - * - */ -showdown.subParser('paragraphs', function (text, options, globals) { - 'use strict'; - - text = globals.converter._dispatch('paragraphs.before', text, options, globals); - // Strip leading and trailing lines: - text = text.replace(/^\n+/g, ''); - text = text.replace(/\n+$/g, ''); - - var grafs = text.split(/\n{2,}/g), - grafsOut = [], - end = grafs.length; // Wrap

tags - - for (var i = 0; i < end; i++) { - var str = grafs[i]; - // if this is an HTML marker, copy it - if (str.search(/~(K|G)(\d+)\1/g) >= 0) { - grafsOut.push(str); - } else { - str = showdown.subParser('spanGamut')(str, options, globals); - str = str.replace(/^([ \t]*)/g, '

'); - str += '

'; - grafsOut.push(str); - } - } - - /** Unhashify HTML blocks */ - end = grafsOut.length; - for (i = 0; i < end; i++) { - var blockText = '', - grafsOutIt = grafsOut[i], - codeFlag = false; - // if this is a marker for an html block... - while (grafsOutIt.search(/~(K|G)(\d+)\1/) >= 0) { - var delim = RegExp.$1, - num = RegExp.$2; - - if (delim === 'K') { - blockText = globals.gHtmlBlocks[num]; - } else { - // we need to check if ghBlock is a false positive - if (codeFlag) { - // use encoded version of all text - blockText = showdown.subParser('encodeCode')(globals.ghCodeBlocks[num].text); - } else { - blockText = globals.ghCodeBlocks[num].codeblock; - } - } - blockText = blockText.replace(/\$/g, '$$$$'); // Escape any dollar signs - - grafsOutIt = grafsOutIt.replace(/(\n\n)?~(K|G)\d+\2(\n\n)?/, blockText); - // Check if grafsOutIt is a pre->code - if (/^]*>\s*]*>/.test(grafsOutIt)) { - codeFlag = true; - } - } - grafsOut[i] = grafsOutIt; - } - text = grafsOut.join('\n\n'); - // Strip leading and trailing lines: - text = text.replace(/^\n+/g, ''); - text = text.replace(/\n+$/g, ''); - return globals.converter._dispatch('paragraphs.after', text, options, globals); -}); - -/** - * Run extension - */ -showdown.subParser('runExtension', function (ext, text, options, globals) { - 'use strict'; - - if (ext.filter) { - text = ext.filter(text, globals.converter, options); - - } else if (ext.regex) { - // TODO remove this when old extension loading mechanism is deprecated - var re = ext.regex; - if (!re instanceof RegExp) { - re = new RegExp(re, 'g'); - } - text = text.replace(re, ext.replace); - } - - return text; -}); - -/** - * These are all the transformations that occur *within* block-level - * tags like paragraphs, headers, and list items. - */ -showdown.subParser('spanGamut', function (text, options, globals) { - 'use strict'; - - text = globals.converter._dispatch('spanGamut.before', text, options, globals); - text = showdown.subParser('codeSpans')(text, options, globals); - text = showdown.subParser('escapeSpecialCharsWithinTagAttributes')(text, options, globals); - text = showdown.subParser('encodeBackslashEscapes')(text, options, globals); - - // Process anchor and image tags. Images must come first, - // because ![foo][f] looks like an anchor. - text = showdown.subParser('images')(text, options, globals); - text = showdown.subParser('anchors')(text, options, globals); - - // Make links out of things like `` - // Must come after _DoAnchors(), because you can use < and > - // delimiters in inline links like [this](). - text = showdown.subParser('autoLinks')(text, options, globals); - text = showdown.subParser('encodeAmpsAndAngles')(text, options, globals); - text = showdown.subParser('italicsAndBold')(text, options, globals); - text = showdown.subParser('strikethrough')(text, options, globals); - - // Do hard breaks: - text = text.replace(/ +\n/g, '
\n'); - - text = globals.converter._dispatch('spanGamut.after', text, options, globals); - return text; -}); - -showdown.subParser('strikethrough', function (text, options, globals) { - 'use strict'; - - if (options.strikethrough) { - text = globals.converter._dispatch('strikethrough.before', text, options, globals); - text = text.replace(/(?:~T){2}([\s\S]+?)(?:~T){2}/g, '$1'); - text = globals.converter._dispatch('strikethrough.after', text, options, globals); - } - - return text; -}); - -/** - * Strip any lines consisting only of spaces and tabs. - * This makes subsequent regexs easier to write, because we can - * match consecutive blank lines with /\n+/ instead of something - * contorted like /[ \t]*\n+/ - */ -showdown.subParser('stripBlankLines', function (text) { - 'use strict'; - return text.replace(/^[ \t]+$/mg, ''); -}); - -/** - * Strips link definitions from text, stores the URLs and titles in - * hash references. - * Link defs are in the form: ^[id]: url "optional title" - * - * ^[ ]{0,3}\[(.+)\]: // id = $1 attacklab: g_tab_width - 1 - * [ \t]* - * \n? // maybe *one* newline - * [ \t]* - * ? // url = $2 - * [ \t]* - * \n? // maybe one newline - * [ \t]* - * (?: - * (\n*) // any lines skipped = $3 attacklab: lookbehind removed - * ["(] - * (.+?) // title = $4 - * [")] - * [ \t]* - * )? // title is optional - * (?:\n+|$) - * /gm, - * function(){...}); - * - */ -showdown.subParser('stripLinkDefinitions', function (text, options, globals) { - 'use strict'; - - var regex = /^ {0,3}\[(.+)]:[ \t]*\n?[ \t]*?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n+|(?=~0))/gm; - - // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug - text += '~0'; - - text = text.replace(regex, function (wholeMatch, linkId, url, width, height, blankLines, title) { - linkId = linkId.toLowerCase(); - globals.gUrls[linkId] = showdown.subParser('encodeAmpsAndAngles')(url); // Link IDs are case-insensitive - - if (blankLines) { - // Oops, found blank lines, so it's not a title. - // Put back the parenthetical statement we stole. - return blankLines + title; - - } else { - if (title) { - globals.gTitles[linkId] = title.replace(/"|'/g, '"'); - } - if (options.parseImgDimensions && width && height) { - globals.gDimensions[linkId] = { - width: width, - height: height - }; - } - } - // Completely remove the definition from the text - return ''; - }); - - // attacklab: strip sentinel - text = text.replace(/~0/, ''); - - return text; -}); - -showdown.subParser('tables', function (text, options, globals) { - 'use strict'; - - if (!options.tables) { - return text; - } - - var tableRgx = /^[ \t]{0,3}\|?.+\|.+\n[ \t]{0,3}\|?[ \t]*:?[ \t]*(?:-|=){2,}[ \t]*:?[ \t]*\|[ \t]*:?[ \t]*(?:-|=){2,}[\s\S]+?(?:\n\n|~0)/gm; - - function parseStyles(sLine) { - if (/^:[ \t]*--*$/.test(sLine)) { - return ' style="text-align:left;"'; - } else if (/^--*[ \t]*:[ \t]*$/.test(sLine)) { - return ' style="text-align:right;"'; - } else if (/^:[ \t]*--*[ \t]*:$/.test(sLine)) { - return ' style="text-align:center;"'; - } else { - return ''; - } - } - - function parseHeaders(header, style) { - var id = ''; - header = header.trim(); - if (options.tableHeaderId) { - id = ' id="' + header.replace(/ /g, '_').toLowerCase() + '"'; - } - header = showdown.subParser('spanGamut')(header, options, globals); - - return '' + header + '\n'; - } - - function parseCells(cell, style) { - var subText = showdown.subParser('spanGamut')(cell, options, globals); - return '' + subText + '\n'; - } - - function buildTable(headers, cells) { - var tb = '\n\n\n', - tblLgn = headers.length; - - for (var i = 0; i < tblLgn; ++i) { - tb += headers[i]; - } - tb += '\n\n\n'; - - for (i = 0; i < cells.length; ++i) { - tb += '\n'; - for (var ii = 0; ii < tblLgn; ++ii) { - tb += cells[i][ii]; - } - tb += '\n'; - } - tb += '\n
\n'; - return tb; - } - - text = globals.converter._dispatch('tables.before', text, options, globals); - - text = text.replace(tableRgx, function (rawTable) { - - var i, tableLines = rawTable.split('\n'); - - // strip wrong first and last column if wrapped tables are used - for (i = 0; i < tableLines.length; ++i) { - if (/^[ \t]{0,3}\|/.test(tableLines[i])) { - tableLines[i] = tableLines[i].replace(/^[ \t]{0,3}\|/, ''); - } - if (/\|[ \t]*$/.test(tableLines[i])) { - tableLines[i] = tableLines[i].replace(/\|[ \t]*$/, ''); - } - } - - var rawHeaders = tableLines[0].split('|').map(function (s) { return s.trim();}), - rawStyles = tableLines[1].split('|').map(function (s) { return s.trim();}), - rawCells = [], - headers = [], - styles = [], - cells = []; - - tableLines.shift(); - tableLines.shift(); - - for (i = 0; i < tableLines.length; ++i) { - if (tableLines[i].trim() === '') { - continue; - } - rawCells.push( - tableLines[i] - .split('|') - .map(function (s) { - return s.trim(); - }) - ); - } - - if (rawHeaders.length < rawStyles.length) { - return rawTable; - } - - for (i = 0; i < rawStyles.length; ++i) { - styles.push(parseStyles(rawStyles[i])); - } - - for (i = 0; i < rawHeaders.length; ++i) { - if (showdown.helper.isUndefined(styles[i])) { - styles[i] = ''; - } - headers.push(parseHeaders(rawHeaders[i], styles[i])); - } - - for (i = 0; i < rawCells.length; ++i) { - var row = []; - for (var ii = 0; ii < headers.length; ++ii) { - if (showdown.helper.isUndefined(rawCells[i][ii])) { - - } - row.push(parseCells(rawCells[i][ii], styles[ii])); - } - cells.push(row); - } - - return buildTable(headers, cells); - }); - - text = globals.converter._dispatch('tables.after', text, options, globals); - - return text; -}); - -/** - * Swap back in all the special characters we've hidden. - */ -showdown.subParser('unescapeSpecialChars', function (text) { - 'use strict'; - - text = text.replace(/~E(\d+)E/g, function (wholeMatch, m1) { - var charCodeToReplace = parseInt(m1); - return String.fromCharCode(charCodeToReplace); - }); - return text; -}); -module.exports = showdown; diff --git a/wxParse/wxDiscode.js b/wxParse/wxDiscode.js deleted file mode 100644 index fca29bb..0000000 --- a/wxParse/wxDiscode.js +++ /dev/null @@ -1,207 +0,0 @@ -// HTML 支持的数学符号 -function strNumDiscode(str){ - str = str.replace(/∀/g, '∀'); - str = str.replace(/∂/g, '∂'); - str = str.replace(/&exists;/g, '∃'); - str = str.replace(/∅/g, '∅'); - str = str.replace(/∇/g, '∇'); - str = str.replace(/∈/g, '∈'); - str = str.replace(/∉/g, '∉'); - str = str.replace(/∋/g, '∋'); - str = str.replace(/∏/g, '∏'); - str = str.replace(/∑/g, '∑'); - str = str.replace(/−/g, '−'); - str = str.replace(/∗/g, '∗'); - str = str.replace(/√/g, '√'); - str = str.replace(/∝/g, '∝'); - str = str.replace(/∞/g, '∞'); - str = str.replace(/∠/g, '∠'); - str = str.replace(/∧/g, '∧'); - str = str.replace(/∨/g, '∨'); - str = str.replace(/∩/g, '∩'); - str = str.replace(/∩/g, '∪'); - str = str.replace(/∫/g, '∫'); - str = str.replace(/∴/g, '∴'); - str = str.replace(/∼/g, '∼'); - str = str.replace(/≅/g, '≅'); - str = str.replace(/≈/g, '≈'); - str = str.replace(/≠/g, '≠'); - str = str.replace(/≤/g, '≤'); - str = str.replace(/≥/g, '≥'); - str = str.replace(/⊂/g, '⊂'); - str = str.replace(/⊃/g, '⊃'); - str = str.replace(/⊄/g, '⊄'); - str = str.replace(/⊆/g, '⊆'); - str = str.replace(/⊇/g, '⊇'); - str = str.replace(/⊕/g, '⊕'); - str = str.replace(/⊗/g, '⊗'); - str = str.replace(/⊥/g, '⊥'); - str = str.replace(/⋅/g, '⋅'); - return str; -} - -//HTML 支持的希腊字母 -function strGreeceDiscode(str){ - str = str.replace(/Α/g, 'Α'); - str = str.replace(/Β/g, 'Β'); - str = str.replace(/Γ/g, 'Γ'); - str = str.replace(/Δ/g, 'Δ'); - str = str.replace(/Ε/g, 'Ε'); - str = str.replace(/Ζ/g, 'Ζ'); - str = str.replace(/Η/g, 'Η'); - str = str.replace(/Θ/g, 'Θ'); - str = str.replace(/Ι/g, 'Ι'); - str = str.replace(/Κ/g, 'Κ'); - str = str.replace(/Λ/g, 'Λ'); - str = str.replace(/Μ/g, 'Μ'); - str = str.replace(/Ν/g, 'Ν'); - str = str.replace(/Ξ/g, 'Ν'); - str = str.replace(/Ο/g, 'Ο'); - str = str.replace(/Π/g, 'Π'); - str = str.replace(/Ρ/g, 'Ρ'); - str = str.replace(/Σ/g, 'Σ'); - str = str.replace(/Τ/g, 'Τ'); - str = str.replace(/Υ/g, 'Υ'); - str = str.replace(/Φ/g, 'Φ'); - str = str.replace(/Χ/g, 'Χ'); - str = str.replace(/Ψ/g, 'Ψ'); - str = str.replace(/Ω/g, 'Ω'); - - str = str.replace(/α/g, 'α'); - str = str.replace(/β/g, 'β'); - str = str.replace(/γ/g, 'γ'); - str = str.replace(/δ/g, 'δ'); - str = str.replace(/ε/g, 'ε'); - str = str.replace(/ζ/g, 'ζ'); - str = str.replace(/η/g, 'η'); - str = str.replace(/θ/g, 'θ'); - str = str.replace(/ι/g, 'ι'); - str = str.replace(/κ/g, 'κ'); - str = str.replace(/λ/g, 'λ'); - str = str.replace(/μ/g, 'μ'); - str = str.replace(/ν/g, 'ν'); - str = str.replace(/ξ/g, 'ξ'); - str = str.replace(/ο/g, 'ο'); - str = str.replace(/π/g, 'π'); - str = str.replace(/ρ/g, 'ρ'); - str = str.replace(/ς/g, 'ς'); - str = str.replace(/σ/g, 'σ'); - str = str.replace(/τ/g, 'τ'); - str = str.replace(/υ/g, 'υ'); - str = str.replace(/φ/g, 'φ'); - str = str.replace(/χ/g, 'χ'); - str = str.replace(/ψ/g, 'ψ'); - str = str.replace(/ω/g, 'ω'); - str = str.replace(/ϑ/g, 'ϑ'); - str = str.replace(/ϒ/g, 'ϒ'); - str = str.replace(/ϖ/g, 'ϖ'); - str = str.replace(/·/g, '·'); - return str; -} - -// - -function strcharacterDiscode(str){ - // 加入常用解析 - str = str.replace(/ /g, ' '); - str = str.replace(/"/g, "'"); - str = str.replace(/&/g, '&'); - // str = str.replace(/</g, '‹'); - // str = str.replace(/>/g, '›'); - - str = str.replace(/</g, '<'); - str = str.replace(/>/g, '>'); - str = str.replace(/•/g, '•'); - - return str; -} - -// HTML 支持的其他实体 -function strOtherDiscode(str){ - str = str.replace(/Œ/g, 'Œ'); - str = str.replace(/œ/g, 'œ'); - str = str.replace(/Š/g, 'Š'); - str = str.replace(/š/g, 'š'); - str = str.replace(/Ÿ/g, 'Ÿ'); - str = str.replace(/ƒ/g, 'ƒ'); - str = str.replace(/ˆ/g, 'ˆ'); - str = str.replace(/˜/g, '˜'); - str = str.replace(/ /g, ''); - str = str.replace(/ /g, ''); - str = str.replace(/ /g, ''); - str = str.replace(/‌/g, ''); - str = str.replace(/‍/g, ''); - str = str.replace(/‎/g, ''); - str = str.replace(/‏/g, ''); - str = str.replace(/–/g, '–'); - str = str.replace(/—/g, '—'); - str = str.replace(/‘/g, '‘'); - str = str.replace(/’/g, '’'); - str = str.replace(/‚/g, '‚'); - str = str.replace(/“/g, '“'); - str = str.replace(/”/g, '”'); - str = str.replace(/„/g, '„'); - str = str.replace(/†/g, '†'); - str = str.replace(/‡/g, '‡'); - str = str.replace(/•/g, '•'); - str = str.replace(/…/g, '…'); - str = str.replace(/‰/g, '‰'); - str = str.replace(/′/g, '′'); - str = str.replace(/″/g, '″'); - str = str.replace(/‹/g, '‹'); - str = str.replace(/›/g, '›'); - str = str.replace(/‾/g, '‾'); - str = str.replace(/€/g, '€'); - str = str.replace(/™/g, '™'); - - str = str.replace(/←/g, '←'); - str = str.replace(/↑/g, '↑'); - str = str.replace(/→/g, '→'); - str = str.replace(/↓/g, '↓'); - str = str.replace(/↔/g, '↔'); - str = str.replace(/↵/g, '↵'); - str = str.replace(/⌈/g, '⌈'); - str = str.replace(/⌉/g, '⌉'); - - str = str.replace(/⌊/g, '⌊'); - str = str.replace(/⌋/g, '⌋'); - str = str.replace(/◊/g, '◊'); - str = str.replace(/♠/g, '♠'); - str = str.replace(/♣/g, '♣'); - str = str.replace(/♥/g, '♥'); - - str = str.replace(/♦/g, '♦'); - str = str.replace(/'/g, '\''); - return str; -} - -function strMoreDiscode(str){ - str = str.replace(/\r\n/g,""); - str = str.replace(/\n/g,""); - - str = str.replace(/code/g,"wxxxcode-style"); - return str; -} - -function strDiscode(str){ - str = strNumDiscode(str); - str = strGreeceDiscode(str); - str = strcharacterDiscode(str); - str = strOtherDiscode(str); - str = strMoreDiscode(str); - return str; -} -function urlToHttpUrl(url,rep){ - - var patt1 = new RegExp("^//"); - var result = patt1.test(url); - if(result){ - url = rep+":"+url; - } - return url; -} - -module.exports = { - strDiscode:strDiscode, - urlToHttpUrl:urlToHttpUrl -} \ No newline at end of file diff --git a/wxParse/wxParse.js b/wxParse/wxParse.js deleted file mode 100644 index 9786417..0000000 --- a/wxParse/wxParse.js +++ /dev/null @@ -1,157 +0,0 @@ -/** - * author: Di (微信小程序开发工程师) - * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com) - * 垂直微信小程序开发交流社区 - * - * github地址: https://github.com/icindy/wxParse - * - * for: 微信小程序富文本解析 - * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184 - */ - -/** - * utils函数引入 - **/ -import showdown from './showdown.js'; -import HtmlToJson from './html2json.js'; -/** - * 配置及公有属性 - **/ -var realWindowWidth = 0; -var realWindowHeight = 0; -tt.getSystemInfo({ - success: function (res) { - realWindowWidth = res.windowWidth - realWindowHeight = res.windowHeight - } -}) -/** - * 主函数入口区 - **/ -function wxParse(bindName = 'wxParseData', type='html', data='
数据不能为空
', target,imagePadding) { - var that = target; - var transData = {};//存放转化后的数据 - if (type == 'html') { - transData = HtmlToJson.html2json(data, bindName); - } else if (type == 'md' || type == 'markdown') { - var converter = new showdown.Converter(); - var html = converter.makeHtml(data); - transData = HtmlToJson.html2json(html, bindName); - } - transData.view = {}; - transData.view.imagePadding = 0; - if(typeof(imagePadding) != 'undefined'){ - transData.view.imagePadding = imagePadding - } - var bindData = {}; - bindData[bindName] = transData; - that.setData(bindData) - that.wxParseImgLoad = wxParseImgLoad; - that.wxParseImgTap = wxParseImgTap; -} -// 图片点击事件 -function wxParseImgTap(e) { - var that = this; - var nowImgUrl = e.target.dataset.src; - var tagFrom = e.target.dataset.from; - if (typeof (tagFrom) != 'undefined' && tagFrom.length > 0) { - tt.previewImage({ - current: nowImgUrl, // 当前显示图片的http链接 - urls: that.data[tagFrom].imageUrls // 需要预览的图片http链接列表 - }) - } -} - -/** - * 图片视觉宽高计算函数区 - **/ -function wxParseImgLoad(e) { - var that = this; - var tagFrom = e.target.dataset.from; - var idx = e.target.dataset.idx; - if (typeof (tagFrom) != 'undefined' && tagFrom.length > 0) { - calMoreImageInfo(e, idx, that, tagFrom) - } -} -// 假循环获取计算图片视觉最佳宽高 -function calMoreImageInfo(e, idx, that, bindName) { - var temData = that.data[bindName]; - if (!temData || temData.images.length == 0) { - return; - } - var temImages = temData.images; - //因为无法获取view宽度 需要自定义padding进行计算,稍后处理 - var recal = wxAutoImageCal(e.detail.width, e.detail.height,that,bindName); - // temImages[idx].width = recal.imageWidth; - // temImages[idx].height = recal.imageheight; - // temData.images = temImages; - // var bindData = {}; - // bindData[bindName] = temData; - // that.setData(bindData); - var index = temImages[idx].index - var key = `${bindName}` - for (var i of index.split('.')) key+=`.nodes[${i}]` - var keyW = key + '.width' - var keyH = key + '.height' - that.setData({ - [keyW]: recal.imageWidth, - [keyH]: recal.imageheight, - }) -} - -// 计算视觉优先的图片宽高 -function wxAutoImageCal(originalWidth, originalHeight,that,bindName) { - //获取图片的原始长宽 - var windowWidth = 0, windowHeight = 0; - var autoWidth = 0, autoHeight = 0; - var results = {}; - var padding = that.data[bindName].view.imagePadding; - windowWidth = realWindowWidth-2*padding; - windowHeight = realWindowHeight; - //判断按照那种方式进行缩放 - // console.log("windowWidth" + windowWidth); - if (originalWidth > windowWidth) {//在图片width大于手机屏幕width时候 - autoWidth = windowWidth; - // console.log("autoWidth" + autoWidth); - autoHeight = (autoWidth * originalHeight) / originalWidth; - // console.log("autoHeight" + autoHeight); - results.imageWidth = autoWidth; - results.imageheight = autoHeight; - } else {//否则展示原来的数据 - results.imageWidth = originalWidth; - results.imageheight = originalHeight; - } - return results; -} - -function wxParseTemArray(temArrayName,bindNameReg,total,that){ - var array = []; - var temData = that.data; - var obj = null; - for(var i = 0; i < total; i++){ - var simArr = temData[bindNameReg+i].nodes; - array.push(simArr); - } - - temArrayName = temArrayName || 'wxParseTemArray'; - obj = JSON.parse('{"'+ temArrayName +'":""}'); - obj[temArrayName] = array; - that.setData(obj); -} - -/** - * 配置emojis - * - */ - -function emojisInit(reg='',baseSrc="/wxParse/emojis/",emojis){ - HtmlToJson.emojisInit(reg,baseSrc,emojis); -} - -module.exports = { - wxParse: wxParse, - wxParseTemArray:wxParseTemArray, - emojisInit:emojisInit -} - - diff --git a/wxParse/wxParse.ttml b/wxParse/wxParse.ttml deleted file mode 100644 index 2608bc9..0000000 --- a/wxParse/wxParse.ttml +++ /dev/null @@ -1,963 +0,0 @@ - - - - - - - - - - - - -