Skip to content

Commit

Permalink
options in separated page and context menu
Browse files Browse the repository at this point in the history
  • Loading branch information
dardesantis committed Apr 15, 2017
1 parent 7260e8a commit cfa7375
Show file tree
Hide file tree
Showing 18 changed files with 389 additions and 271 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ Features
* Works on local files too (if you enable this in `chrome://extensions`)
* You can inspect the JSON by typing `djson` in the console
* Counts items and properties in a collection
* Show JSON path of the elements on hover
* Show JSON path of the elements on hover and copy it with the context menu
* Option to start with JSON collapsed

A background worker is used to prevent the UI freezing when processing very long JSON pages.

Expand Down
Binary file modified djson-viewer.crx
Binary file not shown.
Binary file added extension.zip
Binary file not shown.
2 changes: 1 addition & 1 deletion extension/css/content.css

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions extension/css/content.css.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added extension/images/setting.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
118 changes: 84 additions & 34 deletions extension/js/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

"use strict";

var path, copyPathMenuEntryId;
var path;

// Constants
var
Expand Down Expand Up @@ -374,17 +374,35 @@
}

function copy(value) {
var selElement, selRange, selection;
selElement = document.createElement("span");
selRange = document.createRange();
selElement.innerText = value;
document.body.appendChild(selElement);
selRange.selectNodeContents(selElement);
selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(selRange);
document.execCommand("Copy");
document.body.removeChild(selElement);
if(value.length > 0){
var selElement, selRange, selection;
selElement = document.createElement("span");
selRange = document.createRange();
selElement.innerText = value;
document.body.appendChild(selElement);
selRange.selectNodeContents(selElement);
selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(selRange);
document.execCommand("Copy");
document.body.removeChild(selElement);
}
}

function createContextMenu() {
chrome.contextMenus.create({
title : "Copy JSON Path",
id: "copyJSONPath",
contexts : [ "page", "selection", "link" ],
onclick : function(info, tab) {
copy(path);
}
}, function(){
var err = chrome.runtime.lastError;
if(err && err.hasOwnProperty('message') && err.message.indexOf('Cannot create item with duplicate id') === -1) {
console.warn('Context menu error ignored:', err);
}
});
}

// Listen for requests from content pages wanting to set up a port
Expand All @@ -409,7 +427,21 @@
});
});
});
port.disconnect();
}

else if (msg.type === 'OPEN OPTION TAB') {
var viewTabUrl = chrome.extension.getURL('options.html');
chrome.tabs.query({url: viewTabUrl, currentWindow: true}, function (tabs) {
var tabLenght = tabs.length;
if (tabLenght > 0) {
chrome.tabs.update(tabs[0].id, {'active': true});
} else {
chrome.tabs.query({active: true}, function (tabs) {
var index = tabs[0].index;
chrome.tabs.create({url: viewTabUrl, active: true, index: index + 1});
});
}
});
}

else if (msg.type === 'SENDING TEXT') {
Expand Down Expand Up @@ -497,42 +529,60 @@
var html = jsonObjToHTML(obj, jsonpFunctionName);

// Post the HTML string to the content script
port.postMessage(['FORMATTED', html, validJsonText]);
port.postMessage(['FORMATTED', html, validJsonText, JSON.stringify(localStorage)]);
}

else if (msg.type === 'SAVE THEME') {
localStorage.setItem("theme", msg.theme);
else if (msg.type === 'COPY PATH') {
var contextMenu = localStorage.getItem("contextMenu");
if(contextMenu && contextMenu === "true") {
chrome.permissions.contains({permissions: ['contextMenus']}, function(result) {
if (result) {
path = msg.path;
} else {
localStorage.removeItem("contextMenu");
}
});
}
}

else if (msg.type === 'COPY PATH') {
else if (msg.type === 'ENABLE CONTEXT MENU') {
chrome.permissions.contains({permissions: ['contextMenus']}, function(result) {
function updateContextMenu() {
path = msg.path;
if (typeof copyPathMenuEntryId === "undefined" || copyPathMenuEntryId == null) {
copyPathMenuEntryId = chrome.contextMenus.create({
title : "Copy JSON Path",
contexts : [ "page", "selection", "link" ],
onclick : function(info, tab) {
copy(path);
}
});
} else if (copyPathMenuEntryId && path.length == 0) {
chrome.contextMenus.remove(copyPathMenuEntryId);
copyPathMenuEntryId = null;
}
}
if (result) {
updateContextMenu();
localStorage.setItem("contextMenu", true);
createContextMenu();
} else {
chrome.permissions.request({permissions: ['contextMenus']}, function(granted) {
// The callback argument will be true if the user granted the permissions.
if (granted) {
updateContextMenu();
localStorage.setItem("contextMenu", true);
createContextMenu();
} else {
var contextMenuCheckbox = document.getElementById("contextMenuCheckbox");
if(contextMenuCheckbox) {
contextMenuCheckbox.checked = false;
}
localStorage.removeItem("contextMenu");
}
});
}
});
}

else if (msg.type === 'DISABLE CONTEXT MENU') {
localStorage.removeItem("contextMenu");
chrome.permissions.contains({permissions: ['contextMenus']}, function(result) {
chrome.contextMenus.removeAll();
});
}
});
});

