From a1a7ca4692a8d2f28fe13c4ebb8dd230c6bc8b4d Mon Sep 17 00:00:00 2001 From: tfzh Date: Sun, 5 Aug 2018 19:11:56 +0800 Subject: [PATCH] new fontend interface --- client.html | 214 +- css/looper_ui.css | 1555 ++++++ css/main.css | 75 + js/axios.min.js | 9 + js/main.js | 109 + js/main2.js | 109 + js/vue.js | 10947 ++++++++++++++++++++++++++++++++++++++ tmp/websocket_debug.log | 1 + 8 files changed, 12835 insertions(+), 184 deletions(-) create mode 100644 css/looper_ui.css create mode 100644 css/main.css create mode 100644 js/axios.min.js create mode 100644 js/main.js create mode 100644 js/main2.js create mode 100644 js/vue.js create mode 100644 tmp/websocket_debug.log diff --git a/client.html b/client.html index 0996279..e6d19cd 100644 --- a/client.html +++ b/client.html @@ -1,191 +1,37 @@ - - - - - + + + + + Chat test page + + -
-

websocket聊天室

-
-
-

当前在线:0

-
- -
-
-
-
-
-
-
- +

实时聊天室实现

+
+
+

Your id is:{{ user_id }}

+

当前在线:{{ user_num }}人

+

{{ user }}

+ +
+
+
+

{{item}}

