123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452 |
- // 创建Vue实例并暴露到全局供事件处理使用
- window.vueApp = new Vue({
- el: '#pageContainer',
- data: {
- errorMessage: '',
- tipMessage: 'Tips:',
- errorHighlight: false,
- hasErrorClass: false,
- leftSideError: false,
- rightSideError: false,
- differenceCount: 0,
- isDifferent: false,
- jsonExamples: {
- userInfo: {
- left: {
- "id": 1001,
- "name": "张三",
- "age": 28,
- "email": "[email protected]",
- "address": {
- "city": "北京",
- "district": "朝阳区",
- "street": "建国路88号"
- },
- "tags": ["前端", "JavaScript", "Vue"],
- "isActive": true,
- "lastLogin": "2023-01-15T08:30:00Z"
- },
- right: {
- "id": 1001,
- "name": "张三",
- "age": 30,
- "email": "[email protected]",
- "address": {
- "city": "上海",
- "district": "浦东新区",
- "street": "建国路88号"
- },
- "tags": ["前端", "JavaScript", "React"],
- "isActive": true,
- "lastLogin": "2023-02-20T10:45:00Z"
- }
- },
- productData: {
- left: {
- "products": [
- {
- "id": "p001",
- "name": "智能手机",
- "price": 4999,
- "inventory": 100,
- "category": "电子产品",
- "specs": {
- "brand": "小米",
- "model": "Mi 11",
- "color": "黑色",
- "storage": "128GB"
- }
- },
- {
- "id": "p002",
- "name": "笔记本电脑",
- "price": 6999,
- "inventory": 50,
- "category": "电子产品",
- "specs": {
- "brand": "联想",
- "model": "ThinkPad",
- "color": "银色",
- "storage": "512GB"
- }
- }
- ]
- },
- right: {
- "products": [
- {
- "id": "p001",
- "name": "智能手机",
- "price": 5299,
- "inventory": 85,
- "category": "电子产品",
- "specs": {
- "brand": "小米",
- "model": "Mi 11 Pro",
- "color": "蓝色",
- "storage": "256GB"
- }
- },
- {
- "id": "p002",
- "name": "笔记本电脑",
- "price": 6999,
- "inventory": 50,
- "category": "电子产品",
- "specs": {
- "brand": "联想",
- "model": "ThinkPad",
- "color": "银色",
- "storage": "512GB"
- }
- }
- ]
- }
- },
- configOptions: {
- left: {
- "appConfig": {
- "theme": "light",
- "language": "zh-CN",
- "notifications": {
- "email": true,
- "push": true,
- "sms": false
- },
- "security": {
- "twoFactorAuth": true,
- "passwordExpiry": 90,
- "ipRestriction": false
- },
- "performance": {
- "cacheEnabled": true,
- "compressionLevel": "high",
- "preload": ["home", "dashboard"]
- }
- }
- },
- right: {
- "appConfig": {
- "theme": "dark",
- "language": "zh-CN",
- "notifications": {
- "email": true,
- "push": false,
- "sms": true
- },
- "security": {
- "twoFactorAuth": true,
- "passwordExpiry": 60,
- "ipRestriction": true
- },
- "performance": {
- "cacheEnabled": true,
- "compressionLevel": "medium",
- "preload": ["home", "profile", "dashboard"]
- }
- }
- }
- },
- apiResponse: {
- left: {
- "status": "success",
- "code": 200,
- "data": {
- "users": [
- {"id": 1, "name": "李明", "role": "admin"},
- {"id": 2, "name": "王芳", "role": "user"},
- {"id": 3, "name": "赵强", "role": "editor"}
- ],
- "pagination": {
- "total": 25,
- "page": 1,
- "limit": 10
- },
- "timestamp": 1642558132,
- "version": "1.0.0"
- }
- },
- right: {
- "status": "success",
- "code": 200,
- "data": {
- "users": [
- {"id": 1, "name": "李明", "role": "admin"},
- {"id": 2, "name": "王芳", "role": "user"},
- {"id": 3, "name": "赵强", "role": "moderator"}
- ],
- "pagination": {
- "total": 28,
- "page": 1,
- "limit": 10
- },
- "timestamp": 1652558132,
- "version": "1.2.0"
- }
- }
- }
- }
- },
- computed: {
- // 显示的消息,计算属性替代v-html
- displayMessage: function() {
- return this.tipMessage + this.errorMessage;
- }
- },
- methods: {
- fillExample: function(exampleType) {
- if (this.jsonExamples[exampleType]) {
- const example = this.jsonExamples[exampleType];
- jsonBox.left.setValue(JSON.stringify(example.left, null, 4));
- jsonBox.right.setValue(JSON.stringify(example.right, null, 4));
-
- // 触发比对
- setTimeout(() => {
- jsonBox.left.refresh();
- jsonBox.right.refresh();
- this.compareJson(); // 使用Vue实例的方法进行比对
- }, 100);
- }
- },
- // 添加比对JSON的方法
- compareJson: function() {
- // 使用全局变量中的实例
- let leftText = jsonBox.left.getValue();
- let rightText = jsonBox.right.getValue();
- let leftJson, rightJson;
-
- try {
- if (leftText) {
- leftJson = JSON.parse(leftText);
- }
- this.errorHandler('left', true);
- } catch (e) {
- console.log('left ==>', e);
- this.errorHandler('left', false);
- return;
- }
-
- try {
- if (rightText) {
- rightJson = JSON.parse(rightText);
- }
- this.errorHandler('right', true);
- } catch (e) {
- console.log('right ==>', e);
- this.errorHandler('right', false);
- return;
- }
-
- if (!leftJson || !rightJson) {
- if (!leftJson && !rightJson) {
- this.errorHandler('left-right', false);
- } else if (!leftJson) {
- this.errorHandler('left', false);
- } else {
- this.errorHandler('right', false);
- }
- return;
- }
-
- try {
- // 调用jsonpatch的compare方法进行比对
- let diffs = jsonpatch.compare(leftJson, rightJson);
- this.diffHandler(diffs);
-
- // 清除所有之前的标记
- this.clearMarkers();
-
- // 高亮差异
- diffs.forEach((diff) => {
- try {
- if (diff.op === 'remove') {
- this.highlightDiff(diff, 'remove');
- } else if (diff.op === 'add') {
- this.highlightDiff(diff, 'add');
- } else if (diff.op === 'replace') {
- this.highlightDiff(diff, 'replace');
- }
- } catch (e) {
- console.warn('error while trying to highlight diff', e);
- }
- });
- } catch (e) {
- console.error('比对过程出错:', e);
- }
- },
- // 清除所有标记
- clearMarkers: function() {
- jsonBox.left.getAllMarks().forEach(function(marker) {
- marker.clear();
- });
- jsonBox.right.getAllMarks().forEach(function(marker) {
- marker.clear();
- });
- },
- // 高亮差异
- highlightDiff: function(diff, op) {
- if (op === 'remove') {
- this.highlightRemoval(jsonBox.left, diff);
- } else if (op === 'add') {
- this.highlightAddition(jsonBox.right, diff);
- } else if (op === 'replace') {
- this.highlightChange(jsonBox.left, diff);
- this.highlightChange(jsonBox.right, diff);
- }
- },
- // 高亮删除
- highlightRemoval: function(editor, diff) {
- this._highlight(editor, diff, '#DD4444');
- },
- // 高亮添加
- highlightAddition: function(editor, diff) {
- this._highlight(editor, diff, '#4ba2ff');
- },
- // 高亮修改
- highlightChange: function(editor, diff) {
- this._highlight(editor, diff, '#E5E833');
- },
- // 高亮辅助方法
- _highlight: function(editor, diff, color) {
- try {
- let textValue = editor.getValue();
- // 使用全局jsonSourceMap对象
- let result = jsonSourceMap.parse(textValue);
- let pointers = result.pointers;
- let path = diff.path;
-
- if (!pointers[path]) {
- console.warn('找不到路径的指针:', path);
- return;
- }
-
- let start = {
- line: pointers[path].key ? pointers[path].key.line : pointers[path].value.line,
- ch: pointers[path].key ? pointers[path].key.column : pointers[path].value.column
- };
- let end = {
- line: pointers[path].valueEnd.line,
- ch: pointers[path].valueEnd.column
- };
-
- editor.markText(start, end, {
- css: 'background-color: ' + color
- });
- } catch (e) {
- console.error('高亮过程出错:', e);
- }
- },
- // 错误处理
- errorHandler: function(which, ok) {
- if (ok) {
- this.errorMessage = '两侧JSON比对完成!';
- this.errorHighlight = false;
- this.leftSideError = false;
- this.rightSideError = false;
- } else {
- let side = {'left': '左', 'right': '右', 'left-right': '两'}[which];
- if(!jsonBox.left.getValue().trim().length) {
- this.errorMessage = '请在左侧填入待比对的JSON内容!';
- this.leftSideError = true;
- this.rightSideError = false;
- }else if(!jsonBox.right.getValue().trim().length) {
- this.errorMessage = '请在右侧填入待比对的JSON内容!';
- this.leftSideError = false;
- this.rightSideError = true;
- }else{
- this.errorMessage = side + '侧JSON不合法!';
- if (which === 'left') {
- this.leftSideError = true;
- this.rightSideError = false;
- } else if (which === 'right') {
- this.leftSideError = false;
- this.rightSideError = true;
- } else {
- this.leftSideError = true;
- this.rightSideError = true;
- }
- }
- this.errorHighlight = true;
- }
- },
- // diff处理器
- diffHandler: function(diffs) {
- if (!this.errorHighlight) {
- this.differenceCount = diffs.length;
- this.isDifferent = diffs.length > 0;
- if (diffs.length) {
- this.errorMessage += '共有 ' + diffs.length + ' 处不一致!';
- } else {
- this.errorMessage += '且JSON内容一致!';
- }
- }
- },
- // 打开工具市场页面
- openOptionsPage: function(event){
- event.preventDefault();
- event.stopPropagation();
- chrome.runtime.openOptionsPage();
- },
- openDonateModal: function(event){
- event.preventDefault();
- event.stopPropagation();
- chrome.runtime.sendMessage({
- type: 'fh-dynamic-any-thing',
- thing: 'open-donate-modal',
- params: { toolName: 'json-diff' }
- });
- },
- loadPatchHotfix() {
- // 页面加载时自动获取并注入页面的补丁
- chrome.runtime.sendMessage({
- type: 'fh-dynamic-any-thing',
- thing: 'fh-get-tool-patch',
- toolName: 'json-diff'
- }, patch => {
- if (patch) {
- if (patch.css) {
- const style = document.createElement('style');
- style.textContent = patch.css;
- document.head.appendChild(style);
- }
- if (patch.js) {
- try {
- if (window.evalCore && window.evalCore.getEvalInstance) {
- window.evalCore.getEvalInstance(window)(patch.js);
- }
- } catch (e) {
- console.error('json-diff补丁JS执行失败', e);
- }
- }
- }
- });
- },
- },
- mounted: function () {
- // 初始化JSON编辑器
- let jsonBox = JsonDiff.init(this.$refs.srcLeft, this.$refs.srcRight,
- this.errorHandler.bind(this),
- this.diffHandler.bind(this)
- );
-
- // 添加比较方法
- jsonBox.compare = this.compareJson.bind(this);
-
- // 初始化文本变更监听
- jsonBox.left.on('change', () => {
- setTimeout(() => this.compareJson(), 300);
- });
- jsonBox.right.on('change', () => {
- setTimeout(() => this.compareJson(), 300);
- });
-
- // 暴露到全局,供示例数据使用
- window.jsonBox = jsonBox;
- this.loadPatchHotfix();
- }
- });
|