var contextMenu = localStorage.getItem("contextMenu");
if(contextMenu && contextMenu === "true") {
chrome.permissions.contains({permissions: ['contextMenus']}, function(result) {
if (result) {
createContextMenu();
}
});
}
}());
341 changes: 151 additions & 190 deletions extension/js/content.js

Large diffs are not rendered by default.

81 changes: 81 additions & 0 deletions extension/js/options.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/** @license
DJSON Viewer and Formatter | MIT License
Copyright 2017 Dario De Santis
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

(function () {

"use strict";

// theme
var supportedThemes = ["default", "monokai", "xcode", "solarized", "darkorange", "halewa"];
var theme = localStorage.getItem("theme");
var themeChooserSelect = document.getElementById("themeChooserSelectContainer");
themeChooserSelect= themeChooserSelect.firstElementChild;
supportedThemes.forEach(function (themeName) {
var option = document.createElement('option');
option.value = themeName;
option.innerText = themeName;
if(theme && theme == themeName){
option.selected = 'selected';
document.getElementById("themeChooserPreview").setAttribute('data-theme', themeName);
}
themeChooserSelect.appendChild(option);
});

themeChooserSelect.addEventListener('change', function () {
var selectedTheme = this.options[this.selectedIndex].value;
themeChooserPreview.setAttribute('data-theme', selectedTheme);
localStorage.setItem("theme", selectedTheme);
});


// context menu
var contextMenuCheckbox = document.getElementById("contextMenuCheckbox");
var contextMenu = localStorage.getItem("contextMenu");
if(contextMenu && contextMenu === "true"){
contextMenuCheckbox.checked = true;
}
contextMenuCheckbox.addEventListener('click', function () {
var port = chrome.extension.connect({name: 'djson'});
if(contextMenuCheckbox.checked) {
port.postMessage({type: "ENABLE CONTEXT MENU"});
} else {
port.postMessage({type: "DISABLE CONTEXT MENU"});
}
});

// start JSON collapsed
var startCollapsedCheckbox = document.getElementById("startCollapsedCheckbox");
var startCollapsed = localStorage.getItem("startCollapsed");
if(startCollapsed && startCollapsed === "true"){
startCollapsedCheckbox.checked = true;
}
startCollapsedCheckbox.addEventListener('click', function () {
if(startCollapsedCheckbox.checked) {
localStorage.setItem("startCollapsed", true);
} else {
localStorage.removeItem("startCollapsed")
}
});

})();
7 changes: 4 additions & 3 deletions extension/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "DJSON Viewer and Formatter. JSON",
"name": "DJSON. JSON Viewer & Formatter",
"short_name": "DJSON Viewer",
"version": "0.3.1",
"version": "0.4.0",
"manifest_version": 2,
"description": "Extension to format and view JSON, from Web, Input or File.",
"homepage_url": "https://github.com/dardesantis/DJSON-Viewer",
Expand All @@ -26,5 +26,6 @@
"content_scripts": [
{ "matches": ["<all_urls>"], "js": ["js/content.js"], "run_at": "document_start" }
],
"permissions":["<all_urls>", "clipboardWrite", "tabs"]
"permissions":["<all_urls>", "clipboardWrite", "tabs"],
"optional_permissions": ["contextMenus"]
}
29 changes: 29 additions & 0 deletions extension/options.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Options</title>
<link rel="stylesheet" href="css/content.css">
</head>
<body id="optionScreen">
<h1>Options</h1>
<hr>
<h2>Theme</h2>
<div id="themeChooserContainer">
<div id="themeChooserSelectContainer">
<select></select>
(It will be applied only after the reload of the json)
</div>
<div id="themeChooserPreview">
<pre><span class="b">{</span><br> "<span class="key">number</span>": <span class="n">0.4</span>,<br> "<span class="key">string</span>": <span class="s">"DJSON"</span>,<br> "<span class="key">url</span>": <span class="a">"https://github.com/dardesantis/DJSON-Viewer"</span><br><span class="b">}</span></pre>
</div>
</div>

<h2>Preferences</h2>
<input id="contextMenuCheckbox" type="checkbox" name="context"> Enable Context Menu
<br>
<input id="startCollapsedCheckbox" type="checkbox" name="collapsed"> Load JSON as Collapsed (slower)

<script type="application/javascript" src="js/options.js"></script>
</body>
</html>
4 changes: 4 additions & 0 deletions sass/_theme-darkorange.scss
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ body[data-theme="darkorange"], #themeChooserPreview[data-theme="darkorange"] {
color: $darkorange-color-null;
}

#formattingMsg {
color: $darkorange-color-text-dark;
}

#status {
border-color: $darkorange-color-text-dark;
background-color: $darkorange-color-text;
Expand Down
4 changes: 4 additions & 0 deletions sass/_theme-default.scss
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ body[data-theme="default"], #themeChooserPreview[data-theme="default"] {
color: $default-color-null;
}

#formattingMsg {
color: $default-color-text-dark;
}

#status {
border-color: $default-color-text-dark;
background-color: $default-color-text;
Expand Down
Loading

0 comments on commit cfa7375

Please sign in to comment.