+ +
+
+
+ +
+ + + + - \ No newline at end of file diff --git a/css/looper_ui.css b/css/looper_ui.css new file mode 100644 index 0000000..c5031b2 --- /dev/null +++ b/css/looper_ui.css @@ -0,0 +1,1555 @@ +@charset "utf-8"; +/*typo.css的重置样式*/ +/* 防止用户自定义背景颜色对网页的影响,添加让用户可以自定义字体 */ +html { + color: #333; + background: #fff; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + text-rendering: optimizelegibility; +} + +/* 如果你的项目仅支持 IE9+ | Chrome | Firefox 等,推荐在 中添加 .borderbox 这个 class */ +html.borderbox *, html.borderbox *:before, html.borderbox *:after { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +/* 内外边距通常让各个浏览器样式的表现位置不同 */ +body, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, textarea, p, blockquote, th, td, hr, button, article, aside, details, figcaption, figure, footer, header, menu, nav, section { + margin: 0; + padding: 0; +} + +/* 重设 HTML5 标签, IE 需要在 js 中 createElement(TAG) */ +article, aside, details, figcaption, figure, footer, header, menu, nav, section { + display: block; +} + +/* HTML5 媒体文件跟 img 保持一致 */ +audio, canvas, video { + display: inline-block; +} +i{ + font-style: normal; +} +/* 要注意表单元素并不继承父级 font 的问题 */ +body, button, input, select, textarea { + font: 300 1em/1.8 PingFang SC, Lantinghei SC, Microsoft Yahei, Hiragino Sans GB, Microsoft Sans Serif, WenQuanYi Micro Hei, sans-serif; +} + +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} + +/* 去掉各Table cell 的边距并让其边重合 */ +table { + border-collapse: collapse; + border-spacing: 0; + width: 100%; + text-align: center; +} + +/* 去除默认边框 */ +fieldset, img { + border: 0; +} + +/* 块/段落引用 */ +blockquote { + position: relative; + color: #999; + font-weight: 400; + border-left: 1px solid #1abc9c; + padding-left: 1em; + margin: 1em 3em 1em 2em; +} + +@media only screen and ( max-width: 640px ) { + blockquote { + margin: 1em 0; + } +} + +/* Firefox 以外,元素没有下划线,需添加 */ +acronym, abbr { + border-bottom: 1px dotted; + font-variant: normal; +} + +/* 添加鼠标问号,进一步确保应用的语义是正确的(要知道,交互他们也有洁癖,如果你不去掉,那得多花点口舌) */ +abbr { + cursor: help; +} + +/* 一致的 del 样式 */ +del { + text-decoration: line-through; +} + +address, caption, cite, code, dfn, em, th, var { + font-style: normal; + font-weight: 400; +} + +/* 去掉列表前的标识, li 会继承,大部分网站通常用列表来很多内容,所以应该当去 */ +ul, ol { + list-style: none; +} + +/* 对齐是排版最重要的因素, 别让什么都居中 */ +caption, th { + text-align: center; +} + +q:before, q:after { + content: ''; +} + +/* 统一上标和下标 */ +sub, sup { + font-size: 75%; + line-height: 0; + position: relative; +} + +:root sub, :root sup { + vertical-align: baseline; /* for ie9 and other modern browsers */ +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* 让链接在 hover 状态下显示下划线 */ +a { + color: #1abc9c; +} + +a:hover { + text-decoration: underline; +} + +.typo a { + border-bottom: 1px solid #1abc9c; +} + +.typo a:hover { + border-bottom-color: #555; + color: #555; + text-decoration: none; +} + +/* 默认不显示下划线,保持页面简洁 */ +ins, a { + text-decoration: none; +} + +/* 专名号:虽然 u 已经重回 html5 Draft,但在所有浏览器中都是可以使用的, + * 要做到更好,向后兼容的话,添加 class="typo-u" 来显示专名号 + * 关于 标签:http://www.whatwg.org/specs/web-apps/current-work/multipage/text-level-semantics.html#the-u-element + * 被放弃的是 4,之前一直搞错 http://www.w3.org/TR/html401/appendix/changes.html#idx-deprecated + * 一篇关于 标签的很好文章:http://html5doctor.com/u-element/ + */ +u, .typo-u { + text-decoration: underline; +} + +/* 标记,类似于手写的荧光笔的作用 */ +mark { + background: #fffdd1; + border-bottom: 1px solid #ffedce; + padding: 2px; + margin: 0 5px; +} + +/* 代码片断 */ +pre, code, pre tt { + font-family: Courier, 'Courier New', monospace; +} + +pre { + background: #f8f8f8; + border: 1px solid #ddd; + padding: 1em 1.5em; + display: block; + -webkit-overflow-scrolling: touch; +} + +/* 一致化 horizontal rule */ +hr { + border: none; + border-bottom: 1px solid #cfcfcf; + margin-bottom: 0.8em; + height: 10px; +} + +/* 底部印刷体、版本等标记 */ +small, .typo-small, + /* 图片说明 */ +figcaption { + font-size: 0.9em; + color: #888; +} + +strong, b { + font-weight: bold; + color: #000; +} +strong{ + color: #F60; + font-weight: 400; +} + +/* 可拖动文件添加拖动手势 */ +[draggable] { + cursor: move; +} + +.clearfix:before, .clearfix:after { + content: ""; + display: table; +} + +.clearfix:after { + clear: both; +} + +.clearfix { + zoom: 1; +} + +/* 强制文本换行 */ +.textwrap, .textwrap td, .textwrap th { + word-wrap: break-word; + word-break: break-all; +} + +.textwrap-table { + table-layout: fixed; +} + +/* 提供 serif 版本的字体设置: iOS 下中文自动 fallback 到 sans-serif */ +.serif { + font-family: Palatino, Optima, Georgia, serif; +} + +/* 保证块/段落之间的空白隔行 */ +.typo p, .typo pre, .typo ul, .typo ol, .typo dl, .typo form, .typo hr, .typo table, +.typo-p, .typo-pre, .typo-ul, .typo-ol, .typo-dl, .typo-form, .typo-hr, .typo-table, blockquote { + margin-bottom: 1.2em +} + +h1, h2, h3, h4, h5, h6{ + font-family: PingFang SC, Verdana, Helvetica Neue, Microsoft Yahei, Hiragino Sans GB, Microsoft Sans Serif, WenQuanYi Micro Hei, sans-serif; + font-weight: 100; + color: #000; + line-height: 1.35; + width: 100%; +} +p{ + width: 100%; +} + +/* 标题应该更贴紧内容,并与其他块区分,margin 值要相应做优化 */ +.typo h1, .typo h2, .typo h3, .typo h4, .typo h5, .typo h6, +.typo-h1, .typo-h2, .typo-h3, .typo-h4, .typo-h5, .typo-h6 { + margin-top: 1.2em; + line-height: 1.35; +} + +/* 在文章中,应该还原 ul 和 ol 的样式 */ +.typo ul, .typo-ul { + margin-left: 1.3em; + list-style: disc; +} + +.typo ol, .typo-ol { + list-style: decimal; + margin-left: 1.9em; +} + +.typo li ul, .typo li ol, .typo-ul ul, .typo-ul ol, .typo-ol ul, .typo-ol ol { + margin-bottom: 0.8em; + margin-left: 2em; +} + +.typo li ul, .typo-ul ul, .typo-ol ul { + list-style: circle; +} + +/* 同 ul/ol,在文章中应用 table 基本格式 */ +.typo table th, .typo table td, .typo-table th, .typo-table td, .typo table caption { + border: 1px solid #ddd; + padding: 0.5em 1em; + color: #666; +} + +.typo table th, .typo-table th { + background: #fbfbfb; +} + +.typo table thead th, .typo-table thead th { + background: #f1f1f1; +} + +.typo table caption { + border-bottom: none; +} + +/* 去除 webkit 中 input 和 textarea 的默认样式 */ +.typo-input, .typo-textarea { + -webkit-appearance: none; + border-radius: 0; +} + +.typo-em, .typo em, legend, caption { + color: #000; + font-weight: inherit; +} + +/* 着重号,只能在少量(少于100个字符)且全是全角字符的情况下使用 */ +.typo-em { + position: relative; +} + +.typo-em:after { + position: absolute; + top: 0.65em; + left: 0; + width: 100%; + overflow: hidden; + white-space: nowrap; + content: "・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・"; +} + +/* Responsive images */ +img { + max-width: 100%; +} +/*typo.css的重置样式结束*/ + +/*btn css begin*/ +button{ + width: 100%; + height: 40px; + cursor: pointer; + color: #fff; + border:1px solid #ccc; + border-radius: 5px; + background-color: #aab2bd; + transition: all .2s ease-in-out; + outline: none; +} +button:hover{ + background-color: #BDC3C7; + border-color: #BDC3C7; +} + +.btn_info{ + background-color: #3498DB; + color: #fff; + border-color: #3498DB; +} +.btn_info:hover{ + background-color: #2980B9; + border-color: #2980B9; +} +.btn_warning{ + background-color: #f0ad4e; + color: #fff; + border-color: #f0ad4e; +} +.btn_warning:hover{ + background-color: #E67E22; + border-color: #E67E22; +} +.btn_error{ + background-color: #E74C3C; + color: #fff; + border-color: #E74C3C; +} +.btn_error:hover{ + background-color: #C0392B; + border-color: #C0392B; +} + +.btn_success{ + background-color: #2ECC71; + color: #fff; + border-color: #2ECC71; +} +.btn_success:hover{ + background-color: #27AE60; + border-color: #27AE60; +} +.btn_outline{ + background-color: #fff; + color: #000; + border-color: #000; +} +.btn_outline:hover{ + background-color: #ccc; + color: #fff; + border-color: #ccc; +} +.btn_outline_info{ + background-color: #fff; + color: #3498DB; + border-color: #3498DB; +} +.btn_outline_info:hover{ + background-color: #3498DB; + border-color: #3498DB; + color: #fff; +} +.btn_outline_warning{ + background-color: #fff; + color: #f0ad4e; + border-color: #f0ad4e; +} +.btn_outline_warning:hover{ + background-color: #E67E22; + border-color: #E67E22; + color: #fff; +} +.btn_outline_error{ + background-color: #fff; + color: #E74C3C; + border-color: #E74C3C; +} +.btn_outline_error:hover{ + background-color: #C0392B; + border-color: #C0392B; + color: #fff; +} + +.btn_outline_success{ + background-color: #fff; + color: #2ECC71; + border-color: #2ECC71; +} +.btn_outline_success:hover{ + background-color: #27AE60; + border-color: #27AE60; + color: #fff; +} +.disabled{ + cursor: not-allowed; + background-color: #eaeded; + border-color:#eaeded; + color:#cad2d3; +} +.disabled:hover{ + background-color: #eaeded; + border-color:#eaeded; + color:#cad2d3; +} +/*btn css end*/ + +/*input css begin*/ +*{ + -webkit-tap-highlight-color: rgba(0,0,0,0); +} +input[type="checkbox"],input[type="radio"]{ + display: none; +} +input[type="checkbox"]:checked + label:after{ + transition: all 0.3s ease-in; +} +input[type="checkbox"]:not(:checked) + label:after { + transition: all 0.3s ease-out; +} +input[type="checkbox"]:checked + label, +input[type="checkbox"]:not(:checked) + label{ + transition: all 0.3s ease-in-out; +} +input[type="checkbox"]:checked + label:before,input[type="checkbox"]:checked + label i:before,input[type="checkbox"]:not(:checked) + label i:before, +input[type="checkbox"]:checked + label i:after,input[type="checkbox"]:not(:checked) + label i:after,input[type="checkbox"]:not(:checked) + label:before{ + transition: all 0.3s ease-in-out; +} +input[type="radio"]:checked + label:after, +input[type="radio"]:not(:checked) + label:after { + transition: all 0.3s ease-in-out; +} +.switch_iOS + label{ + background-color: #fff; + border-radius:12px; + cursor: pointer; + display: inline-block; + height: 24px; + position: relative; + box-shadow: 0.2px 0.2px 1px 0.5px rgb(180,180,180); + width: 52px; +} +.switch_iOS + label i:after{ + position: absolute; + left: 15px; + top: 6px; + content: ""; + height: 12px; + width: 2px; + background-color: rgb(255,255,255); + border:0; +} +.switch_iOS + label i:before{ + position: absolute; + content: ""; + height: 10px; + width: 10px; + left: 32px; + border-radius: 50%; + border:2px solid rgb(180,180,180); + top: 5px; +} +.switch_iOS + label:after{ + background-color: #fff; + border-radius: 50%; + content: ""; + height: 22px; + left: 1px; + position: absolute; + top: 1px; + width: 22px; + box-shadow: 0.2px 0.2px 1px 0.5px rgb(180,180,180); +} +.switch_iOS + label:before{ + content: ""; + background-color: #fff; + border-radius:12px; + display: inline-block; + height: 24px; + position: absolute; + top: 0px; + left: 0px; + /*box-shadow: 0px 0px 1px 0.5px rgb(180,180,180);*/ + width: 52px; +} +.switch_iOS:checked + label{ + background-color: #2ECC71; + box-shadow:none; +} +.switch_iOS:checked + label:after{ + left: 29px; +} +.switch_iOS:checked + label:before{ + transform: scale(0,0); + -webkit-transform: scale(0,0); +} +.switch_iOS:checked + label i:before{ + transform: scale(0,0); + -webkit-transform: scale(0,0); +} +.switch_default + label{ + background-color: #e6e6e6; + border-radius:12px; + cursor: pointer; + display: inline-block; + height: 24px; + position: relative; + box-shadow: 0.2px 0.2px 1px 0.5px rgb(180,180,180); + width: 52px; +} +.switch_default + label:after{ + background-color: #fff; + border-radius: 50%; + content: ""; + height: 22px; + left: 1px; + position: absolute; + top: 1px; + width: 22px; + box-shadow: 0.2px 0.2px 1px 0.5px rgb(180,180,180); +} +.switch_default:checked + label{ + background-color: #1ABC9C; + box-shadow:none; +} +.switch_default:checked + label:after{ + left: 29px; +} +.switch_FlymeOS + label{ + background-color: #fff; + border-radius:12px; + cursor: pointer; + display: inline-block; + height: 24px; + position: relative; + box-shadow: 0.2px 0.2px 1px 0.5px rgb(180,180,180); + width: 52px; +} +.switch_FlymeOS + label:after{ + background-color:rgb(180,180,180); + content: ""; + height: 4px; + left: 8px; + position: absolute; + top: 10px; + width: 12px; + border-radius: 2px; + box-shadow: 0.2px 0.2px 0.5px 0px rgb(180,180,180); +} +.switch_FlymeOS:checked + label:after{ + background-color: #3498DB; + border-radius: 50%; + height: 16px; + left: 30px; + top: 4px; + width: 16px; +} +.switch_MIUI + label{ + background-color: #fff; + border-radius:12px; + cursor: pointer; + display: inline-block; + height: 24px; + position: relative; + box-shadow: 0.2px 0.2px 1px 0.5px rgb(180,180,180); + width: 52px; +} +.switch_MIUI + label:after{ + background-color:rgb(180,180,180); + content: ""; + border-radius: 50%; + height: 14px; + left: 6px; + position: absolute; + top: 5px; + width: 14px; + box-shadow: 0.2px 0.2px 0.5px 0px rgb(180,180,180); +} +.switch_MIUI:checked + label:after{ + background-color: #3498DB; + left: 32px; +} +.switch_Diamond + label{ + background-color: #34495E; + cursor: pointer; + display: inline-block; + height: 24px; + position: relative; + width: 52px; + border-radius: 2px; +} +.switch_Diamond + label:after{ + background-color:#fff; + content: ""; + height: 22px; + left: 1px; + position: absolute; + top: 1px; + width: 22px; + border-radius: 2px; +} +.switch_Diamond + label i:after{ + content: ""; + width: 2px; + height: 12px; + position: absolute; + top: 6px; + left: 37px; + background-color: #fff; + transform:rotate(45deg); + border-radius: 1px; +} +.switch_Diamond + label i:before{ + content: ""; + width: 2px; + height: 12px; + position: absolute; + top: 6px; + left: 37px; + background-color: #fff; + transform:rotate(-45deg); + border-radius: 1px; +} +.switch_Diamond:checked + label i:after{ + width: 2px; + height: 12px; + top: 6px; + left: 14px; +} +.switch_Diamond:checked + label i:before{ + width: 2px; + height: 7px; + top: 11px; + left: 8px; +} +.switch_Diamond:checked + label{ + background-color: #2ECC71; +} +.switch_Diamond:checked + label:after{ + left: 29px; +} +.switch_Ellipse + label{ + background-color: #e6e6e6; + border-radius:12px; + cursor: pointer; + display: inline-block; + height: 24px; + position: relative; + box-shadow: 0.2px 0.2px 1px 0.5px rgb(180,180,180); + width: 52px; +} +.switch_Ellipse + label:after{ + animation-name: goleft; + animation-duration: 0.6s; + animation-fill-mode: both; + border-radius: 50%; + background-color: #fff; + content: ""; + height: 18px; + width: 18px; + position: absolute; + top: 3px; + box-shadow: 0.2px 0.2px 1px 0.5px rgb(180,180,180); +} +.switch_Ellipse:checked + label:after{ + animation-name: goright; + animation-duration: 0.6s; + animation-fill-mode: both; + background-color: #3498DB; +} +@keyframes goright{ + 0% { + left: 2px; + } + + 50%{ + left: 21px; + width: 27px; + border-radius: 50% 9px 9px 50%; + } + + 100% { + left: 32px; + width: 18px; + } +} +@keyframes goleft{ + 0% { + left: 32px; + + } + + 50%{ + left: 6px; + width: 27px; + border-radius: 9px 50% 50% 9px; + } + + 100% { + left: 2px; + width: 18px; + } +} +.switch_Color + label{ + background-color: rgb(249,183,61); + cursor: pointer; + border-radius:12px; + height: 24px; + position: relative; + width: 52px; + box-shadow: 0.2px 0.2px 1px 0.5px rgb(180,180,180); +} +.switch_Color + label:after{ + border-radius: 50%; + background-color: #fff; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3Ccircle cx='10' cy='10' r='5' fill='%23FFE4B5' /%3E%3C/svg%3E "); + content: ""; + height: 20px; + width: 20px; + position: absolute; + top: 2px; + left: 1px; + box-shadow: 0.2px 0.2px 1px 0.5px rgb(180,180,180); +} +.switch_Color:checked + label{ + background-color: rgb(167,235,0); +} +.switch_Color:checked + label:after{ + left: 31px; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3Ccircle cx='10' cy='10' r='5' fill='#CAFF70' /%3E%3C/svg%3E "); +} + +.switch_Color + label i:after{ + content: ""; + width: 2px; + height: 12px; + position: absolute; + top: 6px; + left: 37px; + background-color: #fff; + transform:rotate(45deg); + border-radius: 1px; +} +.switch_Color + label i:before{ + content: ""; + width: 2px; + height: 12px; + position: absolute; + top: 6px; + left: 37px; + background-color: #fff; + transform:rotate(-45deg); + border-radius: 1px; +} +.switch_Color:checked + label i:after{ + width: 2px; + height: 12px; + top: 6px; + left: 14px; +} +.switch_Color:checked + label i:before{ + width: 2px; + height: 7px; + top: 11px; + left: 8px; +} +.switch_Gradient + label{ + background-color: rgb(224,228,237); + cursor: pointer; + border-radius:12px; + height: 24px; + position: relative; + width: 52px; + box-shadow: 0.2px 0.2px 1px 0.5px rgb(180,180,180); +} +.switch_Gradient + label:after{ + border-radius: 50%; + background-color: #fff; + background-image: url("data:image/svg+xml,%3Csvg width='100%25' height='100%25' version='1.1'%0Axmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='10' cy='10' r='4' stroke='%23b5b5b5'%0Astroke-width='1' fill='%23fff'/%3E%3C/svg%3E"); + content: ""; + height: 20px; + width: 20px; + position: absolute; + top: 2px; + left: 1px; + box-shadow: 0.2px 0.2px 1px 0.5px rgb(180,180,180); +} +.switch_Gradient:checked + label:after{ + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1.1'%3E%3Cline x1='10' y1='6' x2='10' y2='14' style='stroke:rgb%28180,180,180%29;stroke-width:2' /%3E%3C/svg%3E"); + left: 31px; +} +.switch_Gradient:checked + label{ + background: linear-gradient(to right,rgb(5,201,251) ,rgb(53,131,216)); +} +.switch_Word + label{ + background-color: rgb(230,230,222); + border-radius:12px; + cursor: pointer; + display: inline-block; + height: 24px; + position: relative; + box-shadow: 0.2px 0.2px 1px 0.5px rgb(180,180,180); + width: 52px; +} +.switch_Word + label:after{ + border-radius: 50%; + background-color: #fff; + content: ""; + height: 16px; + width: 16px; + position: absolute; + top: 2px; + left: 1px; + /*box-shadow: 0.2px 0.2px 1px 0.5px rgb(180,180,180);*/ + border:2px solid rgb(156,140,197); +} +.switch_Word + label:before{ + content: "OFF"; + height: 20px; + width: 20px; + color: rgb(180,180,180); + font-size: 12px; + position: absolute; + top: 2px; + left: 25px; +} +.switch_Word:checked + label{ + background-color: rgb(156,140,197); +} +.switch_Word:checked + label:after{ + border:2px solid #fff; + left: 30px; +} +.switch_Word:checked + label:before{ + content: "ON"; + left: 5px; + color: #fff; +} +.switch_Rotate + label{ + background-color: #fff; + cursor: pointer; + display: inline-block; + height: 24px; + position: relative; + width: 52px; + border-radius: 12px; + box-shadow: 0.2px 0.2px 1px 0.5px rgb(180,180,180); +} +.switch_Rotate + label:after{ + background-color:rgb(243,229,211); + content: ""; + height: 20px; + left: 2px; + position: absolute; + top: 2px; + width: 20px; + border-radius: 50%; +} +.switch_Rotate + label i:after{ + content: ""; + width: 2px; + height: 12px; + position: absolute; + background-color: #fff; + border-radius: 1px; + animation-name: roleft; + animation-duration: 0.6s; + animation-fill-mode: both; + z-index: 1; + top: 6px; +} +.switch_Rotate + label i:before{ + content: ""; + width: 2px; + height: 12px; + position: absolute; + background-color: #fff; + animation-name: ro2left; + animation-duration: 0.6s; + animation-fill-mode: both; + border-radius: 1px; + z-index: 1; + top: 6px; +} +.switch_Rotate:checked + label:after{ + left: 31px; + background-color: rgb(126,134,250); +} +.switch_Rotate:checked + label i:after{ + animation-name: roright; + animation-duration: 0.6s; + animation-fill-mode: both; + +} +.switch_Rotate:checked + label i:before{ + animation-name: ro2right; + animation-duration: 0.6s; + animation-fill-mode: both; + height: 7px; +} +@keyframes roright{ + 0% { + left: 11px; + } + 100% { + left: 43px; + height: 12px; + transform:rotate(-135deg); + } +} +@keyframes ro2right{ + 0% { + left: 11px; + } + 100% { + top: 10px; + left: 37px; + transform:rotate(-225deg); + } +} +@keyframes roleft{ + 0% { + left: 43px; + height: 12px; + transform:rotate(-135deg); + + } + 100% { + transform:rotate(45deg); + left: 11px; + } +} + @keyframes ro2left{ + 0% { + left: 37px; + transform:rotate(-225deg); + } + 100% { + transform:rotate(-45deg); + left: 11px; + } +} +.radio_input + label{ + display: inline-block; + width: 18px; + height: 18px; + cursor: pointer; + border-radius: 50%; + border:2px solid rgb(180,180,180); + position: relative; +} +.radio_input + label:after{ + background-color: rgb(180,180,180); + border-radius: 50%; + content: ""; + top: 4px; + height: 10px; + left: 4px; + position: absolute; + width: 10px; +} +.radio_input:checked + label:after{ + background-color: #1ABC9C; +} +.radio_input:checked + label{ + border:2px solid #1ABC9C; +} +.checkbox_input + label{ + display: inline-block; + width: 20px; + height: 20px; + cursor: pointer; + border-radius: 25%; + position: relative; + background-color: rgb(180,180,180); +} +.checkbox_input + label:after{ + content: ""; + width: 2px; + height: 10px; + position: absolute; + top: 5px; + left: 11px; + background-color: #fff; + transform:rotate(45deg); + border-radius: 1px; +} +.checkbox_input + label:before{ + content: ""; + width: 2px; + height: 7px; + position: absolute; + top: 8px; + left: 6px; + background-color: #fff; + transform:rotate(-45deg); + border-radius: 1px; +} +.checkbox_input:checked +label{ + background-color: #1ABC9C; +} +.text_input{ + width: 100%; + padding: .375rem .75rem; + font-size: 1rem; + line-height: 1; + background-color: #fff; + background-image: none; + border: .0625rem solid #ccc; + border-radius: 0.3rem; + background-repeat: no-repeat; + background-position: center right 0.625rem; + -webkit-background-size: 1.25rem 1.25rem; + background-size: 1.25rem 1.25rem; +} +.text_input:focus{ + border:1px solid #1ABC9C; + outline: none; +} +.input_warnning{ + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23f0ad4e' d='M4.4 5.324h-.8v-2.46h.8zm0 1.42h-.8V5.89h.8zM3.76.63L.04 7.075c-.115.2.016.425.26.426h7.397c.242 0 .372-.226.258-.426C6.726 4.924 5.47 2.79 4.253.63c-.113-.174-.39-.174-.494 0z'/%3E%3C/svg%3E"); + color: #f0ad4e; + border-color: #f0ad4e; +} +.input_error{ + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23d9534f' viewBox='-2 -2 7 7'%3E%3Cpath stroke='%23d9534f' d='M0 0l3 3m0-3L0 3'/%3E%3Ccircle r='.5'/%3E%3Ccircle cx='3' r='.5'/%3E%3Ccircle cy='3' r='.5'/%3E%3Ccircle cx='3' cy='3' r='.5'/%3E%3C/svg%3E"); + color: #d9534f; + border-color: #d9534f; +} +.input_success{ + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%235cb85c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E"); + color: #5cb85c; + border-color: #5cb85c; +} + +/*input css end*/ + +/*自适应 css begin*/ +.col_1, .col_2, .col_3, .col_4, .col_5, .col_6, .col_7, .col_8 ,.col_9 ,.col_10 ,.col_11 , .col_12, +.col_xs_1, .col_xs_2, .col_xs_3, .col_xs_4, .col_xs_5, .col_xs_6, .col_xs_7, .col_xs_8, .col_xs_9, .col_xs_10, .col_xs_11, .col_xs_12, +.col_sm_1, .col_sm_2, .col_sm_3, .col_sm_4, .col_sm_5, .col_sm_6, .col_sm_7, .col_sm_8, .col_sm_9, .col_sm_10, .col_sm_11, .col_sm_12, +.col_md_1, .col_md_2, .col_md_3, .col_md_4, .col_md_5, .col_md_6, .col_md_7, .col_md_8, .col_md_9, .col_md_10, .col_md_11, .col_md_12, +.col_lg_1, .col_lg_2, .col_lg_3, .col_lg_4, .col_lg_5, .col_lg_6, .col_lg_7, .col_lg_8, .col_lg_9, .col_lg_10, .col_lg_11, .col_lg_12, +.col_xl_1, .col_xl_2, .col_xl_3, .col_xl_4, .col_xl_5, .col_xl_6, .col_xl_7, .col_xl_8, .col_xl_9, .col_xl_10, .col_xl_11, .col_xl_12{ + display: flex; + flex-flow:row wrap; + justify-content: flex-start; + align-items: flex-start; + align-content: flex-start; +/* display: block; + float: left;*/ +} +.padding{ + padding: 5px; +} +.col_1{ + width: 8.333333%; +} +.col_2 { + width: 16.666666%; +} + +.col_3 { + width: 25%; +} + +.col_4 { + width: 33.333333%; +} + +.col_5 { + width: 41.666666%; +} + +.col_6 { + width: 50%; +} + +.col_7 { + width: 58.333333%; +} + +.col_8 { + width: 66.666666%; +} + +.col_9 { + width: 75%; +} + +.col_10 { + width: 83.333333%; +} + +.col_11 { + width: 91.666666%; +} + +.col_12 { + width: 100%; +} +.offset_1 { + margin-left: 8.333333%; +} + +.offset_2 { + margin-left: 16.666666%; +} + +.offset_3 { + margin-left: 25%; +} + +.offset_4 { + margin-left: 33.333333%; +} + +.offset_5 { + margin-left: 41.666666%; +} + +.offset_6 { + margin-left: 50%; +} + +.offset_7 { + margin-left: 58.333333%; +} + +.offset_8 { + margin-left: 66.666666%; +} + +.offset_9 { + margin-left: 75%; +} + +.offset_10 { + margin-left: 83.333333%; +} + +.offset_11 { + margin-left: 91.666666%; +} +@media (max-width: 575px) { + .col_xs_1 { + width: 8.333333%; + } + .col_xs_2 { + width: 16.666666%; + } + .col_xs_3 { + width: 25%; + } + .col_xs_4 { + width: 33.333333%; + } + .col_xs_5 { + width: 41.666666%; + } + .col_xs_6 { + width: 50%; + } + .col_xs_7 { + width: 58.333333%; + } + .col_xs_8 { + width: 66.666666%; + } + .col_xs_9 { + width: 75%; + } + .col_xs_10 { + width: 83.333333%; + } + .col_xs_11 { + width: 91.666666%; + } + .col_xs_12 { + width: 100%; + } + .offset_xs_1 { + margin-left: 8.333333%; + } + .offset_xs_2 { + margin-left: 16.666666%; + } + .offset_xs_3 { + margin-left: 25%; + } + .offset_xs_4 { + margin-left: 33.333333%; + } + .offset_xs_5 { + margin-left: 41.666666%; + } + .offset_xs_6 { + margin-left: 50%; + } + .offset_xs_7 { + margin-left: 58.333333%; + } + .offset_xs_8 { + margin-left: 66.666666%; + } + .offset_xs_9 { + margin-left: 75%; + } + .offset_xs_10 { + margin-left: 83.333333%; + } + .offset_xs_11 { + margin-left: 91.666666%; + } +} +@media (min-width: 576px) { + .col_sm_1 { + width: 8.333333%; + } + .col_sm_2 { + width: 16.666666%; + } + .col_sm_3 { + width: 25%; + } + .col_sm_4 { + width: 33.333333%; + } + .col_sm_5 { + width: 41.666666%; + } + .col_sm_6 { + width: 50%; + } + .col_sm_7 { + width: 58.333333%; + } + .col_sm_8 { + width: 66.666666%; + } + .col_sm_9 { + width: 75%; + } + .col_sm_10 { + width: 83.333333%; + } + .col_sm_11 { + width: 91.666666%; + } + .col_sm_12 { + width: 100%; + } + .offset_sm_1 { + margin-left: 8.333333%; + } + .offset_sm_2 { + margin-left: 16.666666%; + } + .offset_sm_3 { + margin-left: 25%; + } + .offset_sm_4 { + margin-left: 33.333333%; + } + .offset_sm_5 { + margin-left: 41.666666%; + } + .offset_sm_6 { + margin-left: 50%; + } + .offset_sm_7 { + margin-left: 58.333333%; + } + .offset_sm_8 { + margin-left: 66.666666%; + } + .offset_sm_9 { + margin-left: 75%; + } + .offset_sm_10 { + margin-left: 83.333333%; + } + .offset_sm_11 { + margin-left: 91.666666%; + } +} + +@media (min-width: 768px) { + .col_md_1 { + width: 8.333333%; + } + .col_md_2 { + width: 16.666666%; + } + .col_md_3 { + width: 25%; + } + .col_md_4 { + width: 33.333333%; + } + .col_md_5 { + width: 41.666666%; + } + .col_md_6 { + width: 50%; + } + .col_md_7 { + width: 58.333333%; + } + .col_md_8 { + width: 66.666666%; + } + .col_md_9 { + width: 75%; + } + .col_md_10 { + width: 83.333333%; + } + .col_md_11 { + width: 91.666666%; + } + .col_md_12 { + width: 100%; + } + .offset_md_1 { + margin-left: 8.333333%; + } + .offset_md_2 { + margin-left: 16.666666%; + } + .offset_md_3 { + margin-left: 25%; + } + .offset_md_4 { + margin-left: 33.333333%; + } + .offset_md_5 { + margin-left: 41.666666%; + } + .offset_md_6 { + margin-left: 50%; + } + .offset_md_7 { + margin-left: 58.333333%; + } + .offset_md_8 { + margin-left: 66.666666%; + } + .offset_md_9 { + margin-left: 75%; + } + .offset_md_10 { + margin-left: 83.333333%; + } + .offset_md_11 { + margin-left: 91.666666%; + } +} + +@media (min-width: 992px) { + .col_lg_1 { + width: 8.333333%; + } + .col_lg_2 { + width: 16.666666%; + } + .col_lg_3 { + width: 25%; + } + .col_lg_4 { + width: 33.333333%; + } + .col_lg_5 { + width: 41.666666%; + } + .col_lg_6 { + width: 50%; + } + .col_lg_7 { + width: 58.333333%; + } + .col_lg_8 { + width: 66.666666%; + } + .col_lg_9 { + width: 75%; + } + .col_lg_10 { + width: 83.333333%; + } + .col_lg_11 { + width: 91.666666%; + } + .col_lg_12 { + width: 100%; + } + .offset_lg_0 { + margin-left: 0%; + } + .offset_lg_1 { + margin-left: 8.333333%; + } + .offset_lg_2 { + margin-left: 16.666666%; + } + .offset_lg_3 { + margin-left: 25%; + } + .offset_lg_4 { + margin-left: 33.333333%; + } + .offset_lg_5 { + margin-left: 41.666666%; + } + .offset_lg_6 { + margin-left: 50%; + } + .offset_lg_7 { + margin-left: 58.333333%; + } + .offset_lg_8 { + margin-left: 66.666666%; + } + .offset_lg_9 { + margin-left: 75%; + } + .offset_lg_10 { + margin-left: 83.333333%; + } + .offset_lg_11 { + margin-left: 91.666666%; + } +} + +@media (min-width: 1200px) { + .col_xl_1 { + width: 8.333333%; + } + .col_xl_2 { + width: 16.666666%; + } + .col_xl_3 { + width: 25%; + } + .col_xl_4 { + width: 33.333333%; + } + .col_xl_5 { + width: 41.666666%; + } + .col_xl_6 { + width: 50%; + } + .col_xl_7 { + width: 58.333333%; + } + .col_xl_8 { + width: 66.666666%; + } + .col_xl_9 { + width: 75%; + } + .col_xl_10 { + width: 83.333333%; + } + .col_xl_11 { + width: 91.666666%; + } + .col_xl_12 { + width: 100%; + } + .offset_xl_1 { + margin-left: 8.333333%; + } + .offset_xl_2 { + margin-left: 16.666666%; + } + .offset_xl_3 { + margin-left: 25%; + } + .offset_xl_4 { + margin-left: 33.333333%; + } + .offset_xl_5 { + margin-left: 41.666666%; + } + .offset_xl_6 { + margin-left: 50%; + } + .offset_xl_7 { + margin-left: 58.333333%; + } + .offset_xl_8 { + margin-left: 66.666666%; + } + .offset_xl_9 { + margin-left: 75%; + } + .offset_xl_10 { + margin-left: 83.333333%; + } + .offset_xl_11 { + margin-left: 91.666666%; + } +} +/*自适应 css begin*/ \ No newline at end of file diff --git a/css/main.css b/css/main.css new file mode 100644 index 0000000..de08c5c --- /dev/null +++ b/css/main.css @@ -0,0 +1,75 @@ +.describe{ + text-align: center; + margin-top: 30px; + margin-bottom: 10px; +} +.view{ + font-size: 0; + width: 800px; + height: 500px; + margin-left: calc(50% - 400px); + border: 1px solid #ccc; +} +.chat_list{ + font-size: 18px; + float: left; + width: 200px; + height: 500px; + background-color: rgb(54,63,72); +} +.history{ + font-size: 18px; + float: left; + width: 600px; + height: 500px; +} +.history_box{ + display: block; + height: 440px; + background-color: rgb(240,240,240); + overflow: scroll; +} +.msg_box{ + float: left; + height: 60px; + width: 500px; +} +.send_btn{ + font-size: 16px; + width: 100px; + height: 60px; + border-radius: 0; + border:none; +} +.send_btn:hover{ + background-color: rgb(84,210,137); +} +.text_input{ + border:none; + height: 60px; + padding: 0; + padding-left: 5px; + margin:0; +} + +.text_input:focus{ + border-radius: 0; + border:none; +} +.msg{ + font-size: 16px; + list-style: none; + padding: 5px; + border: none; + border-radius: 5px; + -webkit-border-radius:5px; + -moz-border-radius: 5px; + background-color: white; + /*box-shadow: 3px 3px 3px #ccc;*/ + display:inline; + line-height: 40px; +} +.your_id{ + color: white; + text-align: center; +} \ No newline at end of file diff --git a/js/axios.min.js b/js/axios.min.js new file mode 100644 index 0000000..69cc188 --- /dev/null +++ b/js/axios.min.js @@ -0,0 +1,9 @@ +/* axios v0.18.0 | (c) 2018 by Matt Zabriskie */ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.axios=t():e.axios=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return e[r].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){e.exports=n(1)},function(e,t,n){"use strict";function r(e){var t=new s(e),n=i(s.prototype.request,t);return o.extend(n,s.prototype,t),o.extend(n,t),n}var o=n(2),i=n(3),s=n(5),u=n(6),a=r(u);a.Axios=s,a.create=function(e){return r(o.merge(u,e))},a.Cancel=n(23),a.CancelToken=n(24),a.isCancel=n(20),a.all=function(e){return Promise.all(e)},a.spread=n(25),e.exports=a,e.exports.default=a},function(e,t,n){"use strict";function r(e){return"[object Array]"===R.call(e)}function o(e){return"[object ArrayBuffer]"===R.call(e)}function i(e){return"undefined"!=typeof FormData&&e instanceof FormData}function s(e){var t;return t="undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&e.buffer instanceof ArrayBuffer}function u(e){return"string"==typeof e}function a(e){return"number"==typeof e}function c(e){return"undefined"==typeof e}function f(e){return null!==e&&"object"==typeof e}function p(e){return"[object Date]"===R.call(e)}function d(e){return"[object File]"===R.call(e)}function l(e){return"[object Blob]"===R.call(e)}function h(e){return"[object Function]"===R.call(e)}function m(e){return f(e)&&h(e.pipe)}function y(e){return"undefined"!=typeof URLSearchParams&&e instanceof URLSearchParams}function w(e){return e.replace(/^\s*/,"").replace(/\s*$/,"")}function g(){return("undefined"==typeof navigator||"ReactNative"!==navigator.product)&&("undefined"!=typeof window&&"undefined"!=typeof document)}function v(e,t){if(null!==e&&"undefined"!=typeof e)if("object"!=typeof e&&(e=[e]),r(e))for(var n=0,o=e.length;n + * @license MIT + */ +e.exports=function(e){return null!=e&&(n(e)||r(e)||!!e._isBuffer)}},function(e,t,n){"use strict";function r(e){this.defaults=e,this.interceptors={request:new s,response:new s}}var o=n(6),i=n(2),s=n(17),u=n(18);r.prototype.request=function(e){"string"==typeof e&&(e=i.merge({url:arguments[0]},arguments[1])),e=i.merge(o,{method:"get"},this.defaults,e),e.method=e.method.toLowerCase();var t=[u,void 0],n=Promise.resolve(e);for(this.interceptors.request.forEach(function(e){t.unshift(e.fulfilled,e.rejected)}),this.interceptors.response.forEach(function(e){t.push(e.fulfilled,e.rejected)});t.length;)n=n.then(t.shift(),t.shift());return n},i.forEach(["delete","get","head","options"],function(e){r.prototype[e]=function(t,n){return this.request(i.merge(n||{},{method:e,url:t}))}}),i.forEach(["post","put","patch"],function(e){r.prototype[e]=function(t,n,r){return this.request(i.merge(r||{},{method:e,url:t,data:n}))}}),e.exports=r},function(e,t,n){"use strict";function r(e,t){!i.isUndefined(e)&&i.isUndefined(e["Content-Type"])&&(e["Content-Type"]=t)}function o(){var e;return"undefined"!=typeof XMLHttpRequest?e=n(8):"undefined"!=typeof process&&(e=n(8)),e}var i=n(2),s=n(7),u={"Content-Type":"application/x-www-form-urlencoded"},a={adapter:o(),transformRequest:[function(e,t){return s(t,"Content-Type"),i.isFormData(e)||i.isArrayBuffer(e)||i.isBuffer(e)||i.isStream(e)||i.isFile(e)||i.isBlob(e)?e:i.isArrayBufferView(e)?e.buffer:i.isURLSearchParams(e)?(r(t,"application/x-www-form-urlencoded;charset=utf-8"),e.toString()):i.isObject(e)?(r(t,"application/json;charset=utf-8"),JSON.stringify(e)):e}],transformResponse:[function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(e){}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,validateStatus:function(e){return e>=200&&e<300}};a.headers={common:{Accept:"application/json, text/plain, */*"}},i.forEach(["delete","get","head"],function(e){a.headers[e]={}}),i.forEach(["post","put","patch"],function(e){a.headers[e]=i.merge(u)}),e.exports=a},function(e,t,n){"use strict";var r=n(2);e.exports=function(e,t){r.forEach(e,function(n,r){r!==t&&r.toUpperCase()===t.toUpperCase()&&(e[t]=n,delete e[r])})}},function(e,t,n){"use strict";var r=n(2),o=n(9),i=n(12),s=n(13),u=n(14),a=n(10),c="undefined"!=typeof window&&window.btoa&&window.btoa.bind(window)||n(15);e.exports=function(e){return new Promise(function(t,f){var p=e.data,d=e.headers;r.isFormData(p)&&delete d["Content-Type"];var l=new XMLHttpRequest,h="onreadystatechange",m=!1;if("undefined"==typeof window||!window.XDomainRequest||"withCredentials"in l||u(e.url)||(l=new window.XDomainRequest,h="onload",m=!0,l.onprogress=function(){},l.ontimeout=function(){}),e.auth){var y=e.auth.username||"",w=e.auth.password||"";d.Authorization="Basic "+c(y+":"+w)}if(l.open(e.method.toUpperCase(),i(e.url,e.params,e.paramsSerializer),!0),l.timeout=e.timeout,l[h]=function(){if(l&&(4===l.readyState||m)&&(0!==l.status||l.responseURL&&0===l.responseURL.indexOf("file:"))){var n="getAllResponseHeaders"in l?s(l.getAllResponseHeaders()):null,r=e.responseType&&"text"!==e.responseType?l.response:l.responseText,i={data:r,status:1223===l.status?204:l.status,statusText:1223===l.status?"No Content":l.statusText,headers:n,config:e,request:l};o(t,f,i),l=null}},l.onerror=function(){f(a("Network Error",e,null,l)),l=null},l.ontimeout=function(){f(a("timeout of "+e.timeout+"ms exceeded",e,"ECONNABORTED",l)),l=null},r.isStandardBrowserEnv()){var g=n(16),v=(e.withCredentials||u(e.url))&&e.xsrfCookieName?g.read(e.xsrfCookieName):void 0;v&&(d[e.xsrfHeaderName]=v)}if("setRequestHeader"in l&&r.forEach(d,function(e,t){"undefined"==typeof p&&"content-type"===t.toLowerCase()?delete d[t]:l.setRequestHeader(t,e)}),e.withCredentials&&(l.withCredentials=!0),e.responseType)try{l.responseType=e.responseType}catch(t){if("json"!==e.responseType)throw t}"function"==typeof e.onDownloadProgress&&l.addEventListener("progress",e.onDownloadProgress),"function"==typeof e.onUploadProgress&&l.upload&&l.upload.addEventListener("progress",e.onUploadProgress),e.cancelToken&&e.cancelToken.promise.then(function(e){l&&(l.abort(),f(e),l=null)}),void 0===p&&(p=null),l.send(p)})}},function(e,t,n){"use strict";var r=n(10);e.exports=function(e,t,n){var o=n.config.validateStatus;n.status&&o&&!o(n.status)?t(r("Request failed with status code "+n.status,n.config,null,n.request,n)):e(n)}},function(e,t,n){"use strict";var r=n(11);e.exports=function(e,t,n,o,i){var s=new Error(e);return r(s,t,n,o,i)}},function(e,t){"use strict";e.exports=function(e,t,n,r,o){return e.config=t,n&&(e.code=n),e.request=r,e.response=o,e}},function(e,t,n){"use strict";function r(e){return encodeURIComponent(e).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}var o=n(2);e.exports=function(e,t,n){if(!t)return e;var i;if(n)i=n(t);else if(o.isURLSearchParams(t))i=t.toString();else{var s=[];o.forEach(t,function(e,t){null!==e&&"undefined"!=typeof e&&(o.isArray(e)?t+="[]":e=[e],o.forEach(e,function(e){o.isDate(e)?e=e.toISOString():o.isObject(e)&&(e=JSON.stringify(e)),s.push(r(t)+"="+r(e))}))}),i=s.join("&")}return i&&(e+=(e.indexOf("?")===-1?"?":"&")+i),e}},function(e,t,n){"use strict";var r=n(2),o=["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"];e.exports=function(e){var t,n,i,s={};return e?(r.forEach(e.split("\n"),function(e){if(i=e.indexOf(":"),t=r.trim(e.substr(0,i)).toLowerCase(),n=r.trim(e.substr(i+1)),t){if(s[t]&&o.indexOf(t)>=0)return;"set-cookie"===t?s[t]=(s[t]?s[t]:[]).concat([n]):s[t]=s[t]?s[t]+", "+n:n}}),s):s}},function(e,t,n){"use strict";var r=n(2);e.exports=r.isStandardBrowserEnv()?function(){function e(e){var t=e;return n&&(o.setAttribute("href",t),t=o.href),o.setAttribute("href",t),{href:o.href,protocol:o.protocol?o.protocol.replace(/:$/,""):"",host:o.host,search:o.search?o.search.replace(/^\?/,""):"",hash:o.hash?o.hash.replace(/^#/,""):"",hostname:o.hostname,port:o.port,pathname:"/"===o.pathname.charAt(0)?o.pathname:"/"+o.pathname}}var t,n=/(msie|trident)/i.test(navigator.userAgent),o=document.createElement("a");return t=e(window.location.href),function(n){var o=r.isString(n)?e(n):n;return o.protocol===t.protocol&&o.host===t.host}}():function(){return function(){return!0}}()},function(e,t){"use strict";function n(){this.message="String contains an invalid character"}function r(e){for(var t,r,i=String(e),s="",u=0,a=o;i.charAt(0|u)||(a="=",u%1);s+=a.charAt(63&t>>8-u%1*8)){if(r=i.charCodeAt(u+=.75),r>255)throw new n;t=t<<8|r}return s}var o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";n.prototype=new Error,n.prototype.code=5,n.prototype.name="InvalidCharacterError",e.exports=r},function(e,t,n){"use strict";var r=n(2);e.exports=r.isStandardBrowserEnv()?function(){return{write:function(e,t,n,o,i,s){var u=[];u.push(e+"="+encodeURIComponent(t)),r.isNumber(n)&&u.push("expires="+new Date(n).toGMTString()),r.isString(o)&&u.push("path="+o),r.isString(i)&&u.push("domain="+i),s===!0&&u.push("secure"),document.cookie=u.join("; ")},read:function(e){var t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}}():function(){return{write:function(){},read:function(){return null},remove:function(){}}}()},function(e,t,n){"use strict";function r(){this.handlers=[]}var o=n(2);r.prototype.use=function(e,t){return this.handlers.push({fulfilled:e,rejected:t}),this.handlers.length-1},r.prototype.eject=function(e){this.handlers[e]&&(this.handlers[e]=null)},r.prototype.forEach=function(e){o.forEach(this.handlers,function(t){null!==t&&e(t)})},e.exports=r},function(e,t,n){"use strict";function r(e){e.cancelToken&&e.cancelToken.throwIfRequested()}var o=n(2),i=n(19),s=n(20),u=n(6),a=n(21),c=n(22);e.exports=function(e){r(e),e.baseURL&&!a(e.url)&&(e.url=c(e.baseURL,e.url)),e.headers=e.headers||{},e.data=i(e.data,e.headers,e.transformRequest),e.headers=o.merge(e.headers.common||{},e.headers[e.method]||{},e.headers||{}),o.forEach(["delete","get","head","post","put","patch","common"],function(t){delete e.headers[t]});var t=e.adapter||u.adapter;return t(e).then(function(t){return r(e),t.data=i(t.data,t.headers,e.transformResponse),t},function(t){return s(t)||(r(e),t&&t.response&&(t.response.data=i(t.response.data,t.response.headers,e.transformResponse))),Promise.reject(t)})}},function(e,t,n){"use strict";var r=n(2);e.exports=function(e,t,n){return r.forEach(n,function(n){e=n(e,t)}),e}},function(e,t){"use strict";e.exports=function(e){return!(!e||!e.__CANCEL__)}},function(e,t){"use strict";e.exports=function(e){return/^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(e)}},function(e,t){"use strict";e.exports=function(e,t){return t?e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,""):e}},function(e,t){"use strict";function n(e){this.message=e}n.prototype.toString=function(){return"Cancel"+(this.message?": "+this.message:"")},n.prototype.__CANCEL__=!0,e.exports=n},function(e,t,n){"use strict";function r(e){if("function"!=typeof e)throw new TypeError("executor must be a function.");var t;this.promise=new Promise(function(e){t=e});var n=this;e(function(e){n.reason||(n.reason=new o(e),t(n.reason))})}var o=n(23);r.prototype.throwIfRequested=function(){if(this.reason)throw this.reason},r.source=function(){var e,t=new r(function(t){e=t});return{token:t,cancel:e}},e.exports=r},function(e,t){"use strict";e.exports=function(e){return function(t){return e.apply(null,t)}}}])}); +//# sourceMappingURL=axios.min.map \ No newline at end of file diff --git a/js/main.js b/js/main.js new file mode 100644 index 0000000..01ec12f --- /dev/null +++ b/js/main.js @@ -0,0 +1,109 @@ +//websocket简单聊天室前端部分vue实现 +var app = new Vue({ + el: '#app', + data: { + ws: null, + hist: [ + 'hello world!' + ], + message: '', + user_id:null, + user_list: [ + null + ], + user_num:0 + }, + methods:{ + //init websocket + init:function() + { + this.ws = new WebSocket("ws://127.0.0.1:8080"); + this.ws.onopen = this.wsonopen; +    this.ws.onerror = this.wsonerror; +    this.ws.onmessage = this.wsonmessage; +    this.ws.onclose = this.wsclose; + }, + //生成用户随机id + rand_id:function() + { + let id = Math.random()*100000; + id = Math.ceil(id); + return id; + }, + //ws functions + wsonopen:function() + { + console.log('websocket connected'); + }, + wsonerror:function() + { + console.log('websocket error'); + }, + wsonmessage:function(e) + { + let data = JSON.parse(e.data); + //console.log(data); + + switch(data.type){ + case 'handshake': + let user_info = {'type': 'login', 'content': this.user_id}; + //console.log(user_info); + this.send_msg(user_info); + break; + case 'user': + let new_msg = data.from+':'+data.content; + this.hist.push(new_msg); + break; + case 'login': + let login_msg = data.content+':log in'; + this.hist.push(login_msg); + //更新在线人数和在线用户列表,下次优化 + this.user_list = data.user_list; + this.user_num = this.user_list.length; + break; + case 'logout': + let logout_msg = data.content+':log out'; + this.hist.push(logout_msg); + this.user_list = data.user_list; + this.user_num = this.user_list.length; + break; + } + + + //console.log(this.hist); + }, + //发送自己的消息 + send_my_msg:function() + { + let my_msg = {'content': this.message, 'type': 'user'}; + //console.log(my_msg); + this.send_msg(my_msg); + this.message = ''; + }, + //发送系统消息 + send_msg:function(data) + { + // let send_msg = {'content': this.message, 'type': 'user'}; + // console.log(send_msg); + //console.log(data); + data = JSON.stringify(data); + this.ws.send(data); + }, + wsclose:function() + { + console.log("connection closed (" + e.code + ")"); + }, + test:function() + { + + + } + + }, + //初始化 + created:function(){ + this.user_id = this.rand_id(); + console.log('vue works your id is:'+this.user_id); + this.init(); + } +}) diff --git a/js/main2.js b/js/main2.js new file mode 100644 index 0000000..3792b5d --- /dev/null +++ b/js/main2.js @@ -0,0 +1,109 @@ +//websocket简单聊天室前端部分vue实现 +var app = new Vue({ + el: '#app', + data: { + ws: null, + hist: [ + 'hello world!' + ], + message: '', + user_id:null, + user_list: [ + null + ], + user_num:0 + }, + methods:{ + //init websocket + init:function() + { + this.ws = new WebSocket("ws://127.0.0.1:8081"); + this.ws.onopen = this.wsonopen; +    this.ws.onerror = this.wsonerror; +    this.ws.onmessage = this.wsonmessage; +    this.ws.onclose = this.wsclose; + }, + //生成用户随机id + rand_id:function() + { + let id = Math.random()*100000; + id = Math.ceil(id); + return id; + }, + //ws functions + wsonopen:function() + { + console.log('websocket connected'); + }, + wsonerror:function() + { + console.log('websocket error'); + }, + wsonmessage:function(e) + { + let data = JSON.parse(e.data); + console.log(data); + + switch(data.type){ + case 'handshake': + let user_info = {'type': 'login', 'content': this.user_id}; + //console.log(user_info); + this.send_msg(user_info); + break; + case 'user': + let new_msg = data.from+':'+data.content; + this.hist.push(new_msg); + break; + case 'login': + let login_msg = data.content+':log in'; + this.hist.push(login_msg); + //更新在线人数和在线用户列表,下次优化 + this.user_list = data.user_list; + this.user_num = this.user_list.length; + break; + case 'logout': + let logout_msg = data.content+':log out'; + this.hist.push(logout_msg); + this.user_list = data.user_list; + this.user_num = this.user_list.length; + break; + } + + + //console.log(this.hist); + }, + //发送自己的消息 + send_my_msg:function() + { + let my_msg = {'content': this.message, 'type': 'user'}; + //console.log(my_msg); + this.send_msg(my_msg); + this.message = ''; + }, + //发送系统消息 + send_msg:function(data) + { + // let send_msg = {'content': this.message, 'type': 'user'}; + // console.log(send_msg); + //console.log(data); + data = JSON.stringify(data); + this.ws.send(data); + }, + wsclose:function() + { + console.log("connection closed (" + e.code + ")"); + }, + test:function() + { + + + } + + }, + //初始化 + created:function(){ + this.user_id = this.rand_id(); + console.log('vue works your id is:'+this.user_id); + this.init(); + } +}) diff --git a/js/vue.js b/js/vue.js new file mode 100644 index 0000000..657cb37 --- /dev/null +++ b/js/vue.js @@ -0,0 +1,10947 @@ +/*! + * Vue.js v2.5.16 + * (c) 2014-2018 Evan You + * Released under the MIT License. + */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.Vue = factory()); +}(this, (function () { 'use strict'; + +/* */ + +var emptyObject = Object.freeze({}); + +// these helpers produces better vm code in JS engines due to their +// explicitness and function inlining +function isUndef (v) { + return v === undefined || v === null +} + +function isDef (v) { + return v !== undefined && v !== null +} + +function isTrue (v) { + return v === true +} + +function isFalse (v) { + return v === false +} + +/** + * Check if value is primitive + */ +function isPrimitive (value) { + return ( + typeof value === 'string' || + typeof value === 'number' || + // $flow-disable-line + typeof value === 'symbol' || + typeof value === 'boolean' + ) +} + +/** + * Quick object check - this is primarily used to tell + * Objects from primitive values when we know the value + * is a JSON-compliant type. + */ +function isObject (obj) { + return obj !== null && typeof obj === 'object' +} + +/** + * Get the raw type string of a value e.g. [object Object] + */ +var _toString = Object.prototype.toString; + +function toRawType (value) { + return _toString.call(value).slice(8, -1) +} + +/** + * Strict object type check. Only returns true + * for plain JavaScript objects. + */ +function isPlainObject (obj) { + return _toString.call(obj) === '[object Object]' +} + +function isRegExp (v) { + return _toString.call(v) === '[object RegExp]' +} + +/** + * Check if val is a valid array index. + */ +function isValidArrayIndex (val) { + var n = parseFloat(String(val)); + return n >= 0 && Math.floor(n) === n && isFinite(val) +} + +/** + * Convert a value to a string that is actually rendered. + */ +function toString (val) { + return val == null + ? '' + : typeof val === 'object' + ? JSON.stringify(val, null, 2) + : String(val) +} + +/** + * Convert a input value to a number for persistence. + * If the conversion fails, return original string. + */ +function toNumber (val) { + var n = parseFloat(val); + return isNaN(n) ? val : n +} + +/** + * Make a map and return a function for checking if a key + * is in that map. + */ +function makeMap ( + str, + expectsLowerCase +) { + var map = Object.create(null); + var list = str.split(','); + for (var i = 0; i < list.length; i++) { + map[list[i]] = true; + } + return expectsLowerCase + ? function (val) { return map[val.toLowerCase()]; } + : function (val) { return map[val]; } +} + +/** + * Check if a tag is a built-in tag. + */ +var isBuiltInTag = makeMap('slot,component', true); + +/** + * Check if a attribute is a reserved attribute. + */ +var isReservedAttribute = makeMap('key,ref,slot,slot-scope,is'); + +/** + * Remove an item from an array + */ +function remove (arr, item) { + if (arr.length) { + var index = arr.indexOf(item); + if (index > -1) { + return arr.splice(index, 1) + } + } +} + +/** + * Check whether the object has the property. + */ +var hasOwnProperty = Object.prototype.hasOwnProperty; +function hasOwn (obj, key) { + return hasOwnProperty.call(obj, key) +} + +/** + * Create a cached version of a pure function. + */ +function cached (fn) { + var cache = Object.create(null); + return (function cachedFn (str) { + var hit = cache[str]; + return hit || (cache[str] = fn(str)) + }) +} + +/** + * Camelize a hyphen-delimited string. + */ +var camelizeRE = /-(\w)/g; +var camelize = cached(function (str) { + return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; }) +}); + +/** + * Capitalize a string. + */ +var capitalize = cached(function (str) { + return str.charAt(0).toUpperCase() + str.slice(1) +}); + +/** + * Hyphenate a camelCase string. + */ +var hyphenateRE = /\B([A-Z])/g; +var hyphenate = cached(function (str) { + return str.replace(hyphenateRE, '-$1').toLowerCase() +}); + +/** + * Simple bind polyfill for environments that do not support it... e.g. + * PhantomJS 1.x. Technically we don't need this anymore since native bind is + * now more performant in most browsers, but removing it would be breaking for + * code that was able to run in PhantomJS 1.x, so this must be kept for + * backwards compatibility. + */ + +/* istanbul ignore next */ +function polyfillBind (fn, ctx) { + function boundFn (a) { + var l = arguments.length; + return l + ? l > 1 + ? fn.apply(ctx, arguments) + : fn.call(ctx, a) + : fn.call(ctx) + } + + boundFn._length = fn.length; + return boundFn +} + +function nativeBind (fn, ctx) { + return fn.bind(ctx) +} + +var bind = Function.prototype.bind + ? nativeBind + : polyfillBind; + +/** + * Convert an Array-like object to a real Array. + */ +function toArray (list, start) { + start = start || 0; + var i = list.length - start; + var ret = new Array(i); + while (i--) { + ret[i] = list[i + start]; + } + return ret +} + +/** + * Mix properties into target object. + */ +function extend (to, _from) { + for (var key in _from) { + to[key] = _from[key]; + } + return to +} + +/** + * Merge an Array of Objects into a single Object. + */ +function toObject (arr) { + var res = {}; + for (var i = 0; i < arr.length; i++) { + if (arr[i]) { + extend(res, arr[i]); + } + } + return res +} + +/** + * Perform no operation. + * Stubbing args to make Flow happy without leaving useless transpiled code + * with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/) + */ +function noop (a, b, c) {} + +/** + * Always return false. + */ +var no = function (a, b, c) { return false; }; + +/** + * Return same value + */ +var identity = function (_) { return _; }; + +/** + * Generate a static keys string from compiler modules. + */ +function genStaticKeys (modules) { + return modules.reduce(function (keys, m) { + return keys.concat(m.staticKeys || []) + }, []).join(',') +} + +/** + * Check if two values are loosely equal - that is, + * if they are plain objects, do they have the same shape? + */ +function looseEqual (a, b) { + if (a === b) { return true } + var isObjectA = isObject(a); + var isObjectB = isObject(b); + if (isObjectA && isObjectB) { + try { + var isArrayA = Array.isArray(a); + var isArrayB = Array.isArray(b); + if (isArrayA && isArrayB) { + return a.length === b.length && a.every(function (e, i) { + return looseEqual(e, b[i]) + }) + } else if (!isArrayA && !isArrayB) { + var keysA = Object.keys(a); + var keysB = Object.keys(b); + return keysA.length === keysB.length && keysA.every(function (key) { + return looseEqual(a[key], b[key]) + }) + } else { + /* istanbul ignore next */ + return false + } + } catch (e) { + /* istanbul ignore next */ + return false + } + } else if (!isObjectA && !isObjectB) { + return String(a) === String(b) + } else { + return false + } +} + +function looseIndexOf (arr, val) { + for (var i = 0; i < arr.length; i++) { + if (looseEqual(arr[i], val)) { return i } + } + return -1 +} + +/** + * Ensure a function is called only once. + */ +function once (fn) { + var called = false; + return function () { + if (!called) { + called = true; + fn.apply(this, arguments); + } + } +} + +var SSR_ATTR = 'data-server-rendered'; + +var ASSET_TYPES = [ + 'component', + 'directive', + 'filter' +]; + +var LIFECYCLE_HOOKS = [ + 'beforeCreate', + 'created', + 'beforeMount', + 'mounted', + 'beforeUpdate', + 'updated', + 'beforeDestroy', + 'destroyed', + 'activated', + 'deactivated', + 'errorCaptured' +]; + +/* */ + +var config = ({ + /** + * Option merge strategies (used in core/util/options) + */ + // $flow-disable-line + optionMergeStrategies: Object.create(null), + + /** + * Whether to suppress warnings. + */ + silent: false, + + /** + * Show production mode tip message on boot? + */ + productionTip: "development" !== 'production', + + /** + * Whether to enable devtools + */ + devtools: "development" !== 'production', + + /** + * Whether to record perf + */ + performance: false, + + /** + * Error handler for watcher errors + */ + errorHandler: null, + + /** + * Warn handler for watcher warns + */ + warnHandler: null, + + /** + * Ignore certain custom elements + */ + ignoredElements: [], + + /** + * Custom user key aliases for v-on + */ + // $flow-disable-line + keyCodes: Object.create(null), + + /** + * Check if a tag is reserved so that it cannot be registered as a + * component. This is platform-dependent and may be overwritten. + */ + isReservedTag: no, + + /** + * Check if an attribute is reserved so that it cannot be used as a component + * prop. This is platform-dependent and may be overwritten. + */ + isReservedAttr: no, + + /** + * Check if a tag is an unknown element. + * Platform-dependent. + */ + isUnknownElement: no, + + /** + * Get the namespace of an element + */ + getTagNamespace: noop, + + /** + * Parse the real tag name for the specific platform. + */ + parsePlatformTagName: identity, + + /** + * Check if an attribute must be bound using property, e.g. value + * Platform-dependent. + */ + mustUseProp: no, + + /** + * Exposed for legacy reasons + */ + _lifecycleHooks: LIFECYCLE_HOOKS +}) + +/* */ + +/** + * Check if a string starts with $ or _ + */ +function isReserved (str) { + var c = (str + '').charCodeAt(0); + return c === 0x24 || c === 0x5F +} + +/** + * Define a property. + */ +function def (obj, key, val, enumerable) { + Object.defineProperty(obj, key, { + value: val, + enumerable: !!enumerable, + writable: true, + configurable: true + }); +} + +/** + * Parse simple path. + */ +var bailRE = /[^\w.$]/; +function parsePath (path) { + if (bailRE.test(path)) { + return + } + var segments = path.split('.'); + return function (obj) { + for (var i = 0; i < segments.length; i++) { + if (!obj) { return } + obj = obj[segments[i]]; + } + return obj + } +} + +/* */ + +// can we use __proto__? +var hasProto = '__proto__' in {}; + +// Browser environment sniffing +var inBrowser = typeof window !== 'undefined'; +var inWeex = typeof WXEnvironment !== 'undefined' && !!WXEnvironment.platform; +var weexPlatform = inWeex && WXEnvironment.platform.toLowerCase(); +var UA = inBrowser && window.navigator.userAgent.toLowerCase(); +var isIE = UA && /msie|trident/.test(UA); +var isIE9 = UA && UA.indexOf('msie 9.0') > 0; +var isEdge = UA && UA.indexOf('edge/') > 0; +var isAndroid = (UA && UA.indexOf('android') > 0) || (weexPlatform === 'android'); +var isIOS = (UA && /iphone|ipad|ipod|ios/.test(UA)) || (weexPlatform === 'ios'); +var isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge; + +// Firefox has a "watch" function on Object.prototype... +var nativeWatch = ({}).watch; + +var supportsPassive = false; +if (inBrowser) { + try { + var opts = {}; + Object.defineProperty(opts, 'passive', ({ + get: function get () { + /* istanbul ignore next */ + supportsPassive = true; + } + })); // https://github.com/facebook/flow/issues/285 + window.addEventListener('test-passive', null, opts); + } catch (e) {} +} + +// this needs to be lazy-evaled because vue may be required before +// vue-server-renderer can set VUE_ENV +var _isServer; +var isServerRendering = function () { + if (_isServer === undefined) { + /* istanbul ignore if */ + if (!inBrowser && !inWeex && typeof global !== 'undefined') { + // detect presence of vue-server-renderer and avoid + // Webpack shimming the process + _isServer = global['process'].env.VUE_ENV === 'server'; + } else { + _isServer = false; + } + } + return _isServer +}; + +// detect devtools +var devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__; + +/* istanbul ignore next */ +function isNative (Ctor) { + return typeof Ctor === 'function' && /native code/.test(Ctor.toString()) +} + +var hasSymbol = + typeof Symbol !== 'undefined' && isNative(Symbol) && + typeof Reflect !== 'undefined' && isNative(Reflect.ownKeys); + +var _Set; +/* istanbul ignore if */ // $flow-disable-line +if (typeof Set !== 'undefined' && isNative(Set)) { + // use native Set when available. + _Set = Set; +} else { + // a non-standard Set polyfill that only works with primitive keys. + _Set = (function () { + function Set () { + this.set = Object.create(null); + } + Set.prototype.has = function has (key) { + return this.set[key] === true + }; + Set.prototype.add = function add (key) { + this.set[key] = true; + }; + Set.prototype.clear = function clear () { + this.set = Object.create(null); + }; + + return Set; + }()); +} + +/* */ + +var warn = noop; +var tip = noop; +var generateComponentTrace = (noop); // work around flow check +var formatComponentName = (noop); + +{ + var hasConsole = typeof console !== 'undefined'; + var classifyRE = /(?:^|[-_])(\w)/g; + var classify = function (str) { return str + .replace(classifyRE, function (c) { return c.toUpperCase(); }) + .replace(/[-_]/g, ''); }; + + warn = function (msg, vm) { + var trace = vm ? generateComponentTrace(vm) : ''; + + if (config.warnHandler) { + config.warnHandler.call(null, msg, vm, trace); + } else if (hasConsole && (!config.silent)) { + console.error(("[Vue warn]: " + msg + trace)); + } + }; + + tip = function (msg, vm) { + if (hasConsole && (!config.silent)) { + console.warn("[Vue tip]: " + msg + ( + vm ? generateComponentTrace(vm) : '' + )); + } + }; + + formatComponentName = function (vm, includeFile) { + if (vm.$root === vm) { + return '' + } + var options = typeof vm === 'function' && vm.cid != null + ? vm.options + : vm._isVue + ? vm.$options || vm.constructor.options + : vm || {}; + var name = options.name || options._componentTag; + var file = options.__file; + if (!name && file) { + var match = file.match(/([^/\\]+)\.vue$/); + name = match && match[1]; + } + + return ( + (name ? ("<" + (classify(name)) + ">") : "") + + (file && includeFile !== false ? (" at " + file) : '') + ) + }; + + var repeat = function (str, n) { + var res = ''; + while (n) { + if (n % 2 === 1) { res += str; } + if (n > 1) { str += str; } + n >>= 1; + } + return res + }; + + generateComponentTrace = function (vm) { + if (vm._isVue && vm.$parent) { + var tree = []; + var currentRecursiveSequence = 0; + while (vm) { + if (tree.length > 0) { + var last = tree[tree.length - 1]; + if (last.constructor === vm.constructor) { + currentRecursiveSequence++; + vm = vm.$parent; + continue + } else if (currentRecursiveSequence > 0) { + tree[tree.length - 1] = [last, currentRecursiveSequence]; + currentRecursiveSequence = 0; + } + } + tree.push(vm); + vm = vm.$parent; + } + return '\n\nfound in\n\n' + tree + .map(function (vm, i) { return ("" + (i === 0 ? '---> ' : repeat(' ', 5 + i * 2)) + (Array.isArray(vm) + ? ((formatComponentName(vm[0])) + "... (" + (vm[1]) + " recursive calls)") + : formatComponentName(vm))); }) + .join('\n') + } else { + return ("\n\n(found in " + (formatComponentName(vm)) + ")") + } + }; +} + +/* */ + + +var uid = 0; + +/** + * A dep is an observable that can have multiple + * directives subscribing to it. + */ +var Dep = function Dep () { + this.id = uid++; + this.subs = []; +}; + +Dep.prototype.addSub = function addSub (sub) { + this.subs.push(sub); +}; + +Dep.prototype.removeSub = function removeSub (sub) { + remove(this.subs, sub); +}; + +Dep.prototype.depend = function depend () { + if (Dep.target) { + Dep.target.addDep(this); + } +}; + +Dep.prototype.notify = function notify () { + // stabilize the subscriber list first + var subs = this.subs.slice(); + for (var i = 0, l = subs.length; i < l; i++) { + subs[i].update(); + } +}; + +// the current target watcher being evaluated. +// this is globally unique because there could be only one +// watcher being evaluated at any time. +Dep.target = null; +var targetStack = []; + +function pushTarget (_target) { + if (Dep.target) { targetStack.push(Dep.target); } + Dep.target = _target; +} + +function popTarget () { + Dep.target = targetStack.pop(); +} + +/* */ + +var VNode = function VNode ( + tag, + data, + children, + text, + elm, + context, + componentOptions, + asyncFactory +) { + this.tag = tag; + this.data = data; + this.children = children; + this.text = text; + this.elm = elm; + this.ns = undefined; + this.context = context; + this.fnContext = undefined; + this.fnOptions = undefined; + this.fnScopeId = undefined; + this.key = data && data.key; + this.componentOptions = componentOptions; + this.componentInstance = undefined; + this.parent = undefined; + this.raw = false; + this.isStatic = false; + this.isRootInsert = true; + this.isComment = false; + this.isCloned = false; + this.isOnce = false; + this.asyncFactory = asyncFactory; + this.asyncMeta = undefined; + this.isAsyncPlaceholder = false; +}; + +var prototypeAccessors = { child: { configurable: true } }; + +// DEPRECATED: alias for componentInstance for backwards compat. +/* istanbul ignore next */ +prototypeAccessors.child.get = function () { + return this.componentInstance +}; + +Object.defineProperties( VNode.prototype, prototypeAccessors ); + +var createEmptyVNode = function (text) { + if ( text === void 0 ) text = ''; + + var node = new VNode(); + node.text = text; + node.isComment = true; + return node +}; + +function createTextVNode (val) { + return new VNode(undefined, undefined, undefined, String(val)) +} + +// optimized shallow clone +// used for static nodes and slot nodes because they may be reused across +// multiple renders, cloning them avoids errors when DOM manipulations rely +// on their elm reference. +function cloneVNode (vnode) { + var cloned = new VNode( + vnode.tag, + vnode.data, + vnode.children, + vnode.text, + vnode.elm, + vnode.context, + vnode.componentOptions, + vnode.asyncFactory + ); + cloned.ns = vnode.ns; + cloned.isStatic = vnode.isStatic; + cloned.key = vnode.key; + cloned.isComment = vnode.isComment; + cloned.fnContext = vnode.fnContext; + cloned.fnOptions = vnode.fnOptions; + cloned.fnScopeId = vnode.fnScopeId; + cloned.isCloned = true; + return cloned +} + +/* + * not type checking this file because flow doesn't play well with + * dynamically accessing methods on Array prototype + */ + +var arrayProto = Array.prototype; +var arrayMethods = Object.create(arrayProto); + +var methodsToPatch = [ + 'push', + 'pop', + 'shift', + 'unshift', + 'splice', + 'sort', + 'reverse' +]; + +/** + * Intercept mutating methods and emit events + */ +methodsToPatch.forEach(function (method) { + // cache original method + var original = arrayProto[method]; + def(arrayMethods, method, function mutator () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + var result = original.apply(this, args); + var ob = this.__ob__; + var inserted; + switch (method) { + case 'push': + case 'unshift': + inserted = args; + break + case 'splice': + inserted = args.slice(2); + break + } + if (inserted) { ob.observeArray(inserted); } + // notify change + ob.dep.notify(); + return result + }); +}); + +/* */ + +var arrayKeys = Object.getOwnPropertyNames(arrayMethods); + +/** + * In some cases we may want to disable observation inside a component's + * update computation. + */ +var shouldObserve = true; + +function toggleObserving (value) { + shouldObserve = value; +} + +/** + * Observer class that is attached to each observed + * object. Once attached, the observer converts the target + * object's property keys into getter/setters that + * collect dependencies and dispatch updates. + */ +var Observer = function Observer (value) { + this.value = value; + this.dep = new Dep(); + this.vmCount = 0; + def(value, '__ob__', this); + if (Array.isArray(value)) { + var augment = hasProto + ? protoAugment + : copyAugment; + augment(value, arrayMethods, arrayKeys); + this.observeArray(value); + } else { + this.walk(value); + } +}; + +/** + * Walk through each property and convert them into + * getter/setters. This method should only be called when + * value type is Object. + */ +Observer.prototype.walk = function walk (obj) { + var keys = Object.keys(obj); + for (var i = 0; i < keys.length; i++) { + defineReactive(obj, keys[i]); + } +}; + +/** + * Observe a list of Array items. + */ +Observer.prototype.observeArray = function observeArray (items) { + for (var i = 0, l = items.length; i < l; i++) { + observe(items[i]); + } +}; + +// helpers + +/** + * Augment an target Object or Array by intercepting + * the prototype chain using __proto__ + */ +function protoAugment (target, src, keys) { + /* eslint-disable no-proto */ + target.__proto__ = src; + /* eslint-enable no-proto */ +} + +/** + * Augment an target Object or Array by defining + * hidden properties. + */ +/* istanbul ignore next */ +function copyAugment (target, src, keys) { + for (var i = 0, l = keys.length; i < l; i++) { + var key = keys[i]; + def(target, key, src[key]); + } +} + +/** + * Attempt to create an observer instance for a value, + * returns the new observer if successfully observed, + * or the existing observer if the value already has one. + */ +function observe (value, asRootData) { + if (!isObject(value) || value instanceof VNode) { + return + } + var ob; + if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) { + ob = value.__ob__; + } else if ( + shouldObserve && + !isServerRendering() && + (Array.isArray(value) || isPlainObject(value)) && + Object.isExtensible(value) && + !value._isVue + ) { + ob = new Observer(value); + } + if (asRootData && ob) { + ob.vmCount++; + } + return ob +} + +/** + * Define a reactive property on an Object. + */ +function defineReactive ( + obj, + key, + val, + customSetter, + shallow +) { + var dep = new Dep(); + + var property = Object.getOwnPropertyDescriptor(obj, key); + if (property && property.configurable === false) { + return + } + + // cater for pre-defined getter/setters + var getter = property && property.get; + if (!getter && arguments.length === 2) { + val = obj[key]; + } + var setter = property && property.set; + + var childOb = !shallow && observe(val); + Object.defineProperty(obj, key, { + enumerable: true, + configurable: true, + get: function reactiveGetter () { + var value = getter ? getter.call(obj) : val; + if (Dep.target) { + dep.depend(); + if (childOb) { + childOb.dep.depend(); + if (Array.isArray(value)) { + dependArray(value); + } + } + } + return value + }, + set: function reactiveSetter (newVal) { + var value = getter ? getter.call(obj) : val; + /* eslint-disable no-self-compare */ + if (newVal === value || (newVal !== newVal && value !== value)) { + return + } + /* eslint-enable no-self-compare */ + if ("development" !== 'production' && customSetter) { + customSetter(); + } + if (setter) { + setter.call(obj, newVal); + } else { + val = newVal; + } + childOb = !shallow && observe(newVal); + dep.notify(); + } + }); +} + +/** + * Set a property on an object. Adds the new property and + * triggers change notification if the property doesn't + * already exist. + */ +function set (target, key, val) { + if ("development" !== 'production' && + (isUndef(target) || isPrimitive(target)) + ) { + warn(("Cannot set reactive property on undefined, null, or primitive value: " + ((target)))); + } + if (Array.isArray(target) && isValidArrayIndex(key)) { + target.length = Math.max(target.length, key); + target.splice(key, 1, val); + return val + } + if (key in target && !(key in Object.prototype)) { + target[key] = val; + return val + } + var ob = (target).__ob__; + if (target._isVue || (ob && ob.vmCount)) { + "development" !== 'production' && warn( + 'Avoid adding reactive properties to a Vue instance or its root $data ' + + 'at runtime - declare it upfront in the data option.' + ); + return val + } + if (!ob) { + target[key] = val; + return val + } + defineReactive(ob.value, key, val); + ob.dep.notify(); + return val +} + +/** + * Delete a property and trigger change if necessary. + */ +function del (target, key) { + if ("development" !== 'production' && + (isUndef(target) || isPrimitive(target)) + ) { + warn(("Cannot delete reactive property on undefined, null, or primitive value: " + ((target)))); + } + if (Array.isArray(target) && isValidArrayIndex(key)) { + target.splice(key, 1); + return + } + var ob = (target).__ob__; + if (target._isVue || (ob && ob.vmCount)) { + "development" !== 'production' && warn( + 'Avoid deleting properties on a Vue instance or its root $data ' + + '- just set it to null.' + ); + return + } + if (!hasOwn(target, key)) { + return + } + delete target[key]; + if (!ob) { + return + } + ob.dep.notify(); +} + +/** + * Collect dependencies on array elements when the array is touched, since + * we cannot intercept array element access like property getters. + */ +function dependArray (value) { + for (var e = (void 0), i = 0, l = value.length; i < l; i++) { + e = value[i]; + e && e.__ob__ && e.__ob__.dep.depend(); + if (Array.isArray(e)) { + dependArray(e); + } + } +} + +/* */ + +/** + * Option overwriting strategies are functions that handle + * how to merge a parent option value and a child option + * value into the final value. + */ +var strats = config.optionMergeStrategies; + +/** + * Options with restrictions + */ +{ + strats.el = strats.propsData = function (parent, child, vm, key) { + if (!vm) { + warn( + "option \"" + key + "\" can only be used during instance " + + 'creation with the `new` keyword.' + ); + } + return defaultStrat(parent, child) + }; +} + +/** + * Helper that recursively merges two data objects together. + */ +function mergeData (to, from) { + if (!from) { return to } + var key, toVal, fromVal; + var keys = Object.keys(from); + for (var i = 0; i < keys.length; i++) { + key = keys[i]; + toVal = to[key]; + fromVal = from[key]; + if (!hasOwn(to, key)) { + set(to, key, fromVal); + } else if (isPlainObject(toVal) && isPlainObject(fromVal)) { + mergeData(toVal, fromVal); + } + } + return to +} + +/** + * Data + */ +function mergeDataOrFn ( + parentVal, + childVal, + vm +) { + if (!vm) { + // in a Vue.extend merge, both should be functions + if (!childVal) { + return parentVal + } + if (!parentVal) { + return childVal + } + // when parentVal & childVal are both present, + // we need to return a function that returns the + // merged result of both functions... no need to + // check if parentVal is a function here because + // it has to be a function to pass previous merges. + return function mergedDataFn () { + return mergeData( + typeof childVal === 'function' ? childVal.call(this, this) : childVal, + typeof parentVal === 'function' ? parentVal.call(this, this) : parentVal + ) + } + } else { + return function mergedInstanceDataFn () { + // instance merge + var instanceData = typeof childVal === 'function' + ? childVal.call(vm, vm) + : childVal; + var defaultData = typeof parentVal === 'function' + ? parentVal.call(vm, vm) + : parentVal; + if (instanceData) { + return mergeData(instanceData, defaultData) + } else { + return defaultData + } + } + } +} + +strats.data = function ( + parentVal, + childVal, + vm +) { + if (!vm) { + if (childVal && typeof childVal !== 'function') { + "development" !== 'production' && warn( + 'The "data" option should be a function ' + + 'that returns a per-instance value in component ' + + 'definitions.', + vm + ); + + return parentVal + } + return mergeDataOrFn(parentVal, childVal) + } + + return mergeDataOrFn(parentVal, childVal, vm) +}; + +/** + * Hooks and props are merged as arrays. + */ +function mergeHook ( + parentVal, + childVal +) { + return childVal + ? parentVal + ? parentVal.concat(childVal) + : Array.isArray(childVal) + ? childVal + : [childVal] + : parentVal +} + +LIFECYCLE_HOOKS.forEach(function (hook) { + strats[hook] = mergeHook; +}); + +/** + * Assets + * + * When a vm is present (instance creation), we need to do + * a three-way merge between constructor options, instance + * options and parent options. + */ +function mergeAssets ( + parentVal, + childVal, + vm, + key +) { + var res = Object.create(parentVal || null); + if (childVal) { + "development" !== 'production' && assertObjectType(key, childVal, vm); + return extend(res, childVal) + } else { + return res + } +} + +ASSET_TYPES.forEach(function (type) { + strats[type + 's'] = mergeAssets; +}); + +/** + * Watchers. + * + * Watchers hashes should not overwrite one + * another, so we merge them as arrays. + */ +strats.watch = function ( + parentVal, + childVal, + vm, + key +) { + // work around Firefox's Object.prototype.watch... + if (parentVal === nativeWatch) { parentVal = undefined; } + if (childVal === nativeWatch) { childVal = undefined; } + /* istanbul ignore if */ + if (!childVal) { return Object.create(parentVal || null) } + { + assertObjectType(key, childVal, vm); + } + if (!parentVal) { return childVal } + var ret = {}; + extend(ret, parentVal); + for (var key$1 in childVal) { + var parent = ret[key$1]; + var child = childVal[key$1]; + if (parent && !Array.isArray(parent)) { + parent = [parent]; + } + ret[key$1] = parent + ? parent.concat(child) + : Array.isArray(child) ? child : [child]; + } + return ret +}; + +/** + * Other object hashes. + */ +strats.props = +strats.methods = +strats.inject = +strats.computed = function ( + parentVal, + childVal, + vm, + key +) { + if (childVal && "development" !== 'production') { + assertObjectType(key, childVal, vm); + } + if (!parentVal) { return childVal } + var ret = Object.create(null); + extend(ret, parentVal); + if (childVal) { extend(ret, childVal); } + return ret +}; +strats.provide = mergeDataOrFn; + +/** + * Default strategy. + */ +var defaultStrat = function (parentVal, childVal) { + return childVal === undefined + ? parentVal + : childVal +}; + +/** + * Validate component names + */ +function checkComponents (options) { + for (var key in options.components) { + validateComponentName(key); + } +} + +function validateComponentName (name) { + if (!/^[a-zA-Z][\w-]*$/.test(name)) { + warn( + 'Invalid component name: "' + name + '". Component names ' + + 'can only contain alphanumeric characters and the hyphen, ' + + 'and must start with a letter.' + ); + } + if (isBuiltInTag(name) || config.isReservedTag(name)) { + warn( + 'Do not use built-in or reserved HTML elements as component ' + + 'id: ' + name + ); + } +} + +/** + * Ensure all props option syntax are normalized into the + * Object-based format. + */ +function normalizeProps (options, vm) { + var props = options.props; + if (!props) { return } + var res = {}; + var i, val, name; + if (Array.isArray(props)) { + i = props.length; + while (i--) { + val = props[i]; + if (typeof val === 'string') { + name = camelize(val); + res[name] = { type: null }; + } else { + warn('props must be strings when using array syntax.'); + } + } + } else if (isPlainObject(props)) { + for (var key in props) { + val = props[key]; + name = camelize(key); + res[name] = isPlainObject(val) + ? val + : { type: val }; + } + } else { + warn( + "Invalid value for option \"props\": expected an Array or an Object, " + + "but got " + (toRawType(props)) + ".", + vm + ); + } + options.props = res; +} + +/** + * Normalize all injections into Object-based format + */ +function normalizeInject (options, vm) { + var inject = options.inject; + if (!inject) { return } + var normalized = options.inject = {}; + if (Array.isArray(inject)) { + for (var i = 0; i < inject.length; i++) { + normalized[inject[i]] = { from: inject[i] }; + } + } else if (isPlainObject(inject)) { + for (var key in inject) { + var val = inject[key]; + normalized[key] = isPlainObject(val) + ? extend({ from: key }, val) + : { from: val }; + } + } else { + warn( + "Invalid value for option \"inject\": expected an Array or an Object, " + + "but got " + (toRawType(inject)) + ".", + vm + ); + } +} + +/** + * Normalize raw function directives into object format. + */ +function normalizeDirectives (options) { + var dirs = options.directives; + if (dirs) { + for (var key in dirs) { + var def = dirs[key]; + if (typeof def === 'function') { + dirs[key] = { bind: def, update: def }; + } + } + } +} + +function assertObjectType (name, value, vm) { + if (!isPlainObject(value)) { + warn( + "Invalid value for option \"" + name + "\": expected an Object, " + + "but got " + (toRawType(value)) + ".", + vm + ); + } +} + +/** + * Merge two option objects into a new one. + * Core utility used in both instantiation and inheritance. + */ +function mergeOptions ( + parent, + child, + vm +) { + { + checkComponents(child); + } + + if (typeof child === 'function') { + child = child.options; + } + + normalizeProps(child, vm); + normalizeInject(child, vm); + normalizeDirectives(child); + var extendsFrom = child.extends; + if (extendsFrom) { + parent = mergeOptions(parent, extendsFrom, vm); + } + if (child.mixins) { + for (var i = 0, l = child.mixins.length; i < l; i++) { + parent = mergeOptions(parent, child.mixins[i], vm); + } + } + var options = {}; + var key; + for (key in parent) { + mergeField(key); + } + for (key in child) { + if (!hasOwn(parent, key)) { + mergeField(key); + } + } + function mergeField (key) { + var strat = strats[key] || defaultStrat; + options[key] = strat(parent[key], child[key], vm, key); + } + return options +} + +/** + * Resolve an asset. + * This function is used because child instances need access + * to assets defined in its ancestor chain. + */ +function resolveAsset ( + options, + type, + id, + warnMissing +) { + /* istanbul ignore if */ + if (typeof id !== 'string') { + return + } + var assets = options[type]; + // check local registration variations first + if (hasOwn(assets, id)) { return assets[id] } + var camelizedId = camelize(id); + if (hasOwn(assets, camelizedId)) { return assets[camelizedId] } + var PascalCaseId = capitalize(camelizedId); + if (hasOwn(assets, PascalCaseId)) { return assets[PascalCaseId] } + // fallback to prototype chain + var res = assets[id] || assets[camelizedId] || assets[PascalCaseId]; + if ("development" !== 'production' && warnMissing && !res) { + warn( + 'Failed to resolve ' + type.slice(0, -1) + ': ' + id, + options + ); + } + return res +} + +/* */ + +function validateProp ( + key, + propOptions, + propsData, + vm +) { + var prop = propOptions[key]; + var absent = !hasOwn(propsData, key); + var value = propsData[key]; + // boolean casting + var booleanIndex = getTypeIndex(Boolean, prop.type); + if (booleanIndex > -1) { + if (absent && !hasOwn(prop, 'default')) { + value = false; + } else if (value === '' || value === hyphenate(key)) { + // only cast empty string / same name to boolean if + // boolean has higher priority + var stringIndex = getTypeIndex(String, prop.type); + if (stringIndex < 0 || booleanIndex < stringIndex) { + value = true; + } + } + } + // check default value + if (value === undefined) { + value = getPropDefaultValue(vm, prop, key); + // since the default value is a fresh copy, + // make sure to observe it. + var prevShouldObserve = shouldObserve; + toggleObserving(true); + observe(value); + toggleObserving(prevShouldObserve); + } + { + assertProp(prop, key, value, vm, absent); + } + return value +} + +/** + * Get the default value of a prop. + */ +function getPropDefaultValue (vm, prop, key) { + // no default, return undefined + if (!hasOwn(prop, 'default')) { + return undefined + } + var def = prop.default; + // warn against non-factory defaults for Object & Array + if ("development" !== 'production' && isObject(def)) { + warn( + 'Invalid default value for prop "' + key + '": ' + + 'Props with type Object/Array must use a factory function ' + + 'to return the default value.', + vm + ); + } + // the raw prop value was also undefined from previous render, + // return previous default value to avoid unnecessary watcher trigger + if (vm && vm.$options.propsData && + vm.$options.propsData[key] === undefined && + vm._props[key] !== undefined + ) { + return vm._props[key] + } + // call factory function for non-Function types + // a value is Function if its prototype is function even across different execution context + return typeof def === 'function' && getType(prop.type) !== 'Function' + ? def.call(vm) + : def +} + +/** + * Assert whether a prop is valid. + */ +function assertProp ( + prop, + name, + value, + vm, + absent +) { + if (prop.required && absent) { + warn( + 'Missing required prop: "' + name + '"', + vm + ); + return + } + if (value == null && !prop.required) { + return + } + var type = prop.type; + var valid = !type || type === true; + var expectedTypes = []; + if (type) { + if (!Array.isArray(type)) { + type = [type]; + } + for (var i = 0; i < type.length && !valid; i++) { + var assertedType = assertType(value, type[i]); + expectedTypes.push(assertedType.expectedType || ''); + valid = assertedType.valid; + } + } + if (!valid) { + warn( + "Invalid prop: type check failed for prop \"" + name + "\"." + + " Expected " + (expectedTypes.map(capitalize).join(', ')) + + ", got " + (toRawType(value)) + ".", + vm + ); + return + } + var validator = prop.validator; + if (validator) { + if (!validator(value)) { + warn( + 'Invalid prop: custom validator check failed for prop "' + name + '".', + vm + ); + } + } +} + +var simpleCheckRE = /^(String|Number|Boolean|Function|Symbol)$/; + +function assertType (value, type) { + var valid; + var expectedType = getType(type); + if (simpleCheckRE.test(expectedType)) { + var t = typeof value; + valid = t === expectedType.toLowerCase(); + // for primitive wrapper objects + if (!valid && t === 'object') { + valid = value instanceof type; + } + } else if (expectedType === 'Object') { + valid = isPlainObject(value); + } else if (expectedType === 'Array') { + valid = Array.isArray(value); + } else { + valid = value instanceof type; + } + return { + valid: valid, + expectedType: expectedType + } +} + +/** + * Use function string name to check built-in types, + * because a simple equality check will fail when running + * across different vms / iframes. + */ +function getType (fn) { + var match = fn && fn.toString().match(/^\s*function (\w+)/); + return match ? match[1] : '' +} + +function isSameType (a, b) { + return getType(a) === getType(b) +} + +function getTypeIndex (type, expectedTypes) { + if (!Array.isArray(expectedTypes)) { + return isSameType(expectedTypes, type) ? 0 : -1 + } + for (var i = 0, len = expectedTypes.length; i < len; i++) { + if (isSameType(expectedTypes[i], type)) { + return i + } + } + return -1 +} + +/* */ + +function handleError (err, vm, info) { + if (vm) { + var cur = vm; + while ((cur = cur.$parent)) { + var hooks = cur.$options.errorCaptured; + if (hooks) { + for (var i = 0; i < hooks.length; i++) { + try { + var capture = hooks[i].call(cur, err, vm, info) === false; + if (capture) { return } + } catch (e) { + globalHandleError(e, cur, 'errorCaptured hook'); + } + } + } + } + } + globalHandleError(err, vm, info); +} + +function globalHandleError (err, vm, info) { + if (config.errorHandler) { + try { + return config.errorHandler.call(null, err, vm, info) + } catch (e) { + logError(e, null, 'config.errorHandler'); + } + } + logError(err, vm, info); +} + +function logError (err, vm, info) { + { + warn(("Error in " + info + ": \"" + (err.toString()) + "\""), vm); + } + /* istanbul ignore else */ + if ((inBrowser || inWeex) && typeof console !== 'undefined') { + console.error(err); + } else { + throw err + } +} + +/* */ +/* globals MessageChannel */ + +var callbacks = []; +var pending = false; + +function flushCallbacks () { + pending = false; + var copies = callbacks.slice(0); + callbacks.length = 0; + for (var i = 0; i < copies.length; i++) { + copies[i](); + } +} + +// Here we have async deferring wrappers using both microtasks and (macro) tasks. +// In < 2.4 we used microtasks everywhere, but there are some scenarios where +// microtasks have too high a priority and fire in between supposedly +// sequential events (e.g. #4521, #6690) or even between bubbling of the same +// event (#6566). However, using (macro) tasks everywhere also has subtle problems +// when state is changed right before repaint (e.g. #6813, out-in transitions). +// Here we use microtask by default, but expose a way to force (macro) task when +// needed (e.g. in event handlers attached by v-on). +var microTimerFunc; +var macroTimerFunc; +var useMacroTask = false; + +// Determine (macro) task defer implementation. +// Technically setImmediate should be the ideal choice, but it's only available +// in IE. The only polyfill that consistently queues the callback after all DOM +// events triggered in the same loop is by using MessageChannel. +/* istanbul ignore if */ +if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) { + macroTimerFunc = function () { + setImmediate(flushCallbacks); + }; +} else if (typeof MessageChannel !== 'undefined' && ( + isNative(MessageChannel) || + // PhantomJS + MessageChannel.toString() === '[object MessageChannelConstructor]' +)) { + var channel = new MessageChannel(); + var port = channel.port2; + channel.port1.onmessage = flushCallbacks; + macroTimerFunc = function () { + port.postMessage(1); + }; +} else { + /* istanbul ignore next */ + macroTimerFunc = function () { + setTimeout(flushCallbacks, 0); + }; +} + +// Determine microtask defer implementation. +/* istanbul ignore next, $flow-disable-line */ +if (typeof Promise !== 'undefined' && isNative(Promise)) { + var p = Promise.resolve(); + microTimerFunc = function () { + p.then(flushCallbacks); + // in problematic UIWebViews, Promise.then doesn't completely break, but + // it can get stuck in a weird state where callbacks are pushed into the + // microtask queue but the queue isn't being flushed, until the browser + // needs to do some other work, e.g. handle a timer. Therefore we can + // "force" the microtask queue to be flushed by adding an empty timer. + if (isIOS) { setTimeout(noop); } + }; +} else { + // fallback to macro + microTimerFunc = macroTimerFunc; +} + +/** + * Wrap a function so that if any code inside triggers state change, + * the changes are queued using a (macro) task instead of a microtask. + */ +function withMacroTask (fn) { + return fn._withTask || (fn._withTask = function () { + useMacroTask = true; + var res = fn.apply(null, arguments); + useMacroTask = false; + return res + }) +} + +function nextTick (cb, ctx) { + var _resolve; + callbacks.push(function () { + if (cb) { + try { + cb.call(ctx); + } catch (e) { + handleError(e, ctx, 'nextTick'); + } + } else if (_resolve) { + _resolve(ctx); + } + }); + if (!pending) { + pending = true; + if (useMacroTask) { + macroTimerFunc(); + } else { + microTimerFunc(); + } + } + // $flow-disable-line + if (!cb && typeof Promise !== 'undefined') { + return new Promise(function (resolve) { + _resolve = resolve; + }) + } +} + +/* */ + +var mark; +var measure; + +{ + var perf = inBrowser && window.performance; + /* istanbul ignore if */ + if ( + perf && + perf.mark && + perf.measure && + perf.clearMarks && + perf.clearMeasures + ) { + mark = function (tag) { return perf.mark(tag); }; + measure = function (name, startTag, endTag) { + perf.measure(name, startTag, endTag); + perf.clearMarks(startTag); + perf.clearMarks(endTag); + perf.clearMeasures(name); + }; + } +} + +/* not type checking this file because flow doesn't play well with Proxy */ + +var initProxy; + +{ + var allowedGlobals = makeMap( + 'Infinity,undefined,NaN,isFinite,isNaN,' + + 'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' + + 'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' + + 'require' // for Webpack/Browserify + ); + + var warnNonPresent = function (target, key) { + warn( + "Property or method \"" + key + "\" is not defined on the instance but " + + 'referenced during render. Make sure that this property is reactive, ' + + 'either in the data option, or for class-based components, by ' + + 'initializing the property. ' + + 'See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.', + target + ); + }; + + var hasProxy = + typeof Proxy !== 'undefined' && isNative(Proxy); + + if (hasProxy) { + var isBuiltInModifier = makeMap('stop,prevent,self,ctrl,shift,alt,meta,exact'); + config.keyCodes = new Proxy(config.keyCodes, { + set: function set (target, key, value) { + if (isBuiltInModifier(key)) { + warn(("Avoid overwriting built-in modifier in config.keyCodes: ." + key)); + return false + } else { + target[key] = value; + return true + } + } + }); + } + + var hasHandler = { + has: function has (target, key) { + var has = key in target; + var isAllowed = allowedGlobals(key) || key.charAt(0) === '_'; + if (!has && !isAllowed) { + warnNonPresent(target, key); + } + return has || !isAllowed + } + }; + + var getHandler = { + get: function get (target, key) { + if (typeof key === 'string' && !(key in target)) { + warnNonPresent(target, key); + } + return target[key] + } + }; + + initProxy = function initProxy (vm) { + if (hasProxy) { + // determine which proxy handler to use + var options = vm.$options; + var handlers = options.render && options.render._withStripped + ? getHandler + : hasHandler; + vm._renderProxy = new Proxy(vm, handlers); + } else { + vm._renderProxy = vm; + } + }; +} + +/* */ + +var seenObjects = new _Set(); + +/** + * Recursively traverse an object to evoke all converted + * getters, so that every nested property inside the object + * is collected as a "deep" dependency. + */ +function traverse (val) { + _traverse(val, seenObjects); + seenObjects.clear(); +} + +function _traverse (val, seen) { + var i, keys; + var isA = Array.isArray(val); + if ((!isA && !isObject(val)) || Object.isFrozen(val) || val instanceof VNode) { + return + } + if (val.__ob__) { + var depId = val.__ob__.dep.id; + if (seen.has(depId)) { + return + } + seen.add(depId); + } + if (isA) { + i = val.length; + while (i--) { _traverse(val[i], seen); } + } else { + keys = Object.keys(val); + i = keys.length; + while (i--) { _traverse(val[keys[i]], seen); } + } +} + +/* */ + +var normalizeEvent = cached(function (name) { + var passive = name.charAt(0) === '&'; + name = passive ? name.slice(1) : name; + var once$$1 = name.charAt(0) === '~'; // Prefixed last, checked first + name = once$$1 ? name.slice(1) : name; + var capture = name.charAt(0) === '!'; + name = capture ? name.slice(1) : name; + return { + name: name, + once: once$$1, + capture: capture, + passive: passive + } +}); + +function createFnInvoker (fns) { + function invoker () { + var arguments$1 = arguments; + + var fns = invoker.fns; + if (Array.isArray(fns)) { + var cloned = fns.slice(); + for (var i = 0; i < cloned.length; i++) { + cloned[i].apply(null, arguments$1); + } + } else { + // return handler return value for single handlers + return fns.apply(null, arguments) + } + } + invoker.fns = fns; + return invoker +} + +function updateListeners ( + on, + oldOn, + add, + remove$$1, + vm +) { + var name, def, cur, old, event; + for (name in on) { + def = cur = on[name]; + old = oldOn[name]; + event = normalizeEvent(name); + /* istanbul ignore if */ + if (isUndef(cur)) { + "development" !== 'production' && warn( + "Invalid handler for event \"" + (event.name) + "\": got " + String(cur), + vm + ); + } else if (isUndef(old)) { + if (isUndef(cur.fns)) { + cur = on[name] = createFnInvoker(cur); + } + add(event.name, cur, event.once, event.capture, event.passive, event.params); + } else if (cur !== old) { + old.fns = cur; + on[name] = old; + } + } + for (name in oldOn) { + if (isUndef(on[name])) { + event = normalizeEvent(name); + remove$$1(event.name, oldOn[name], event.capture); + } + } +} + +/* */ + +function mergeVNodeHook (def, hookKey, hook) { + if (def instanceof VNode) { + def = def.data.hook || (def.data.hook = {}); + } + var invoker; + var oldHook = def[hookKey]; + + function wrappedHook () { + hook.apply(this, arguments); + // important: remove merged hook to ensure it's called only once + // and prevent memory leak + remove(invoker.fns, wrappedHook); + } + + if (isUndef(oldHook)) { + // no existing hook + invoker = createFnInvoker([wrappedHook]); + } else { + /* istanbul ignore if */ + if (isDef(oldHook.fns) && isTrue(oldHook.merged)) { + // already a merged invoker + invoker = oldHook; + invoker.fns.push(wrappedHook); + } else { + // existing plain hook + invoker = createFnInvoker([oldHook, wrappedHook]); + } + } + + invoker.merged = true; + def[hookKey] = invoker; +} + +/* */ + +function extractPropsFromVNodeData ( + data, + Ctor, + tag +) { + // we are only extracting raw values here. + // validation and default values are handled in the child + // component itself. + var propOptions = Ctor.options.props; + if (isUndef(propOptions)) { + return + } + var res = {}; + var attrs = data.attrs; + var props = data.props; + if (isDef(attrs) || isDef(props)) { + for (var key in propOptions) { + var altKey = hyphenate(key); + { + var keyInLowerCase = key.toLowerCase(); + if ( + key !== keyInLowerCase && + attrs && hasOwn(attrs, keyInLowerCase) + ) { + tip( + "Prop \"" + keyInLowerCase + "\" is passed to component " + + (formatComponentName(tag || Ctor)) + ", but the declared prop name is" + + " \"" + key + "\". " + + "Note that HTML attributes are case-insensitive and camelCased " + + "props need to use their kebab-case equivalents when using in-DOM " + + "templates. You should probably use \"" + altKey + "\" instead of \"" + key + "\"." + ); + } + } + checkProp(res, props, key, altKey, true) || + checkProp(res, attrs, key, altKey, false); + } + } + return res +} + +function checkProp ( + res, + hash, + key, + altKey, + preserve +) { + if (isDef(hash)) { + if (hasOwn(hash, key)) { + res[key] = hash[key]; + if (!preserve) { + delete hash[key]; + } + return true + } else if (hasOwn(hash, altKey)) { + res[key] = hash[altKey]; + if (!preserve) { + delete hash[altKey]; + } + return true + } + } + return false +} + +/* */ + +// The template compiler attempts to minimize the need for normalization by +// statically analyzing the template at compile time. +// +// For plain HTML markup, normalization can be completely skipped because the +// generated render function is guaranteed to return Array. There are +// two cases where extra normalization is needed: + +// 1. When the children contains components - because a functional component +// may return an Array instead of a single root. In this case, just a simple +// normalization is needed - if any child is an Array, we flatten the whole +// thing with Array.prototype.concat. It is guaranteed to be only 1-level deep +// because functional components already normalize their own children. +function simpleNormalizeChildren (children) { + for (var i = 0; i < children.length; i++) { + if (Array.isArray(children[i])) { + return Array.prototype.concat.apply([], children) + } + } + return children +} + +// 2. When the children contains constructs that always generated nested Arrays, +// e.g.