// ==UserScript==
// @name json-viewer-updated
// @namespace http://tampermonkey.net/
// @version 0.4.2
// @description 在原作者 0.4 版本上加入支持每行单独为 json 的文本输出
// @description 修复 0.4.1 版本 bug
// @author sgd/robin.cai
// @match *://*/*
// @grant none
// @require https://code.jquery.com/jquery-3.4.1.min.js
// @icon https://www.easyicon.net/api/resizeApi.php?id=501159&size=128
// @downloadURL https://update.greasyfork.icu/scripts/457185/json-viewer-updated.user.js
// @updateURL https://update.greasyfork.icu/scripts/457185/json-viewer-updated.meta.js
// ==/UserScript==
// 解决和原网页jquery版本冲突
var jq = jQuery.noConflict(true);
// jquery.json-viewer 插件 开始
(function(jq){
function isCollapsable(arg) {
return arg instanceof Object && Object.keys(arg).length > 0;
}
function isUrl(string) {
var regexp = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
return regexp.test(string);
}
function json2html(json, options) {
var html = '';
if (typeof json === 'string') {
/* Escape tags */
json = json.replace(/&/g, '&').replace(//g, '>');
if (isUrl(json)){
html += '"' + json + '"';
}
else{
html += '"' + json + '"';
}
}
else if (typeof json === 'number') {
html += '' + json + '';
}
else if (typeof json === 'boolean') {
html += '' + json + '';
}
else if (json === null) {
html += 'null';
}
else if (json instanceof Array) {
if (json.length > 0) {
html += '[
';
for (var i = 0; i < json.length; ++i) {
html += '
';
/* Add toggle button if item is collapsable */
if (isCollapsable(json[i])) {
html += '';
}
html += json2html(json[i], options);
/* Add comma if item is not last */
if (i < json.length - 1) {
html += ',';
}
html += '
';
}
html += ']';
}
else {
html += '[]';
}
}
else if (typeof json === 'object') {
var key_count = Object.keys(json).length;
if (key_count > 0) {
html += '{
';
for (var key in json) {
if (json.hasOwnProperty(key)) {
html += '
';
var keyRepr = options.withQuotes ?
'"' + key + '"' : key;
/* Add toggle button if item is collapsable */
if (isCollapsable(json[key])) {
html += '' + keyRepr + '';
}
else {
html += keyRepr;
}
html += ': ' + json2html(json[key], options);
/* Add comma if item is not last */
if (--key_count > 0){
html += ',';
}
html += '
';
}
}
html += '
}';
}
else {
html += '{}';
}
}
return html;
}
jq.fn.jsonViewer = function(json, options) {
options = options || {};
return this.each(function() {
/* Transform to HTML */
var html = json2html(json, options);
if (isCollapsable(json)){
html = '' + html;
}
/* Insert HTML in target DOM element */
jq(this).html(html);
/* Bind click on toggle buttons */
jq(this).off('click');
jq(this).on('click', 'a.json-toggle', function() {
var target = jq(this).toggleClass('collapsed').siblings('ul.json-dict, ol.json-array');
target.toggle();
if (target.is(':visible')) {
target.siblings('.json-placeholder').remove();
}
else {
var count = target.children('li').length;
var placeholder = count + (count > 1 ? ' items' : ' item');
target.after('' + placeholder + '');
}
return false;
});
/* Simulate click on toggle button when placeholder is clicked */
jq(this).on('click', 'a.json-placeholder', function() {
jq(this).siblings('a.json-toggle').click();
return false;
});
if (options.collapsed == true) {
/* Trigger click to collapse all nodes */
jq(this).find('a.json-toggle').click();
}
});
};
})(jq);
// jquery.json-viewer 插件 结束
(function() {
'use strict';
// 添加样式
var style = document.createElement("style");
style.type = "text/css";
var text = document.createTextNode("body{margin-bottom: 200px;}per{margin:20px;}#btn{position: fixed;top: 20px;right: 20px;background-color: transparent;border: 1px solid rgb(218, 220, 224);border-radius: 4px;box-sizing: border-box;color: rgb(26, 115, 232);cursor: pointer;line-height:30px;}#btn:hover{background-color:rgb(210, 227, 252);} ul.json-dict, ol.json-array {list-style-type: none;margin: 0 0 0 1px;border-left: 1px dotted #ccc;padding-left: 2em;}.json-string {color: #0B7500;}.json-literal {color: #1A01CC;font-weight: bold;}a.json-toggle {position: relative;color: inherit;text-decoration: none;}a.json-toggle:focus {outline: none;}a.json-toggle:before {color: #aaa;content: \"\\25BC\";position: absolute;display: inline-block;width: 1em;left: -1em;}a.json-toggle.collapsed:before {transform: rotate(-90deg);-ms-transform: rotate(-90deg);-webkit-transform: rotate(-90deg);}a.json-placeholder {color: #aaa;padding: 0 1em;text-decoration: none;} a.json-placeholder:hover { text-decoration: underline; }");
style.appendChild(text);
var head = document.getElementsByTagName("head")[0];
head.appendChild(style);
var source = jq('pre[style="word-wrap: break-word; white-space: pre-wrap;"]');
// 根据上面这一点没办法确定是需要添加json格式化工具,再加上对内容进行判断是不是json格式的内容
if(source.length > 0 && source.first().html().includes("}\n{")){
var rawStr = source.first().html()
var newStr = rawStr.replace(/}\n{/g, "},{")
newStr = "[" + newStr + "]"
if (isJSON(newStr)) {
source.first().html(newStr)
} else {
source.first().html(rawStr)
}
}
// 如果是直接打开的json接口地址才需要格式化插件
if(source.length > 0 && isJSON(source.first().html())){
console.log("json-viewer 插件初始化成功");
source = source.first();
source.attr("id", "json-source")
source.hide();
var src = source.html();// 获取到内容
// 添加一个格式化显示的per元素
jq("body").append(jq(''))
console.log(src);
// 将内容用eval函数处理下
var input = eval('(' + src + ')');
// 调用格式化方法,参数:是否收缩所有的节点 是否为Key添加双引号
jq('#json-renderer').jsonViewer(input, {collapsed: false,withQuotes: true});
// 添加原文、格式化后内容的切换按钮
jq("body").append('');
jq("body").on("click","#btn",function(){
var v = jq(this).val();
if(v=='View Source'){
jq(this).val("Format Content");
// 查看原文
jq('#json-renderer').hide();
jq('#json-source').show();
}else{
jq(this).val("View Source");
// 格式化
jq('#json-renderer').show();
jq('#json-source').hide();
}
});
// 所有a标签,看是否是图片,是图片生成预览图
jq(document).on("mouseenter mouseleave","a.json-string",function(event){
if(event.type=='mouseenter'){
// 移入
var href = jq(this).attr('href');
if(isImg(href)){
jq("body").append('
');
var xPos = parseInt(event.pageX) + "px";
var yPos = parseInt(event.pageY) + "px";
jq(".preview").css("left", xPos);
jq(".preview").css("top", yPos);
jq(".preview").show();
}
}else{
// 移除
jq(".preview").remove();
}
});
}
/*检查是否是图片链接*/
function isImg(pathImg) {
var regexp = /^(http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?\/([\w#!:.?+=&%@!\-\/])*\.(gif|jpg|jpeg|png|GIF|JPG|PNG)([\w#!:.?+=&%@!\-\/])?/;
return regexp.test(pathImg);
}
/** 检验内容是否是json格式的内容*/
function isJSON(str) {
if (typeof str == 'string') {
try {
var obj=JSON.parse(str);
if(typeof obj == 'object' && obj ){
console.log("is json")
return true;
}else{
console.log("is not json")
return false;
}
} catch(e) {
console.log('error:'+str+'!!!'+e);
return false;
}
}
console.log('It is not a string!')
}
})();