@@ -5,7 +5,7 @@ module.exports = function(grunt) {
|
|||||||
watch: {
|
watch: {
|
||||||
haml: {
|
haml: {
|
||||||
files: ['app/assets/templates/**/*.haml'],
|
files: ['app/assets/templates/**/*.haml'],
|
||||||
tasks: ['newer:haml', 'ngtemplates', 'concat'],
|
tasks: ['newer:haml', 'ngtemplates', 'concat:app', 'babel', 'browserify', 'concat:dist'],
|
||||||
options: {
|
options: {
|
||||||
spawn: false,
|
spawn: false,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -516,17 +516,22 @@ angular.module('app.frontend')
|
|||||||
var handleTab = function (event) {
|
var handleTab = function (event) {
|
||||||
if (!event.shiftKey && event.which == 9) {
|
if (!event.shiftKey && event.which == 9) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
var start = this.selectionStart;
|
|
||||||
var end = this.selectionEnd;
|
|
||||||
var spaces = " ";
|
|
||||||
|
|
||||||
// Insert 4 spaces
|
// Using document.execCommand gives us undo support
|
||||||
this.value = this.value.substring(0, start)
|
if(!document.execCommand("insertText", false, "\t")) {
|
||||||
+ spaces + this.value.substring(end);
|
// document.execCommand works great on Chrome/Safari but not Firefox
|
||||||
|
var start = this.selectionStart;
|
||||||
|
var end = this.selectionEnd;
|
||||||
|
var spaces = " ";
|
||||||
|
|
||||||
// Place cursor 4 spaces away from where
|
// Insert 4 spaces
|
||||||
// the tab key was pressed
|
this.value = this.value.substring(0, start)
|
||||||
this.selectionStart = this.selectionEnd = start + 4;
|
+ spaces + this.value.substring(end);
|
||||||
|
|
||||||
|
// Place cursor 4 spaces away from where
|
||||||
|
// the tab key was pressed
|
||||||
|
this.selectionStart = this.selectionEnd = start + 4;
|
||||||
|
}
|
||||||
|
|
||||||
parent.note.text = this.value;
|
parent.note.text = this.value;
|
||||||
parent.changesMade();
|
parent.changesMade();
|
||||||
|
|||||||
@@ -9,12 +9,8 @@ angular.module('app.frontend')
|
|||||||
}
|
}
|
||||||
|
|
||||||
$rootScope.lockApplication = function() {
|
$rootScope.lockApplication = function() {
|
||||||
// Render first to show lock screen immediately, then refresh
|
|
||||||
$scope.needsUnlock = true;
|
|
||||||
// Reloading wipes current objects from memory
|
// Reloading wipes current objects from memory
|
||||||
setTimeout(function () {
|
window.location.reload();
|
||||||
window.location.reload();
|
|
||||||
}, 100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function load() {
|
function load() {
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ angular.module('app.frontend')
|
|||||||
.controller('NotesCtrl', function (authManager, $timeout, $rootScope, modelManager, storageManager) {
|
.controller('NotesCtrl', function (authManager, $timeout, $rootScope, modelManager, storageManager) {
|
||||||
|
|
||||||
this.sortBy = storageManager.getItem("sortBy") || "created_at";
|
this.sortBy = storageManager.getItem("sortBy") || "created_at";
|
||||||
|
this.showArchived = storageManager.getBooleanValue("showArchived") || false;
|
||||||
this.sortDescending = this.sortBy != "title";
|
this.sortDescending = this.sortBy != "title";
|
||||||
|
|
||||||
$rootScope.$on("editorFocused", function(){
|
$rootScope.$on("editorFocused", function(){
|
||||||
@@ -53,15 +54,26 @@ angular.module('app.frontend')
|
|||||||
this.notesToDisplay += 20
|
this.notesToDisplay += 20
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sortByTitle = function() {
|
this.optionsSubtitle = function() {
|
||||||
var base = "Sort |";
|
var base = "Sorting by";
|
||||||
if(this.sortBy == "created_at") {
|
if(this.sortBy == "created_at") {
|
||||||
return base + " Date added";
|
base += " date added";
|
||||||
} else if(this.sortBy == "updated_at") {
|
} else if(this.sortBy == "updated_at") {
|
||||||
return base + " Date modifed";
|
base += " date modifed";
|
||||||
} else if(this.sortBy == "title") {
|
} else if(this.sortBy == "title") {
|
||||||
return base + " Title";
|
base += " title";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.showArchived && (!this.tag || !this.tag.archiveTag)) {
|
||||||
|
base += " | Including archived"
|
||||||
|
}
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.toggleShowArchived = function() {
|
||||||
|
this.showArchived = !this.showArchived;
|
||||||
|
storageManager.setBooleanValue("showArchived", this.showArchived);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.tagDidChange = function(tag, oldTag) {
|
this.tagDidChange = function(tag, oldTag) {
|
||||||
@@ -114,11 +126,13 @@ angular.module('app.frontend')
|
|||||||
|
|
||||||
this.filterNotes = function(note) {
|
this.filterNotes = function(note) {
|
||||||
if(this.tag.archiveTag) {
|
if(this.tag.archiveTag) {
|
||||||
return note.archived;
|
note.visible = note.archived;
|
||||||
|
return note.visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(note.archived) {
|
if(note.archived && !this.showArchived) {
|
||||||
return false;
|
note.visible = false;
|
||||||
|
return note.visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
var filterText = this.noteFilter.text.toLowerCase();
|
var filterText = this.noteFilter.text.toLowerCase();
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ angular.module('app.frontend')
|
|||||||
this.user = {uuid: idData};
|
this.user = {uuid: idData};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.checkForSecurityUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.offline = function() {
|
this.offline = function() {
|
||||||
@@ -152,6 +154,8 @@ angular.module('app.frontend')
|
|||||||
this.handleAuthResponse(response, email, url, authParams, keys);
|
this.handleAuthResponse(response, email, url, authParams, keys);
|
||||||
storageManager.setModelStorageMode(ephemeral ? StorageManager.Ephemeral : StorageManager.Fixed);
|
storageManager.setModelStorageMode(ephemeral ? StorageManager.Ephemeral : StorageManager.Fixed);
|
||||||
|
|
||||||
|
this.checkForSecurityUpdate();
|
||||||
|
|
||||||
callback(response);
|
callback(response);
|
||||||
}.bind(this), function(response){
|
}.bind(this), function(response){
|
||||||
console.error("Error logging in", response);
|
console.error("Error logging in", response);
|
||||||
@@ -267,8 +271,6 @@ angular.module('app.frontend')
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.checkForSecurityUpdate();
|
|
||||||
|
|
||||||
this.staticifyObject = function(object) {
|
this.staticifyObject = function(object) {
|
||||||
return JSON.parse(JSON.stringify(object));
|
return JSON.parse(JSON.stringify(object));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -185,15 +185,24 @@ class AccountMenu {
|
|||||||
$scope.importData.loading = true;
|
$scope.importData.loading = true;
|
||||||
// allow loading indicator to come up with timeout
|
// allow loading indicator to come up with timeout
|
||||||
$timeout(function(){
|
$timeout(function(){
|
||||||
$scope.importJSONData(data, password, function(response){
|
$scope.importJSONData(data, password, function(response, errorCount){
|
||||||
$timeout(function(){
|
$timeout(function(){
|
||||||
$scope.importData.loading = false;
|
$scope.importData.loading = false;
|
||||||
$scope.importData = null;
|
$scope.importData = null;
|
||||||
if(!response) {
|
|
||||||
alert("There was an error importing your data. Please try again.");
|
// Update UI before showing alert
|
||||||
} else {
|
setTimeout(function () {
|
||||||
alert("Your data was successfully imported.")
|
if(!response) {
|
||||||
}
|
alert("There was an error importing your data. Please try again.");
|
||||||
|
} else {
|
||||||
|
if(errorCount > 0) {
|
||||||
|
var message = `Import complete. ${errorCount} items were not imported because there was an error decrypting them. Make sure the password is correct and try again.`;
|
||||||
|
alert(message);
|
||||||
|
} else {
|
||||||
|
alert("Your data was successfully imported.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 10);
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -225,7 +234,7 @@ class AccountMenu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$scope.importJSONData = function(data, password, callback) {
|
$scope.importJSONData = function(data, password, callback) {
|
||||||
var onDataReady = function() {
|
var onDataReady = function(errorCount) {
|
||||||
var items = modelManager.mapResponseItemsToLocalModels(data.items);
|
var items = modelManager.mapResponseItemsToLocalModels(data.items);
|
||||||
items.forEach(function(item){
|
items.forEach(function(item){
|
||||||
item.setDirty(true);
|
item.setDirty(true);
|
||||||
@@ -233,7 +242,9 @@ class AccountMenu {
|
|||||||
item.markAllReferencesDirty();
|
item.markAllReferencesDirty();
|
||||||
})
|
})
|
||||||
|
|
||||||
syncManager.sync(callback, {additionalFields: ["created_at", "updated_at"]});
|
syncManager.sync((response) => {
|
||||||
|
callback(response, errorCount);
|
||||||
|
}, {additionalFields: ["created_at", "updated_at"]});
|
||||||
}.bind(this)
|
}.bind(this)
|
||||||
|
|
||||||
if(data.auth_params) {
|
if(data.auth_params) {
|
||||||
@@ -244,8 +255,19 @@ class AccountMenu {
|
|||||||
data.items.forEach(function(item){
|
data.items.forEach(function(item){
|
||||||
item.enc_item_key = null;
|
item.enc_item_key = null;
|
||||||
item.auth_hash = null;
|
item.auth_hash = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
var errorCount = 0;
|
||||||
|
// Don't import items that didn't decrypt properly
|
||||||
|
data.items = data.items.filter(function(item){
|
||||||
|
if(item.errorDecrypting) {
|
||||||
|
errorCount++;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
})
|
})
|
||||||
onDataReady();
|
|
||||||
|
onDataReady(errorCount);
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
console.log("Error decrypting", e);
|
console.log("Error decrypting", e);
|
||||||
@@ -490,9 +512,12 @@ class AccountMenu {
|
|||||||
$scope.formData.showPasscodeForm = false;
|
$scope.formData.showPasscodeForm = false;
|
||||||
var offline = authManager.offline();
|
var offline = authManager.offline();
|
||||||
|
|
||||||
var message = "You've succesfully set an app passcode.";
|
// Allow UI to update before showing alert
|
||||||
if(offline) { message += " Your items will now be encrypted using this passcode."; }
|
setTimeout(function () {
|
||||||
alert(message);
|
var message = "You've succesfully set an app passcode.";
|
||||||
|
if(offline) { message += " Your items will now be encrypted using this passcode."; }
|
||||||
|
alert(message);
|
||||||
|
}, 10);
|
||||||
|
|
||||||
if(offline) {
|
if(offline) {
|
||||||
syncManager.markAllItemsDirtyAndSaveOffline();
|
syncManager.markAllItemsDirtyAndSaveOffline();
|
||||||
|
|||||||
@@ -111,6 +111,14 @@ class StorageManager {
|
|||||||
return storage.getItem(key);
|
return storage.getItem(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setBooleanValue(key, value, vault) {
|
||||||
|
this.setItem(key, JSON.stringify(value), vault);
|
||||||
|
}
|
||||||
|
|
||||||
|
getBooleanValue(key, vault) {
|
||||||
|
return JSON.parse(this.getItem(key, vault));
|
||||||
|
}
|
||||||
|
|
||||||
removeItem(key, vault) {
|
removeItem(key, vault) {
|
||||||
var storage = this.getVault(vault);
|
var storage = this.getVault(vault);
|
||||||
storage.removeItem(key);
|
storage.removeItem(key);
|
||||||
|
|||||||
@@ -25,6 +25,34 @@ ul.section-menu-bar {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
|
&.full-width {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.item-with-subtitle {
|
||||||
|
label {
|
||||||
|
// float: left;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
margin-top: 1px;
|
||||||
|
opacity: 0.5;
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 12px;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 1; /* number of lines to show */
|
||||||
|
$line-height: 18px;
|
||||||
|
line-height: $line-height; /* fallback */
|
||||||
|
max-height: calc(#{$line-height} * 1); /* fallback */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
&.selected {
|
&.selected {
|
||||||
background-color: $blue-color;
|
background-color: $blue-color;
|
||||||
border-radius: 1px;
|
border-radius: 1px;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
max-width: 350px;
|
max-width: 350px;
|
||||||
min-width: 170px;
|
min-width: 170px;
|
||||||
|
|
||||||
$notes-title-bar-height: 130px;
|
$notes-title-bar-height: 147px;
|
||||||
|
|
||||||
#notes-title-bar {
|
#notes-title-bar {
|
||||||
color: rgba(black, 0.40);
|
color: rgba(black, 0.40);
|
||||||
@@ -26,11 +26,11 @@
|
|||||||
right: 14px;
|
right: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#tag-menu-bar {
|
#notes-menu-bar {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 0 -14px;
|
margin: 0 -14px;
|
||||||
margin-top: 14px;
|
margin-top: 14px;
|
||||||
// padding-left: 4px;
|
height: 45px;
|
||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -124,11 +124,11 @@
|
|||||||
%p Add an app passcode to lock the app and encrypt on-device key storage.
|
%p Add an app passcode to lock the app and encrypt on-device key storage.
|
||||||
%a.block.mt-5{"ng-click" => "addPasscodeClicked()", "ng-if" => "!formData.showPasscodeForm"} Add Passcode
|
%a.block.mt-5{"ng-click" => "addPasscodeClicked()", "ng-if" => "!formData.showPasscodeForm"} Add Passcode
|
||||||
|
|
||||||
.mt-5{"ng-if" => "formData.showPasscodeForm"}
|
%form.mt-5{"ng-if" => "formData.showPasscodeForm", "ng-submit" => "submitPasscodeForm()"}
|
||||||
%p.bold Choose a passcode:
|
%p.bold Choose a passcode:
|
||||||
%input.form-control.mt-10{:type => 'password', "ng-model" => "formData.passcode", "placeholder" => "Passcode", "autofocus" => "true"}
|
%input.form-control.mt-10{:type => 'password', "ng-model" => "formData.passcode", "placeholder" => "Passcode", "autofocus" => "true"}
|
||||||
%input.form-control.mt-10{:type => 'password', "ng-model" => "formData.confirmPasscode", "placeholder" => "Confirm Passcode"}
|
%input.form-control.mt-10{:type => 'password', "ng-model" => "formData.confirmPasscode", "placeholder" => "Confirm Passcode"}
|
||||||
%button.standard.ui-button.block.tinted.mt-5{"ng-click" => "submitPasscodeForm()"} Set Passcode
|
%button.standard.ui-button.block.tinted.mt-5{"type" => "submit"} Set Passcode
|
||||||
%div{"ng-if" => "hasPasscode()"}
|
%div{"ng-if" => "hasPasscode()"}
|
||||||
%p
|
%p
|
||||||
Passcode lock is enabled.
|
Passcode lock is enabled.
|
||||||
@@ -149,16 +149,17 @@
|
|||||||
%input{"type" => "radio", "ng-model" => "archiveFormData.encrypted", "ng-value" => "false", "ng-change" => "archiveFormData.encrypted = false"}
|
%input{"type" => "radio", "ng-model" => "archiveFormData.encrypted", "ng-value" => "false", "ng-change" => "archiveFormData.encrypted = false"}
|
||||||
Decrypted
|
Decrypted
|
||||||
|
|
||||||
%a.block.mt-5{"ng-click" => "downloadDataArchive()", "ng-class" => "{'mt-5' : !user}"} Download Data Archive
|
%a.block.mt-5{"ng-click" => "downloadDataArchive()", "ng-class" => "{'mt-5' : !user}"} Export Data Archive
|
||||||
|
|
||||||
%label.block.mt-5
|
%label.block.mt-5
|
||||||
%input{"type" => "file", "style" => "display: none;", "file-change" => "->", "handler" => "importFileSelected(files)"}
|
%input{"type" => "file", "style" => "display: none;", "file-change" => "->", "handler" => "importFileSelected(files)"}
|
||||||
.fake-link.tinted Import Data from Archive
|
.fake-link.tinted Import Data from Archive
|
||||||
|
|
||||||
%div{"ng-if" => "importData.requestPassword"}
|
%div{"ng-if" => "importData.requestPassword"}
|
||||||
%p Enter the account password associated with the import file.
|
%form{"ng-submit" => "submitImportPassword()"}
|
||||||
%input.form-control.mt-5{:type => 'password', "ng-model" => "importData.password", "autofocus" => "true"}
|
%p Enter the account password associated with the import file.
|
||||||
%button.standard.ui-button.block.tinted.mt-5{"ng-click" => "submitImportPassword()"} Decrypt & Import
|
%input.form-control.mt-5{:type => 'password', "ng-model" => "importData.password", "autofocus" => "true"}
|
||||||
|
%button.standard.ui-button.block.tinted.mt-5{"type" => "submit"} Decrypt & Import
|
||||||
|
|
||||||
%p.mt-5{"ng-if" => "user"} Notes are downloaded in the Standard File format, which allows you to re-import back into this app easily. To download as plain text files, choose "Decrypted".
|
%p.mt-5{"ng-if" => "user"} Notes are downloaded in the Standard File format, which allows you to re-import back into this app easily. To download as plain text files, choose "Decrypted".
|
||||||
|
|
||||||
|
|||||||
@@ -7,23 +7,35 @@
|
|||||||
.filter-section
|
.filter-section
|
||||||
%input.filter-bar{"select-on-click" => "true", "ng-model" => "ctrl.noteFilter.text", "placeholder" => "Search", "ng-change" => "ctrl.filterTextChanged()", "lowercase" => "true"}
|
%input.filter-bar{"select-on-click" => "true", "ng-model" => "ctrl.noteFilter.text", "placeholder" => "Search", "ng-change" => "ctrl.filterTextChanged()", "lowercase" => "true"}
|
||||||
#search-clear-button{"ng-if" => "ctrl.noteFilter.text", "ng-click" => "ctrl.noteFilter.text = ''; ctrl.filterTextChanged()"} ✕
|
#search-clear-button{"ng-if" => "ctrl.noteFilter.text", "ng-click" => "ctrl.noteFilter.text = ''; ctrl.filterTextChanged()"} ✕
|
||||||
%ul.section-menu-bar#tag-menu-bar
|
%ul.section-menu-bar#notes-menu-bar
|
||||||
%li{"ng-class" => "{'selected' : ctrl.showMenu}"}
|
%li.item-with-subtitle{"ng-class" => "{'selected' : ctrl.showMenu}"}
|
||||||
%label{"ng-click" => "ctrl.showMenu = !ctrl.showMenu"} {{ctrl.sortByTitle()}}
|
.wrapper{"ng-click" => "ctrl.showMenu = !ctrl.showMenu"}
|
||||||
|
%label Options
|
||||||
|
.subtitle {{ctrl.optionsSubtitle()}}
|
||||||
|
|
||||||
%ul.dropdown-menu{"ng-if" => "ctrl.showMenu"}
|
.sectioned-menu.dropdown-menu{"ng-if" => "ctrl.showMenu"}
|
||||||
%li
|
%ul
|
||||||
%label{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.selectedSortByCreated()"}
|
.header
|
||||||
%span.top.mt-5.mr-5{"ng-if" => "ctrl.sortBy == 'created_at'"} ✓
|
.title Sort by
|
||||||
By date added
|
%li{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.selectedSortByCreated()"}
|
||||||
%li
|
%label
|
||||||
%label{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.selectedSortByUpdated()"}
|
%span.top.mt-5.mr-5{"ng-if" => "ctrl.sortBy == 'created_at'"} ✓
|
||||||
%span.top.mt-5.mr-5{"ng-if" => "ctrl.sortBy == 'updated_at'"} ✓
|
By date added
|
||||||
By date modified
|
%li{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.selectedSortByUpdated()"}
|
||||||
%li
|
%label
|
||||||
%label{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.selectedSortByTitle()"}
|
%span.top.mt-5.mr-5{"ng-if" => "ctrl.sortBy == 'updated_at'"} ✓
|
||||||
%span.top.mt-5.mr-5{"ng-if" => "ctrl.sortBy == 'title'"} ✓
|
By date modified
|
||||||
By title
|
%li{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.selectedSortByTitle()"}
|
||||||
|
%label
|
||||||
|
%span.top.mt-5.mr-5{"ng-if" => "ctrl.sortBy == 'title'"} ✓
|
||||||
|
By title
|
||||||
|
%ul{"ng-if" => "!ctrl.tag.archiveTag"}
|
||||||
|
.header
|
||||||
|
.title Archives
|
||||||
|
%li{"ng-click" => "ctrl.selectedMenuItem($event); ctrl.toggleShowArchived()"}
|
||||||
|
%label
|
||||||
|
%span.top.mt-5.mr-5{"ng-if" => "ctrl.showArchived == true"} ✓
|
||||||
|
Show archived notes
|
||||||
|
|
||||||
.scrollable
|
.scrollable
|
||||||
.infinite-scroll{"infinite-scroll" => "ctrl.paginate()", "can-load" => "true", "threshold" => "200"}
|
.infinite-scroll{"infinite-scroll" => "ctrl.paginate()", "can-load" => "true", "threshold" => "200"}
|
||||||
@@ -36,6 +48,10 @@
|
|||||||
%i.icon.ion-ios-flag
|
%i.icon.ion-ios-flag
|
||||||
%strong.medium Pinned
|
%strong.medium Pinned
|
||||||
|
|
||||||
|
.archived.tinted{"ng-if" => "note.archived && !ctrl.tag.archiveTag", "ng-class" => "{'tinted-selected' : ctrl.selectedNote == note}"}
|
||||||
|
%i.icon.ion-ios-box
|
||||||
|
%strong.medium Archived
|
||||||
|
|
||||||
.tags-string{"ng-if" => "ctrl.tag.all"}
|
.tags-string{"ng-if" => "ctrl.tag.all"}
|
||||||
.faded {{note.tagsString()}}
|
.faded {{note.tagsString()}}
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ module Neeto
|
|||||||
block_all_mixed_content: false, # see http://www.w3.org/TR/mixed-content/
|
block_all_mixed_content: false, # see http://www.w3.org/TR/mixed-content/
|
||||||
child_src: ["*"],
|
child_src: ["*"],
|
||||||
connect_src: ["*"],
|
connect_src: ["*"],
|
||||||
font_src: %w('self'),
|
font_src: %w(* 'self'),
|
||||||
form_action: %w('self'),
|
form_action: %w('self'),
|
||||||
frame_ancestors: %w('none'),
|
frame_ancestors: %w('none'),
|
||||||
img_src: %w('self' data:),
|
img_src: %w('self' data:),
|
||||||
|
|||||||
Reference in New Issue
Block a user