diff --git a/dev/typo.dic b/dev/typo.dic index 485d380..54c79f6 100644 --- a/dev/typo.dic +++ b/dev/typo.dic @@ -1,2 +1,3 @@ +anim eruda scss \ No newline at end of file diff --git a/eustia/isCrossOrig.js b/eustia/isCrossOrig.js new file mode 100644 index 0000000..e4cac95 --- /dev/null +++ b/eustia/isCrossOrig.js @@ -0,0 +1,8 @@ +_('startWith'); + +var origin = window.location.origin; + +function exports(url) +{ + return !startWith(url, origin); +} \ No newline at end of file diff --git a/package.json b/package.json index e505503..d446418 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eruda", - "version": "0.5.9", + "version": "0.6.0", "description": "Console for Mobile Browsers", "main": "dist/eruda.js", "scripts": { diff --git a/src/Console/Console.scss b/src/Console/Console.scss index 5cb764c..fafde1c 100644 --- a/src/Console/Console.scss +++ b/src/Console/Console.scss @@ -1,42 +1,42 @@ @import "../style/variable"; +@import "../style/mixin"; .dev-tools { .tools { .console { .control { - position: absolute; - left: 0; - top: 0; + @include absolute(100%, 40px); padding: 10px 10px 10px 40px; background: #fff; - height: 40px; line-height: 20px; - width: 100%; + border-bottom: 1px solid $gray-light; .icon-ban, .icon-info-circle { display: inline-block; color: $gray; - padding: 5px; - font-size: 16px; + padding: 10px; + font-size: $font-size-l; position: absolute; - top: 6px; + top: 1px; + transition: color $anim-duration; &:active { color: $gray-light; } } .icon-ban { - left: 10px; + left: 0; } .icon-info-circle { - right: 10px; + right: 0; } .filter { color: $gray; margin: 0 1px; - font-size: 12px; + font-size: $font-size-s; height: 20px; display: inline-block; padding: 0 4px; line-height: 20px; - border-radius: 4px; + border-radius: $border-radius; + transition: background $anim-duration, color $anim-duration; &.active { background: $gray; color: #fff; @@ -51,6 +51,7 @@ bottom: 0; width: 100%; background: #fff; + border-top: 1px solid $gray-light; height: 40px; .buttons { display: none; @@ -60,7 +61,7 @@ width: 100%; height: 40px; color: $gray; - font-size: 12px; + font-size: $font-size-s; border-bottom: 1px solid $gray-light; .button { width: 50%; @@ -73,6 +74,7 @@ &:last-child { border-right: none; } + transition: background $anim-duration, color $anim-duration; &:active { background: $blue; color: #fff; diff --git a/src/Console/Log.scss b/src/Console/Log.scss index b784dfc..2e032b5 100644 --- a/src/Console/Log.scss +++ b/src/Console/Log.scss @@ -1,14 +1,17 @@ @import "../style/variable"; +@import "../style/mixin"; .dev-tools { .tools { .console { .logs { - transform: translateZ(0); + @include overflow-auto(y); height: 100%; - overflow-y: auto; - -webkit-overflow-scrolling: touch; - font-size: 14px; + font-size: $font-size; li { - padding: 10px; + background: #fff; + margin: 10px 0; + padding: $padding; + border-top: 1px solid $gray-light; + border-bottom: 1px solid $gray-light; &:after { content: ''; display: block; @@ -51,20 +54,17 @@ } .log-content { + @include overflow-auto(x); line-height: 20px; - overflow-x: auto; - -webkit-overflow-scrolling: touch; } &.input { background: #fff; } - &.log, &.output, &.info, &.dir { - border-bottom: 1px solid #b4b4b4; - } &.html { table { width: 100%; background: #fff; + border-bottom: 1px solid $gray-light; border-collapse: collapse; th { background: $blue; diff --git a/src/DevTools/DevTools.scss b/src/DevTools/DevTools.scss index 1885b62..39eea63 100644 --- a/src/DevTools/DevTools.scss +++ b/src/DevTools/DevTools.scss @@ -1,34 +1,24 @@ @import "../style/variable"; +@import "../style/mixin"; .dev-tools { - position: absolute; - width: 100%; - height: 100%; - bottom: 0; - left: 0; - padding-top: 50px !important; + @include absolute(); + padding-top: 55px !important; background: #fff; z-index: 500; display: none; opacity: 0; - transition: opacity .3s; - transform: translateZ(0); + transition: opacity $anim-duration; .tools { + @include overflow-auto(); height: 100%; width: 100%; position: relative; - overflow: auto; - -webkit-overflow-scrolling: touch; .tool { - transform: translateZ(0); - position: absolute; + @include absolute(); overflow: hidden; display: none; - left: 0; - top: 0; - background: $gray-light; - width: 100%; - height: 100%; + background: #f8f9fa; } } } diff --git a/src/DevTools/NavBar.scss b/src/DevTools/NavBar.scss index d3c4dd8..cdbe4d7 100644 --- a/src/DevTools/NavBar.scss +++ b/src/DevTools/NavBar.scss @@ -1,14 +1,13 @@ @import "../style/variable"; +@import "../style/mixin"; + +$height: 55px; +$item-width: 69px; .dev-tools { .nav-bar { - height: 50px; - overflow-y: auto; - position: absolute; - width: 100%; - -webkit-overflow-scrolling: touch; - left: 0; - top: 0; + @include absolute(100%, $height); + @include overflow-auto(y); box-shadow: $box-shadow; z-index: 100; background: $blue; @@ -17,30 +16,28 @@ li { cursor: pointer; display: inline-block; - height: 50px; - line-height: 50px; - width: 69px; - color: $gray-light; - font-size: 12px; + height: $height; + line-height: $height; + width: $item-width; + color: #fff; + font-size: $font-size-s; text-align: center; - opacity: 0.5; text-transform: capitalize; - transition: all .3s; + transition: all $anim-duration; &.active { color: #fff; - opacity: 1; background: $blue-light; } } } .bottom-bar { - transition: left .3s; + transition: left $anim-duration; height: 3px; background: #fff; position: absolute; bottom: 0; left: 0; - width: 69px; + width: $item-width; } } } \ No newline at end of file diff --git a/src/Elements/Elements.es6 b/src/Elements/Elements.es6 index 1faaa36..496192b 100644 --- a/src/Elements/Elements.es6 +++ b/src/Elements/Elements.es6 @@ -304,12 +304,15 @@ function formatChildNodes(nodes) for (let i = 0, len = nodes.length; i < len; i++) { - var child = nodes[i]; - if (child.nodeType === 3) + var child = nodes[i], + nodeType = child.nodeType; + + if (nodeType === 3 || nodeType === 8) { var val = child.nodeValue.trim(); if (val !== '') ret.push({ text: val, + isCmt: nodeType === 8, idx: i }); continue; @@ -317,7 +320,7 @@ function formatChildNodes(nodes) var isSvg = !util.isStr(child.className); - if (child.nodeType === 1 && + if (nodeType === 1 && child.id !== 'eruda' && (isSvg || child.className.indexOf('eruda') < 0)) { diff --git a/src/Elements/Elements.hbs b/src/Elements/Elements.hbs index 33958ce..eeb6260 100644 --- a/src/Elements/Elements.hbs +++ b/src/Elements/Elements.hbs @@ -4,7 +4,7 @@ {{#if children}} {{/if}} diff --git a/src/Elements/Elements.scss b/src/Elements/Elements.scss index 4f16c56..ae740ad 100644 --- a/src/Elements/Elements.scss +++ b/src/Elements/Elements.scss @@ -1,40 +1,38 @@ @import "../style/variable"; +@import "../style/mixin"; .dev-tools { .tools { .elements { padding-bottom: 40px; font-size: 14px; .show-area { - overflow-y: auto; - -webkit-overflow-scrolling: touch; + @include overflow-auto(y); height: 100%; } .breadcrumb { background: #fff; - padding: $common-padding; + padding: $padding; margin-bottom: 10px; word-break: break-all; } .section { h2 { background: $blue; - padding: $common-padding; + padding: $padding; color: #fff; - font-size: 14px; + font-size: $font-size; } margin-bottom: 10px; } .children { background: #fff; margin-bottom: 10px !important; + border-bottom: 1px solid $gray-light; li { - padding: $common-padding; - overflow-x: auto; - -webkit-overflow-scrolling: touch; - border-top: 1px solid $gray; - &:last-child { - border-bottom: 1px solid $gray; - } + @include overflow-auto(x); + padding: $padding; + border-top: 1px solid $gray-light; + white-space: nowrap; } } .attributes { @@ -53,7 +51,7 @@ .text-content { background: #fff; .content { - padding: $common-padding; + padding: $padding; overflow-x: auto; -webkit-overflow-scrolling: touch; } @@ -87,11 +85,11 @@ background: #fff; font-size: 12px; .style-wrapper { - padding: $common-padding; + padding: $padding; .style-rules { box-shadow: $box-shadow; border: 1px solid $gray; - padding: $common-padding; + padding: $padding; background: #fff; margin-bottom: 10px; .rule { @@ -111,18 +109,18 @@ background: #fff; font-size: 12px; .listener-wrapper { - padding: $common-padding; + padding: $padding; .listener { box-shadow: $box-shadow; margin-bottom: 10px; background: #fff; .listener-type { - padding: $common-padding; + padding: $padding; background: $blue; color: #fff; } .listener-content li { - padding: $common-padding; + padding: $padding; border: 1px solid $gray; border-top: none; overflow-x: auto; @@ -142,6 +140,7 @@ bottom: 0; width: 100%; font-size: 0; + border-top: 1px solid $gray-light; .btn { text-align: center; color: $gray; diff --git a/src/Info/Info.scss b/src/Info/Info.scss index 4a65ac5..3f03f5d 100644 --- a/src/Info/Info.scss +++ b/src/Info/Info.scss @@ -2,23 +2,24 @@ .dev-tools { .tools { .info { - overflow-y: auto; - -webkit-overflow-scrolling: touch; - font-size: 14px; + font-size: $font-size; li { - overflow-x: auto; - border-bottom: 1px solid $gray; + background: #fff; + margin: 10px; + box-shadow: $box-shadow; .title, .content { - padding: 10px; - } - .content { - margin: 0; + padding: $padding; } .title { padding-bottom: 0; font-size: 16px; color: $blue; } + .content { + margin: 0; + user-select: text; + word-break: break-all; + } } } } } \ No newline at end of file diff --git a/src/Network/Network.scss b/src/Network/Network.scss index 5316590..3dd3fc7 100644 --- a/src/Network/Network.scss +++ b/src/Network/Network.scss @@ -1,23 +1,23 @@ @import "../style/variable"; +@import "../style/mixin"; .dev-tools { .tools { .network { overflow-y: auto; -webkit-overflow-scrolling: touch; .performance-timing { - padding: 10px; + padding: $padding; .inner-wrapper { background: $blue; .bar { + @include overflow-auto(x); border-bottom: 1px solid #fff; - overflow-x: auto; - -webkit-overflow-scrolling: touch; span { - font-size: 12px; + font-size: $font-size-s; white-space: nowrap; color: #fff; padding: 5px 0; - background: $red-dark; + background: $red; display: inline-block; } &:last-child { @@ -48,10 +48,10 @@ } .requests, .entries { background: #fff; - border-bottom: 1px solid $gray; + border-bottom: 1px solid $gray-light; margin-bottom: 10px; li { - border-top: 1px solid $gray; + border-top: 1px solid $gray-light; overflow: auto; height: 41px; -webkit-overflow-scrolling: touch; diff --git a/src/Network/Request.es6 b/src/Network/Request.es6 index 915b8ae..b8550e0 100644 --- a/src/Network/Request.es6 +++ b/src/Network/Request.es6 @@ -8,7 +8,7 @@ export default class Request extends util.Emitter this._xhr = xhr; this._method = method; - this._url = url; + this._url = fullUrl(url); this._id = util.uniqId('request'); } handleSend(data) @@ -32,7 +32,7 @@ export default class Request extends util.Emitter this.emit('update', this._id, { type: type.type, subType: type.subType, - size: getSize(xhr, true), + size: getSize(xhr, true, this._url), time: util.now(), resHeaders: getHeaders(xhr) }); @@ -47,7 +47,7 @@ export default class Request extends util.Emitter this.emit('update', this._id, { status: xhr.status, done: true, - size: getSize(xhr), + size: getSize(xhr, false, this._url), time: util.now(), resTxt: resTxt }); @@ -87,7 +87,7 @@ function getType(contentType) } } -function getSize(xhr, headersOnly) +function getSize(xhr, headersOnly, url) { var size = 0; @@ -100,11 +100,17 @@ function getSize(xhr, headersOnly) } } - try { - size = util.toNum(xhr.getResponseHeader('Content-Length')); - } catch (e) + if (util.isCrossOrig(url)) { getStrSize(); + } else + { + try { + size = util.toNum(xhr.getResponseHeader('Content-Length')); + } catch (e) + { + getStrSize(); + } } if (size === 0) getStrSize(); @@ -119,4 +125,13 @@ function lenToUtf8Bytes(str) var m = encodeURIComponent(str).match(/%[89ABab]/g); return str.length + (m ? m.length : 0); +} + +var origin = window.location.origin; + +function fullUrl(url) +{ + if (util.startWith(url, 'http')) return url; + + return origin + url; } \ No newline at end of file diff --git a/src/Resources/Resources.es6 b/src/Resources/Resources.es6 index 2595ef5..dcf91d2 100644 --- a/src/Resources/Resources.es6 +++ b/src/Resources/Resources.es6 @@ -177,7 +177,7 @@ export default class Resources extends Tool { var key = util.$(this).data('key'); - util.cookie.remove(key); + delCookie(key); self.refreshCookie()._render(); }) .on('click', '.eruda-storage-val', function () @@ -222,7 +222,7 @@ export default class Resources extends Tool { var url = util.$(this).attr('href'); - if (!isCrossOrig(url)) + if (!util.isCrossOrig(url)) { e.preventDefault(); @@ -293,8 +293,34 @@ function getState(type, len) return 'eruda-ok'; } -var origin = window.location.origin; +var {hostname, pathname} = window.location; -var isCrossOrig = url => !util.startWith(url, origin); +function delCookie(key) +{ + util.cookie.remove(key); + + let hostNames = hostname.split('.'), + pathNames = pathname.split('/'), + domain = '', + pathLen = pathNames.length, + path; + + for (let i = hostNames.length - 1; i >= 0; i--) + { + let hostName = hostNames[i]; + if (hostName === '') continue; + domain = (domain === '') ? hostName : hostName + '.' + domain ; + + path = '/'; + util.cookie.remove(key, {domain, path}); + for (let j = 0; j < pathLen; j++) + { + let pathName = pathNames[j]; + if (pathName === '') continue; + path += pathName; + util.cookie.remove(key, {domain, path}); + } + } +} var sliceStr = (str, len) => str.length < len ? str : str.slice(0, len) + '...'; \ No newline at end of file diff --git a/src/Settings/Settings.scss b/src/Settings/Settings.scss index 9c06d17..b16779c 100644 --- a/src/Settings/Settings.scss +++ b/src/Settings/Settings.scss @@ -8,7 +8,7 @@ height: 10px; } .text { - padding: $common-padding; + padding: $padding; color: $gray-dark; font-size: 12px; } @@ -55,7 +55,7 @@ } } .input:checked ~ .label { - background: #47a8d8; + background: $blue; box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15), inset 0 0 3px rgba(0, 0, 0, 0.2); } .input:checked ~ .label:before { diff --git a/src/Sources/Sources.scss b/src/Sources/Sources.scss index 69feb6d..ced2654 100644 --- a/src/Sources/Sources.scss +++ b/src/Sources/Sources.scss @@ -7,7 +7,7 @@ font-size: 14px; .code, .raw { background: #fff; - padding: $common-padding; + padding: $padding; overflow-x: auto; -webkit-overflow-scrolling: touch; min-height: 100%; @@ -15,7 +15,7 @@ .image { .breadcrumb { background: #fff; - padding: $common-padding; + padding: $padding; margin-bottom: 10px; word-break: break-all; } @@ -35,7 +35,7 @@ .http { .breadcrumb { background: #fff; - padding: $common-padding; + padding: $padding; margin-bottom: 10px; word-break: break-all; } @@ -43,7 +43,7 @@ background: #fff; h2 { background: $blue; - padding: $common-padding; + padding: $padding; color: #fff; font-size: 16px; } @@ -60,7 +60,7 @@ } .response, .data { background: #fff; - padding: $common-padding; + padding: $padding; margin-bottom: 10px; overflow-x: auto; -webkit-overflow-scrolling: touch; @@ -71,7 +71,7 @@ line-height: 1.2; background: #fff; min-height: 100%; - padding: $common-padding 25px 10px; + padding: $padding 25px 10px; overflow-x: auto; -webkit-overflow-scrolling: touch; &, ul { diff --git a/src/index.es6 b/src/index.es6 index cd48456..7398fb9 100644 --- a/src/index.es6 +++ b/src/index.es6 @@ -13,37 +13,26 @@ import util from './lib/util' import config from './lib/config.es6' module.exports = { - init(options) + init(options = {}) { require('./style/style.scss'); require('./style/reset.scss'); require('./style/icon.css'); - options = options || {}; util.defaults(options, { tool: ['console', 'elements', 'network', 'resources', 'sources', 'info', 'snippets', 'features'] }); options.tool = util.toArr(options.tool).reverse(); this._options = options; - this.config = config; - this.util = util; - - this.Console = Console; - this.Elements = Elements; - this.Network = Network; - this.Sources = Sources; - this.Resources = Resources; - this.Info = Info; - this.Snippets = Snippets; - this.Features = Features; - this._initContainer(); this._initDevTools(); this._initEntryBtn(); this._initSettings(); this._initTools(); }, + config, util, + Console, Elements, Network, Sources, Resources, Info, Snippets, Features, get(name) { return util.isUndef(name) ? this._devTools : this._devTools.get(name); @@ -68,18 +57,13 @@ module.exports = { }, _initContainer() { - var el; + let el = this._options.container; - var container = this._options.container; - if (util.isEl(container)) - { - el = container; - } else + if (!el) { el = document.createElement('div'); document.documentElement.appendChild(el); } - el.id = 'eruda'; el.className = 'eruda-container'; @@ -91,15 +75,15 @@ module.exports = { }, _initEntryBtn() { - var entryBtn = this._entryBtn = new EntryBtn(this._$el); + let entryBtn = this._entryBtn = new EntryBtn(this._$el); entryBtn.on('click', () => this._devTools.toggle()); }, _initSettings() { - var devTools = this._devTools; + let devTools = this._devTools, + settings = new Settings(); - var settings = new Settings(); devTools.add(settings); settings.separator() @@ -112,18 +96,15 @@ module.exports = { }, _initTools() { - var tool = this._options.tool, + let tool = this._options.tool, devTools = this._devTools; tool.forEach(name => { - var Tool = this[util.upperFirst(name)]; - + let Tool = this[util.upperFirst(name)]; if (Tool) devTools.add(new Tool()); }); devTools.showTool(util.last(tool) || 'settings'); } }; - - diff --git a/src/lib/util.js b/src/lib/util.js index f633609..ffc1dc4 100644 --- a/src/lib/util.js +++ b/src/lib/util.js @@ -935,6 +935,45 @@ module.exports = (function () return exports; })({}); + /* ------------------------------ startWith ------------------------------ */ + + var startWith = _.startWith = (function (exports) + { + /* Check if string starts with the given target string. + * + * |Name |Type |Desc | + * |------------------------------------------------| + * |str |string |The string to search | + * |prefix|string |String prefix | + * |return|boolean|True if string starts with prefix| + * + * ```javascript + * startWith('ab', 'a'); // -> true + * ``` + */ + + exports = function (str, prefix) + { + return str.indexOf(prefix) === 0; + }; + + return exports; + })({}); + + /* ------------------------------ isCrossOrig ------------------------------ */ + + var isCrossOrig = _.isCrossOrig = (function (exports) + { + var origin = window.location.origin; + + function exports(url) + { + return !startWith(url, origin); + } + + return exports; + })({}); + /* ------------------------------ isEl ------------------------------ */ var isEl = _.isEl = (function (exports) @@ -1172,6 +1211,17 @@ module.exports = (function () return exports; })({}); + /* ------------------------------ noop ------------------------------ */ + + var noop = _.noop = (function (exports) + { + /* A no-operation function. */ + + exports = function () {}; + + return exports; + })({}); + /* ------------------------------ now ------------------------------ */ var now = _.now = (function (exports) @@ -1367,6 +1417,42 @@ module.exports = (function () * |methods|object |Public methods | * |statics|object |Static methods | * |return |function|Function used to create instances| + * + * ```javascript + * var People = Class({ + * initialize: function (name, age) + * { + * this.name = name; + * this.age = age; + * }, + * introduce: function () + * { + * return 'I am ' + this.name + ', ' + this.age + ' years old.'. + * } + * }); + * + * var Student = People.extend({ + * initialize: function (name, age, school) + * { + * this.callSuper('initialize', name, age); + * + * this.school = school. + * }, + * introduce: function () + * { + * return this.callSuper('introduce') + '\n I study at ' + this.school + '.'. + * } + * }, { + * is: function (obj) + * { + * return obj instanceof Student; + * } + * }); + * + * var a = new Student('allen', 17, 'Hogwarts'); + * a.introduce(); // -> 'I am allen, 17 years old. \n I study at Hogwarts.' + * Student.is(a); // -> true + * ``` */ var regCallSuper = /callSuper/; @@ -2491,31 +2577,6 @@ module.exports = (function () return exports; })({}); - /* ------------------------------ startWith ------------------------------ */ - - var startWith = _.startWith = (function (exports) - { - /* Check if string starts with the given target string. - * - * |Name |Type |Desc | - * |------------------------------------------------| - * |str |string |The string to search | - * |prefix|string |String prefix | - * |return|boolean|True if string starts with prefix| - * - * ```javascript - * startWith('ab', 'a'); // -> true - * ``` - */ - - exports = function (str, prefix) - { - return str.indexOf(prefix) === 0; - }; - - return exports; - })({}); - /* ------------------------------ toStr ------------------------------ */ var toStr = _.toStr = (function (exports) diff --git a/src/style/mixin.scss b/src/style/mixin.scss new file mode 100644 index 0000000..99ee46b --- /dev/null +++ b/src/style/mixin.scss @@ -0,0 +1,17 @@ +@mixin absolute($width: 100%, $height: 100%) { + position: absolute; + width: $width; + height: $height; + left: 0; + top: 0; +} + +@mixin overflow-auto($direction: 'both') +{ + @if $direction == 'both' { + overflow: auto; + } @else { + overflow-#{$direction}: auto; + } + -webkit-overflow-scrolling: touch; +} \ No newline at end of file diff --git a/src/style/style.scss b/src/style/style.scss index e74554b..13a74cc 100644 --- a/src/style/style.scss +++ b/src/style/style.scss @@ -9,12 +9,14 @@ width: 100%; height: 100%; z-index: 100000; + color: $gray-dark; transform: translateZ(0); font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; - font-size: 16px; + font-size: $font-size; * { box-sizing: border-box; pointer-events: all; + user-select: none; -webkit-tap-highlight-color: transparent; } ul { @@ -35,3 +37,7 @@ color: $red; } +.green { + color: $green; +} + diff --git a/src/style/variable.scss b/src/style/variable.scss index 662e47d..91f2ac4 100644 --- a/src/style/variable.scss +++ b/src/style/variable.scss @@ -1,13 +1,22 @@ $box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .05), 0 1px 4px 0 rgba(0, 0, 0, .08), 0 3px 1px -2px rgba(0, 0, 0, .2); -$common-padding: 10px; +$border-radius: 4px; -$blue: #76a2ee; -$blue-light: #afc5ea; -$gray: #b4b4b4; -$gray-light: #f2f2f2; -$gray-dark: #888; -$red: #eda29b; +$padding: 10px; + +$font-size: 14px; +$font-size-s: 12px; +$font-size-l: 16px; + +$anim-duration: .3s; + +// https://www.google.com/design/spec/style/color.html#color-color-palette +$blue: #2196f3; +$blue-light: #90caf9; +$gray: #707d8b; +$gray-light: #eceffe; +$gray-dark: #263238; +$red: #f44336; $red-dark: #f73c37; -$green: #8de191; -$yellow: #fff5c2; +$green: #009688; +$yellow: #ff9800; $yellow-dark: #ff9900; \ No newline at end of file diff --git a/test/index.html b/test/index.html index a603940..686f2ea 100644 --- a/test/index.html +++ b/test/index.html @@ -15,6 +15,7 @@
+
One
Two
GitHub