diff --git a/_locales/am/messages.json b/_locales/am/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/am/messages.json
+++ b/_locales/am/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/ar/messages.json b/_locales/ar/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/ar/messages.json
+++ b/_locales/ar/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/bg/messages.json b/_locales/bg/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/bg/messages.json
+++ b/_locales/bg/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/bn/messages.json b/_locales/bn/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/bn/messages.json
+++ b/_locales/bn/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/ca/messages.json b/_locales/ca/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/ca/messages.json
+++ b/_locales/ca/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/cs/messages.json b/_locales/cs/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/cs/messages.json
+++ b/_locales/cs/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/da/messages.json b/_locales/da/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/da/messages.json
+++ b/_locales/da/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/de/messages.json b/_locales/de/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/de/messages.json
+++ b/_locales/de/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/el/messages.json b/_locales/el/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/el/messages.json
+++ b/_locales/el/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/es/messages.json b/_locales/es/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/es/messages.json
+++ b/_locales/es/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/et/messages.json b/_locales/et/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/et/messages.json
+++ b/_locales/et/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/fa/messages.json b/_locales/fa/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/fa/messages.json
+++ b/_locales/fa/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/fi/messages.json b/_locales/fi/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/fi/messages.json
+++ b/_locales/fi/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/fil/messages.json b/_locales/fil/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/fil/messages.json
+++ b/_locales/fil/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/fr/messages.json b/_locales/fr/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/fr/messages.json
+++ b/_locales/fr/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/gu/messages.json b/_locales/gu/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/gu/messages.json
+++ b/_locales/gu/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/he/messages.json b/_locales/he/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/he/messages.json
+++ b/_locales/he/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/hi/messages.json b/_locales/hi/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/hi/messages.json
+++ b/_locales/hi/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/hin/messages.json b/_locales/hin/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/hin/messages.json
+++ b/_locales/hin/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/hr/messages.json b/_locales/hr/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/hr/messages.json
+++ b/_locales/hr/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/hu/messages.json b/_locales/hu/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/hu/messages.json
+++ b/_locales/hu/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/id/messages.json b/_locales/id/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/id/messages.json
+++ b/_locales/id/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/it/messages.json b/_locales/it/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/it/messages.json
+++ b/_locales/it/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/ja/messages.json b/_locales/ja/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/ja/messages.json
+++ b/_locales/ja/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/kn/messages.json b/_locales/kn/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/kn/messages.json
+++ b/_locales/kn/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/ko/messages.json b/_locales/ko/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/ko/messages.json
+++ b/_locales/ko/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/lt/messages.json b/_locales/lt/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/lt/messages.json
+++ b/_locales/lt/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/lv/messages.json b/_locales/lv/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/lv/messages.json
+++ b/_locales/lv/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/ml/messages.json b/_locales/ml/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/ml/messages.json
+++ b/_locales/ml/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/mr/messages.json b/_locales/mr/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/mr/messages.json
+++ b/_locales/mr/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/ms/messages.json b/_locales/ms/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/ms/messages.json
+++ b/_locales/ms/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/nb_NO/messages.json b/_locales/nb_NO/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/nb_NO/messages.json
+++ b/_locales/nb_NO/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/nl/messages.json b/_locales/nl/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/nl/messages.json
+++ b/_locales/nl/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/no/messages.json b/_locales/no/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/no/messages.json
+++ b/_locales/no/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/pl/messages.json b/_locales/pl/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/pl/messages.json
+++ b/_locales/pl/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/pt_BR/messages.json b/_locales/pt_BR/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/pt_BR/messages.json
+++ b/_locales/pt_BR/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/pt_PT/messages.json b/_locales/pt_PT/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/pt_PT/messages.json
+++ b/_locales/pt_PT/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/ro/messages.json b/_locales/ro/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/ro/messages.json
+++ b/_locales/ro/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/ru/messages.json b/_locales/ru/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/ru/messages.json
+++ b/_locales/ru/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/sk/messages.json b/_locales/sk/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/sk/messages.json
+++ b/_locales/sk/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/sl/messages.json b/_locales/sl/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/sl/messages.json
+++ b/_locales/sl/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/sr/messages.json b/_locales/sr/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/sr/messages.json
+++ b/_locales/sr/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/sv/messages.json b/_locales/sv/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/sv/messages.json
+++ b/_locales/sv/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/sw/messages.json b/_locales/sw/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/sw/messages.json
+++ b/_locales/sw/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/ta/messages.json b/_locales/ta/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/ta/messages.json
+++ b/_locales/ta/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/te/messages.json b/_locales/te/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/te/messages.json
+++ b/_locales/te/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/th/messages.json b/_locales/th/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/th/messages.json
+++ b/_locales/th/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/tr/messages.json b/_locales/tr/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/tr/messages.json
+++ b/_locales/tr/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/uk/messages.json b/_locales/uk/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/uk/messages.json
+++ b/_locales/uk/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/vi/messages.json b/_locales/vi/messages.json
index 9e26dfe..025a5f6 100644
--- a/_locales/vi/messages.json
+++ b/_locales/vi/messages.json
@@ -1 +1,71 @@
-{}
\ No newline at end of file
+{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
+ "bytes": {
+ "message": "Bytes"
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "characters": {
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
+ },
+ "column": {
+ "message": "Column"
+ },
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "file": {
+ "message": "File"
+ },
+ "help": {
+ "message": "Help"
+ },
+ "line": {
+ "message": "Line"
+ },
+ "lines": {
+ "message": "lines"
+ },
+ "newFile": {
+ "message": "New file"
+ },
+ "openFile": {
+ "message": "Open file..."
+ },
+ "quit": {
+ "message": "Quit"
+ },
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAs": {
+ "message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
+ }
+}
\ No newline at end of file
diff --git a/_locales/zh_CN/messages.json b/_locales/zh_CN/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/zh_CN/messages.json
+++ b/_locales/zh_CN/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/_locales/zh_TW/messages.json b/_locales/zh_TW/messages.json
index d9ba4e4..025a5f6 100644
--- a/_locales/zh_TW/messages.json
+++ b/_locales/zh_TW/messages.json
@@ -1,26 +1,71 @@
{
+ "areYouSureYouWantToDeleteTheFile": {
+ "message": "Are you sure you want to delete the file?"
+ },
"bytes": {
"message": "Bytes"
},
+ "cancel": {
+ "message": "Cancel"
+ },
"characters": {
- "message": "Characters"
+ "message": "characters"
+ },
+ "closeFile": {
+ "message": "Close file"
},
"column": {
"message": "Column"
},
+ "delete": {
+ "message": "Delete"
+ },
+ "deleteFile": {
+ "message": "Delete file"
+ },
+ "edit": {
+ "message": "Edit"
+ },
"file": {
"message": "File"
},
+ "help": {
+ "message": "Help"
+ },
"line": {
"message": "Line"
},
+ "lines": {
+ "message": "lines"
+ },
"newFile": {
"message": "New file"
},
+ "openFile": {
+ "message": "Open file..."
+ },
"quit": {
"message": "Quit"
},
+ "redo": {
+ "message": "Redo"
+ },
+ "rename": {
+ "message": "Rename"
+ },
+ "reportABug": {
+ "message": "Report a bug"
+ },
+ "save": {
+ "message": "Save"
+ },
"saveAs": {
"message": "Save as..."
+ },
+ "selected": {
+ "message": "selected"
+ },
+ "undo": {
+ "message": "Undo"
}
}
\ No newline at end of file
diff --git a/icons/128.png b/icons/128.png
index 60645db..483c75d 100644
Binary files a/icons/128.png and b/icons/128.png differ
diff --git a/icons/16.png b/icons/16.png
index 3bddb3e..ba267fb 100644
Binary files a/icons/16.png and b/icons/16.png differ
diff --git a/icons/32.png b/icons/32.png
index 4dfbbca..6c76283 100644
Binary files a/icons/32.png and b/icons/32.png differ
diff --git a/icons/48.png b/icons/48.png
index 91efea7..2d4f150 100644
Binary files a/icons/48.png and b/icons/48.png differ
diff --git a/manifest.json b/manifest.json
index 74ea21c..5b32fc1 100644
--- a/manifest.json
+++ b/manifest.json
@@ -4,10 +4,16 @@
"description": "",
"version": "2.0",
"default_locale": "en",
+ "icons": {
+ "16": "icons/16.png",
+ "32": "icons/32.png",
+ "48": "icons/48.png",
+ "128": "icons/128.png"
+ },
"action": {
- "default_popup": "popup.html"
+ "default_popup": "ui/popup.html"
},
- "options_page": "options.html",
+ "options_page": "ui/options.html",
"offline_enabled": true,
"optional_permissions": [
"downloads"
diff --git a/script.js b/script.js
deleted file mode 100644
index 84fd7a8..0000000
--- a/script.js
+++ /dev/null
@@ -1,152 +0,0 @@
-/*--------------------------------------------------------------
->>> TEXT EDITOR
-----------------------------------------------------------------
-#
---------------------------------------------------------------*/
-
-/*--------------------------------------------------------------
-#
---------------------------------------------------------------*/
-
-var skeleton = {
- component: 'base',
-
- menubar: {
- component: 'menubar',
- items: [
- [{
- component: 'button',
- text: 'file'
- },
- {
- component: 'button',
- text: 'newFile'
- },
- {
- component: 'button',
- text: 'saveAs'
- },
- {
- component: 'button',
- text: 'quit'
- }
- ]
- ]
- },
- main: {
- component: 'main',
-
- textarea: {
- component: 'textarea',
- on: {
- input: function () {
- var section_align_end = skeleton.footer.section_align_end,
- characters = this.value.length,
- bytes = new Blob([this.value]).size;
-
- section_align_end.characters.value.rendered.textContent = characters;
- section_align_end.bytes.value.rendered.textContent = bytes;
- },
- selectionchange: function () {
- var textarea = skeleton.main.textarea.rendered,
- section_align_start = skeleton.footer.section_align_start,
- column = 0;
-
- if (textarea.selectionDirection === 'forward') {
- var column = textarea.selectionEnd;
- } else {
- var column = textarea.selectionStart;
- }
-
- var lines = textarea.value.substr(0, column).split('\n');
-
- section_align_start.line.value.rendered.textContent = lines.length;
- section_align_start.column.value.rendered.textContent = lines[lines.length - 1].length + 1;
- }
- }
- }
- },
- footer: {
- component: 'footer',
-
- section_align_start: {
- component: 'section',
- variant: 'align-start',
-
- line: {
- component: 'span',
-
- label: {
- component: 'span',
- text: 'line'
- },
- value: {
- component: 'span',
- text: '0'
- }
- },
- column: {
- component: 'span',
-
- label: {
- component: 'span',
- text: 'column'
- },
- value: {
- component: 'span',
- text: '0'
- }
- }
- },
- section_align_end: {
- component: 'section',
- variant: 'align-end',
-
- characters: {
- component: 'span',
-
- label: {
- component: 'span',
- text: 'characters'
- },
- value: {
- component: 'span',
- text: '0'
- }
- },
- bytes: {
- component: 'span',
-
- label: {
- component: 'span',
- text: 'bytes'
- },
- value: {
- component: 'span',
- text: '0'
- }
- }
- }
- }
-};
-
-
-/*--------------------------------------------------------------
-# INITIALIZATION
---------------------------------------------------------------*/
-
-satus.storage.import(function (items) {
- var language = items.language || window.navigator.language;
-
- if (language.indexOf('en') === 0) {
- language = 'en';
- }
-
- satus.fetch('_locales/' + language + '/messages.json', function (object) {
- for (var key in object) {
- satus.locale.strings[key] = object[key].message;
- }
-
- satus.render(skeleton);
- });
-});
\ No newline at end of file
diff --git a/styles.css b/styles.css
deleted file mode 100644
index 4ee6028..0000000
--- a/styles.css
+++ /dev/null
@@ -1,66 +0,0 @@
-/*--------------------------------------------------------------
->>> TEXT EDITOR
-----------------------------------------------------------------
-# Base
-# Main
-# Footer
---------------------------------------------------------------*/
-
-/*--------------------------------------------------------------
-# BASE
---------------------------------------------------------------*/
-
-.satus-base {
- --satus-menubar-background: #1a1f23;
- --satus-menubar-text: #6e7377;
- --satus-main-background: #2f3841;
-}
-
-
-/*--------------------------------------------------------------
-# MAIN
---------------------------------------------------------------*/
-
-.satus-main {
- flex: 1;
-}
-
-.satus-textarea {
- font: inherit;
- box-sizing: border-box;
- width: 100%;
- height: 100%;
- padding: 4px 0;
- resize: none;
- color: #d8dee9;
- border: none;
- outline: none;
- background: transparent;
-}
-
-
-/*--------------------------------------------------------------
-# FOOTER
---------------------------------------------------------------*/
-
-.satus-footer {
- font-size: 14px;
- display: flex;
- box-sizing: border-box;
- height: 32px;
- padding: 0 8px;
- color: #6e7377;
- background: #1a1f23;
- justify-content: space-between;
- align-items: center;
-}
-
-.satus-footer .satus-section> :not(:last-child)::after {
- margin: 0 4px 0 0;
- content: ',';
-}
-
-.satus-footer .satus-section>*> :not(:last-child)::after {
- margin: 0 4px 0 0;
- content: ':';
-}
\ No newline at end of file
diff --git a/options.html b/ui/options.html
similarity index 80%
rename from options.html
rename to ui/options.html
index f3bacfe..cb5be04 100644
--- a/options.html
+++ b/ui/options.html
@@ -6,19 +6,17 @@
Text Editor
-
+
diff --git a/popup.html b/ui/popup.html
similarity index 81%
rename from popup.html
rename to ui/popup.html
index 190c7ea..f2bd077 100644
--- a/popup.html
+++ b/ui/popup.html
@@ -6,13 +6,11 @@
Text Editor
diff --git a/satus/satus.css b/ui/satus/satus.css
similarity index 85%
rename from satus/satus.css
rename to ui/satus/satus.css
index b24a83d..088ec0c 100644
--- a/satus/satus.css
+++ b/ui/satus/satus.css
@@ -1,17 +1,4 @@
-/*--------------------------------------------------------------
->>> ELEMENTS:
-----------------------------------------------------------------
-# Hidden
---------------------------------------------------------------*/
-
-/*--------------------------------------------------------------
-# HIDDEN
---------------------------------------------------------------*/
-
-[hidden] {
- display: none;
-}
/*--------------------------------------------------------------
>>> THEMES:
----------------------------------------------------------------
@@ -23,16 +10,20 @@
--------------------------------------------------------------*/
body {
+ --satus-contrast: 0, 0, 0;
--satus-primary: #f6b465;
- --satus-switch-background: rgba(0,0,0,.08);
+ --satus-switch-background: rgba(var(--satus-contrast),.08);
--satus-header-background: #fff;
+ --satus-header-border: rgba(var(--satus-contrast),.1);
--satus-header-text: #848471;
--satus-layers-background: #f6f6f4;
--satus-layers-text: #848471;
--satus-section-card-background: #fff;
+ --satus-section-card-border: rgba(var(--satus-contrast),.1);
--satus-modal-background: #f6f6f4;
+ --satus-modal-border: rgba(var(--satus-contrast), .1);
--satus-modal-text: #848471;
- --satus-hover: rgba(0, 0, 0, .04);
+ --satus-hover: rgba(var(--satus-contrast), .04);
--satus-text-field--background: #e8e8e3;
--satus-text-field--border: #d6d6cd;
--satus-text-field--text: #848471;
@@ -40,14 +31,14 @@ body {
--satus-switch-track--active: var(--satus-primary);
--satus-switch-thumb: #fff;
--satus-tabs: #fff;
- --satus-tooltip: rgba(0,0,0,.4);
- --satus-sortable-ghost: rgba(0, 0, 0, .80);
- --satus-sortable-background: #f9cf9f;
- --satus-sortable-text: #fff;
- --satus-divider: #e0e0e0;
+ --satus-tooltip: rgba(var(--satus-contrast),.4);
+ --satus-sortable-ghost: rgba(var(--satus-contrast), .80);
+ --satus-sortable-background: rgba(var(--satus-contrast), .08);
+ --satus-sortable-text: currentColor;
+ --satus-divider: rgba(var(--satus-contrast),.1);
--satus-tabs-background: #e8e8e3;
--satus-tabs-foreground: #fff;
- --satus-context-menu--border: #ccc;
+ --satus-tabs-border: rgba(var(--satus-contrast), .1);
--satus-checkbox--background: rgb(90, 90, 73, .08);
--satus-checkbox--border: rgb(90, 90, 73, .16);
--satus-checkbox--mark: #fff;
@@ -56,757 +47,1003 @@ body {
--satus-alert-error-color: #ad5f5f;
}
-body[theme=dark] {
- --satus-primary: #90a5e0;
- --satus-switch-background: rgba(0,0,0,.08);
- --satus-header-background: #232b43;
- --satus-header-text: #bcc4dc;
- --satus-layers-background: #0e111b;
- --satus-layers-text: #bcc4dc;
- --satus-section-card-background: #1d2335;
- --satus-modal-background: #252e46;
- --satus-modal-text: #bcc4dc;
- --satus-hover: rgba(255, 255, 255, .08);
- --satus-text-field--background: #20273c;
- --satus-text-field--border: #2e3957;
- --satus-text-field--text: #c4c4d4;
- --satus-switch-track: #101219;
+body[data-theme=dark] {
+ --satus-contrast: 255, 255, 255;
+ --satus-primary: #8f8f8f;
+ --satus-switch-background: rgba(var(--satus-contrast),.08);
+ --satus-header-background: #1f1f1f;
+ --satus-header-border: rgba(var(--satus-contrast),.08);
+ --satus-header-text: #ccc;
+ --satus-layers-background: #000;
+ --satus-layers-text: #ccc;
+ --satus-section-card-background: #1e1e1e;
+ --satus-section-card-border: rgba(var(--satus-contrast),.08);
+ --satus-modal-background: #212121;
+ --satus-modal-border: rgba(var(--satus-contrast),.08);
+ --satus-modal-text: #ccc;
+ --satus-hover: rgba(var(--satus-contrast), .05);
+ --satus-text-field--background: #333333;
+ --satus-text-field--border: #525252;
+ --satus-text-field--text: #ccc;
+ --satus-switch-track: #111;
--satus-switch-track--active: var(--satus-primary);
- --satus-switch-thumb: #d7dcea;
- --satus-tooltip: rgba(255,255,255,.4);
- --satus-sortable-ghost: rgba(255, 255, 255, .8);
- --satus-sortable-background: var(--satus-primary);
+ --satus-switch-thumb: #ddd;
+ --satus-tooltip: rgba(var(--satus-contrast),.4);
+ --satus-sortable-ghost: rgba(var(--satus-contrast), .8);
+ --satus-sortable-background: rgba(var(--satus-contrast), .1);
--satus-sortable-text: #fff;
- --satus-divider: #3e4865;
- --satus-tabs-background: #1f2433;
- --satus-tabs-foreground: #344165;
- --satus-context-menu--border: #2e3957;
- --satus-checkbox--background: rgb(233, 234, 237, .08);
- --satus-checkbox--border: rgb(233, 234, 237, .16);
+ --satus-divider: rgba(var(--satus-contrast),.08);
+ --satus-tabs-background: #111;
+ --satus-tabs-foreground: #2e2e2e;
+ --satus-tabs-border: #2f2f2f;
+ --satus-checkbox--background: rgb(var(--satus-contrast), .08);
+ --satus-checkbox--border: #2f2f2f;
--satus-checkbox--mark: #fff;
--satus-alert-error-background: #501616;
--satus-alert-error-border: #6f1f1f;
--satus-alert-error-color: #cf7777;
}
-body[theme=black] {
+body[data-theme=black] {
+ --satus-contrast: 255, 255, 255;
--satus-primary: #8f8f8f;
- --satus-switch-background: rgba(255,255,255,.08);
- --satus-header-background: #1f1f1f;
+ --satus-switch-background: rgba(var(--satus-contrast),.08);
+ --satus-header-background: #000;
+ --satus-header-border: rgba(var(--satus-contrast),.16);
--satus-header-text: #ccc;
--satus-layers-background: #000;
--satus-layers-text: #ccc;
- --satus-section-card-background: #1a1a1a;
- --satus-modal-background: #212121;
+ --satus-section-card-background: #000;
+ --satus-section-card-border: rgba(var(--satus-contrast),.16);
+ --satus-modal-background: #000;
+ --satus-modal-border: rgba(var(--satus-contrast),.16);
--satus-modal-text: #ccc;
- --satus-hover: rgba(255, 255, 255, .08);
+ --satus-hover: rgba(var(--satus-contrast), .05);
--satus-text-field--background: #333333;
--satus-text-field--border: #525252;
--satus-text-field--text: #ccc;
- --satus-switch-track: #111;
+ --satus-switch-track: rgba(var(--satus-contrast),.16);
--satus-switch-track--active: var(--satus-primary);
--satus-switch-thumb: #ddd;
- --satus-tooltip: rgba(255,255,255,.4);
- --satus-sortable-ghost: rgba(255, 255, 255, .8);
- --satus-sortable-background: var(--satus-primary);
+ --satus-tooltip: rgba(var(--satus-contrast),.4);
+ --satus-sortable-ghost: rgba(var(--satus-contrast), .8);
+ --satus-sortable-background: rgba(var(--satus-contrast), .1);
--satus-sortable-text: #fff;
- --satus-divider: #444;
+ --satus-divider: rgba(var(--satus-contrast),.08);
--satus-tabs-background: #111;
--satus-tabs-foreground: #2e2e2e;
- --satus-context-menu--border: #525252;
- --satus-checkbox--background: rgb(235, 235, 235, .08);
- --satus-checkbox--border: rgb(235, 235, 235, .16);
+ --satus-tabs-border: #2f2f2f;
+ --satus-checkbox--background: rgb(var(--satus-contrast), .08);
+ --satus-checkbox--border: #2f2f2f;
--satus-checkbox--mark: #fff;
--satus-alert-error-background: #501616;
--satus-alert-error-border: #6f1f1f;
--satus-alert-error-color: #cf7777;
}
/*--------------------------------------------------------------
->>> COLOR PICKER:
+>>> ELEMENTS:
----------------------------------------------------------------
-# Button
-# Modal
+# Reset
+# Attributes
+ # Hidden
--------------------------------------------------------------*/
-
/*--------------------------------------------------------------
-# BUTTON
+# RESET
--------------------------------------------------------------*/
-.satus-color-picker {
- font-size: inherit;
- position: relative;
- display: flex;
- box-sizing: border-box;
- margin: 0;
- cursor: pointer;
- color: inherit;
- border: none;
- outline: none;
- background-color: var(--satus-theme-button);
- justify-content: space-between;
- -webkit-tap-highlight-color: transparent;
- align-items: center;
- -webkit-appearance: none;
+:where([class^=satus]:not(iframe, canvas, img, svg, video, svg *, symbol *)) {
+ display: revert;
+ all: unset;
}
-.satus-color-picker__value {
- width: 22px;
- height: 22px;
- border: 2px solid rgba(0, 0, 0, .16);
- border-radius: 50%;
- background: #fff;
+:where([class^=satus]:not(iframe, canvas, img, svg, video, svg *, symbol *)) {
+ box-sizing: border-box;
}
/*--------------------------------------------------------------
-# MODAL
+# ATTRIBUTES
--------------------------------------------------------------*/
-.satus-modal--color-picker {
- position: relative;
-}
+/*--------------------------------------------------------------
+# HIDDEN
+--------------------------------------------------------------*/
-.satus-modal--color-picker .satus-modal__surface {
- padding-top: 0;
-}
+[class^=satus][hidden] {
+ display: none;
+}
+/*--------------------------------------------------------------
+>>> PLUVIAM
+--------------------------------------------------------------*/
-.satus-color-picker__palette {
- position: relative;
- overflow: hidden;
- width: 100%;
- height: 256px;
- background-color: #f00;
+.satus-pluviam {
+ position: absolute;
+ transform: scale(0);
+ animation-name: pluviam;
+ animation-duration: 1000ms;
+ opacity: var(--satus-pluviam-opacity, .08);
+ border-radius: 50%;
+ background: var(--satus-pluviam-background, #000);
+ animation-fill-mode: forwards;
}
-.satus-color-picker__palette:before {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- content: '';
- background-image: linear-gradient(0deg, black, transparent), linear-gradient(90deg, white, transparent);
-}
+@keyframes pluviam {
+ 0% {
+ transform: scale(0);
+ opacity: var(--satus-pluviam-opacity, .08);
+ }
+ 70% {
+ transform: scale(.8);
+ opacity: var(--satus-pluviam-opacity, .08);
+ }
+ 100% {
+ transform: scale(1);
+ opacity: 0;
+ }
+}
+/*--------------------------------------------------------------
+>>> SORTABLE
+--------------------------------------------------------------*/
-.satus-color-picker__cursor {
- position: absolute;
- width: 5px;
- height: 5px;
- transform: translate(-50%, -50%);
- pointer-events: none;
- border: 1px solid #fff;
- border-radius: 50%;
- box-shadow: 0 0 0 1px #000;
+.satus-sortable__chosen {
+ color: var(--satus-sortable-text) !important;
+ background-color: var(--satus-sortable-background) !important;
}
-.satus-modal--color-picker .satus-modal__surface .satus-section--color {
- margin: 8px 16px 0;
- align-items: center;
+.satus-sortable__ghost {
+ position: fixed !important;
+ z-index: 999 !important;
+ top: 0 !important;
+ left: 0 !important;
+ pointer-events: none !important;
+ box-shadow: 0 1px 3px rgb(0, 0, 0, .2), 0 4px 8px rgb(0, 0, 0, .1), inset 0 0 0 1px rgb(0, 0, 0, .16);
+ will-change: transform !important;
+ opacity: .8 !important;
+}
+/*--------------------------------------------------------------
+>>> CONTEXT MENU
+--------------------------------------------------------------*/
+
+.satus-modal--contextmenu .satus-modal__scrim {
+ background: none;
+ backdrop-filter: none;
+ animation: none;
+ visibility: visible;
+ opacity: 1;
+ transform: none;
}
-.satus-color-picker__color {
- width: 32px;
- height: 32px;
- margin: 0 16px 0 0;
- border: 2px solid rgba(0, 0, 0, .16);
- border-radius: 50%;
- background: #f00;
+.satus-modal--contextmenu .satus-modal__surface {
+ position: absolute;
+ margin: 0;
+ box-sizing: border-box;
+ min-width: 200px;
+ max-width: 200px;
+ padding: 4px 0;
+ border-radius: 4px;
+ box-shadow: none;
+ animation: none;
+ visibility: visible;
+ opacity: 1;
+ transform: none;
}
-.satus-slider.satus-color-picker__hue {
- padding: 0;
- flex: 1;
+.satus-modal--contextmenu .satus-modal__surface > * {
+
}
-.satus-color-picker__hue .satus-slider__track {
- height: 16px;
- border-radius: 4px;
- background-image: linear-gradient(90deg, #f00, #ff2a00, #f50, #ff7f00, #fa0, #ffd400, #ff0, #d4ff00, #af0, #80ff00, #5f0, #2bff00, #0f0, #00ff2b, #0f5, #00ff80, #0fa, #00ffd5, #0ff, #00d4ff, #0af, #007fff, #05f, #002bff, #00f, #2a00ff, #50f, #7f00ff, #a0f, #d400ff, #f0f, #ff00d4, #f0a, #ff0080, #f05, #ff002b, #f00);
+.satus-modal--contextmenu .satus-modal__surface>* {
+ display: flex;
+ height: 32px;
+ padding: 0 16px;
+ align-items: center;
}
-.satus-color-picker__hue .satus-slider__handle {
- width: 16px;
- height: 16px;
- background: #fff;
- box-shadow: 0 0 4px rgb(0, 0, 0, .64);
+.satus-modal--contextmenu .satus-modal__surface .satus-button svg {
+ width: 20px;
+ height: 18px;
+ margin: 0 14px 0 0;
+ opacity: .75;
+ fill: none;
+ stroke: var(--satus-primary);
+ flex: 0 0 20px;
}
-.satus-color-picker__hue::before,
-.satus-color-picker__hue .satus-slider__track-fill,
-.satus-color-picker__hue .satus-slider__handle:focus::after {
- display: none;
+.satus-modal--contextmenu .satus-modal__surface .satus-button .satus-span {
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
}
/*--------------------------------------------------------------
-# MAIN
+>>> BASE
--------------------------------------------------------------*/
-.satus-main {
- color: var(--satus-main-text);
- background: var(--satus-main-background);
- overflow-y: auto;
+.satus-base {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ height: 100%
+}
+/**/
+
+.satus-aside {
+ color: var(--satus-aside-text);
+ background: var(--satus-aside-background);
box-sizing: border-box;
}
/*--------------------------------------------------------------
->>> TABS
+>>> RADIO
+--------------------------------------------------------------*/
+/*--------------------------------------------------------------
+>>> CHECKBOX
--------------------------------------------------------------*/
-.satus-tabs {
+.satus-checkbox {
+ position: relative;
+ font: inherit;
display: flex;
- height: 26px !important;
+ color: inherit;
+ border: none;
+ background: transparent;
+ appearance: none;
+ align-items: center;
+ justify-content: flex-start;
}
-.satus-tabs__content {
- position: relative;
+.satus-checkbox:hover {
+ cursor: pointer;
+ background-color: var(--satus-hover);
+}
+
+.satus-checkbox:focus {
+ outline: none;
+}
+
+.satus-checkbox__content {
+ display: block;
+ white-space: nowrap;
+ text-overflow: ellipsis;
overflow: hidden;
- width: 100%;
- height: 100%;
- border: 2px solid var(--satus-tabs-background);
- border-radius: 4px;
- background: var(--satus-tabs-background);
}
-.satus-tabs__selection {
- position: absolute;
- z-index: 0;
- top: 0;
- left: 0;
- height: 100%;
- transition: left .25s;
- border-radius: 4px;
- background: var(--satus-tabs-foreground);
+.satus-checkbox::before {
+ display: flex;
+ min-width: 16px;
+ width: 16px;
+ height: 16px;
+ margin: 0 12px 0 0;
+ content: '';
+ border: 1px solid var(--satus-checkbox--border);
+ border-radius: 6px;
+ background: var(--satus-checkbox--background);
+ align-items: center;
+ justify-content: center;
}
-.satus-tabs__button {
- font: inherit;
- position: relative;
- z-index: 1;
- overflow: hidden;
- height: 100%;
- padding: 0 4px;
- white-space: nowrap;
- text-overflow: ellipsis;
- color: inherit;
- border: none;
- background: transparent;
- flex: 1;
+.satus-checkbox[data-value=true]::before {
+ background: var(--satus-primary);
}
-.satus-tabs__button:hover {
- cursor: pointer;
+.satus-checkbox[data-value=true]::after {
+ position: absolute;
+ top: 20px;
+ left: 20px;
+ width: 8px;
+ height: 4px;
+ content: '';
+ transform: rotate(-45deg);
+ border: 2px solid var(--satus-checkbox--mark);
+ border-top: none;
+ border-right: none;
}
/*--------------------------------------------------------------
->>> MENUBAR
+>>> SELECT
--------------------------------------------------------------*/
-.satus-menubar,
-.satus-menubar ul {
- margin: 0;
- padding: 0;
- list-style: none;
- background: var(--satus-menubar-background);
- color: var(--satus-menubar-text);
+.satus-select {
+ position: relative;
+ display: flex;
+ box-sizing: border-box;
+ align-items: center;
+ justify-content: space-between;
}
-.satus-menubar li > .satus-button {
- height: 32px;
- font-size: 14px;
+.satus-select__content {
+ display: flex;
+ align-items: center;
}
-.satus-menubar > li > ul {
- display: none;
+.satus-select__content > svg {
+ width: 20px;
+
+ height: 18px;
+ margin: 0 14px 0 0;
+ opacity: .75;
+}
+
+.satus-select__value {
+ margin-left: 16px;
+ text-align: right;
+ opacity: .75;
+}
+
+.satus-select select {
+ font: inherit;
position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ padding: inherit;
+ cursor: pointer;
+ opacity: 0;
+ border: none;
+ outline: none;
+ background: none;
+ appearance: none;
}
-.satus-menubar > li > ul:hover,
-.satus-menubar > li > *:focus + ul {
- display: block;
+.satus-select:hover {
+ cursor: pointer;
+ background-color: var(--satus-hover);
}
/*--------------------------------------------------------------
->>> RADIO
---------------------------------------------------------------*/
-/*--------------------------------------------------------------
-# BUTTON
+>>> SHORTCUT:
+----------------------------------------------------------------
+#
--------------------------------------------------------------*/
-.satus-button {
- font: inherit;
- position: relative;
+.satus-shortcut {
+ justify-content: space-between;
+}
+
+.satus-shortcut__value {
+ font-size: 11px;
display: flex;
- overflow: hidden;
- height: 48px;
- margin: 0;
- padding: 8px;
- text-align: left;
- color: var(--satus-button-text, inherit);
- border: none;
- background: var(--satus-button-background, transparent);
- appearance: none;
+ text-transform: uppercase;
align-items: center;
}
-.satus-button:hover {
- cursor: pointer;
- background-color: var(--satus-hover);
+.satus-shortcut__actions {
+ display: flex;
+ justify-content: flex-end;
}
-.satus-button[hidden] {
- display: none;
+.satus-shortcut__actions .satus-button {
+ height: 32px;
+ margin: 8px 4px 0;
+ border-radius: 8px;
+ background: rgba(0, 0, 0, .15);
}
-.satus-button>svg {
- min-width: 20px;
+.satus-shortcut__actions .satus-button:hover {
+ background: rgba(0, 0, 0, .25);
}
-.satus-button>.satus-span--label {
- display: block;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
-}
-/*--------------------------------------------------------------
->>> LIST:
---------------------------------------------------------------*/
-
-.satus-list {
- list-style: none;
- margin: 0;
+.satus-shortcut__primary {
+ display: flex;
+ box-sizing: border-box;
+ width: 100%;
+ height: 68px;
+ padding: 16px;
+ background: rgba(0, 0, 0, .16);
+ align-items: center;
}
-.satus-list__item {
- display: flex;
+.satus-shortcut__key {
+ display: flex;
+ box-sizing: border-box;
+ min-width: 32px;
+ height: 32px;
+ padding: 4px 8px;
+ border-radius: 4px;
+ background: #fff;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, .15), inset 0 -3px 0 rgba(0, 0, 0, .1);
align-items: center;
- justify-content: space-between;
- min-height: 48px;
+ justify-content: center;
}
-.satus-list__item>*:last-child {
- text-align: right;
-}
-/*--------------------------------------------------------------
->>> SECTION:
-----------------------------------------------------------------
-# Align
-# Card
---------------------------------------------------------------*/
+.satus-shortcut__value>.satus-shortcut__key {
+ font-size: 14px;
+ min-width: 24px;
+ height: 24px;
+}
-.satus-section {
- display: flex;
- box-sizing: border-box;
- flex-wrap: wrap;
+.satus-shortcut__plus {
+ position: relative;
+ width: 12px;
+ height: 12px;
+ margin: 8px;
}
+.satus-shortcut__plus::before {
+ position: absolute;
+ top: 0;
+ left: 5px;
+ width: 2px;
+ height: 12px;
+ content: '';
+ background-color: #aaa;
+}
-/*--------------------------------------------------------------
-# ALIGN
---------------------------------------------------------------*/
+.satus-shortcut__plus::after {
+ position: absolute;
+ top: 5px;
+ left: 0;
+ width: 12px;
+ height: 2px;
+ content: '';
+ background-color: #aaa;
+}
-.satus-section--align-start {
- align-items: center;
- justify-content: flex-start;
+.satus-shortcut__mouse {
+ position: relative;
+ display: flex;
+ width: 28px;
+ height: 36px;
+ border-radius: 50%;
+ border-top-left-radius: 12px;
+ border-top-right-radius: 12px;
+ background: #fff;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, .15), inset 0 -3px 0 rgba(0, 0, 0, .1);
}
-.satus-section--align-end {
- align-items: center;
- justify-content: flex-end;
+.satus-shortcut__value>.satus-shortcut__mouse {
+ width: 22px;
+ height: 28px;
}
-.satus-section--space-between {
- align-items: center;
- justify-content: space-between;
+.satus-shortcut__mouse>div {
+ position: absolute;
+ top: 0;
+ left: calc(50% - 1px);
+ width: 2px;
+ height: 11px;
+ border-radius: 2px;
+ background: #ccc;
}
-.satus-section--column {
- flex-direction: column;
+.satus-shortcut__mouse::before {
+ position: absolute;
+ top: -16%;
+ right: 14%;
+ width: 2px;
+ height: 60%;
+ content: '';
+ background: #f96754;
}
+.satus-shortcut__mouse.false::before {
+ top: -6%;
+}
-/*--------------------------------------------------------------
-# CARD
---------------------------------------------------------------*/
+.satus-shortcut__mouse.false::after {
+ position: absolute;
+ top: -20%;
+ right: calc(14% - 4px);
+ width: 0;
+ height: 0;
+ content: '';
+ border-right: 5px solid transparent;
+ border-bottom: 8px solid #f96754;
+ border-left: 5px solid transparent;
+}
-.satus-section--card {
- flex-direction: column;
- box-sizing: border-box;
- width: 100%;
- max-width: 900px;
- margin: 8px auto;
- padding: 8px 0;
- color: var(--satus-section-card-text);
- border: 1px solid rgba(0, 0, 0, .1);
- border-radius: 8px;
- background: var(--satus-section-card-background);
- justify-content: stretch;
+.satus-shortcut__mouse.true::after {
+ position: absolute;
+ top: 40%;
+ right: calc(14% - 4px);
+ width: 0;
+ height: 0;
+ content: '';
+ border-top: 8px solid #f96754;
+ border-right: 5px solid transparent;
+ border-left: 5px solid transparent;
}
-.satus-section--card>*:not(.satus-button) {
- box-sizing: border-box;
- min-height: 48px;
- padding: 0 16px;
- text-align: left;
+.satus-shortcut__mouse.click::before {
+ position: absolute;
+ top: 0;
+ left: -1px;
+ width: 10px;
+ height: 10px;
+ content: '';
+ border-radius: 50%;
+ background: #f96754;
}
-.satus-section--card>.satus-switch,
-.satus-section--card>.satus-select,
-.satus-section--card>.satus-radio {
- display: flex;
- justify-content: space-between;
- align-items: center;
+.satus-shortcut__mouse.context::before {
+ position: absolute;
+ top: 0;
+ left: 15px;
+ width: 10px;
+ height: 10px;
+ content: '';
+ border-radius: 50%;
+ background: #f96754;
}
-.satus-section--card>.satus-button:hover,
-.satus-section--card>.satus-switch:hover,
-.satus-section--card>.satus-select:hover,
-.satus-section--card>.satus-slider:hover,
-.satus-section--card>.satus-radio:hover {
- background-color: var(--satus-hover);
+.satus-section_shortcut {
+ width: 100%;
+ margin: 8px 0 0;
+ justify-content: flex-end;
}
-.satus-section--card>.satus-button {
- width: 100%;
- padding: 0 16px;
+.satus-button_shortcut {
+ font-weight: 500;
+ overflow: hidden;
+ height: 28px;
+ min-height: 28px;
+ margin-right: 2px;
+ padding: 4px 8px;
+ text-transform: uppercase;
+ color: #f96754;
+ border-radius: 4px;
+}
+/*--------------------------------------------------------------
+>>> SWITCH
+----------------------------------------------------------------
+# Container
+# Track
+# Thumb
+--------------------------------------------------------------*/
+
+
+/*--------------------------------------------------------------
+# CONTAINER
+--------------------------------------------------------------*/
+
+.satus-switch {
+ font: inherit;
+ display: flex;
+ transition: background-color 75ms;
+ color: inherit;
+ border: none;
+ outline: none;
+ background-color: transparent;
+ justify-content: space-between;
+ align-items: center;
}
-.satus-section--card>.satus-button>svg {
- width: 20px;
- margin: 2px 16px 0 0;
- color: var(--satus-primary);
+.satus-switch:hover {
+ cursor: pointer;
}
-.satus-section--card>.satus-span {
- display: flex;
- align-items: center;
-}
+.satus-switch__content {
+ display: flex;
+ align-items: center;
+}
+
+.satus-switch__content>svg {
+ width: 20px;
+ height: 18px;
+ margin: 0 14px 0 0;
+ opacity: .75;
+}
+
+
/*--------------------------------------------------------------
-# SCROLLBAR
+# TRACK
--------------------------------------------------------------*/
-::-webkit-scrollbar {
- width: 4px;
+.satus-switch>i {
+ width: 32px;
+ height: 18px;
+ transition: background-color 150ms;
+ border-radius: 18px;
+ background-color: var(--satus-switch-track);
+ flex: 0 0 32px;
}
-::-webkit-scrollbar:hover {
- width: 8px;
+.satus-section--card .satus-switch>i {
+ margin-left: 16px;
+}
+
+.satus-switch[data-value='true']>i {
+ background-color: var(--satus-switch-track--active);
+}
+
+
+/*--------------------------------------------------------------
+# THUMB
+--------------------------------------------------------------*/
+
+.satus-switch>i::before {
+ display: block;
+ width: 14px;
+ height: 14px;
+ margin: 2px;
+ content: '';
+ transition: transform 150ms cubic-bezier(.4, 0, .2, 1);
+ border-radius: 50%;
+ background-color: var(--satus-switch-thumb);
+ will-change: transform;
}
-::-webkit-scrollbar-thumb {
- background: rgba(0, 0, 0, .3);
+.satus-switch[data-value='true']>i::before {
+ transform: translateX(14px);
}
/*--------------------------------------------------------------
->>> MODAL
+>>> LAYERS
--------------------------------------------------------------*/
-.satus-modal {
- position: absolute;
- z-index: 100;
- top: 0;
- left: 0;
- display: flex;
- width: 100%;
- height: 100vh;
- justify-content: center;
- align-items: center;
+.satus-layers {
+ position: relative;
+ overflow: hidden;
+ color: var(--satus-layers-text);
+ background: var(--satus-layers-background);
+ flex: 1;
}
-.satus-modal__scrim {
+.satus-layer {
position: absolute;
top: 0;
left: 0;
- width: 100%;
- height: 100%;
- animation: modalFadeIn 150ms linear forwards;
- opacity: 0;
- background: rgba(0, 0, 0, .16);
- backdrop-filter: blur(8px);
-}
-
-.satus-modal__surface {
display: flex;
overflow-y: auto;
flex-direction: column;
- width: 95%;
- min-width: 240px;
- max-width: 560px;
- max-height: 80%;
- margin: 0 16px;
- padding: 12px 16px;
- transform: scale(.8);
- animation: modalZoomIn 150ms linear forwards;
- animation-delay: 20ms;
- opacity: 0;
- color: var(--satus-modal-text);
- border-radius: 6px;
- background-color: var(--satus-modal-background);
- box-shadow: inset 0 -1px 1px 1px rgb(0, 0, 0, .1), 0 2px 6px rgb(0, 0, 0, .15);
-}
+ box-sizing: border-box;
+ width: 100%;
+ height: 100%;
+ padding: 0 12px;
+ align-content: center;
+}
+/*--------------------------------------------------------------
+# INPUT
+--------------------------------------------------------------*/
-.satus-modal__surface .satus-section--actions {
- display: flex;
+.satus-input[type=text],
+.satus-input[type=password] {
+ font: inherit;
+ box-sizing: border-box;
width: 100%;
- margin: 8px 0 0;
- padding: 0;
- justify-content: flex-end;
- align-items: center;
+ margin: 0;
+ padding: 6px 8px;
+ color: var(--satus-text-field--text, inherit);
+ border: none;
+ outline: none;
+ background: none;
+ appearance: none;
+ font-size: 16px;
+ margin: 8px 0;
+ border: 1px solid var(--satus-text-field--border);
+ border-radius: 4px;
+ background-color: var(--satus-text-field--background);
+}
+/*--------------------------------------------------------------
+>>> MENUBAR
+--------------------------------------------------------------*/
+
+.satus-menubar {
+ display: flex;
}
-.satus-modal__surface .satus-section--actions .satus-button {
- font-weight: 500;
- height: 32px;
- margin-left: 8px;
- padding: 0 8px;
- letter-spacing: .5px;
- color: var(--satus-primary);
- border-radius: 4px;
+.satus-menubar,
+.satus-menubar ul {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ color: var(--satus-menubar-text);
+ background: var(--satus-menubar-background);
}
-.satus-modal--closing .satus-modal__scrim {
- animation: modalFadeOut 70ms linear forwards;
+.satus-menubar li {
+ position: relative;
}
-.satus-modal--closing .satus-modal__surface {
- animation: modalZoomOut 70ms linear forwards;
+.satus-menubar li:focus,
+.satus-menubar li:hover {
+ background: var(--satus-menubar-hover);
}
-.satus-modal--vertical .satus-modal__surface {
+.satus-menubar>li ul {
position: absolute;
- top: 8px;
- right: 8px;
- left: auto;
- min-width: 200px;
- max-width: 200px;
- margin: 0;
- padding: 8px 0;
- transform-origin: right top;
+ min-width: 126px;
}
-.satus-modal--vertical .satus-modal__surface>.satus-button,
-.satus-modal--vertical .satus-modal__surface>.satus-switch,
-.satus-modal--vertical .satus-modal__surface>.satus-select {
- display: flex;
- height: 36px;
- padding: 0 16px;
- align-items: center;
+.satus-menubar>li>ul ul {
+ top: 0;
+ left: 100%;
}
-.satus-modal--vertical .satus-modal__surface>.satus-tabs {
- padding: 0 12px;
+.satus-menubar li>ul {
+ position: absolute;
+ display: none;
}
-.satus-modal--vertical .satus-modal__surface>.satus-span {
- font-size: 13px;
- font-weight: 500;
- margin: 6px 0;
- padding: 0 12px;
+.satus-menubar li>*:not(ul):focus+ul,
+.satus-menubar li>*:not(ul):hover+ul,
+.satus-menubar li>ul:hover {
+ display: block;
}
-.satus-modal--vertical .satus-modal__surface>.satus-button:hover,
-.satus-modal--vertical .satus-modal__surface>.satus-switch:hover,
-.satus-modal--vertical .satus-modal__surface>.satus-select:hover {
- background-color: var(--satus-hover);
-}
+.satus-menubar li> :not(ul) {
+ font-size: 14px;
+ display: flex;
+ width: 100%;
+ height: 32px;
+ align-items: center;
+}
+/*--------------------------------------------------------------
+# MAIN
+--------------------------------------------------------------*/
-.satus-modal--vertical .satus-button svg {
- width: 20px;
- height: 18px;
- margin: 0 14px 0 0;
- opacity: .75;
- flex: 0 0 20px;
-}
+.satus-main {
+ color: var(--satus-main-text);
+ background: var(--satus-main-background);
+ overflow-y: auto;
+ box-sizing: border-box;
+}
+/*--------------------------------------------------------------
+# SCROLLBAR
+--------------------------------------------------------------*/
-.satus-modal--vertical .satus-button .satus-span {
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
+::-webkit-scrollbar {
+ width: 4px;
}
+::-webkit-scrollbar:hover {
+ width: 8px;
+}
+::-webkit-scrollbar-thumb {
+ background: rgba(0, 0, 0, .3);
+}
/*--------------------------------------------------------------
-# ANIMATIONS
+>>> TEXTAREA
--------------------------------------------------------------*/
-@keyframes modalFadeIn {
- from {
- opacity: 0;
- }
- to {
- opacity: 1;
- }
+.satus-textarea {
+ position: relative;
+ display: flex;
+ overflow: hidden;
+ color: var(--satus-textarea-color, inherit);
+ background: var(--satus-textarea-background);
}
-@keyframes modalFadeOut {
- from {
- opacity: 1;
- }
- to {
- opacity: 0;
- }
+.satus-textarea textarea {
+ font-size: inherit;
+ line-height: 1.2;
+ overflow: auto;
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ resize: none;
+ white-space: pre;
+ word-break: break-all;
+ color: inherit;
+ border: none;
+ outline: none;
+ background: transparent;
+ overflow-wrap: normal;
}
-@keyframes modalZoomIn {
- from {
- transform: scale(.8);
- opacity: 0;
- }
- to {
- transform: scale(1);
- opacity: 1;
- }
+.satus-textarea__line-number {
+ padding: 0 16px 0 8px;
+ opacity: .5;
}
-@keyframes modalZoomOut {
- from {
- transform: scale(1);
- opacity: 1;
- }
- to {
- transform: scale(.8);
- opacity: 0;
- }
+.satus-textarea__line-number>span {
+ font-size: inherit;
+ line-height: 1.2;
+ display: block;
+ width: 100%;
+ text-align: right;
}
/*--------------------------------------------------------------
->>> CHECKBOX
+>>> DIVIDER
--------------------------------------------------------------*/
-.satus-checkbox {
+.satus-divider {
+ height: 1px;
+ margin: 16px 0 12px;
+ background: var(--satus-divider);
+}
+/*--------------------------------------------------------------
+>>> TEXT FIELD
+--------------------------------------------------------------*/
+
+.satus-text-field {
position: relative;
- font: inherit;
+ padding: 0 16px;
+ background-color: var(--satus-text-field--background);
+ border-radius: 8px;
+ color: var(--satus-text-field--text);
+ overflow: hidden;
display: flex;
- color: inherit;
- border: none;
- background: transparent;
- appearance: none;
+}
+
+.satus-text-field__pre {
+ display: flex;
+ position: relative;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ overflow: hidden;
align-items: center;
- justify-content: flex-start;
+ flex: 1;
}
-.satus-checkbox:hover {
- cursor: pointer;
- background-color: var(--satus-hover);
+.satus-text-field__input {
+ font: inherit;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ min-width: 0;
+ max-width: none;
+ height: 100%;
+ min-height: 0;
+ max-height: none;
+ margin: 0;
+ padding: 0;
+ opacity: 0;
+ border: none;
+ appearance: none;
+ z-index: 9;
}
-.satus-checkbox:focus {
- outline: none;
+.satus-text-field__hidden-text {
+ position: absolute;
+ pointer-events: none;
+ opacity: 0;
}
-.satus-checkbox__content {
- display: block;
- white-space: nowrap;
- text-overflow: ellipsis;
- overflow: hidden;
+.satus-text-field__text {
+ position: absolute;
+ top: 0;
+ left: 0;
+ display: flex;
+ height: 100%;
+ margin: 0;
+ align-items: center;
}
-.satus-checkbox::before {
- display: flex;
- min-width: 16px;
- width: 16px;
- height: 16px;
- margin: 0 12px 0 0;
- content: '';
- border: 1px solid var(--satus-checkbox--border);
- border-radius: 6px;
- background: var(--satus-checkbox--background);
- align-items: center;
- justify-content: center;
+.satus-text-field__cursor {
+ position: absolute;
+ top: 6px;
+ left: 0;
+ display: none;
+ width: 2px;
+ height: 25px;
+ animation: blink 1s step-end 8;
+ background: #fa0;
}
-.satus-checkbox[data-value=true]::before {
- background: var(--satus-primary);
+.satus-text-field__selection {
+ position: absolute;
+ top: 5px;
+ left: 0;
+ display: none;
+ width: 0;
+ height: 25px;
+ border: 1px solid rgba(255, 255, 255, .2);
+ border-radius: 3px;
+ background: rgba(255, 255, 255, .1);
}
-.satus-checkbox[data-value=true]::after {
- position: absolute;
- top: 20px;
- left: 20px;
- width: 8px;
- height: 4px;
- content: '';
- transform: rotate(-45deg);
- border: 2px solid var(--satus-checkbox--mark);
- border-top: none;
- border-right: none;
-}
-/*--------------------------------------------------------------
->>> SWITCH
-----------------------------------------------------------------
-# Container
-# Track
-# Thumb
---------------------------------------------------------------*/
+.satus-text-field__input:focus + * + * + * + .satus-text-field__cursor,
+.satus-text-field__selection:not([disabled]) {
+ display: block;
+}
+
+@keyframes blink {
+ from,
+ to {
+ opacity: 1;
+ }
+ 50% {
+ opacity: 0;
+ }
+}
/*--------------------------------------------------------------
-# CONTAINER
+# SYNTAX HIGHLIGHTING
--------------------------------------------------------------*/
-.satus-switch {
- font: inherit;
- display: flex;
- transition: background-color 75ms;
- color: inherit;
- border: none;
- outline: none;
- background-color: transparent;
- justify-content: space-between;
- align-items: center;
+.satus-text-field__text>.group {
+ color: #47ff47;
+ background-color: rgb(71, 255, 71, .16);
}
-.satus-switch:hover {
- cursor: pointer;
+.satus-text-field__text>.character-class {
+ color: #ffc247;
+ background-color: rgb(255, 170, 0, .16);
}
-.satus-switch__content {
- display: flex;
- align-items: center;
+.satus-text-field__text>.quantifier {
+ color: #47c2ff;
+ background-color: rgb(71, 194, 255, .16);
}
-.satus-switch__content>svg {
- width: 20px;
- height: 18px;
- margin: 0 14px 0 0;
- opacity: .75;
+.satus-text-field__text>.anchor {
+ color: #47c2ff;
+ background-color: rgb(71, 194, 255, .16);
}
+.satus-text-field__text>.metasequence {
+ color: #47ff47;
+ background-color: rgb(71, 255, 71, .16);
+}
+.satus-text-field__text>.text {
+ color: #c4c4d4;
+ background-color: rgb(196, 196, 212, .16);
+}
/*--------------------------------------------------------------
-# TRACK
+>>> TABS
--------------------------------------------------------------*/
-.satus-switch>i {
- width: 32px;
- height: 18px;
- transition: background-color 150ms;
- border-radius: 18px;
- background-color: var(--satus-switch-track);
- flex: 0 0 32px;
+.satus-tabs {
+ display: flex;
+ height: 26px !important;
}
-.satus-section--card .satus-switch>i {
- margin-left: 16px;
+.satus-tabs__content {
+ position: relative;
+ overflow: hidden;
+ width: 100%;
+ height: 100%;
+ border: 2px solid var(--satus-tabs-background);
+ border-radius: 4px;
+ background: var(--satus-tabs-background);
+ display: flex;
}
-.satus-switch[data-value='true']>i {
- background-color: var(--satus-switch-track--active);
+.satus-tabs__selection {
+ position: absolute;
+ z-index: 0;
+ top: 0;
+ left: 0;
+ height: 100%;
+ transition: left .25s;
+ border-radius: 4px;
+ background: var(--satus-tabs-foreground);
+ box-sizing: border-box;
+ border: 1px solid var(--satus-tabs-border);
}
+.satus-tabs__button {
+ font: inherit;
+ position: relative;
+ z-index: 1;
+ overflow: hidden;
+ height: 100%;
+ padding: 0 4px;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ color: inherit;
+ border: none;
+ background: transparent;
+ flex: 1;
+ text-align: center;
+}
+.satus-tabs__button:hover {
+ cursor: pointer;
+}
/*--------------------------------------------------------------
-# THUMB
+>>> ALERT
--------------------------------------------------------------*/
-.satus-switch>i::before {
- display: block;
- width: 14px;
- height: 14px;
- margin: 2px;
- content: '';
- transition: transform 150ms cubic-bezier(.4, 0, .2, 1);
- border-radius: 50%;
- background-color: var(--satus-switch-thumb);
- will-change: transform;
+.satus-alert {
+ display: flex;
+ box-sizing: border-box;
+ min-height: 48px;
+ margin: 8px 0 0;
+ padding: 8px 16px;
+ border-radius: 8px;
+ align-items: center;
}
-.satus-switch[data-value='true']>i::before {
- transform: translateX(14px);
+.satus-alert--error {
+ color: var(--satus-alert-error-color);
+ border: 1px solid var(--satus-alert-error-border);
+ background: var(--satus-alert-error-background);
}
/*--------------------------------------------------------------
>>> SLIDER
@@ -821,74 +1058,75 @@ body[theme=black] {
.satus-slider__container {
position: relative;
- height: 32px;
+ display: block;
width: 100%;
+ height: 32px;
}
.satus-slider__track {
position: absolute;
top: 50%;
left: 0;
- height: 2px;
width: 100%;
+ height: 2px;
transform: translateY(-50%);
}
.satus-slider__track::before {
position: absolute;
- left: 0;
top: 0;
+ left: 0;
width: 100%;
height: 100%;
- background: var(--satus-primary);
- opacity: .24;
content: '';
+ opacity: .24;
+ background: var(--satus-primary);
}
.satus-slider__handle:focus::after {
- content: attr(data-value);
position: absolute;
- left: 50%;
top: -2px;
- background: var(--satus-primary);
- color: #fff;
+ left: 50%;
display: block;
- transform: translate(-50%, -100%);
padding: 1px 4px;
+ content: attr(data-value);
+ transform: translate(-50%, -100%);
+ color: #fff;
border-radius: 4px;
+ background: var(--satus-primary);
}
.satus-slider__track-fill {
position: absolute;
- left: 0;
top: 0;
+ left: 0;
height: 100%;
background: var(--satus-primary);
}
.satus-slider__handle {
position: absolute;
+ top: 50%;
+ left: 0;
width: 10px;
height: 10px;
- background: var(--satus-primary);
- border-radius: 50%;
transform: translate(-50%, -50%);
- top: 50%;
- left: 0;
+ border-radius: 50%;
+ background: var(--satus-primary);
}
.satus-slider__handle::before {
- content: '';
- background: var(--satus-primary);
position: absolute;
- left: 50%;
top: 50%;
+ left: 50%;
width: 1px;
height: 1px;
+ content: '';
+ transition: .2s;
+ transform: translate(-50%, -50%) scale(1);
opacity: 0;
border-radius: 50%;
- transform: translate(-50%, -50%) scale(1);
- transition: .2s;
+ background: var(--satus-primary);
}
.satus-slider:focus .satus-slider__handle::before {
@@ -896,339 +1134,239 @@ body[theme=black] {
opacity: .24;
}
/*--------------------------------------------------------------
->>> SHORTCUT:
+>>> COLOR PICKER:
----------------------------------------------------------------
-#
+# Button
+# Modal
--------------------------------------------------------------*/
-.satus-shortcut {
- justify-content: space-between;
-}
-
-.satus-shortcut__value {
- font-size: 11px;
- display: flex;
- text-transform: uppercase;
- align-items: center;
-}
-
-.satus-shortcut__actions {
- display: flex;
- justify-content: flex-end;
-}
-
-.satus-shortcut__actions .satus-button {
- height: 32px;
- margin: 8px 4px 0;
- border-radius: 8px;
- background: rgba(0, 0, 0, .15);
-}
-.satus-shortcut__actions .satus-button:hover {
- background: rgba(0, 0, 0, .25);
-}
+/*--------------------------------------------------------------
+# BUTTON
+--------------------------------------------------------------*/
-.satus-shortcut__primary {
+.satus-color-picker {
+ font-size: inherit;
+ position: relative;
display: flex;
box-sizing: border-box;
- width: 100%;
- height: 68px;
- padding: 16px;
- background: rgba(0, 0, 0, .16);
+ margin: 0;
+ cursor: pointer;
+ color: inherit;
+ border: none;
+ outline: none;
+ background-color: var(--satus-theme-button);
+ justify-content: space-between;
+ -webkit-tap-highlight-color: transparent;
align-items: center;
+ -webkit-appearance: none;
}
-.satus-shortcut__key {
- display: flex;
- box-sizing: border-box;
- min-width: 32px;
- height: 32px;
- padding: 4px 8px;
- border-radius: 4px;
+.satus-color-picker__value {
+ width: 22px;
+ height: 22px;
+ border: 2px solid rgba(0, 0, 0, .16);
+ border-radius: 50%;
background: #fff;
- box-shadow: 0 1px 3px rgba(0, 0, 0, .15), inset 0 -3px 0 rgba(0, 0, 0, .1);
- align-items: center;
- justify-content: center;
}
-.satus-shortcut__value>.satus-shortcut__key {
- font-size: 14px;
- min-width: 24px;
- height: 24px;
-}
-.satus-shortcut__plus {
- position: relative;
- width: 12px;
- height: 12px;
- margin: 8px;
-}
+/*--------------------------------------------------------------
+# MODAL
+--------------------------------------------------------------*/
-.satus-shortcut__plus::before {
- position: absolute;
- top: 0;
- left: 5px;
- width: 2px;
- height: 12px;
- content: '';
- background-color: #aaa;
+.satus-modal--color-picker {
+ position: relative;
}
-.satus-shortcut__plus::after {
- position: absolute;
- top: 5px;
- left: 0;
- width: 12px;
- height: 2px;
- content: '';
- background-color: #aaa;
+.satus-modal--color-picker .satus-modal__surface {
+ padding-top: 0;
}
-.satus-shortcut__mouse {
+.satus-color-picker__palette {
position: relative;
- display: flex;
- width: 28px;
- height: 36px;
- border-radius: 50%;
- border-top-left-radius: 12px;
- border-top-right-radius: 12px;
- background: #fff;
- box-shadow: 0 1px 3px rgba(0, 0, 0, .15), inset 0 -3px 0 rgba(0, 0, 0, .1);
-}
-
-.satus-shortcut__value>.satus-shortcut__mouse {
- width: 22px;
- height: 28px;
+ overflow: hidden;
+ width: 100%;
+ height: 256px;
+ background-color: #f00;
}
-.satus-shortcut__mouse>div {
+.satus-color-picker__palette:before {
position: absolute;
top: 0;
- left: calc(50% - 1px);
- width: 2px;
- height: 11px;
- border-radius: 2px;
- background: #ccc;
-}
-
-.satus-shortcut__mouse::before {
- position: absolute;
- top: -16%;
- right: 14%;
- width: 2px;
- height: 60%;
+ left: 0;
+ width: 100%;
+ height: 100%;
content: '';
- background: #f96754;
-}
-
-.satus-shortcut__mouse.false::before {
- top: -6%;
+ background-image: linear-gradient(0deg, black, transparent), linear-gradient(90deg, white, transparent);
}
-.satus-shortcut__mouse.false::after {
+.satus-color-picker__cursor {
position: absolute;
- top: -20%;
- right: calc(14% - 4px);
- width: 0;
- height: 0;
- content: '';
- border-right: 5px solid transparent;
- border-bottom: 8px solid #f96754;
- border-left: 5px solid transparent;
+ width: 5px;
+ height: 5px;
+ transform: translate(-50%, -50%);
+ pointer-events: none;
+ border: 1px solid #fff;
+ border-radius: 50%;
+ box-shadow: 0 0 0 1px #000;
}
-.satus-shortcut__mouse.true::after {
- position: absolute;
- top: 40%;
- right: calc(14% - 4px);
- width: 0;
- height: 0;
- content: '';
- border-top: 8px solid #f96754;
- border-right: 5px solid transparent;
- border-left: 5px solid transparent;
+.satus-modal--color-picker .satus-modal__surface .satus-section--color {
+ margin: 8px 16px 0;
+ align-items: center;
}
-.satus-shortcut__mouse.click::before {
- position: absolute;
- top: 0;
- left: -1px;
- width: 10px;
- height: 10px;
- content: '';
+.satus-color-picker__color {
+ width: 32px;
+ height: 32px;
+ margin: 0 16px 0 0;
+ border: 2px solid rgba(0, 0, 0, .16);
border-radius: 50%;
- background: #f96754;
+ background: #f00;
}
-.satus-shortcut__mouse.context::before {
- position: absolute;
- top: 0;
- left: 15px;
- width: 10px;
- height: 10px;
- content: '';
- border-radius: 50%;
- background: #f96754;
+.satus-slider.satus-color-picker__hue {
+ padding: 0;
+ flex: 1;
}
-.satus-section_shortcut {
- width: 100%;
- margin: 8px 0 0;
- justify-content: flex-end;
+.satus-color-picker__hue .satus-slider__track {
+ height: 16px;
+ border-radius: 4px;
+ background-image: linear-gradient(90deg, #f00, #ff2a00, #f50, #ff7f00, #fa0, #ffd400, #ff0, #d4ff00, #af0, #80ff00, #5f0, #2bff00, #0f0, #00ff2b, #0f5, #00ff80, #0fa, #00ffd5, #0ff, #00d4ff, #0af, #007fff, #05f, #002bff, #00f, #2a00ff, #50f, #7f00ff, #a0f, #d400ff, #f0f, #ff00d4, #f0a, #ff0080, #f05, #ff002b, #f00);
}
-.satus-button_shortcut {
- font-weight: 500;
- overflow: hidden;
- height: 28px;
- min-height: 28px;
- margin-right: 2px;
- padding: 4px 8px;
- text-transform: uppercase;
- color: #f96754;
- border-radius: 4px;
+.satus-color-picker__hue .satus-slider__handle {
+ width: 16px;
+ height: 16px;
+ background: #fff;
+ box-shadow: 0 0 4px rgb(0, 0, 0, .64);
+}
+
+.satus-color-picker__hue::before,
+.satus-color-picker__hue .satus-slider__track-fill,
+.satus-color-picker__hue .satus-slider__handle:focus::after {
+ display: none;
}
/*--------------------------------------------------------------
->>> BASE
+>>> SECTION:
+----------------------------------------------------------------
+# Align
+# Card
--------------------------------------------------------------*/
-.satus-base{
- display: flex;
- flex-direction: column;
- width: 100%;
- height: 100%;
-}
+.satus-section {
+ display: flex;
+ box-sizing: border-box;
+ flex-wrap: wrap;
+}
+
+
/*--------------------------------------------------------------
->>> TEXT FIELD
+# ALIGN
--------------------------------------------------------------*/
-.satus-text-field {
- position: relative;
- padding: 0 16px;
- background-color: var(--satus-text-field--background);
- border-radius: 8px;
- color: var(--satus-text-field--text);
- overflow: hidden;
- display: flex;
+.satus-section--align-start {
+ align-items: center;
+ justify-content: flex-start;
}
-.satus-text-field__pre {
- display: flex;
- position: relative;
- height: 100%;
- margin: 0;
- padding: 0;
- overflow: hidden;
- align-items: center;
- flex: 1;
+.satus-section--align-end {
+ align-items: center;
+ justify-content: flex-end;
}
-.satus-text-field__input {
- font: inherit;
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- min-width: 0;
- max-width: none;
- height: 100%;
- min-height: 0;
- max-height: none;
- margin: 0;
- padding: 0;
- opacity: 0;
- border: none;
- appearance: none;
- z-index: 9;
+.satus-section--space-between {
+ align-items: center;
+ justify-content: space-between;
}
-.satus-text-field__hidden-text {
- position: absolute;
- pointer-events: none;
- opacity: 0;
+.satus-section--column {
+ flex-direction: column;
}
-.satus-text-field__text {
- position: absolute;
- top: 0;
- left: 0;
- display: flex;
- height: 100%;
- margin: 0;
- align-items: center;
-}
-.satus-text-field__cursor {
- position: absolute;
- top: 6px;
- left: 0;
- display: none;
- width: 2px;
- height: 25px;
- animation: blink 1s step-end 8;
- background: #fa0;
-}
+/*--------------------------------------------------------------
+# CARD
+--------------------------------------------------------------*/
-.satus-text-field__selection {
- position: absolute;
- top: 5px;
- left: 0;
- display: none;
- width: 0;
- height: 25px;
- border: 1px solid rgba(255, 255, 255, .2);
- border-radius: 3px;
- background: rgba(255, 255, 255, .1);
+.satus-section--card {
+ flex-direction: column;
+ box-sizing: border-box;
+ width: 100%;
+ max-width: 900px;
+ margin: 8px auto;
+ padding: 8px 0;
+ color: var(--satus-section-card-text);
+ border: 1px solid var(--satus-section-card-border);
+ border-radius: 8px;
+ background: var(--satus-section-card-background);
+ justify-content: stretch;
}
-.satus-text-field__input:focus + * + * + * + .satus-text-field__cursor,
-.satus-text-field__selection:not([disabled]) {
- display: block;
+.satus-section--label {
+ width: 100%;
+ max-width: 900px;
+ margin: 8px auto;
}
-@keyframes blink {
- from,
- to {
- opacity: 1;
- }
- 50% {
- opacity: 0;
- }
+.satus-section--card>*:not(.satus-button) {
+ box-sizing: border-box;
+ min-height: 48px;
+ padding: 0 16px;
+ text-align: left;
}
+.satus-section--card>.satus-switch,
+.satus-section--card>.satus-select,
+.satus-section--card>.satus-radio {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
-/*--------------------------------------------------------------
-# SYNTAX HIGHLIGHTING
---------------------------------------------------------------*/
-
-.satus-text-field__text>.group {
- color: #47ff47;
- background-color: rgb(71, 255, 71, .16);
+.satus-section--card>.satus-button:hover,
+.satus-section--card>.satus-switch:hover,
+.satus-section--card>.satus-select:hover,
+.satus-section--card>.satus-slider:hover,
+.satus-section--card>.satus-radio:hover {
+ background-color: var(--satus-hover);
}
-.satus-text-field__text>.character-class {
- color: #ffc247;
- background-color: rgb(255, 170, 0, .16);
+.satus-section--card>.satus-button {
+ width: 100%;
+ padding: 0 16px;
}
-.satus-text-field__text>.quantifier {
- color: #47c2ff;
- background-color: rgb(71, 194, 255, .16);
+.satus-section--card>.satus-button>svg {
+ width: 20px;
+ margin: 2px 16px 0 0;
+ color: var(--satus-primary);
}
-.satus-text-field__text>.anchor {
- color: #47c2ff;
- background-color: rgb(71, 194, 255, .16);
+.satus-section--card>.satus-span {
+ display: flex;
+ align-items: center;
+}
+/*--------------------------------------------------------------
+>>> LIST:
+--------------------------------------------------------------*/
+
+.satus-list {
+ list-style: none;
+ margin: 0;
}
-.satus-text-field__text>.metasequence {
- color: #47ff47;
- background-color: rgb(71, 255, 71, .16);
+.satus-list__item {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ min-height: 48px;
}
-.satus-text-field__text>.text {
- color: #c4c4d4;
- background-color: rgb(196, 196, 212, .16);
+.satus-list__item>*:last-child {
+ text-align: right;
}
/*--------------------------------------------------------------
>>> HEADER
@@ -1242,6 +1380,7 @@ body[theme=black] {
padding: 0 12px;
color: var(--satus-header-text);
background: var(--satus-header-background);
+ border-bottom: 1px solid var(--satus-header-border);
box-shadow: 0 0 3px rgb(0, 0, 0, .1);
align-items: center;
justify-content: space-between;
@@ -1256,255 +1395,232 @@ body[theme=black] {
border-radius: 50%;
}
-.satus-header .satus-section--align-start > * {
+.satus-header .satus-section--align-start>* {
margin-right: 8px;
}
.satus-header .satus-span--title {
font-size: 15px;
+ font-weight: 500;
overflow: hidden;
white-space: nowrap;
letter-spacing: .0125em;
text-overflow: ellipsis;
flex: 1;
-}
-
-/*--------------------------------------------------------------
->>> ALERT
---------------------------------------------------------------*/
-
-.satus-alert {
- display: flex;
- box-sizing: border-box;
- min-height: 48px;
- margin: 8px 0 0;
- padding: 8px 16px;
- border-radius: 8px;
- align-items: center;
-}
-
-.satus-alert--error {
- color: var(--satus-alert-error-color);
- border: 1px solid var(--satus-alert-error-border);
- background: var(--satus-alert-error-background);
}
/*--------------------------------------------------------------
->>> LAYERS
+# BUTTON
--------------------------------------------------------------*/
-.satus-layers {
+.satus-button {
+ font: inherit;
position: relative;
- overflow: hidden;
- color: var(--satus-layers-text);
- background: var(--satus-layers-background);
- flex: 1;
-}
-
-.satus-layer {
- position: absolute;
- top: 0;
- left: 0;
display: flex;
- overflow-y: auto;
- box-sizing: border-box;
- width: 100%;
- height: 100%;
- padding: 0 12px;
- flex-wrap: wrap;
- align-content: flex-start;
-}
-/*--------------------------------------------------------------
->>> DIVIDER
---------------------------------------------------------------*/
-
-.satus-divider {
- height: 1px;
- margin: 16px 0 12px;
- background: var(--satus-divider);
-}
-/*--------------------------------------------------------------
-# INPUT
---------------------------------------------------------------*/
-
-.satus-input[type=text],
-.satus-input[type=password] {
- font: inherit;
- box-sizing: border-box;
- width: 100%;
+ overflow: hidden;
+ height: 48px;
margin: 0;
- padding: 0 8px;
- color: var(--satus-text-field--text, inherit);
+ padding: 8px;
+ text-align: left;
+ color: var(--satus-button-text, inherit);
border: none;
- outline: none;
- background: none;
+ background: var(--satus-button-background, transparent);
appearance: none;
- font-size: 16px;
- margin: 8px 0;
- border: 1px solid var(--satus-text-field--border);
- border-radius: 4px;
- background-color: var(--satus-text-field--background);
-}
-/**/
+ align-items: center;
+}
+
+.satus-button:hover {
+ cursor: pointer;
+ background-color: var(--satus-hover);
+}
-.satus-aside {
- color: var(--satus-aside-text);
- background: var(--satus-aside-background);
- box-sizing: border-box;
+.satus-button[hidden] {
+ display: none;
+}
+
+.satus-button>svg {
+ min-width: 20px;
+}
+
+.satus-button>.satus-span--label {
+ display: block;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
}
/*--------------------------------------------------------------
->>> SELECT
+>>> MODAL
--------------------------------------------------------------*/
-.satus-select {
- position: relative;
- display: flex;
- box-sizing: border-box;
- align-items: center;
- justify-content: space-between;
+.satus-modal {
+ position: absolute;
+ z-index: 100;
+ top: 0;
+ left: 0;
+ display: flex;
+ width: 100%;
+ height: 100vh;
+ justify-content: center;
+ align-items: center;
}
-.satus-select__content {
- display: flex;
- align-items: center;
+.satus-modal__scrim {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ animation: modalFadeIn 150ms linear forwards;
+ opacity: 0;
+ background: rgba(0, 0, 0, .16);
+ backdrop-filter: blur(8px);
}
-.satus-select__content > svg {
- width: 20px;
-
- height: 18px;
- margin: 0 14px 0 0;
- opacity: .75;
+.satus-modal__surface {
+ display: flex;
+ overflow-y: auto;
+ flex-direction: column;
+ width: 95%;
+ min-width: 240px;
+ max-width: 560px;
+ max-height: 80%;
+ margin: 0 16px;
+ padding: 12px 16px;
+ transform: scale(.8);
+ animation: modalZoomIn 150ms linear forwards;
+ animation-delay: 20ms;
+ opacity: 0;
+ color: var(--satus-modal-text);
+ border-radius: 6px;
+ background-color: var(--satus-modal-background);
+ border: 1px solid var(--satus-modal-border);
+ box-shadow: 0 2px 6px rgb(0, 0, 0, .15);
+ box-sizing: border-box;
}
-.satus-select__value {
- margin-left: 16px;
- text-align: right;
- opacity: .75;
+.satus-modal__surface .satus-section--actions {
+ display: flex;
+ width: 100%;
+ margin: 8px 0 0;
+ padding: 0;
+ justify-content: flex-end;
+ align-items: center;
}
-.satus-select select {
- font: inherit;
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- margin: 0;
- padding: 0;
- padding: inherit;
- cursor: pointer;
- opacity: 0;
- color: inherit;
- border: none;
- outline: none;
- background: none;
- appearance: none;
+.satus-modal__surface .satus-section--actions .satus-button {
+ font-weight: 500;
+ height: 32px;
+ margin-left: 8px;
+ padding: 0 8px;
+ letter-spacing: .5px;
+ color: var(--satus-primary);
+ border-radius: 4px;
}
-.satus-select:hover {
- cursor: pointer;
- background-color: var(--satus-hover);
-}
-/*--------------------------------------------------------------
->>> CONTEXT MENU
---------------------------------------------------------------*/
+.satus-modal__surface .satus-section--actions .satus-button:hover {
+ background: rgba(var(--satus-contrast), .075);
+}
-.satus-modal--contextmenu .satus-modal__scrim {
- background: none;
- backdrop-filter: none;
- animation: none;
- visibility: visible;
- opacity: 1;
- transform: none;
+.satus-modal--closing .satus-modal__scrim {
+ animation: modalFadeOut 70ms linear forwards;
}
-.satus-modal--contextmenu .satus-modal__surface {
+.satus-modal--closing .satus-modal__surface {
+ animation: modalZoomOut 70ms linear forwards;
+}
+
+.satus-modal--vertical .satus-modal__surface {
position: absolute;
- margin: 0;
- box-sizing: border-box;
+ top: 8px;
+ right: 8px;
+ left: auto;
min-width: 200px;
max-width: 200px;
- padding: 4px 0;
- border-radius: 4px;
- border: 1px solid var(--satus-context-menu--border);
- box-shadow: none;
- animation: none;
- visibility: visible;
- opacity: 1;
- transform: none;
-}
-
-.satus-modal--contextmenu .satus-modal__surface > * {
-
+ margin: 0;
+ padding: 8px 0;
+ transform-origin: right top;
}
-.satus-modal--contextmenu .satus-modal__surface>* {
+.satus-modal--vertical .satus-modal__surface>.satus-button,
+.satus-modal--vertical .satus-modal__surface>.satus-switch,
+.satus-modal--vertical .satus-modal__surface>.satus-select {
display: flex;
- height: 32px;
+ height: 36px;
padding: 0 16px;
align-items: center;
}
-.satus-modal--contextmenu .satus-modal__surface .satus-button svg {
+.satus-modal--vertical .satus-modal__surface>.satus-tabs {
+ padding: 0 12px;
+}
+
+.satus-modal--vertical .satus-modal__surface>.satus-span {
+ font-size: 13px;
+ font-weight: 500;
+ margin: 6px 0;
+ padding: 0 12px;
+}
+
+.satus-modal--vertical .satus-modal__surface>.satus-button:hover,
+.satus-modal--vertical .satus-modal__surface>.satus-switch:hover,
+.satus-modal--vertical .satus-modal__surface>.satus-select:hover {
+ background-color: var(--satus-hover);
+}
+
+.satus-modal--vertical .satus-button svg {
width: 20px;
height: 18px;
margin: 0 14px 0 0;
opacity: .75;
- fill: none;
- stroke: var(--satus-primary);
flex: 0 0 20px;
}
-.satus-modal--contextmenu .satus-modal__surface .satus-button .satus-span {
+.satus-modal--vertical .satus-button .satus-span {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
-}
+}
+
+
/*--------------------------------------------------------------
->>> PLUVIAM
+# ANIMATIONS
--------------------------------------------------------------*/
-.satus-pluviam {
- position: absolute;
- transform: scale(0);
- animation-name: pluviam;
- animation-duration: 1000ms;
- opacity: var(--satus-pluviam-opacity, .08);
- border-radius: 50%;
- background: var(--satus-pluviam-background, #000);
- animation-fill-mode: forwards;
+@keyframes modalFadeIn {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
}
-@keyframes pluviam {
- 0% {
- transform: scale(0);
- opacity: var(--satus-pluviam-opacity, .08);
- }
- 70% {
- transform: scale(.8);
- opacity: var(--satus-pluviam-opacity, .08);
- }
- 100% {
- transform: scale(1);
- opacity: 0;
- }
-}
-/*--------------------------------------------------------------
->>> SORTABLE
---------------------------------------------------------------*/
+@keyframes modalFadeOut {
+ from {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ }
+}
-.satus-sortable__chosen {
- color: var(--satus-sortable-text) !important;
- background-color: var(--satus-sortable-background) !important;
+@keyframes modalZoomIn {
+ from {
+ transform: scale(.8);
+ opacity: 0;
+ }
+ to {
+ transform: scale(1);
+ opacity: 1;
+ }
}
-.satus-sortable__ghost {
- position: fixed !important;
- z-index: 999 !important;
- top: 0 !important;
- left: 0 !important;
- pointer-events: none !important;
- box-shadow: 0 1px 3px rgb(0, 0, 0, .2), 0 4px 8px rgb(0, 0, 0, .1), inset 0 0 0 1px rgb(0, 0, 0, .16);
- will-change: transform !important;
- opacity: .8 !important;
+@keyframes modalZoomOut {
+ from {
+ transform: scale(1);
+ opacity: 1;
+ }
+ to {
+ transform: scale(.8);
+ opacity: 0;
+ }
}
\ No newline at end of file
diff --git a/satus/satus.js b/ui/satus/satus.js
similarity index 85%
rename from satus/satus.js
rename to ui/satus/satus.js
index 3b7f95d..6b4d7c1 100644
--- a/satus/satus.js
+++ b/ui/satus/satus.js
@@ -196,6 +196,8 @@ satus.fetch = function (url, success, error) {
} else {
error();
}
+ }).catch(function () {
+ error(success);
});
};
@@ -254,7 +256,7 @@ satus.storage.get = function (name) {
# SET
--------------------------------------------------------------*/
-satus.storage.set = function (name, value) {
+satus.storage.set = function (name, value, callback) {
var items = {},
target = satus.storage.data;
@@ -290,10 +292,10 @@ satus.storage.set = function (name, value) {
}
if (satus.storage.attributes[name]) {
- document.body.setAttribute(name, value);
+ document.body.setAttribute('data-' + name, value);
}
- chrome.storage.local.set(items);
+ chrome.storage.local.set(items, callback);
};
@@ -312,11 +314,17 @@ satus.storage.remove = function (name) {
# IMPORT
--------------------------------------------------------------*/
-satus.storage.import = function (callback) {
- chrome.storage.local.get(function (items) {
+satus.storage.import = function (keys, callback) {
+ if (typeof keys === 'function') {
+ callback = keys;
+
+ keys = undefined;
+ }
+
+ chrome.storage.local.get(keys, function (items) {
for (var key in items) {
if (satus.storage.attributes[key]) {
- document.body.setAttribute(key, items[key]);
+ document.body.setAttribute('data-' + key, items[key]);
}
satus.storage.data[key] = items[key];
@@ -357,8 +365,8 @@ satus.locale.get = function (string) {
# IMPORT
--------------------------------------------------------------*/
-satus.locale.import = function (string, path, callback) {
- var language = string || window.navigator.language;
+satus.locale.import = function (code, path, callback) {
+ var language = code || window.navigator.language;
if (language.indexOf('en') === 0) {
language = 'en';
@@ -368,20 +376,16 @@ satus.locale.import = function (string, path, callback) {
path = '_locales/';
}
- satus.ajax(path + language + '/messages.json', function (response) {
- try {
- response = JSON.parse(response);
-
- for (var key in response) {
- satus.locale.strings[key] = response[key].message;
- }
- } catch (error) {
- console.error(error);
+ satus.fetch(chrome.runtime.getURL(path + language + '/messages.json'), function (response) {
+ for (var key in response) {
+ satus.locale.strings[key] = response[key].message;
}
callback();
}, function (success) {
- satus.ajax(path + 'en/messages.json', success);
+ satus.fetch(chrome.runtime.getURL(path + 'en/messages.json'), success, function () {
+ success();
+ });
});
};
@@ -787,897 +791,1047 @@ satus.render = function (skeleton, container, skip, property) {
return component;
};
/*--------------------------------------------------------------
->>> COLOR PICKER
+>>> COLOR:
+----------------------------------------------------------------
+# RGB to HSL
+# HUE to RGB
+# HSL to RGB
--------------------------------------------------------------*/
-satus.components.colorPicker = function (skeleton) {
- var component = document.createElement('button'),
- component_label = document.createElement('span'),
- component_value = document.createElement('span');
-
- component.inner = component_label;
- component.valueElement = component_value;
-
- component.className = 'satus-button';
- component_value.className = 'satus-color-picker__value';
-
- component.appendChild(component_label);
- component.appendChild(component_value);
+satus.color = {};
- component.addEventListener('click', function () {
- var rgb = this.rgb,
- hsl = satus.color.rgbToHsl(rgb),
- s = hsl[1] / 100,
- l = hsl[2] / 100;
- s *= l < .5 ? l : 1 - l;
+/*--------------------------------------------------------------
+# RGB TO HSL
+--------------------------------------------------------------*/
- var v = l + s;
+satus.color.rgbToHsl = function (array) {
+ var r = array[0] / 255,
+ g = array[1] / 255,
+ b = array[2] / 255,
+ min = Math.min(r, g, b),
+ max = Math.max(r, g, b),
+ h = 0,
+ s = 0,
+ l = (min + max) / 2;
- s = 2 * s / (l + s);
+ if (min === max) {
+ h = 0;
+ s = 0;
+ } else {
+ var delta = max - min;
- satus.render({
- component: 'modal',
- variant: 'color-picker',
- value: hsl,
- parent: this,
+ s = l <= 0.5 ? delta / (max + min) : delta / (2 - max - min);
- palette: {
- component: 'div',
- class: 'satus-color-picker__palette',
- style: {
- 'backgroundColor': 'hsl(' + hsl[0] + 'deg, 100%, 50%)'
- },
- on: {
- mousedown: function () {
- var palette = this,
- rect = this.getBoundingClientRect(),
- cursor = this.children[0];
+ if (max === r) {
+ h = (g - b) / delta + (g < b ? 6 : 0);
+ } else if (max === g) {
+ h = (b - r) / delta + 2;
+ } else if (max === b) {
+ h = (r - g) / delta + 4;
+ }
- function mousemove(event) {
- var hsl = palette.skeleton.parent.value,
- x = event.clientX - rect.left,
- y = event.clientY - rect.top,
- s;
+ h /= 6;
+ }
- x = Math.min(Math.max(x, 0), rect.width) / (rect.width / 100);
- y = Math.min(Math.max(y, 0), rect.height) / (rect.height / 100);
+ h *= 360;
+ s *= 100;
+ l *= 100;
- var v = 100 - y,
- l = (2 - x / 100) * v / 2;
+ if (array.length === 3) {
+ return [h, s, l];
+ } else {
+ return [h, s, l, array[3]];
+ }
+};
- hsl[1] = x * v / (l < 50 ? l * 2 : 200 - l * 2);
- hsl[2] = l;
- cursor.style.left = x + '%';
- cursor.style.top = y + '%';
+/*--------------------------------------------------------------
+# HUE TO RGB
+--------------------------------------------------------------*/
- palette.nextSibling.children[0].style.backgroundColor = 'hsl(' + hsl[0] + 'deg,' + hsl[1] + '%, ' + hsl[2] + '%)';
+satus.color.hueToRgb = function (array) {
+ var t1 = array[0],
+ t2 = array[1],
+ hue = array[2];
- event.preventDefault();
- }
+ if (hue < 0) {
+ hue += 6;
+ }
- function mouseup() {
- window.removeEventListener('mousemove', mousemove);
- window.removeEventListener('mouseup', mouseup);
- }
+ if (hue >= 6) {
+ hue -= 6;
+ }
- window.addEventListener('mousemove', mousemove);
- window.addEventListener('mouseup', mouseup);
- }
- },
+ if (hue < 1) {
+ return (t2 - t1) * hue + t1;
+ } else if (hue < 3) {
+ return t2;
+ } else if (hue < 4) {
+ return (t2 - t1) * (4 - hue) + t1;
+ } else {
+ return t1;
+ }
+};
- cursor: {
- component: 'div',
- class: 'satus-color-picker__cursor',
- style: {
- 'left': s * 100 + '%',
- 'top': 100 - v * 100 + '%'
- }
- }
- },
- section: {
- component: 'section',
- variant: 'color',
- color: {
- component: 'div',
- class: 'satus-color-picker__color',
- style: {
- 'backgroundColor': 'rgb(' + this.rgb.join(',') + ')'
- }
- },
- hue: {
- component: 'slider',
- class: 'satus-color-picker__hue',
- storage: false,
- value: hsl[0],
- max: 360,
- on: {
- change: function () {
- var modal = this.skeleton.parent.parent,
- hsl = modal.value;
+/*--------------------------------------------------------------
+# HSL TO RGB
+--------------------------------------------------------------*/
- hsl[0] = this.values[0];
+satus.color.hslToRgb = function (array) {
+ var h = array[0] / 360,
+ s = array[1] / 100,
+ l = array[2] / 100,
+ r, g, b;
- this.previousSibling.style.backgroundColor = 'hsl(' + hsl[0] + 'deg,' + hsl[1] + '%, ' + hsl[2] + '%)';
- this.parentNode.previousSibling.style.backgroundColor = 'hsl(' + hsl[0] + 'deg, 100%, 50%)';
- }
- }
- }
- },
- actions: {
- component: 'section',
- variant: 'actions',
+ if (s == 0) {
+ r = g = b = l;
+ } else {
+ var hue2rgb = function hue2rgb(p, q, t) {
+ if (t < 0) t += 1;
+ if (t > 1) t -= 1;
+ if (t < 1 / 6) return p + (q - p) * 6 * t;
+ if (t < 1 / 2) return q;
+ if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
+ return p;
+ }
- reset: {
- component: 'button',
- text: 'reset',
- on: {
- click: function () {
- var modal = this.skeleton.parent.parent,
- component = modal.parent;
+ var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+ var p = 2 * l - q;
+ r = hue2rgb(p, q, h + 1 / 3);
+ g = hue2rgb(p, q, h);
+ b = hue2rgb(p, q, h - 1 / 3);
+ }
- component.rgb = component.skeleton.value;
+ return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
+};
+/*--------------------------------------------------------------
+>>> PLUVIAM
+--------------------------------------------------------------*/
- component.storageValue = component.rgb;
- component.storageChange();
+satus.events.add('render', function (component, skeleton) {
+ if (skeleton.pluviam === true) {
+ function createPluviam(event) {
+ var pluviam = document.createElement('span'),
+ rect = this.getBoundingClientRect(),
+ x = event.clientX - rect.left,
+ y = event.clientY - rect.top,
+ diameter = Math.sqrt(Math.pow(rect.width * 2, 2) + Math.pow(rect.height * 2, 2));
- component.valueElement.style.backgroundColor = 'rgb(' + component.rgb.join(',') + ')';
+ pluviam.className = 'satus-pluviam';
- modal.rendered.close();
- }
- }
- },
- cancel: {
- component: 'button',
- text: 'cancel',
- on: {
- click: function () {
- this.skeleton.parent.parent.rendered.close();
- }
- }
- },
- ok: {
- component: 'button',
- text: 'OK',
- on: {
- click: function () {
- var modal = this.skeleton.parent.parent,
- component = modal.parent;
+ pluviam.style.left = x - diameter / 2 + 'px';
+ pluviam.style.top = y - diameter / 2 + 'px';
+ pluviam.style.width = diameter + 'px';
+ pluviam.style.height = diameter + 'px';
- component.rgb = satus.color.hslToRgb(modal.value);
+ this.appendChild(pluviam);
- component.storageValue = component.rgb;
- component.storageChange();
+ setTimeout(function () {
+ pluviam.remove();
+ }, 1000);
+ }
- component.valueElement.style.backgroundColor = 'rgb(' + component.rgb.join(',') + ')';
+ component.addEventListener('mousedown', createPluviam);
+ component.addEventListener('mouseover', createPluviam);
+ }
+});
+/*--------------------------------------------------------------
+>>> EXTENSION STORAGE
+--------------------------------------------------------------*/
+/*--------------------------------------------------------------
+>>> INDEXEDDB:
+----------------------------------------------------------------
+# Global variable
+# Methods
+ # Open
+ # Get
+ # Get by key
+ # Set
+ # Clear
+ # Delete
+ # Search
+--------------------------------------------------------------*/
- modal.rendered.close();
- }
- }
- }
- }
- });
- });
+/*--------------------------------------------------------------
+# GLOBAL VARIABLE
+--------------------------------------------------------------*/
- component.addEventListener('render', function () {
- component.rgb = this.storageValue || [0, 100, 50];
+satus.indexeddb = {
+ request: null
+};
- component_value.style.backgroundColor = 'rgb(' + component.rgb.join(',') + ')';
- });
- return component;
-};
/*--------------------------------------------------------------
->>> TABS
+# METHODS
--------------------------------------------------------------*/
-satus.components.tabs = function (skeleton) {
- var component = document.createElement('div'),
- content = document.createElement('div'),
- selection = document.createElement('div');
+/*--------------------------------------------------------------
+# OPEN
+----------------------------------------------------------------
+satus.indexeddb.open('rootCellar', {
+ fruits: {
+ indexes: [
+ 'id',
+ 'name',
+ 'amount',
+ ...
+ ],
+ keyOptions: {
+ keyPath: 'id',
+ autoIncrement: true
+ }
+ },
+ ...
+}, function () { ... });
+--------------------------------------------------------------*/
- content.className = 'satus-tabs__content';
- selection.className = 'satus-tabs__selection';
- selection.style.width = 100 / skeleton.items.length + '%';
+satus.indexeddb.open = function (name, objects, callback) {
+ var request = indexedDB.open(name);
- content.appendChild(selection);
+ request.onerror = function (event) {
+ callback();
+ };
- component.selection = selection;
+ request.onblocked = function(event) {
+ satus.indexeddb.open(callback);
+ };
- for (var i = 0, l = skeleton.items.length; i < l; i++) {
- var item = skeleton.items[i],
- button = document.createElement('button');
+ request.onsuccess = function (event) {
+ satus.indexeddb.request = this.result;
- button.className = 'satus-tabs__button';
- button.value = item;
- button.style.width = 100 / l + '%';
+ callback();
+ };
- satus.text(button, item);
+ request.onupgradeneeded = function (event) {
+ satus.indexeddb.request = this.result;
- button.addEventListener('click', function () {
- var component = this.parentNode.parentNode;
+ for (var key in objects) {
+ var object = objects[key];
- component.selection.style.left = 100 / (this.parentNode.children.length - 1) * (satus.indexOf(this) - 1) + '%';
+ if (!this.result.objectStoreNames.contains(key)) {
+ var object_store = this.result.createObjectStore(key, object.keyOptions);
- component.storageValue = this.value;
- component.storageChange();
- });
+ for (var i = 0, l = object.indexes.length; i < l; i++) {
+ var name = object.indexes[i];
- if (skeleton.value === item) {
- selection.style.left = i * 50 + '%';
+ object_store.createIndex(name, name);
+ }
+ }
}
- content.appendChild(button);
- }
-
- component.appendChild(content);
-
- component.addEventListener('render', function () {
- var index = satus.indexOf(this.storageValue, this.skeleton.items);
+ this.result.onversionchange = function (event) {
+ satus.indexeddb.close();
- if (index === -1) {
- index = 0;
- }
+ satus.indexeddb.open(callback);
+ };
+ };
+};
- this.selection.style.left = 100 / this.skeleton.items.length * index + '%';
- });
- return component;
-};
/*--------------------------------------------------------------
->>> MENUBAR
+# GET
+----------------------------------------------------------------
+satus.indexeddb.get({
+ fruits: {
+ direction: 'next',
+ index: 'name',
+ offset: 0,
+ limit: 100
+ },
+ ...
+}, function (result) { ... });
--------------------------------------------------------------*/
-satus.components.menubar = function (skeleton) {
- var component = document.createElement('ul');
+satus.indexeddb.get = function (items, callback) {
+ var queue = [],
+ results = {};
- if (skeleton.items) {
- for (var i = 0, l = skeleton.items.length; i < l; i++) {
- var item = skeleton.items[i],
- li = document.createElement('li');
+ for (var key in items) {
+ var item = items[key];
+
+ queue.push({
+ name: key,
+ direction: item.direction,
+ index: item.index,
+ offset: item.offset
+ });
+ }
- if (Array.isArray(item) === true) {
- var ul = document.createElement('ul');
+ function handle() {
+ var item = queue[0],
+ transaction = satus.indexeddb.request.transaction(item.name, 'readonly'),
+ object_store = transaction.objectStore(item.name),
+ object_result = [],
+ offset = item.offset || 0,
+ limit = item.limit || 100;
- satus.render(item[0], li);
+ if (item.index) {
+ object_store = object_store.index(item.index);
+ }
- for (var j = 1, k = item.length; j < k; j++) {
- var li2 = document.createElement('li');
+ results[item.name] = object_result;
- satus.render(item[j], li2);
+ object_store.openCursor(null, item.direction).onsuccess = function(event) {
+ var cursor = event.target.result;
- ul.appendChild(li2);
- }
+ if (cursor) {
+ if (item.offset > 0) {
+ cursor.advance(item.offset);
- li.appendChild(ul);
+ item.offset = 0;
+ } else if (object_result.length < limit) {
+ object_result.push(cursor.value);
+
+ cursor.continue();
+ }
} else {
- satus.render(item, li);
- }
+ object_store.count().onsuccess = function(event) {
+ object_result.fullLength = event.target.result;
- component.appendChild(li);
- }
+ queue.shift();
+
+ if (queue.length === 0) {
+ callback(results);
+ } else {
+ handle();
+ }
+ };
+ }
+ };
}
- return component;
-};
+ handle();
+};
+
+
/*--------------------------------------------------------------
->>> RADIO
+# GET BY KEY
+----------------------------------------------------------------
+satus.indexeddb.getByKey({
+ fruits: [1],
+ ...
+}, function (result) { ... });
--------------------------------------------------------------*/
-satus.components.radio = function (skeleton) {
- var component = document.createElement('label'),
- content = document.createElement('span'),
- radio = document.createElement('input');
+satus.indexeddb.getByKey = function (items, callback) {
+ var queue = [],
+ results = {};
- component.inner = content;
+ for (var name in items) {
+ queue.push({
+ name: name,
+ keys: items[name]
+ });
+ }
- radio.type = 'radio';
+ function handle() {
+ var item = queue[0],
+ transaction = satus.indexeddb.request.transaction(item.name, 'readonly'),
+ object_store = transaction.objectStore(item.name),
+ object_result = [];
- if (skeleton.group) {
- component.storage = skeleton.group;
- radio.name = skeleton.group;
- }
+ results[item.name] = object_result;
- if (skeleton.value) {
- radio.value = skeleton.value;
- }
+ for (var i = 0, l = item.keys.length; i < l; i++) {
+ var key = item.keys[i];
- component.addEventListener('render', function () {
- this.storageValue = satus.storage.get(this.storage);
+ object_store.get(key).onsuccess = function(event) {
+ var result = event.target.result;
- if (satus.isset(this.storageValue)) {
- radio.checked = this.storageValue === skeleton.value;
- } else if (skeleton.checked) {
- radio.checked = true;
+ if (result) {
+ object_result.push(result);
+ }
+
+ object_store.count().onsuccess = function(event) {
+ object_result.fullLength = event.target.result;
+
+ queue.shift();
+
+ if (queue.length === 0) {
+ callback(results);
+ } else {
+ handle();
+ }
+ };
+ };
}
- });
+ }
- radio.addEventListener('change', function () {
- component.storageValue = this.value;
- component.storageChange();
- });
+ handle();
+};
- component.appendChild(content);
- component.appendChild(radio);
- return component;
-};
/*--------------------------------------------------------------
->>> LIST
+# SET
+----------------------------------------------------------------
+satus.indexeddb.set({
+ fruits: [
+ { name: 'apple', amount: 500 },
+ ...
+ ],
+ ...
+}, function () { ... });
--------------------------------------------------------------*/
-satus.components.list = function (skeleton) {
- var ul = document.createElement('ul');
+satus.indexeddb.set = function (items, callback) {
+ var threads = 0;
- for (var i = 0, l = skeleton.items.length; i < l; i++) {
- var li = document.createElement('li'),
- item = skeleton.items[i];
+ for (var name in items) {
+ var item = items[name],
+ transaction = this.request.transaction(name, 'readwrite'),
+ object_store = transaction.objectStore(name);
- li.className = 'satus-list__item';
+ for (var i = 0, l = item.length; i < l; i++) {
+ var request = object_store.put(item[i]);
- for (var j = 0, k = item.length; j < k; j++) {
- var child = item[j];
+ threads++;
- if (typeof child === 'string') {
- var span = document.createElement('span');
+ request.onsuccess = function () {
+ threads--;
- span.textContent = satus.locale.get(child);
+ if (callback && threads === 0) {
+ callback();
+ }
+ };
- li.appendChild(span);
- } else {
- satus.render(child, li);
- }
- }
+ request.onerror = function () {
+ threads--;
- ul.appendChild(li);
+ if (callback && threads === 0) {
+ callback();
+ }
+ };
+ }
}
+};
+
- return ul;
-};
/*--------------------------------------------------------------
->>> MODAL
+# CLEAR
+----------------------------------------------------------------
+satus.indexeddb.clear(['fruits'], function (result) { ... });
--------------------------------------------------------------*/
-satus.components.modal = function (skeleton) {
- var component = document.createElement('div'),
- scrim = document.createElement('div'),
- surface = document.createElement('div');
-
- component.inner = surface;
+satus.indexeddb.clear = function (items) {
+ if (typeof items === 'string') {
+ items = [items];
+ }
- scrim.className = 'satus-modal__scrim';
- surface.className = 'satus-modal__surface';
+ for (var i = 0, l = items.length; i < l; i++) {
+ var name = items[i],
+ transaction = satus.indexeddb.request.transaction(name, 'readwrite'),
+ object_store = transaction.objectStore(name);
- component.close = function () {
- var component = this,
- component_surface = this.children[1];
+ object_store.clear();
+ }
+};
- this.classList.add('satus-modal--closing');
- setTimeout(function () {
- component.remove();
+/*--------------------------------------------------------------
+# DELETE
+----------------------------------------------------------------
+satus.indexeddb.delete({
+ fruits: {
+ name: [
+ 'apple'
+ ]
+ }
+});
+--------------------------------------------------------------*/
- component.dispatchEvent(new CustomEvent('close'));
- }, satus.getAnimationDuration(component_surface));
- };
+satus.indexeddb.delete = function (stores, callback) {
+ var queue = [];
- scrim.addEventListener('click', function () {
- this.parentNode.close();
- });
+ for (var name in stores) {
+ var store = stores[name];
- component.appendChild(scrim);
- component.appendChild(surface);
+ for (var index in store) {
+ queue.push({
+ object_store_name: name,
+ index_name: index,
+ keys: store[index]
+ });
+ }
+ }
- return component;
-};
-/*--------------------------------------------------------------
->>> CHECKBOX
---------------------------------------------------------------*/
+ function handle() {
+ var item = queue[0],
+ transaction = satus.indexeddb.request.transaction(item.object_store_name, 'readwrite'),
+ object_store = transaction.objectStore(item.object_store_name),
+ object_result = [];
-satus.components.checkbox = function (skeleton) {
- var component = document.createElement('button'),
- content = document.createElement('span');
+ if (item.index_name) {
+ object_store = object_store.index(item.index_name);
+ }
- component.inner = content;
+ object_store.openCursor(null, item.direction).onsuccess = function(event) {
+ var cursor = event.target.result;
- content.className = 'satus-checkbox__content';
+ if (cursor) {
+ cursor.delete();
+ }
- component.appendChild(content);
+ queue.shift();
- component.addEventListener('click', function () {
- if (this.dataset.value === 'true') {
- this.storageValue = false;
- this.dataset.value = 'false';
- } else {
- this.storageValue = true;
- this.dataset.value = 'true';
- }
+ if (queue.length === 0) {
+ callback();
+ } else {
+ handle();
+ }
+ };
+ }
- this.storageChange();
- });
+ handle();
+};
- component.addEventListener('render', function () {
- this.dataset.value = this.storageValue;
- });
- return component;
-};
/*--------------------------------------------------------------
->>> SWITCH
+# SEARCH
+----------------------------------------------------------------
+satus.indexeddb.search({
+ fruits: {
+ query: 'apple', // or function () { ... }
+ direction: 'next',
+ index: 'name',
+ offset: 0,
+ limit: 0
+ },
+ ...
+}, function () { ... });
--------------------------------------------------------------*/
-satus.components.switch = function (skeleton) {
- var component = document.createElement('button'),
- component_content = document.createElement('span'),
- component_thumb = document.createElement('i');
+satus.indexeddb.search = function (items, callback) {
+ var queue = [],
+ results = {};
- component.inner = component_content;
+ for (var key in items) {
+ var item = items[key];
- component_content.className = 'satus-switch__content';
+ queue.push({
+ name: key,
+ direction: item.direction,
+ index: item.index,
+ offset: item.offset
+ });
+ }
- component.addEventListener('click', function () {
- if (this.dataset.value === 'true') {
- this.storageValue = false;
- this.dataset.value = 'false';
- } else {
- this.storageValue = true;
- this.dataset.value = 'true';
+ function handle() {
+ var item = queue[0],
+ transaction = satus.indexeddb.request.transaction(item.name, 'readonly'),
+ object_store = transaction.objectStore(item.name),
+ object_result = [],
+ offset = item.offset || 0,
+ limit = item.limit || 100;
+
+ if (item.index) {
+ object_store = object_store.index(item.index);
}
- this.storageChange();
- });
+ results[item.name] = object_result;
- component.addEventListener('render', function () {
- this.dataset.value = this.storageValue;
- });
+ object_store.openCursor(null, item.direction).onsuccess = function(event) {
+ var cursor = event.target.result;
- component.appendChild(component_content);
- component.appendChild(component_thumb);
+ if (cursor) {
+ if (item.offset > 0) {
+ cursor.advance(item.offset);
- return component;
-};
-/*--------------------------------------------------------------
->>> SLIDER
---------------------------------------------------------------*/
+ item.offset = 0;
+ } else if (limit && object_result.length < limit) {
+ object_result.push(cursor.value);
-satus.components.slider = function (skeleton) {
- var component = document.createElement('div'),
- content = document.createElement('div'),
- container = document.createElement('div'),
- track = document.createElement('div'),
- track_fill = document.createElement('div');
+ cursor.continue();
+ }
+ } else {
+ object_store.count().onsuccess = function(event) {
+ object_result.fullLength = event.target.result;
- container.className = 'satus-slider__container';
- track.className = 'satus-slider__track';
- track_fill.className = 'satus-slider__track-fill';
+ queue.shift();
- component.min = skeleton.min || 0;
- component.max = skeleton.max || 1;
- component.step = (skeleton.step || 1);
- component.percent = 100 / ((component.max - component.min) / component.step);
- component.precision = String(component.step).replace(/[0-9]./, '').length;
+ if (queue.length === 0) {
+ callback(results);
+ } else {
+ handle();
+ }
+ };
+ }
+ };
+ }
- component.container = container;
- component.track = track_fill;
- component.handles = [];
- component.inner = content;
+ handle();
+};
+/*--------------------------------------------------------------
+>>> SORTABLE
+--------------------------------------------------------------*/
- component.toPercent = function (number) {
- return number / this.step * this.percent + '%';
- };
+satus.events.add('render', function (component, skeleton) {
+ if (skeleton.sortable === true) {
+ component.addEventListener('mousedown', function (event) {
+ if (event.button !== 0) {
+ return false;
+ }
- component.createHandle = function (index) {
- var handle = document.createElement('div');
+ var component = this,
+ rect = this.getBoundingClientRect(),
+ x = event.clientX,
+ y = event.clientY,
+ offset_x = event.clientX - rect.left,
+ offset_y = event.clientY - rect.top,
+ ghost = satus.clone(this),
+ children = this.parentNode.children,
+ appended = false;
- handle.className = 'satus-slider__handle';
- handle.handleIndex = index;
- handle.tabIndex = 0;
+ ghost.classList.add('satus-sortable__ghost');
- this.handles.push(handle);
+ function mousemove(event) {
+ if (appended === false && (Math.abs(event.clientX - x) > 4 || Math.abs(event.clientY - y) > 4)) {
+ appended = true;
- this.container.appendChild(handle);
- };
+ component.classList.add('satus-sortable__chosen');
- component.update = function () {
- if (this.values.length > 1) {
- var min = Math.min.apply(null, this.values) - this.min,
- max = Math.max.apply(null, this.values) - this.min;
+ component.parentNode.appendChild(ghost);
+ }
- this.track.style.left = this.toPercent(min);
- this.track.style.width = this.toPercent(max - min);
+ ghost.style.transform = 'translate(' + (event.clientX - offset_x) + 'px, ' + (event.clientY - offset_y) + 'px)';
+ }
- for (var i = 0, l = this.handles.length; i < l; i++) {
- var handle = this.handles[i],
- value = this.values[i];
+ function mouseup(event) {
+ component.classList.remove('satus-sortable__chosen');
+ ghost.remove();
- handle.style.left = this.toPercent(value - this.min);
- handle.dataset.value = value;
- }
- } else {
- var value = this.values[0];
+ window.removeEventListener('mousemove', mousemove, true);
+ window.removeEventListener('mouseup', mouseup, true);
- this.track.style.width = this.toPercent(value - this.min);
- this.handles[0].style.left = this.toPercent(value - this.min);
- this.handles[0].dataset.value = value;
- }
- };
+ for (var i = 0, l = children.length; i < l; i++) {
+ var child = children[i];
- component.appendChild(content);
- track.appendChild(track_fill);
- container.appendChild(track);
- component.appendChild(container);
+ if (child !== component) {
+ child.removeEventListener('mouseover', siblingMouseOver);
+ }
+ }
- component.addEventListener('keydown', function (event) {
- var code = event.keyCode;
+ component.dispatchEvent(new CustomEvent('sort'));
- console.log(code);
- });
+ event.stopPropagation();
- component.addEventListener('render', function () {
- var value = this.storageValue;
+ return false;
+ }
- if (satus.isArray(value)) {
- this.values = value;
- } else if (satus.isNumber(value)) {
- this.values = [value];
- } else {
- this.values = this.skeleton.values || [satus.isset(this.skeleton.value) ? this.skeleton.value : 1];
- }
+ window.addEventListener('mousemove', mousemove, {
+ passive: true,
+ capture: true
+ });
- for (var i = 0, l = this.values.length; i < l; i++) {
- this.createHandle(i);
- }
+ window.addEventListener('mouseup', mouseup, {
+ passive: true,
+ capture: true
+ });
- this.update();
- });
+ function siblingMouseOver(event) {
+ var target = event.target,
+ parent = target.parentNode,
+ y = event.layerY / (target.offsetHeight / 100);
- container.addEventListener('mousedown', function (event) {
- if (event.button === 0) {
- var component = this.parentNode,
- rect = this.getBoundingClientRect(),
- cursor_x = event.clientX - rect.left,
- percent = cursor_x / rect.width * 100,
- steps = percent / component.percent * component.step + component.min,
- closest_value = component.values.indexOf(component.values.reduce(function(previous, current, index) {
- return Math.abs(current - steps) < Math.abs(previous - steps) ? current : previous;
- })),
- handle_index = component.handles[closest_value].handleIndex;
+ if (y < 50 && target.previousSibling !== component || y >= 50 && target.nextSibling === component) {
+ parent.insertBefore(component, target);
+ } else {
+ parent.insertBefore(component, target.nextSibling);
+ }
+ }
- setTimeout(function () {
- component.handles[closest_value].focus();
- });
+ for (var i = 0, l = children.length; i < l; i++) {
+ var child = children[i];
- function update(event) {
- var cursor_x = Math.min(Math.max(event.clientX - rect.left, 0), rect.width),
- percent = cursor_x / rect.width * 100,
- value = percent / component.percent * component.step + component.min;
+ if (child !== component) {
+ child.addEventListener('mouseover', siblingMouseOver);
+ }
+ }
- value = (Math.round(value / component.step) * component.step);
+ event.stopPropagation();
+ event.preventDefault();
- value = Number(value.toFixed(component.precision));
+ return false;
+ });
+ }
+});
+/*--------------------------------------------------------------
+>>> USER
+--------------------------------------------------------------*/
- if (component.values[handle_index] !== value) {
- component.values[handle_index] = value;
+satus.user = function () {
+ /*--------------------------------------------------------------
+ 1.0 VARIABLES
+ --------------------------------------------------------------*/
- component.storageValue = component.values.length === 1 ? component.values[0] : component.values;
- component.value = component.storageValue;
+ var user_agent = navigator.userAgent,
+ random_cookie = 'ta{t`nX6cMXK,Wsc',
+ video = document.createElement('video'),
+ video_formats = {
+ ogg: 'video/ogg; codecs="theora"',
+ h264: 'video/mp4; codecs="avc1.42E01E"',
+ webm: 'video/webm; codecs="vp8, vorbis"',
+ vp9: 'video/webm; codecs="vp9"',
+ hls: 'application/x-mpegURL; codecs="avc1.42E01E"'
+ },
+ audio = document.createElement('audio'),
+ audio_formats = {
+ mp3: 'audio/mpeg',
+ mp4: 'audio/mp4',
+ aif: 'audio/x-aiff'
+ },
+ cvs = document.createElement('canvas'),
+ ctx = cvs.getContext('webgl'),
+ data = {
+ browser: {
+ audio: null,
+ cookies: null,
+ flash: null,
+ java: null,
+ languages: null,
+ name: null,
+ platform: null,
+ version: null,
+ video: null,
+ webgl: null
+ },
+ os: {
+ name: null,
+ type: null
+ },
+ device: {
+ connection: {
+ type: null,
+ speed: null
+ },
+ cores: null,
+ gpu: null,
+ max_touch_points: null,
+ ram: null,
+ screen: null,
+ touch: null
+ }
+ };
- component.storageChange();
- }
- component.update();
- }
+ /*--------------------------------------------------------------
+ 2.0 SOFTWARE
+ --------------------------------------------------------------*/
- function mousemove(event) {
- update(event);
- }
+ /*--------------------------------------------------------------
+ 2.1.0 OS
+ --------------------------------------------------------------*/
- function mouseup(event) {
- window.removeEventListener('mousemove', mousemove);
- window.removeEventListener('mouseup', mouseup);
- };
+ /*--------------------------------------------------------------
+ 2.1.1 NAME
+ --------------------------------------------------------------*/
- window.addEventListener('mousemove', mousemove);
- window.addEventListener('mouseup', mouseup);
+ if (navigator.appVersion.indexOf('Win') !== -1) {
+ if (navigator.appVersion.match(/(Windows 10.0|Windows NT 10.0)/)) {
+ data.os.name = 'Windows 10';
+ } else if (navigator.appVersion.match(/(Windows 8.1|Windows NT 6.3)/)) {
+ data.os.name = 'Windows 8.1';
+ } else if (navigator.appVersion.match(/(Windows 8|Windows NT 6.2)/)) {
+ data.os.name = 'Windows 8';
+ } else if (navigator.appVersion.match(/(Windows 7|Windows NT 6.1)/)) {
+ data.os.name = 'Windows 7';
+ } else if (navigator.appVersion.match(/(Windows NT 6.0)/)) {
+ data.os.name = 'Windows Vista';
+ } else if (navigator.appVersion.match(/(Windows NT 5.1|Windows XP)/)) {
+ data.os.name = 'Windows XP';
+ } else {
+ data.os.name = 'Windows';
+ }
+ } else if (navigator.appVersion.indexOf('(iPhone|iPad|iPod)') !== -1) {
+ data.os.name = 'iOS';
+ } else if (navigator.appVersion.indexOf('Mac') !== -1) {
+ data.os.name = 'macOS';
+ } else if (navigator.appVersion.indexOf('Android') !== -1) {
+ data.os.name = 'Android';
+ } else if (navigator.appVersion.indexOf('OpenBSD') !== -1) {
+ data.os.name = 'OpenBSD';
+ } else if (navigator.appVersion.indexOf('SunOS') !== -1) {
+ data.os.name = 'SunOS';
+ } else if (navigator.appVersion.indexOf('Linux') !== -1) {
+ data.os.name = 'Linux';
+ } else if (navigator.appVersion.indexOf('X11') !== -1) {
+ data.os.name = 'UNIX';
+ }
- update(event);
+ /*--------------------------------------------------------------
+ 2.1.2 TYPE
+ --------------------------------------------------------------*/
- return true;
- }
- });
+ if (navigator.appVersion.match(/(Win64|x64|x86_64|WOW64)/)) {
+ data.os.type = '64-bit';
+ } else {
+ data.os.type = '32-bit';
+ }
- return component;
-};
-/*--------------------------------------------------------------
->>> SHORTCUT
---------------------------------------------------------------*/
-satus.components.shortcut = function (skeleton) {
- var component = document.createElement('button'),
- content = document.createElement('span'),
- value = document.createElement('div');
+ /*--------------------------------------------------------------
+ 2.2.0 BROWSER
+ --------------------------------------------------------------*/
- component.inner = content;
+ /*--------------------------------------------------------------
+ 2.2.1 NAME
+ --------------------------------------------------------------*/
- component.className = 'satus-button';
- value.className = 'satus-shortcut__value';
+ if (user_agent.indexOf('Opera') !== -1) {
+ data.browser.name = 'Opera';
+ } else if (user_agent.indexOf('Vivaldi') !== -1) {
+ data.browser.name = 'Vivaldi';
+ } else if (user_agent.indexOf('Edge') !== -1) {
+ data.browser.name = 'Edge';
+ } else if (user_agent.indexOf('Chrome') !== -1) {
+ data.browser.name = 'Chrome';
+ } else if (user_agent.indexOf('Safari') !== -1) {
+ data.browser.name = 'Safari';
+ } else if (user_agent.indexOf('Firefox') !== -1) {
+ data.browser.name = 'Firefox';
+ } else if (user_agent.indexOf('MSIE') !== -1) {
+ data.browser.name = 'IE';
+ }
- component.render = function (parent) {
- var self = this,
- parent = parent || self.primary,
- children = parent.children;
- satus.empty(parent);
+ /*--------------------------------------------------------------
+ 2.2.2 VERSION
+ --------------------------------------------------------------*/
- function createElement(name) {
- var element = document.createElement('div');
+ var browser_version = user_agent.match(new RegExp(data.browser.name + '/([0-9.]+)'));
- element.className = 'satus-shortcut__' + name;
+ if (browser_version[1]) {
+ data.browser.version = browser_version[1];
+ }
- parent.appendChild(element);
- return element;
- }
+ /*--------------------------------------------------------------
+ 2.2.3 PLATFORM
+ --------------------------------------------------------------*/
- if (this.data.alt) {
- createElement('key').textContent = 'Alt';
- }
+ data.browser.platform = navigator.platform || null;
- if (this.data.ctrl) {
- if (children.length && children[children.length - 1].className.indexOf('key') !== -1) {
- createElement('plus');
- }
- createElement('key').textContent = 'Ctrl';
- }
+ /*--------------------------------------------------------------
+ 2.2.4 LANGUAGES
+ --------------------------------------------------------------*/
- if (this.data.shift) {
- if (children.length && children[children.length - 1].className.indexOf('key') !== -1) {
- createElement('plus');
- }
+ data.browser.languages = navigator.languages || null;
- createElement('key').textContent = 'Shift';
+
+ /*--------------------------------------------------------------
+ 2.2.5 COOKIES
+ --------------------------------------------------------------*/
+
+ if (document.cookie) {
+ document.cookie = random_cookie;
+
+ if (document.cookie.indexOf(random_cookie) !== -1) {
+ data.browser.cookies = true;
}
+ }
- for (var code in this.data.keys) {
- var key = this.data.keys[code].key,
- arrows = ['ArrowUp', 'ArrowRight', 'ArrowDown', 'ArrowLeft'],
- index = arrows.indexOf(key);
- if (children.length && children[children.length - 1].className.indexOf('key') !== -1) {
- createElement('plus');
- }
+ /*--------------------------------------------------------------
+ 2.2.6 FLASH
+ --------------------------------------------------------------*/
- if (index !== -1) {
- createElement('key').textContent = ['↑', '→', '↓', '←'][index];
- } else if (key === ' ') {
- createElement('key').textContent = '␣';
- } else {
- createElement('key').textContent = key.toUpperCase();
- }
+ try {
+ if (new ActiveXObject('ShockwaveFlash.ShockwaveFlash')) {
+ data.browser.flash = true;
+ }
+ } catch (e) {
+ if (navigator.mimeTypes['application/x-shockwave-flash']) {
+ data.browser.flash = true;
}
+ }
- if (this.data.wheel) {
- if (children.length && children[children.length - 1].className.indexOf('key') !== -1) {
- createElement('plus');
- }
- var mouse = createElement('mouse'),
- div = document.createElement('div');
+ /*--------------------------------------------------------------
+ 2.2.7 JAVA
+ --------------------------------------------------------------*/
- mouse.appendChild(div);
+ if (typeof navigator.javaEnabled === 'function' && navigator.javaEnabled()) {
+ data.browser.java = true;
+ }
- mouse.className += ' ' + (this.data.wheel > 0);
- }
- if (this.data.click) {
- if (children.length && children[children.length - 1].className.indexOf('key') !== -1) {
- createElement('plus');
- }
+ /*--------------------------------------------------------------
+ 2.2.8 VIDEO FORMATS
+ --------------------------------------------------------------*/
- var mouse = createElement('mouse'),
- div = document.createElement('div');
+ if (typeof video.canPlayType === 'function') {
+ data.browser.video = {};
- mouse.appendChild(div);
+ for (var i in video_formats) {
+ var can_play_type = video.canPlayType(video_formats[i]);
- mouse.className += ' click';
+ if (can_play_type === '') {
+ data.browser.video[i] = false;
+ } else {
+ data.browser.video[i] = can_play_type;
+ }
}
+ }
- if (this.data.context) {
- if (children.length && children[children.length - 1].className.indexOf('key') !== -1) {
- createElement('plus');
- }
- var mouse = createElement('mouse'),
- div = document.createElement('div');
+ /*--------------------------------------------------------------
+ 2.2.9 AUDIO FORMATS
+ --------------------------------------------------------------*/
- mouse.appendChild(div);
+ if (typeof audio.canPlayType === 'function') {
+ data.browser.audio = {};
- mouse.className += ' context';
+ for (var i in audio_formats) {
+ var can_play_type = audio.canPlayType(audio_formats[i]);
+
+ if (can_play_type == '') {
+ data.browser.audio[i] = false;
+ } else {
+ data.browser.audio[i] = can_play_type;
+ }
}
- };
+ }
- component.valueElement = value;
- component.appendChild(content);
- component.appendChild(value);
+ /*--------------------------------------------------------------
+ 2.2.10 WEBGL
+ --------------------------------------------------------------*/
- component.keydown = function (event) {
- event.preventDefault();
- event.stopPropagation();
+ if (ctx && ctx instanceof WebGLRenderingContext) {
+ data.browser.webgl = true;
+ }
- component.data = {
- alt: event.altKey,
- ctrl: event.ctrlKey,
- shift: event.shiftKey,
- keys: {}
- };
- if (['control', 'alt', 'altgraph', 'shift'].indexOf(event.key.toLowerCase()) === -1) {
- component.data.keys[event.keyCode] = {
- code: event.code,
- key: event.key
- };
- }
+ /*--------------------------------------------------------------
+ 3.0 HARDWARE
+ --------------------------------------------------------------*/
- component.data.wheel = 0;
+ /*--------------------------------------------------------------
+ 3.1 SCREEN
+ --------------------------------------------------------------*/
- component.render();
+ if (screen) {
+ data.device.screen = screen.width + 'x' + screen.height;
+ }
- return false;
- };
- component.mousewheel = function (event) {
- event.stopPropagation();
+ /*--------------------------------------------------------------
+ 3.2 RAM
+ --------------------------------------------------------------*/
- if (
- (
- component.data.wheel === 0 &&
- (
- Object.keys(component.data.keys).length === 0 &&
- component.data.alt === false &&
- component.data.ctrl === false &&
- component.data.shift === false
- )
- ) ||
- component.data.wheel < 0 && event.deltaY > 0 ||
- component.data.wheel > 0 && event.deltaY < 0) {
- component.data = {
- alt: false,
- ctrl: false,
- shift: false,
- keys: {}
- };
- }
-
- component.data.wheel = event.deltaY < 0 ? -1 : 1;
-
- component.render();
+ if ('deviceMemory' in navigator) {
+ data.device.ram = navigator.deviceMemory + ' GB';
+ }
- return false;
- };
- component.addEventListener('render', function () {
- this.data = this.storageValue || {
- alt: false,
- ctrl: false,
- shift: false,
- keys: {},
- wheel: 0
- };
+ /*--------------------------------------------------------------
+ 3.3 GPU
+ --------------------------------------------------------------*/
- this.render(this.valueElement);
- });
+ if (
+ ctx &&
+ ctx instanceof WebGLRenderingContext &&
+ 'getParameter' in ctx &&
+ 'getExtension' in ctx
+ ) {
+ var info = ctx.getExtension('WEBGL_debug_renderer_info');
- component.addEventListener('click', function () {
- satus.render({
- component: 'modal',
- on: {
- close: function () {
- window.removeEventListener('keydown', component.keydown);
- window.removeEventListener('mousewheel', component.mousewheel);
- }
- },
+ if (info) {
+ data.device.gpu = ctx.getParameter(info.UNMASKED_RENDERER_WEBGL);
+ }
+ }
- primary: {
- component: 'div',
- class: 'satus-shortcut__primary',
- on: {
- render: function () {
- component.primary = this;
- if (component.skeleton.mouseButtons === true) {
- this.addEventListener('click', function () {
- component.data.context = false;
- component.data.click = true;
+ /*--------------------------------------------------------------
+ 3.4 CORES
+ --------------------------------------------------------------*/
- component.render();
- });
+ if (navigator.hardwareConcurrency) {
+ data.device.cores = navigator.hardwareConcurrency;
+ }
- this.addEventListener('contextmenu', function (event) {
- event.preventDefault();
- event.stopPropagation();
- component.data.context = true;
- component.data.click = false;
+ /*--------------------------------------------------------------
+ 3.5 TOUCH
+ --------------------------------------------------------------*/
- component.render();
+ if (
+ window.hasOwnProperty('ontouchstart') ||
+ window.DocumentTouch && document instanceof window.DocumentTouch ||
+ navigator.maxTouchPoints > 0 ||
+ window.navigator.msMaxTouchPoints > 0
+ ) {
+ data.device.touch = true;
+ data.device.max_touch_points = navigator.maxTouchPoints;
+ }
- return false;
- });
- }
- component.render();
- }
- }
- },
- actions: {
- component: 'section',
- variant: 'actions',
+ /*--------------------------------------------------------------
+ 3.6 CONNECTION
+ --------------------------------------------------------------*/
- reset: {
- component: 'button',
- text: 'reset',
- on: {
- click: function () {
- component.data = component.skeleton.value;
+ if (typeof navigator.connection === 'object') {
+ data.device.connection.type = navigator.connection.effectiveType || null;
- component.render(component.valueElement);
+ if (navigator.connection.downlink) {
+ data.device.connection.speed = navigator.connection.downlink + ' Mbps';
+ }
+ }
- satus.storage.set(skeleton.storage, false);
- this.parentNode.parentNode.parentNode.close();
+ /*--------------------------------------------------------------
+ 4.0 CLEARING
+ --------------------------------------------------------------*/
- window.removeEventListener('keydown', component.keydown);
- window.removeEventListener('mousewheel', component.mousewheel);
- }
- }
- },
- cancel: {
- component: 'button',
- text: 'cancel',
- on: {
- click: function () {
- component.data = satus.storage.get(component.storage) || component.skeleton.value;
+ video.remove();
+ audio.remove();
+ cvs.remove();
- component.render(component.valueElement);
- this.parentNode.parentNode.parentNode.close();
+ return data;
+};
+/*--------------------------------------------------------------
+>>> UUID
+--------------------------------------------------------------*/
- window.removeEventListener('keydown', component.keydown);
- window.removeEventListener('mousewheel', component.mousewheel);
- }
- }
- },
- save: {
- component: 'button',
- text: 'save',
- on: {
- click: function () {
- component.storageValue = component.data;
+satus.uuid = function () {
+ return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, function (match) {
+ return (match ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> match / 4).toString(16)
+ });
+};
+/*--------------------------------------------------------------
+>>> CONTEXT MENU
+--------------------------------------------------------------*/
- component.storageChange();
+satus.events.add('render', function (component, skeleton) {
+ if (skeleton.contextMenu) {
+ component.addEventListener('contextmenu', function (event) {
+ var x = event.clientX,
+ y = event.clientY,
+ modal = satus.render({
+ component: 'modal',
+ variant: 'contextmenu',
+ parent: this.skeleton
+ });
- component.render(component.valueElement);
+ if (window.innerWidth - x < 200) {
+ x = window.innerWidth - 200;
+ }
- this.parentNode.parentNode.parentNode.close();
+ modal.inner.style.left = x + 'px';
+ modal.inner.style.top = y + 'px';
- window.removeEventListener('keydown', component.keydown);
- window.removeEventListener('mousewheel', component.mousewheel);
- }
- }
- }
- }
- });
+ satus.render(this.skeleton.contextMenu, modal.inner);
- window.addEventListener('keydown', this.keydown);
- window.addEventListener('mousewheel', this.mousewheel);
- });
+ event.preventDefault();
+ event.stopPropagation();
- return component;
-};
+ return false;
+ });
+ }
+});
/*--------------------------------------------------------------
>>> BASE
--------------------------------------------------------------*/
@@ -1690,985 +1844,1318 @@ satus.components.base = function (skeleton) {
return component;
};
/*--------------------------------------------------------------
->>> TEXT FIELD
+>>> RADIO
--------------------------------------------------------------*/
-satus.components.textField = function (skeleton) {
- var component = document.createElement('div'),
- pre = document.createElement('pre'),
- input = document.createElement('textarea'),
- hidden_text = document.createElement('span'),
- text = document.createElement('span'),
- selection = document.createElement('div'),
- cursor = document.createElement('div');
+satus.components.radio = function (skeleton) {
+ var component = document.createElement('label'),
+ content = document.createElement('span'),
+ radio = document.createElement('input');
- input.className = 'satus-text-field__input';
- pre.className = 'satus-text-field__pre';
- hidden_text.className = 'satus-text-field__hidden-text';
- text.className = 'satus-text-field__text';
- selection.className = 'satus-text-field__selection';
- cursor.className = 'satus-text-field__cursor';
+ component.inner = content;
- component.inputElement = input;
- component.textElement = text;
- component.languages = {
- regex: function (component) {
- var regex_token = /\[\^?]?(?:[^\\\]]+|\\[\S\s]?)*]?|\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9][0-9]*|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|c[A-Za-z]|[\S\s]?)|\((?:\?[:=!]?)?|(?:[?*+]|\{[0-9]+(?:,[0-9]*)?\})\??|[^.?*+^${[()|\\]+|./g,
- char_class_token = /[^\\-]+|-|\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|c[A-Za-z]|[\S\s]?)/g,
- char_class_parts = /^(\[\^?)(]?(?:[^\\\]]+|\\[\S\s]?)*)(]?)$/,
- quantifier = /^(?:[?*+]|\{[0-9]+(?:,[0-9]*)?\})\??$/,
- matches = component.inputElement.value.match(regex_token);
+ radio.type = 'radio';
- function create(type, string) {
- var span = document.createElement('span');
+ if (skeleton.group) {
+ component.storage = skeleton.group;
+ radio.name = skeleton.group;
+ }
- span.className = type;
- span.textContent = string;
+ if (skeleton.value) {
+ radio.value = skeleton.value;
+ }
- component.textElement.appendChild(span);
- }
+ component.addEventListener('render', function () {
+ this.storageValue = satus.storage.get(this.storage);
- for (var i = 0, l = matches.length; i < l; i++) {
- var match = matches[i];
+ if (satus.isset(this.storageValue)) {
+ radio.checked = this.storageValue === skeleton.value;
+ } else if (skeleton.checked) {
+ radio.checked = true;
+ }
+ });
- if (match[0] === '[') {
- create('character-class', match);
- } else if (match[0] === '(') {
- create('group', match);
- } else if (match[0] === ')') {
- create('group', match);
- } else if (match[0] === '\\' || match === '^') {
- create('anchor', match);
- } else if (quantifier.test(match)) {
- create('quantifier', match);
- } else if (match === '|' || match === '.') {
- create('metasequence', match);
- } else {
- create('text', match);
- }
- }
- }
- };
- component._syntax = skeleton.syntax;
-
- Object.defineProperty(component, 'value', {
- get: function () {
- return this.inputElement.value;
- },
- set: function (value) {
- var input = this.inputElement;
-
- input.value = value;
-
- input.updateValue();
- input.updateCursor();
- }
- });
-
- Object.defineProperty(component, 'syntax', {
- get: function () {
- return this._syntax;
- },
- set: function (value) {
- var input = this.inputElement;
-
- this._syntax = value;
-
- input.updateValue();
- input.updateCursor();
- }
+ radio.addEventListener('change', function () {
+ component.storageValue = this.value;
+ component.storageChange();
});
- input.rows = skeleton.rows || 1;
- input.autocapitalize = 'none';
- input.autocomplete = 'off';
- input.autocorrect = 'off';
- input.spellcheck = false;
- input.autofocus = true;
- input.textElement = text;
- input.hiddenTextElement = hidden_text;
- input.selectionElement = selection;
- input.cursorElement = cursor;
+ component.appendChild(content);
+ component.appendChild(radio);
- input.updateValue = function () {
- var component = this.parentNode.parentNode;
+ return component;
+};
+/*--------------------------------------------------------------
+>>> CHECKBOX
+--------------------------------------------------------------*/
- for (var i = this.textElement.childNodes.length - 1; i > -1; i--) {
- this.textElement.childNodes[i].remove();
- }
+satus.components.checkbox = function (skeleton) {
+ var component = document.createElement('button'),
+ content = document.createElement('span');
- if (this.value.length > 0) {
- if (component.languages[component._syntax]) {
- component.languages[component._syntax](component);
- } else {
- this.textElement.textContent = this.value;
- }
- }
- };
+ component.inner = content;
- input.updateCursor = function () {
- var cursor = this.cursorElement,
- selection = this.selectionElement,
- hidden_text = this.hiddenTextElement,
- start = this.selectionStart,
- end = this.selectionEnd;
+ content.className = 'satus-checkbox__content';
- cursor.style.animation = 'none';
+ component.appendChild(content);
- if (start === end) {
- selection.setAttribute('disabled', '');
+ component.addEventListener('click', function () {
+ if (this.dataset.value === 'true') {
+ this.storageValue = false;
+ this.dataset.value = 'false';
} else {
- selection.removeAttribute('disabled');
+ this.storageValue = true;
+ this.dataset.value = 'true';
+ }
- hidden_text.textContent = this.value.substring(0, start);
+ this.storageChange();
+ });
- selection.style.left = hidden_text.offsetWidth - this.scrollLeft + 'px';
+ component.addEventListener('render', function () {
+ this.dataset.value = this.storageValue;
+ });
- hidden_text.textContent = this.value.substring(start, end);
+ return component;
+};
+/*--------------------------------------------------------------
+>>> SELECT
+--------------------------------------------------------------*/
- selection.style.width = hidden_text.offsetWidth + 'px';
- }
+satus.components.select = function (skeleton) {
+ var component = document.createElement('div'),
+ component_content = document.createElement('span'),
+ component_value = document.createElement('span'),
+ select = document.createElement('select');
- if (this.selectionDirection === 'forward') {
- hidden_text.textContent = this.value.substring(0, end);
- } else {
- hidden_text.textContent = this.value.substring(0, start);
- }
+ component_content.className = 'satus-select__content';
+ component_value.className = 'satus-select__value';
- cursor.style.left = hidden_text.offsetWidth - this.scrollLeft + 'px';
+ for (var i = 0, l = skeleton.options.length; i < l; i++) {
+ var option = document.createElement('option');
- cursor.style.animation = '';
+ option.value = skeleton.options[i].value;
- hidden_text.textContent = '';
- };
+ satus.text(option, skeleton.options[i].text);
- input.addEventListener('keydown', function () {
- var self = this;
+ select.appendChild(option);
+ }
- setTimeout(function () {
- var component = self.parentNode.parentNode;
+ component.selectElement = select;
+ select.valueElement = component_value;
- component.storageValue = self.value;
- component.storageChange();
+ select.addEventListener('change', function () {
+ satus.empty(this.valueElement);
- self.updateValue();
- self.updateCursor();
- });
- });
+ satus.text(this.valueElement, this.options[this.selectedIndex].text);
- input.addEventListener('scroll', function (event) {
- this.textElement.style.left = -this.scrollLeft + 'px';
- });
+ this.parentNode.storageValue = this.value;
- document.addEventListener('selectionchange', function () {
- input.updateCursor();
+ this.parentNode.storageChange();
});
- selection.setAttribute('disabled', '');
-
- pre.appendChild(input);
- pre.appendChild(hidden_text);
- pre.appendChild(text);
- pre.appendChild(selection);
- pre.appendChild(cursor);
- component.appendChild(pre);
+ component.appendChild(component_content);
+ component.appendChild(component_value);
+ component.appendChild(select);
component.addEventListener('render', function () {
- input.value = this.storageValue;
+ select.value = this.storageValue || this.skeleton.options[0].value;
- this.inputElement.updateValue();
- this.inputElement.updateCursor();
+ satus.text(select.valueElement, select.options[select.selectedIndex].text);
});
- return component;
-};
-/*--------------------------------------------------------------
->>> ALERT
---------------------------------------------------------------*/
-
-satus.components.alert = function (skeleton) {
- var component = document.createElement('div');
+ component.inner = component_content;
return component;
};
/*--------------------------------------------------------------
->>> LAYERS
+>>> SHORTCUT
--------------------------------------------------------------*/
-satus.components.layers = function (skeleton) {
- var component = document.createElement('div');
-
- component.path = [skeleton];
+satus.components.shortcut = function (skeleton) {
+ var component = document.createElement('button'),
+ content = document.createElement('span'),
+ value = document.createElement('div');
- component.back = function () {
- if (this.path.length > 1) {
- this.path.pop();
+ component.inner = content;
- this.open();
- }
- };
+ component.className = 'satus-button';
+ value.className = 'satus-shortcut__value';
- component.open = function (skeleton) {
- var layer = document.createElement('div');
+ component.render = function (parent) {
+ var self = this,
+ parent = parent || self.primary,
+ children = parent.children;
- if (skeleton) {
- this.path.push(skeleton);
- } else {
- skeleton = this.path[this.path.length - 1];
- }
+ satus.empty(parent);
- layer.className = 'satus-layer';
+ function createElement(name) {
+ var element = document.createElement('div');
- layer.skeleton = skeleton;
- layer.base = this.base;
+ element.className = 'satus-shortcut__' + name;
- satus.render(skeleton, layer, skeleton.component === 'layers');
+ parent.appendChild(element);
- satus.empty(this);
+ return element;
+ }
- this.appendChild(layer);
+ if (this.data.alt) {
+ createElement('key').textContent = 'Alt';
+ }
- this.dispatchEvent(new Event('open'));
- };
+ if (this.data.ctrl) {
+ if (children.length && children[children.length - 1].className.indexOf('key') !== -1) {
+ createElement('plus');
+ }
- component.update = function () {
- var layer = this.querySelector('.satus-layer');
+ createElement('key').textContent = 'Ctrl';
+ }
- satus.empty(layer);
+ if (this.data.shift) {
+ if (children.length && children[children.length - 1].className.indexOf('key') !== -1) {
+ createElement('plus');
+ }
- satus.render(layer.skeleton, layer);
- };
+ createElement('key').textContent = 'Shift';
+ }
- component.render_children = false;
+ for (var code in this.data.keys) {
+ var key = this.data.keys[code].key,
+ arrows = ['ArrowUp', 'ArrowRight', 'ArrowDown', 'ArrowLeft'],
+ index = arrows.indexOf(key);
- component.addEventListener('render', function () {
- this.open();
- });
+ if (children.length && children[children.length - 1].className.indexOf('key') !== -1) {
+ createElement('plus');
+ }
- return component;
-};
-/*--------------------------------------------------------------
->>> DIVIDER
---------------------------------------------------------------*/
+ if (index !== -1) {
+ createElement('key').textContent = ['↑', '→', '↓', '←'][index];
+ } else if (key === ' ') {
+ createElement('key').textContent = '␣';
+ } else if (key) {
+ createElement('key').textContent = key.toUpperCase();
+ }
+ }
-satus.components.divider = function () {
- var component = document.createElement('div');
+ if (this.data.wheel) {
+ if (children.length && children[children.length - 1].className.indexOf('key') !== -1) {
+ createElement('plus');
+ }
- return component;
-};
-/*--------------------------------------------------------------
->>> INPUT
---------------------------------------------------------------*/
+ var mouse = createElement('mouse'),
+ div = document.createElement('div');
-satus.components.input = function (skeleton) {
- var component = document.createElement('input');
+ mouse.appendChild(div);
- if (skeleton.attr) {
- var key = skeleton.attr.name || skeleton.storage,
- value;
+ mouse.className += ' ' + (this.data.wheel > 0);
+ }
- if (satus.isset(satus.storage.get(key))) {
- value = satus.storage.get(key);
- } else {
- value = skeleton.value;
- }
+ if (this.data.click) {
+ if (children.length && children[children.length - 1].className.indexOf('key') !== -1) {
+ createElement('plus');
+ }
- if (skeleton.attr.type === 'radio') {
- component.checked = value === skeleton.attr.value || skeleton.value;
- } else if (satus.isset(value)) {
- component.value = value;
- }
+ var mouse = createElement('mouse'),
+ div = document.createElement('div');
- component.addEventListener('change', function () {
- var key = this.skeleton.attr.name || this.skeleton.storage;
+ mouse.appendChild(div);
- satus.storage.set(key, this.value);
- });
- } else {
- var key = skeleton.name || skeleton.storage,
- value;
+ mouse.className += ' click';
+ }
- component.type = skeleton.type;
+ if (this.data.context) {
+ if (children.length && children[children.length - 1].className.indexOf('key') !== -1) {
+ createElement('plus');
+ }
- if (satus.isset(satus.storage.get(key))) {
- value = satus.storage.get(key);
- } else {
- value = skeleton.value;
- }
+ var mouse = createElement('mouse'),
+ div = document.createElement('div');
- if (skeleton.type === 'radio') {
- component.checked = value === skeleton.value || skeleton.value;
- } else if (satus.isset(value)) {
- component.value = value;
- }
+ mouse.appendChild(div);
- component.addEventListener('change', function () {
- var key = this.skeleton.name || this.skeleton.storage;
+ mouse.className += ' context';
+ }
+ };
- satus.storage.set(key, this.value);
- });
- }
+ component.valueElement = value;
- return component;
-};
-/*--------------------------------------------------------------
->>> SELECT
---------------------------------------------------------------*/
+ component.appendChild(content);
+ component.appendChild(value);
-satus.components.select = function (skeleton) {
- var component = document.createElement('div'),
- component_content = document.createElement('span'),
- component_value = document.createElement('span'),
- select = document.createElement('select');
+ component.keydown = function (event) {
+ event.preventDefault();
+ event.stopPropagation();
- component_content.className = 'satus-select__content';
- component_value.className = 'satus-select__value';
+ component.data = {
+ alt: event.altKey,
+ ctrl: event.ctrlKey,
+ shift: event.shiftKey,
+ keys: {}
+ };
- for (var i = 0, l = skeleton.options.length; i < l; i++) {
- var option = document.createElement('option');
+ if (['control', 'alt', 'altgraph', 'shift'].indexOf(event.key.toLowerCase()) === -1) {
+ component.data.keys[event.keyCode] = {
+ code: event.code,
+ key: event.key
+ };
+ }
- option.value = skeleton.options[i].value;
+ component.data.wheel = 0;
- satus.text(option, skeleton.options[i].text);
+ component.render();
- select.appendChild(option);
- }
+ return false;
+ };
- component.selectElement = select;
- select.valueElement = component_value;
+ component.mousewheel = function (event) {
+ event.stopPropagation();
- select.addEventListener('change', function () {
- satus.empty(this.valueElement);
+ if (
+ (
+ component.data.wheel === 0 &&
+ (
+ Object.keys(component.data.keys).length === 0 &&
+ component.data.alt === false &&
+ component.data.ctrl === false &&
+ component.data.shift === false
+ )
+ ) ||
+ component.data.wheel < 0 && event.deltaY > 0 ||
+ component.data.wheel > 0 && event.deltaY < 0) {
+ component.data = {
+ alt: false,
+ ctrl: false,
+ shift: false,
+ keys: {}
+ };
+ }
- satus.text(this.valueElement, this.options[this.selectedIndex].text);
+ component.data.wheel = event.deltaY < 0 ? -1 : 1;
- this.parentNode.storageValue = this.value;
+ component.render();
- this.parentNode.storageChange();
- });
+ return false;
+ };
- component.appendChild(component_content);
- component.appendChild(component_value);
- component.appendChild(select);
+ component.addEventListener('render', function () {
+ this.data = this.storageValue || {
+ alt: false,
+ ctrl: false,
+ shift: false,
+ keys: {},
+ wheel: 0
+ };
- component.addEventListener('render', function () {
- select.value = this.storageValue || this.skeleton.options[0].value;
+ this.render(this.valueElement);
+ });
- satus.text(select.valueElement, select.options[select.selectedIndex].text);
- });
+ component.addEventListener('click', function () {
+ satus.render({
+ component: 'modal',
+ on: {
+ close: function () {
+ window.removeEventListener('keydown', component.keydown);
+ window.removeEventListener('wheel', component.mousewheel);
+ }
+ },
- component.inner = component_content;
+ primary: {
+ component: 'div',
+ class: 'satus-shortcut__primary',
+ on: {
+ render: function () {
+ component.primary = this;
- return component;
-};
-/*--------------------------------------------------------------
->>> COLOR:
-----------------------------------------------------------------
-# RGB to HSL
-# HUE to RGB
-# HSL to RGB
---------------------------------------------------------------*/
+ if (component.skeleton.mouseButtons === true) {
+ this.addEventListener('click', function () {
+ component.data.context = false;
+ component.data.click = true;
-satus.color = {};
+ component.render();
+ });
+ this.addEventListener('contextmenu', function (event) {
+ event.preventDefault();
+ event.stopPropagation();
-/*--------------------------------------------------------------
-# RGB TO HSL
---------------------------------------------------------------*/
+ component.data.context = true;
+ component.data.click = false;
-satus.color.rgbToHsl = function (array) {
- var r = array[0] / 255,
- g = array[1] / 255,
- b = array[2] / 255,
- min = Math.min(r, g, b),
- max = Math.max(r, g, b),
- h = 0,
- s = 0,
- l = (min + max) / 2;
+ component.render();
- if (min === max) {
- h = 0;
- s = 0;
- } else {
- var delta = max - min;
+ return false;
+ });
+ }
- s = l <= 0.5 ? delta / (max + min) : delta / (2 - max - min);
+ component.render();
+ }
+ }
+ },
+ actions: {
+ component: 'section',
+ variant: 'actions',
- if (max === r) {
- h = (g - b) / delta + (g < b ? 6 : 0);
- } else if (max === g) {
- h = (b - r) / delta + 2;
- } else if (max === b) {
- h = (r - g) / delta + 4;
- }
+ reset: {
+ component: 'button',
+ text: 'reset',
+ on: {
+ click: function () {
+ component.data = component.skeleton.value || {};
- h /= 6;
- }
+ component.render(component.valueElement);
- h *= 360;
- s *= 100;
- l *= 100;
+ satus.storage.set(skeleton.storage, false);
- if (array.length === 3) {
- return [h, s, l];
+ this.parentNode.parentNode.parentNode.close();
+
+ window.removeEventListener('keydown', component.keydown);
+ window.removeEventListener('wheel', component.mousewheel);
+ }
+ }
+ },
+ cancel: {
+ component: 'button',
+ text: 'cancel',
+ on: {
+ click: function () {
+ component.data = satus.storage.get(component.storage) || component.skeleton.value || {};
+
+ component.render(component.valueElement);
+
+ this.parentNode.parentNode.parentNode.close();
+
+ window.removeEventListener('keydown', component.keydown);
+ window.removeEventListener('wheel', component.mousewheel);
+ }
+ }
+ },
+ save: {
+ component: 'button',
+ text: 'save',
+ on: {
+ click: function () {
+ component.storageValue = component.data;
+
+ component.storageChange();
+
+ component.render(component.valueElement);
+
+ this.parentNode.parentNode.parentNode.close();
+
+ window.removeEventListener('keydown', component.keydown);
+ window.removeEventListener('wheel', component.mousewheel);
+ }
+ }
+ }
+ }
+ });
+
+ window.addEventListener('keydown', this.keydown);
+ window.addEventListener('wheel', this.mousewheel);
+ });
+
+ return component;
+};
+/*--------------------------------------------------------------
+>>> SWITCH
+--------------------------------------------------------------*/
+
+satus.components.switch = function (skeleton) {
+ var component = document.createElement('button'),
+ component_content = document.createElement('span'),
+ component_thumb = document.createElement('i');
+
+ component.inner = component_content;
+
+ component_content.className = 'satus-switch__content';
+
+ component.addEventListener('click', function () {
+ if (this.dataset.value === 'true') {
+ this.storageValue = false;
+ this.dataset.value = 'false';
+ } else {
+ this.storageValue = true;
+ this.dataset.value = 'true';
+ }
+
+ this.storageChange();
+ });
+
+ component.addEventListener('render', function () {
+ this.dataset.value = this.storageValue;
+ });
+
+ component.appendChild(component_content);
+ component.appendChild(component_thumb);
+
+ return component;
+};
+/*--------------------------------------------------------------
+>>> LAYERS
+--------------------------------------------------------------*/
+
+satus.components.layers = function (skeleton) {
+ var component = document.createElement('div');
+
+ component.path = [skeleton];
+
+ component.back = function () {
+ if (this.path.length > 1) {
+ this.path.pop();
+
+ this.open();
+ }
+ };
+
+ component.open = function (skeleton) {
+ var layer = document.createElement('div');
+
+ if (skeleton) {
+ this.path.push(skeleton);
+ } else {
+ skeleton = this.path[this.path.length - 1];
+ }
+
+ layer.className = 'satus-layer';
+
+ layer.skeleton = skeleton;
+ layer.base = this.base;
+
+ satus.render(skeleton, layer, skeleton.component === 'layers');
+
+ satus.empty(this);
+
+ this.appendChild(layer);
+
+ this.dispatchEvent(new Event('open'));
+ };
+
+ component.update = function () {
+ var layer = this.querySelector('.satus-layer');
+
+ satus.empty(layer);
+
+ satus.render(layer.skeleton, layer);
+ };
+
+ component.render_children = false;
+
+ component.addEventListener('render', function () {
+ this.open();
+ });
+
+ return component;
+};
+/*--------------------------------------------------------------
+>>> INPUT
+--------------------------------------------------------------*/
+
+satus.components.input = function (skeleton) {
+ var component = document.createElement('input');
+
+ if (skeleton.attr) {
+ var key = skeleton.attr.name || skeleton.storage,
+ value;
+
+ if (satus.isset(satus.storage.get(key))) {
+ value = satus.storage.get(key);
+ } else {
+ value = skeleton.value;
+ }
+
+ if (skeleton.attr.type === 'radio') {
+ component.checked = value === skeleton.attr.value || skeleton.value;
+ } else if (satus.isset(value)) {
+ component.value = value;
+ }
+
+ component.addEventListener('change', function () {
+ var key = this.skeleton.attr.name || this.skeleton.storage;
+
+ satus.storage.set(key, this.value);
+ });
} else {
- return [h, s, l, array[3]];
+ var key = skeleton.name || skeleton.storage,
+ value;
+
+ component.type = skeleton.type;
+
+ if (satus.isset(satus.storage.get(key))) {
+ value = satus.storage.get(key);
+ } else {
+ value = skeleton.value;
+ }
+
+ if (skeleton.type === 'radio') {
+ component.checked = value === skeleton.value || skeleton.value;
+ } else if (satus.isset(value)) {
+ component.value = value;
+ }
+
+ component.addEventListener('change', function () {
+ var key = this.skeleton.name || this.skeleton.storage;
+
+ satus.storage.set(key, this.value);
+ });
}
-};
+ return component;
+};
+/*--------------------------------------------------------------
+>>> MENUBAR
+--------------------------------------------------------------*/
+
+satus.components.menubar = function (skeleton) {
+ function createList(items) {
+ var ul = document.createElement('ul');
+
+ for (var key in items) {
+ var item = items[key],
+ li = document.createElement('li');
+
+ satus.render(item, li);
+
+ if (item.items) {
+ li.appendChild(createList(item.items));
+ }
+
+ ul.appendChild(li);
+ }
+
+ return ul;
+ }
+
+ return createList(skeleton.items);
+};
+/*--------------------------------------------------------------
+>>> TEXTAREA
+--------------------------------------------------------------*/
+
+satus.components.textarea = function (skeleton) {
+ var component = document.createElement('div'),
+ line_number = document.createElement('div'),
+ textarea = document.createElement('textarea');
+
+ line_number.className = 'satus-textarea__line-number';
+
+ component.line_number = line_number;
+ component.textarea = textarea;
+
+ Object.defineProperty(component, 'value', {
+ get() {
+ return this.textarea.value;
+ },
+ set(value) {
+ this.textarea.value = value;
+
+ this.line_number.update();
+ }
+ });
+
+ line_number.update = function () {
+ var count = this.parentNode.textarea.value.split('\n').length;
+
+ if (count !== this.children.length) {
+ satus.empty(this);
+
+ for (var i = 1; i <= count; i++) {
+ var span = document.createElement('span');
+
+ span.textContent = i;
+
+ this.appendChild(span);
+ }
+ }
+ };
+
+ textarea.addEventListener('input', function () {
+ this.parentNode.line_number.update();
+ });
+
+ textarea.addEventListener('selectionchange', function () {
+ this.parentNode.line_number.update();
+ });
+
+ textarea.addEventListener('scroll', function () {
+ this.parentNode.line_number.style.transform = 'translateY(-' + this.scrollTop + 'px)';
+
+ this.parentNode.line_number.update();
+ });
+
+ component.appendChild(line_number);
+ component.appendChild(textarea);
+
+ line_number.update(1);
+
+ return component;
+};
+/*--------------------------------------------------------------
+>>> DIVIDER
+--------------------------------------------------------------*/
+
+satus.components.divider = function () {
+ var component = document.createElement('div');
+
+ return component;
+};
+/*--------------------------------------------------------------
+>>> TEXT FIELD
+--------------------------------------------------------------*/
+
+satus.components.textField = function (skeleton) {
+ var component = document.createElement('div'),
+ pre = document.createElement('pre'),
+ input = document.createElement('textarea'),
+ hidden_text = document.createElement('span'),
+ text = document.createElement('span'),
+ selection = document.createElement('div'),
+ cursor = document.createElement('div');
+
+ input.className = 'satus-text-field__input';
+ pre.className = 'satus-text-field__pre';
+ hidden_text.className = 'satus-text-field__hidden-text';
+ text.className = 'satus-text-field__text';
+ selection.className = 'satus-text-field__selection';
+ cursor.className = 'satus-text-field__cursor';
+
+ component.inputElement = input;
+ component.textElement = text;
+ component.languages = {
+ regex: function (component) {
+ var regex_token = /\[\^?]?(?:[^\\\]]+|\\[\S\s]?)*]?|\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9][0-9]*|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|c[A-Za-z]|[\S\s]?)|\((?:\?[:=!]?)?|(?:[?*+]|\{[0-9]+(?:,[0-9]*)?\})\??|[^.?*+^${[()|\\]+|./g,
+ char_class_token = /[^\\-]+|-|\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|c[A-Za-z]|[\S\s]?)/g,
+ char_class_parts = /^(\[\^?)(]?(?:[^\\\]]+|\\[\S\s]?)*)(]?)$/,
+ quantifier = /^(?:[?*+]|\{[0-9]+(?:,[0-9]*)?\})\??$/,
+ matches = component.inputElement.value.match(regex_token);
+
+ function create(type, string) {
+ var span = document.createElement('span');
+
+ span.className = type;
+ span.textContent = string;
+
+ component.textElement.appendChild(span);
+ }
+
+ for (var i = 0, l = matches.length; i < l; i++) {
+ var match = matches[i];
+
+ if (match[0] === '[') {
+ create('character-class', match);
+ } else if (match[0] === '(') {
+ create('group', match);
+ } else if (match[0] === ')') {
+ create('group', match);
+ } else if (match[0] === '\\' || match === '^') {
+ create('anchor', match);
+ } else if (quantifier.test(match)) {
+ create('quantifier', match);
+ } else if (match === '|' || match === '.') {
+ create('metasequence', match);
+ } else {
+ create('text', match);
+ }
+ }
+ }
+ };
+ component._syntax = skeleton.syntax;
+
+ Object.defineProperty(component, 'value', {
+ get: function () {
+ return this.inputElement.value;
+ },
+ set: function (value) {
+ var input = this.inputElement;
+
+ input.value = value;
+
+ input.updateValue();
+ input.updateCursor();
+ }
+ });
+
+ Object.defineProperty(component, 'syntax', {
+ get: function () {
+ return this._syntax;
+ },
+ set: function (value) {
+ var input = this.inputElement;
+
+ this._syntax = value;
+
+ input.updateValue();
+ input.updateCursor();
+ }
+ });
+
+ input.rows = skeleton.rows || 1;
+ input.autocapitalize = 'none';
+ input.autocomplete = 'off';
+ input.autocorrect = 'off';
+ input.spellcheck = false;
+ input.autofocus = true;
+ input.textElement = text;
+ input.hiddenTextElement = hidden_text;
+ input.selectionElement = selection;
+ input.cursorElement = cursor;
+
+ input.updateValue = function () {
+ var component = this.parentNode.parentNode;
+
+ for (var i = this.textElement.childNodes.length - 1; i > -1; i--) {
+ this.textElement.childNodes[i].remove();
+ }
+
+ if (this.value.length > 0) {
+ if (component.languages[component._syntax]) {
+ component.languages[component._syntax](component);
+ } else {
+ this.textElement.textContent = this.value;
+ }
+ }
+ };
+
+ input.updateCursor = function () {
+ var cursor = this.cursorElement,
+ selection = this.selectionElement,
+ hidden_text = this.hiddenTextElement,
+ start = this.selectionStart,
+ end = this.selectionEnd;
+
+ cursor.style.animation = 'none';
+
+ if (start === end) {
+ selection.setAttribute('disabled', '');
+ } else {
+ selection.removeAttribute('disabled');
+
+ hidden_text.textContent = this.value.substring(0, start);
+
+ selection.style.left = hidden_text.offsetWidth - this.scrollLeft + 'px';
+
+ hidden_text.textContent = this.value.substring(start, end);
+
+ selection.style.width = hidden_text.offsetWidth + 'px';
+ }
+
+ if (this.selectionDirection === 'forward') {
+ hidden_text.textContent = this.value.substring(0, end);
+ } else {
+ hidden_text.textContent = this.value.substring(0, start);
+ }
+
+ cursor.style.left = hidden_text.offsetWidth - this.scrollLeft + 'px';
+
+ cursor.style.animation = '';
+
+ hidden_text.textContent = '';
+ };
+
+ input.addEventListener('keydown', function () {
+ var self = this;
+
+ setTimeout(function () {
+ var component = self.parentNode.parentNode;
+
+ component.storageValue = self.value;
+ component.storageChange();
+
+ self.updateValue();
+ self.updateCursor();
+ });
+ });
+
+ input.addEventListener('scroll', function (event) {
+ this.textElement.style.left = -this.scrollLeft + 'px';
+ });
+
+ document.addEventListener('selectionchange', function () {
+ input.updateCursor();
+ });
+
+ selection.setAttribute('disabled', '');
+
+ pre.appendChild(input);
+ pre.appendChild(hidden_text);
+ pre.appendChild(text);
+ pre.appendChild(selection);
+ pre.appendChild(cursor);
+ component.appendChild(pre);
+
+ component.addEventListener('render', function () {
+ input.value = this.storageValue;
+
+ this.inputElement.updateValue();
+ this.inputElement.updateCursor();
+ });
+
+ return component;
+};
+/*--------------------------------------------------------------
+>>> TABS
+--------------------------------------------------------------*/
+
+satus.components.tabs = function (skeleton) {
+ var component = document.createElement('div'),
+ content = document.createElement('div'),
+ selection = document.createElement('div');
+
+ content.className = 'satus-tabs__content';
+ selection.className = 'satus-tabs__selection';
+ selection.style.width = 100 / skeleton.items.length + '%';
+
+ content.appendChild(selection);
+
+ component.selection = selection;
+
+ for (var i = 0, l = skeleton.items.length; i < l; i++) {
+ var item = skeleton.items[i],
+ button = document.createElement('button');
+
+ button.className = 'satus-tabs__button';
+ button.value = item;
+ button.style.width = 100 / l + '%';
+
+ satus.text(button, item);
+
+ button.addEventListener('click', function () {
+ var component = this.parentNode.parentNode;
+
+ component.selection.style.left = 100 / (this.parentNode.children.length - 1) * (satus.indexOf(this) - 1) + '%';
-/*--------------------------------------------------------------
-# HUE TO RGB
---------------------------------------------------------------*/
+ component.storageValue = this.value;
+ component.storageChange();
+ });
-satus.color.hueToRgb = function (array) {
- var t1 = array[0],
- t2 = array[1],
- hue = array[2];
+ if (skeleton.value === item) {
+ selection.style.left = i * 50 + '%';
+ }
- if (hue < 0) {
- hue += 6;
+ content.appendChild(button);
}
+
+ component.appendChild(content);
- if (hue >= 6) {
- hue -= 6;
- }
+ component.addEventListener('render', function () {
+ var index = satus.indexOf(this.storageValue, this.skeleton.items);
- if (hue < 1) {
- return (t2 - t1) * hue + t1;
- } else if (hue < 3) {
- return t2;
- } else if (hue < 4) {
- return (t2 - t1) * (4 - hue) + t1;
- } else {
- return t1;
- }
-};
+ if (index === -1) {
+ index = 0;
+ }
+ this.selection.style.left = 100 / this.skeleton.items.length * index + '%';
+ });
+ return component;
+};
/*--------------------------------------------------------------
-# HSL TO RGB
+>>> ALERT
--------------------------------------------------------------*/
-satus.color.hslToRgb = function (array) {
- var h = array[0] / 360,
- s = array[1] / 100,
- l = array[2] / 100,
- r, g, b;
-
- if (s == 0) {
- r = g = b = l;
- } else {
- var hue2rgb = function hue2rgb(p, q, t) {
- if (t < 0) t += 1;
- if (t > 1) t -= 1;
- if (t < 1 / 6) return p + (q - p) * 6 * t;
- if (t < 1 / 2) return q;
- if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
- return p;
- }
-
- var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
- var p = 2 * l - q;
- r = hue2rgb(p, q, h + 1 / 3);
- g = hue2rgb(p, q, h);
- b = hue2rgb(p, q, h - 1 / 3);
- }
+satus.components.alert = function (skeleton) {
+ var component = document.createElement('div');
- return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
+ return component;
};
/*--------------------------------------------------------------
->>> USER
+>>> SLIDER
--------------------------------------------------------------*/
-satus.user = function () {
- /*--------------------------------------------------------------
- 1.0 VARIABLES
- --------------------------------------------------------------*/
-
- var user_agent = navigator.userAgent,
- random_cookie = 'ta{t`nX6cMXK,Wsc',
- video = document.createElement('video'),
- video_formats = {
- ogg: 'video/ogg; codecs="theora"',
- h264: 'video/mp4; codecs="avc1.42E01E"',
- webm: 'video/webm; codecs="vp8, vorbis"',
- vp9: 'video/webm; codecs="vp9"',
- hls: 'application/x-mpegURL; codecs="avc1.42E01E"'
- },
- audio = document.createElement('audio'),
- audio_formats = {
- mp3: 'audio/mpeg',
- mp4: 'audio/mp4',
- aif: 'audio/x-aiff'
- },
- cvs = document.createElement('canvas'),
- ctx = cvs.getContext('webgl'),
- data = {
- browser: {
- audio: null,
- cookies: null,
- flash: null,
- java: null,
- languages: null,
- name: null,
- platform: null,
- version: null,
- video: null,
- webgl: null
- },
- os: {
- name: null,
- type: null
- },
- device: {
- connection: {
- type: null,
- speed: null
- },
- cores: null,
- gpu: null,
- max_touch_points: null,
- ram: null,
- screen: null,
- touch: null
- }
- };
+satus.components.slider = function (skeleton) {
+ var component = document.createElement('div'),
+ content = document.createElement('div'),
+ container = document.createElement('div'),
+ track = document.createElement('div'),
+ track_fill = document.createElement('div');
+ container.className = 'satus-slider__container';
+ track.className = 'satus-slider__track';
+ track_fill.className = 'satus-slider__track-fill';
- /*--------------------------------------------------------------
- 2.0 SOFTWARE
- --------------------------------------------------------------*/
+ component.min = skeleton.min || 0;
+ component.max = skeleton.max || 1;
+ component.step = (skeleton.step || 1);
+ component.percent = 100 / ((component.max - component.min) / component.step);
+ component.precision = String(component.step).replace(/[0-9]./, '').length;
- /*--------------------------------------------------------------
- 2.1.0 OS
- --------------------------------------------------------------*/
+ component.container = container;
+ component.track = track_fill;
+ component.handles = [];
+ component.inner = content;
- /*--------------------------------------------------------------
- 2.1.1 NAME
- --------------------------------------------------------------*/
+ component.toPercent = function (number) {
+ return number / this.step * this.percent + '%';
+ };
- if (navigator.appVersion.indexOf('Win') !== -1) {
- if (navigator.appVersion.match(/(Windows 10.0|Windows NT 10.0)/)) {
- data.os.name = 'Windows 10';
- } else if (navigator.appVersion.match(/(Windows 8.1|Windows NT 6.3)/)) {
- data.os.name = 'Windows 8.1';
- } else if (navigator.appVersion.match(/(Windows 8|Windows NT 6.2)/)) {
- data.os.name = 'Windows 8';
- } else if (navigator.appVersion.match(/(Windows 7|Windows NT 6.1)/)) {
- data.os.name = 'Windows 7';
- } else if (navigator.appVersion.match(/(Windows NT 6.0)/)) {
- data.os.name = 'Windows Vista';
- } else if (navigator.appVersion.match(/(Windows NT 5.1|Windows XP)/)) {
- data.os.name = 'Windows XP';
- } else {
- data.os.name = 'Windows';
- }
- } else if (navigator.appVersion.indexOf('(iPhone|iPad|iPod)') !== -1) {
- data.os.name = 'iOS';
- } else if (navigator.appVersion.indexOf('Mac') !== -1) {
- data.os.name = 'macOS';
- } else if (navigator.appVersion.indexOf('Android') !== -1) {
- data.os.name = 'Android';
- } else if (navigator.appVersion.indexOf('OpenBSD') !== -1) {
- data.os.name = 'OpenBSD';
- } else if (navigator.appVersion.indexOf('SunOS') !== -1) {
- data.os.name = 'SunOS';
- } else if (navigator.appVersion.indexOf('Linux') !== -1) {
- data.os.name = 'Linux';
- } else if (navigator.appVersion.indexOf('X11') !== -1) {
- data.os.name = 'UNIX';
- }
+ component.createHandle = function (index) {
+ var handle = document.createElement('div');
- /*--------------------------------------------------------------
- 2.1.2 TYPE
- --------------------------------------------------------------*/
+ handle.className = 'satus-slider__handle';
+ handle.handleIndex = index;
+ handle.tabIndex = 0;
- if (navigator.appVersion.match(/(Win64|x64|x86_64|WOW64)/)) {
- data.os.type = '64-bit';
- } else {
- data.os.type = '32-bit';
- }
+ this.handles.push(handle);
+ this.container.appendChild(handle);
+ };
- /*--------------------------------------------------------------
- 2.2.0 BROWSER
- --------------------------------------------------------------*/
+ component.update = function () {
+ if (this.values.length > 1) {
+ var min = Math.min.apply(null, this.values) - this.min,
+ max = Math.max.apply(null, this.values) - this.min;
- /*--------------------------------------------------------------
- 2.2.1 NAME
- --------------------------------------------------------------*/
+ this.track.style.left = this.toPercent(min);
+ this.track.style.width = this.toPercent(max - min);
- if (user_agent.indexOf('Opera') !== -1) {
- data.browser.name = 'Opera';
- } else if (user_agent.indexOf('Vivaldi') !== -1) {
- data.browser.name = 'Vivaldi';
- } else if (user_agent.indexOf('Edge') !== -1) {
- data.browser.name = 'Edge';
- } else if (user_agent.indexOf('Chrome') !== -1) {
- data.browser.name = 'Chrome';
- } else if (user_agent.indexOf('Safari') !== -1) {
- data.browser.name = 'Safari';
- } else if (user_agent.indexOf('Firefox') !== -1) {
- data.browser.name = 'Firefox';
- } else if (user_agent.indexOf('MSIE') !== -1) {
- data.browser.name = 'IE';
- }
+ for (var i = 0, l = this.handles.length; i < l; i++) {
+ var handle = this.handles[i],
+ value = this.values[i];
+ handle.style.left = this.toPercent(value - this.min);
+ handle.dataset.value = value;
+ }
+ } else {
+ var value = this.values[0];
- /*--------------------------------------------------------------
- 2.2.2 VERSION
- --------------------------------------------------------------*/
+ this.track.style.width = this.toPercent(value - this.min);
+ this.handles[0].style.left = this.toPercent(value - this.min);
+ this.handles[0].dataset.value = value;
+ }
+ };
- var browser_version = user_agent.match(new RegExp(data.browser.name + '/([0-9.]+)'));
+ component.appendChild(content);
+ track.appendChild(track_fill);
+ container.appendChild(track);
+ component.appendChild(container);
- if (browser_version[1]) {
- data.browser.version = browser_version[1];
- }
+ component.addEventListener('keydown', function (event) {
+ var code = event.keyCode;
+ console.log(code);
+ });
- /*--------------------------------------------------------------
- 2.2.3 PLATFORM
- --------------------------------------------------------------*/
+ component.addEventListener('render', function () {
+ var value = this.storageValue;
- data.browser.platform = navigator.platform || null;
+ if (satus.isArray(value)) {
+ this.values = value;
+ } else if (satus.isNumber(value)) {
+ this.values = [value];
+ } else {
+ this.values = this.skeleton.values || [satus.isset(this.skeleton.value) ? this.skeleton.value : 1];
+ }
+ for (var i = 0, l = this.values.length; i < l; i++) {
+ this.createHandle(i);
+ }
- /*--------------------------------------------------------------
- 2.2.4 LANGUAGES
- --------------------------------------------------------------*/
+ this.update();
+ });
- data.browser.languages = navigator.languages || null;
+ container.addEventListener('mousedown', function (event) {
+ if (event.button === 0) {
+ var component = this.parentNode,
+ rect = this.getBoundingClientRect(),
+ cursor_x = event.clientX - rect.left,
+ percent = cursor_x / rect.width * 100,
+ steps = percent / component.percent * component.step + component.min,
+ closest_value = component.values.indexOf(component.values.reduce(function(previous, current, index) {
+ return Math.abs(current - steps) < Math.abs(previous - steps) ? current : previous;
+ })),
+ handle_index = component.handles[closest_value].handleIndex;
+ setTimeout(function () {
+ component.handles[closest_value].focus();
+ });
- /*--------------------------------------------------------------
- 2.2.5 COOKIES
- --------------------------------------------------------------*/
+ function update(event) {
+ var cursor_x = Math.min(Math.max(event.clientX - rect.left, 0), rect.width),
+ percent = cursor_x / rect.width * 100,
+ value = percent / component.percent * component.step + component.min;
- if (document.cookie) {
- document.cookie = random_cookie;
+ value = (Math.round(value / component.step) * component.step);
- if (document.cookie.indexOf(random_cookie) !== -1) {
- data.browser.cookies = true;
- }
- }
+ value = Number(value.toFixed(component.precision));
+ if (component.values[handle_index] !== value) {
+ component.values[handle_index] = value;
- /*--------------------------------------------------------------
- 2.2.6 FLASH
- --------------------------------------------------------------*/
+ component.storageValue = component.values.length === 1 ? component.values[0] : component.values;
+ component.value = component.storageValue;
- try {
- if (new ActiveXObject('ShockwaveFlash.ShockwaveFlash')) {
- data.browser.flash = true;
- }
- } catch (e) {
- if (navigator.mimeTypes['application/x-shockwave-flash']) {
- data.browser.flash = true;
- }
- }
+ component.storageChange();
+ }
+ component.update();
+ }
- /*--------------------------------------------------------------
- 2.2.7 JAVA
- --------------------------------------------------------------*/
+ function mousemove(event) {
+ update(event);
+ }
- if (typeof navigator.javaEnabled === 'function' && navigator.javaEnabled()) {
- data.browser.java = true;
- }
+ function mouseup(event) {
+ window.removeEventListener('mousemove', mousemove);
+ window.removeEventListener('mouseup', mouseup);
+ };
+ window.addEventListener('mousemove', mousemove);
+ window.addEventListener('mouseup', mouseup);
- /*--------------------------------------------------------------
- 2.2.8 VIDEO FORMATS
- --------------------------------------------------------------*/
+ update(event);
- if (typeof video.canPlayType === 'function') {
- data.browser.video = {};
+ return true;
+ }
+ });
- for (var i in video_formats) {
- var can_play_type = video.canPlayType(video_formats[i]);
+ return component;
+};
+/*--------------------------------------------------------------
+>>> COLOR PICKER
+--------------------------------------------------------------*/
- if (can_play_type === '') {
- data.browser.video[i] = false;
- } else {
- data.browser.video[i] = can_play_type;
- }
- }
- }
+satus.components.colorPicker = function (skeleton) {
+ var component = document.createElement('button'),
+ component_label = document.createElement('span'),
+ component_value = document.createElement('span');
+ component.inner = component_label;
+ component.valueElement = component_value;
- /*--------------------------------------------------------------
- 2.2.9 AUDIO FORMATS
- --------------------------------------------------------------*/
+ component.className = 'satus-button';
+ component_value.className = 'satus-color-picker__value';
- if (typeof audio.canPlayType === 'function') {
- data.browser.audio = {};
+ component.appendChild(component_label);
+ component.appendChild(component_value);
- for (var i in audio_formats) {
- var can_play_type = audio.canPlayType(audio_formats[i]);
+ component.addEventListener('click', function () {
+ var rgb = this.rgb,
+ hsl = satus.color.rgbToHsl(rgb),
+ s = hsl[1] / 100,
+ l = hsl[2] / 100;
- if (can_play_type == '') {
- data.browser.audio[i] = false;
- } else {
- data.browser.audio[i] = can_play_type;
- }
- }
- }
+ s *= l < .5 ? l : 1 - l;
+ var v = l + s;
- /*--------------------------------------------------------------
- 2.2.10 WEBGL
- --------------------------------------------------------------*/
+ s = 2 * s / (l + s);
- if (ctx && ctx instanceof WebGLRenderingContext) {
- data.browser.webgl = true;
- }
+ satus.render({
+ component: 'modal',
+ variant: 'color-picker',
+ value: hsl,
+ parent: this,
+ palette: {
+ component: 'div',
+ class: 'satus-color-picker__palette',
+ style: {
+ 'backgroundColor': 'hsl(' + hsl[0] + 'deg, 100%, 50%)'
+ },
+ on: {
+ mousedown: function () {
+ var palette = this,
+ rect = this.getBoundingClientRect(),
+ cursor = this.children[0];
- /*--------------------------------------------------------------
- 3.0 HARDWARE
- --------------------------------------------------------------*/
+ function mousemove(event) {
+ var hsl = palette.skeleton.parent.value,
+ x = event.clientX - rect.left,
+ y = event.clientY - rect.top,
+ s;
- /*--------------------------------------------------------------
- 3.1 SCREEN
- --------------------------------------------------------------*/
+ x = Math.min(Math.max(x, 0), rect.width) / (rect.width / 100);
+ y = Math.min(Math.max(y, 0), rect.height) / (rect.height / 100);
- if (screen) {
- data.device.screen = screen.width + 'x' + screen.height;
- }
+ var v = 100 - y,
+ l = (2 - x / 100) * v / 2;
+ hsl[1] = x * v / (l < 50 ? l * 2 : 200 - l * 2);
+ hsl[2] = l;
- /*--------------------------------------------------------------
- 3.2 RAM
- --------------------------------------------------------------*/
+ cursor.style.left = x + '%';
+ cursor.style.top = y + '%';
- if ('deviceMemory' in navigator) {
- data.device.ram = navigator.deviceMemory + ' GB';
- }
+ palette.nextSibling.children[0].style.backgroundColor = 'hsl(' + hsl[0] + 'deg,' + hsl[1] + '%, ' + hsl[2] + '%)';
+ event.preventDefault();
+ }
- /*--------------------------------------------------------------
- 3.3 GPU
- --------------------------------------------------------------*/
+ function mouseup() {
+ window.removeEventListener('mousemove', mousemove);
+ window.removeEventListener('mouseup', mouseup);
+ }
- if (
- ctx &&
- ctx instanceof WebGLRenderingContext &&
- 'getParameter' in ctx &&
- 'getExtension' in ctx
- ) {
- var info = ctx.getExtension('WEBGL_debug_renderer_info');
+ window.addEventListener('mousemove', mousemove);
+ window.addEventListener('mouseup', mouseup);
+ }
+ },
- if (info) {
- data.device.gpu = ctx.getParameter(info.UNMASKED_RENDERER_WEBGL);
- }
- }
+ cursor: {
+ component: 'div',
+ class: 'satus-color-picker__cursor',
+ style: {
+ 'left': s * 100 + '%',
+ 'top': 100 - v * 100 + '%'
+ }
+ }
+ },
+ section: {
+ component: 'section',
+ variant: 'color',
+ color: {
+ component: 'div',
+ class: 'satus-color-picker__color',
+ style: {
+ 'backgroundColor': 'rgb(' + this.rgb.join(',') + ')'
+ }
+ },
+ hue: {
+ component: 'slider',
+ class: 'satus-color-picker__hue',
+ storage: false,
+ value: hsl[0],
+ max: 360,
+ on: {
+ change: function () {
+ var modal = this.skeleton.parent.parent,
+ hsl = modal.value;
- /*--------------------------------------------------------------
- 3.4 CORES
- --------------------------------------------------------------*/
+ hsl[0] = this.values[0];
- if (navigator.hardwareConcurrency) {
- data.device.cores = navigator.hardwareConcurrency;
- }
+ this.previousSibling.style.backgroundColor = 'hsl(' + hsl[0] + 'deg,' + hsl[1] + '%, ' + hsl[2] + '%)';
+ this.parentNode.previousSibling.style.backgroundColor = 'hsl(' + hsl[0] + 'deg, 100%, 50%)';
+ }
+ }
+ }
+ },
+ actions: {
+ component: 'section',
+ variant: 'actions',
+ reset: {
+ component: 'button',
+ text: 'reset',
+ on: {
+ click: function () {
+ var modal = this.skeleton.parent.parent,
+ component = modal.parent;
- /*--------------------------------------------------------------
- 3.5 TOUCH
- --------------------------------------------------------------*/
+ component.rgb = component.skeleton.value;
- if (
- window.hasOwnProperty('ontouchstart') ||
- window.DocumentTouch && document instanceof window.DocumentTouch ||
- navigator.maxTouchPoints > 0 ||
- window.navigator.msMaxTouchPoints > 0
- ) {
- data.device.touch = true;
- data.device.max_touch_points = navigator.maxTouchPoints;
- }
+ component.storageValue = component.rgb;
+ component.storageChange();
+ component.valueElement.style.backgroundColor = 'rgb(' + component.rgb.join(',') + ')';
- /*--------------------------------------------------------------
- 3.6 CONNECTION
- --------------------------------------------------------------*/
+ modal.rendered.close();
+ }
+ }
+ },
+ cancel: {
+ component: 'button',
+ text: 'cancel',
+ on: {
+ click: function () {
+ this.skeleton.parent.parent.rendered.close();
+ }
+ }
+ },
+ ok: {
+ component: 'button',
+ text: 'OK',
+ on: {
+ click: function () {
+ var modal = this.skeleton.parent.parent,
+ component = modal.parent;
- if (typeof navigator.connection === 'object') {
- data.device.connection.type = navigator.connection.effectiveType || null;
+ component.rgb = satus.color.hslToRgb(modal.value);
- if (navigator.connection.downlink) {
- data.device.connection.speed = navigator.connection.downlink + ' Mbps';
- }
- }
+ component.storageValue = component.rgb;
+ component.storageChange();
+ component.valueElement.style.backgroundColor = 'rgb(' + component.rgb.join(',') + ')';
- /*--------------------------------------------------------------
- 4.0 CLEARING
- --------------------------------------------------------------*/
+ modal.rendered.close();
+ }
+ }
+ }
+ }
+ });
+ });
- video.remove();
- audio.remove();
- cvs.remove();
+ component.addEventListener('render', function () {
+ component.rgb = this.storageValue || [0, 100, 50];
+ component_value.style.backgroundColor = 'rgb(' + component.rgb.join(',') + ')';
+ });
- return data;
+ return component;
};
/*--------------------------------------------------------------
->>> CONTEXT MENU
+>>> LIST
--------------------------------------------------------------*/
-satus.events.add('render', function (component, skeleton) {
- if (skeleton.contextMenu) {
- component.addEventListener('contextmenu', function (event) {
- var x = event.clientX,
- y = event.clientY,
- modal = satus.render({
- component: 'modal',
- variant: 'contextmenu',
- parent: skeleton
- });
-
- if (window.innerWidth - x < 200) {
- x = window.innerWidth - 200;
- }
-
- modal.inner.style.left = x + 'px';
- modal.inner.style.top = y + 'px';
-
- satus.render(skeleton.contextMenu, modal.inner);
-
- event.preventDefault();
- event.stopPropagation();
+satus.components.list = function (skeleton) {
+ var ul = document.createElement('ul');
- return false;
- });
- }
-});
-/*--------------------------------------------------------------
->>> EXTENSION STORAGE
---------------------------------------------------------------*/
-/*--------------------------------------------------------------
->>> PLUVIAM
---------------------------------------------------------------*/
+ for (var i = 0, l = skeleton.items.length; i < l; i++) {
+ var li = document.createElement('li'),
+ item = skeleton.items[i];
-satus.events.add('render', function (component, skeleton) {
- if (skeleton.pluviam === true) {
- function createPluviam(event) {
- var pluviam = document.createElement('span'),
- rect = this.getBoundingClientRect(),
- x = event.clientX - rect.left,
- y = event.clientY - rect.top,
- diameter = Math.sqrt(Math.pow(rect.width * 2, 2) + Math.pow(rect.height * 2, 2));
+ li.className = 'satus-list__item';
- pluviam.className = 'satus-pluviam';
+ for (var j = 0, k = item.length; j < k; j++) {
+ var child = item[j];
- pluviam.style.left = x - diameter / 2 + 'px';
- pluviam.style.top = y - diameter / 2 + 'px';
- pluviam.style.width = diameter + 'px';
- pluviam.style.height = diameter + 'px';
+ if (typeof child === 'string') {
+ var span = document.createElement('span');
- this.appendChild(pluviam);
+ span.textContent = satus.locale.get(child);
- setTimeout(function () {
- pluviam.remove();
- }, 1000);
+ li.appendChild(span);
+ } else {
+ satus.render(child, li);
+ }
}
- component.addEventListener('mousedown', createPluviam);
- component.addEventListener('mouseover', createPluviam);
+ ul.appendChild(li);
}
-});
+
+ return ul;
+};
/*--------------------------------------------------------------
->>> SORTABLE
+>>> MODAL
--------------------------------------------------------------*/
-satus.events.add('render', function (component, skeleton) {
- if (skeleton.sortable === true) {
- component.addEventListener('mousedown', function (event) {
- if (event.button !== 0) {
- return false;
- }
-
- var component = this,
- rect = this.getBoundingClientRect(),
- x = event.clientX,
- y = event.clientY,
- offset_x = event.clientX - rect.left,
- offset_y = event.clientY - rect.top,
- ghost = satus.clone(this),
- children = this.parentNode.children,
- appended = false;
-
- ghost.classList.add('satus-sortable__ghost');
-
- function mousemove(event) {
- if (appended === false && (Math.abs(event.clientX - x) > 4 || Math.abs(event.clientY - y) > 4)) {
- appended = true;
-
- component.classList.add('satus-sortable__chosen');
-
- component.parentNode.appendChild(ghost);
- }
-
- ghost.style.transform = 'translate(' + (event.clientX - offset_x) + 'px, ' + (event.clientY - offset_y) + 'px)';
- }
-
- function mouseup(event) {
- component.classList.remove('satus-sortable__chosen');
- ghost.remove();
-
- window.removeEventListener('mousemove', mousemove, true);
- window.removeEventListener('mouseup', mouseup, true);
-
- for (var i = 0, l = children.length; i < l; i++) {
- var child = children[i];
-
- if (child !== component) {
- child.removeEventListener('mouseover', siblingMouseOver);
- }
- }
-
- component.dispatchEvent(new CustomEvent('sort'));
-
- event.stopPropagation();
+satus.components.modal = function (skeleton) {
+ var component = document.createElement('div'),
+ scrim = document.createElement('div'),
+ surface = document.createElement('div');
- return false;
- }
+ component.inner = surface;
- window.addEventListener('mousemove', mousemove, {
- passive: true,
- capture: true
- });
+ scrim.className = 'satus-modal__scrim';
+ surface.className = 'satus-modal__surface';
- window.addEventListener('mouseup', mouseup, {
- passive: true,
- capture: true
- });
+ component.close = function () {
+ var component = this,
+ component_surface = this.children[1];
- function siblingMouseOver(event) {
- var target = event.target,
- parent = target.parentNode,
- y = event.layerY / (target.offsetHeight / 100);
+ this.classList.add('satus-modal--closing');
- if (y < 50 && target.previousSibling !== component || y >= 50 && target.nextSibling === component) {
- parent.insertBefore(component, target);
- } else {
- parent.insertBefore(component, target.nextSibling);
- }
- }
+ setTimeout(function () {
+ component.remove();
- for (var i = 0, l = children.length; i < l; i++) {
- var child = children[i];
+ component.dispatchEvent(new CustomEvent('close'));
+ }, satus.getAnimationDuration(component_surface));
+ };
- if (child !== component) {
- child.addEventListener('mouseover', siblingMouseOver);
- }
- }
+ scrim.addEventListener('click', function () {
+ this.parentNode.close();
+ });
- event.stopPropagation();
- event.preventDefault();
+ component.appendChild(scrim);
+ component.appendChild(surface);
- return false;
- });
- }
-});
\ No newline at end of file
+ return component;
+};
\ No newline at end of file
diff --git a/ui/script.js b/ui/script.js
new file mode 100644
index 0000000..e5a27c4
--- /dev/null
+++ b/ui/script.js
@@ -0,0 +1,842 @@
+/*--------------------------------------------------------------
+>>> TEXT EDITOR:
+----------------------------------------------------------------
+# Global variables
+# Functions
+# Skeleton
+# Initialization
+--------------------------------------------------------------*/
+
+/*--------------------------------------------------------------
+# GLOBAL VARIABLES
+--------------------------------------------------------------*/
+
+var functions = {};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*--------------------------------------------------------------
+# FUNCTIONS
+--------------------------------------------------------------*/
+
+/*--------------------------------------------------------------
+# NEW FILE
+--------------------------------------------------------------*/
+
+functions.newFile = function () {
+ var textarea = skeleton.main.textarea.rendered;
+
+ textarea.indexId = undefined;
+ textarea.name = undefined;
+ textarea.value = '';
+
+ satus.indexeddb.clear('session');
+
+ skeleton.footer.section_align_start.span.rendered.update();
+ skeleton.footer.section_align_end.span.rendered.update();
+};
+
+
+/*--------------------------------------------------------------
+# OPEN FILE
+--------------------------------------------------------------*/
+
+functions.openFile = function (id) {
+ satus.indexeddb.clear('session');
+
+ satus.indexeddb.getByKey({
+ content: [
+ id
+ ],
+ files: [
+ id
+ ]
+ }, function (items) {
+ if (items.files[0]) {
+ var textarea = skeleton.main.textarea.rendered;
+
+ textarea.indexId = id;
+ textarea.name = items.files[0].name;
+ textarea.value = items.content[0].content;
+
+ skeleton.main.sidebar.list.update();
+
+ skeleton.footer.section_align_start.span.rendered.update();
+ skeleton.footer.section_align_end.span.rendered.update();
+
+ satus.indexeddb.set({
+ session: [
+ {id}
+ ]
+ });
+ }
+ });
+};
+
+
+/*--------------------------------------------------------------
+# SAVE
+--------------------------------------------------------------*/
+
+functions.save = function (name, content, id) {
+ if (satus.isset(id) || name) {
+ var object = {
+ time: new Date().getTime(),
+ name: name
+ };
+
+ if (id) {
+ object.id = id;
+ }
+
+ satus.indexeddb.clear('session');
+
+ satus.indexeddb.set({
+ files: [
+ object
+ ]
+ }, function () {
+ satus.indexeddb.get({
+ files: {
+ direction: 'prev',
+ limit: 1
+ }
+ }, function (items) {
+ if (items.files[0]) {
+ skeleton.main.textarea.indexId = items.files[0].id;
+
+ satus.indexeddb.set({
+ content: [
+ {
+ id: items.files[0].id,
+ content: content
+ }
+ ],
+ session: [
+ {
+ id: items.files[0].id
+ }
+ ]
+ }, function () {
+ satus.indexeddb.get({
+ content: {
+ direction: 'prev',
+ limit: 1
+ }
+ }, function (items) {
+ if (items.content[0]) {
+ skeleton.main.sidebar.list.update();
+ }
+ });
+ });
+ }
+ });
+ });
+ } else {
+ satus.render({
+ component: 'modal',
+
+ input: {
+ component: 'input',
+ properties: {
+ type: 'text',
+ value: name || 'untitled'
+ },
+ on: {
+ render: function () {
+ this.focus();
+ }
+ }
+ },
+ section_align_end: {
+ component: 'section',
+ variant: 'actions',
+
+ cancel: {
+ component: 'button',
+ text: 'cancel',
+ on: {
+ click: function () {
+ this.parentNode.parentNode.parentNode.close();
+ }
+ }
+ },
+ save: {
+ component: 'button',
+ text: 'save',
+ on: {
+ click: function () {
+ var modal = this.parentNode.parentNode.parentNode;
+
+ functions.save(modal.skeleton.input.rendered.value, content, id);
+
+ modal.close();
+ }
+ }
+ }
+ }
+ });
+ }
+};
+
+
+/*--------------------------------------------------------------
+# SAVE AS
+--------------------------------------------------------------*/
+
+functions.saveAs = function () {
+ var textarea = skeleton.main.textarea.rendered;
+
+ chrome.permissions.request({
+ permissions: ['downloads']
+ }, function (granted) {
+ if (granted) {
+ chrome.downloads.download({
+ url: URL.createObjectURL(new Blob([textarea.value], {
+ type: 'text/plain;charset=utf-8'
+ })),
+ filename: textarea.name || 'untitled',
+ saveAs: true
+ });
+ }
+ });
+};
+
+
+/*--------------------------------------------------------------
+# IMPORT
+--------------------------------------------------------------*/
+
+functions.import = function () {
+ var input = document.createElement('input');
+
+ input.type = 'file';
+
+ input.addEventListener('change', function () {
+ var file_reader = new FileReader();
+
+ file_reader.onload = function (event) {
+ var textarea = skeleton.main.textarea.rendered;
+
+ textarea.name = input.files[0].name;
+ textarea.value = this.result;
+
+ skeleton.footer.section_align_start.span.rendered.update();
+ skeleton.footer.section_align_end.span.rendered.update();
+
+ functions.save(
+ textarea.name,
+ textarea.value
+ );
+ };
+
+ file_reader.readAsText(this.files[0]);
+ });
+
+ input.click();
+};
+
+
+/*--------------------------------------------------------------
+# DELETE
+--------------------------------------------------------------*/
+
+functions.delete = function (id) {
+ satus.render({
+ component: 'modal',
+
+ label: {
+ component: 'span',
+ text: 'areYouSureYouWantToDeleteTheFile'
+ },
+ section: {
+ component: 'section',
+ variant: 'actions',
+
+ cancel: {
+ component: 'button',
+ text: 'cancel',
+ on: {
+ click: function () {
+ var modal = this.parentNode.parentNode.parentNode;
+
+ modal.close();
+ }
+ }
+ },
+ delete: {
+ component: 'button',
+ text: 'delete',
+ on: {
+ click: function () {
+ var modal = this.parentNode.parentNode.parentNode;
+
+ satus.indexeddb.delete({
+ content: {
+ id: [id]
+ },
+ files: {
+ id: [id]
+ },
+ session: {
+ id: [id]
+ }
+ }, function () {
+ var textarea = skeleton.main.textarea.rendered;
+
+ textarea.indexId = null;
+ textarea.name = undefined;
+ textarea.value = '';
+
+ skeleton.footer.section_align_start.span.rendered.update();
+ skeleton.footer.section_align_end.span.rendered.update();
+
+ satus.indexeddb.set({
+ session: [
+ {id}
+ ]
+ }, function () {
+ skeleton.main.sidebar.list.update();
+ });
+ });
+
+ modal.close();
+ }
+ }
+ }
+ }
+ });
+};
+
+
+/*--------------------------------------------------------------
+# CLOSE FILE
+--------------------------------------------------------------*/
+
+functions.closeFile = function () {
+ var textarea = skeleton.main.textarea.rendered;
+
+ textarea.indexId = null;
+ textarea.name = undefined;
+ textarea.value = '';
+
+ satus.indexeddb.clear('session');
+
+ skeleton.main.sidebar.list.update();
+
+ skeleton.footer.section_align_start.span.rendered.update();
+ skeleton.footer.section_align_end.span.rendered.update();
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*--------------------------------------------------------------
+# SKELETON
+--------------------------------------------------------------*/
+
+var skeleton = {
+ component: 'base',
+
+ menubar: {
+ component: 'menubar',
+ items: {
+ file: {
+ component: 'button',
+ text: 'file',
+ items: {
+ newFile: {
+ component: 'button',
+ text: 'newFile',
+ on: {
+ click: functions.newFile
+ }
+ },
+ openFile: {
+ component: 'button',
+ text: 'openFile',
+ on: {
+ click: functions.import
+ }
+ },
+ save: {
+ component: 'button',
+ text: 'save',
+ on: {
+ click: function () {
+ var textarea = skeleton.main.textarea.rendered;
+
+ textarea.saved = true;
+
+ functions.save(
+ textarea.name,
+ textarea.value
+ );
+ }
+ }
+ },
+ saveAs: {
+ component: 'button',
+ text: 'saveAs',
+ on: {
+ click: functions.saveAs
+ }
+ },
+ deleteFile: {
+ component: 'button',
+ text: 'deleteFile',
+ on: {
+ click: function () {
+ functions.delete(skeleton.main.textarea.rendered.indexId);
+ }
+ }
+ },
+ closeFile: {
+ component: 'button',
+ text: 'closeFile',
+ on: {
+ click: function () {
+ functions.closeFile();
+ }
+ }
+ },
+ quit: {
+ component: 'button',
+ text: 'quit',
+ on: {
+ click: function () {
+ window.close();
+ }
+ }
+ }
+ }
+ },
+ edit: {
+ component: 'button',
+ text: 'edit',
+ items: {
+ undo: {
+ component: 'button',
+ text: 'undo',
+ on: {
+ click: function () {
+ document.execCommand('undo', false, null);
+
+ }
+ }
+ },
+ redo: {
+ component: 'button',
+ text: 'redo',
+ on: {
+ click: function () {
+ document.execCommand('redo', false, null);
+ }
+ }
+ }
+ }
+ },
+ help: {
+ component: 'button',
+ text: 'help',
+ items: {
+ reportABug: {
+ component: 'button',
+ text: 'reportABug',
+ on: {
+ click: function () {
+ window.open('https://github.com/victor-savinov/text-editor/issues', '_blank');
+ }
+ }
+ },
+ github: {
+ component: 'button',
+ text: 'GitHub',
+ on: {
+ click: function () {
+ window.open('https://github.com/victor-savinov/text-editor', '_blank');
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ main: {
+ component: 'main',
+
+ sidebar: {
+ component: 'sidebar',
+ class: 'empty',
+
+ h1: {
+ component: 'h1',
+ text: 'files'
+ },
+ list: {
+ component: 'ul',
+ on: {
+ render: function () {
+ this.skeleton.update();
+ }
+ },
+ update: function () {
+ var list = this.rendered;
+
+ satus.indexeddb.get({
+ files: {
+ index: 'time'
+ }
+ }, function (items) {
+ var textarea = skeleton.main.textarea.rendered;
+
+ satus.empty(list);
+
+ if (items.files.length > 0) {
+ skeleton.main.sidebar.rendered.classList.remove('empty');
+ } else {
+ skeleton.main.sidebar.rendered.classList.add('empty');
+ }
+
+ for (var i = 0, l = items.files.length; i < l; i++) {
+ var file = items.files[i];
+
+ satus.render({
+ component: 'li',
+ text: file.name || 'untitled',
+ class: file.id === textarea.indexId ? 'selected' : '',
+ properties: {
+ indexId: file.id
+ },
+ on: {
+ click: function () {
+ functions.openFile(this.indexId);
+ }
+ },
+ contextMenu: {
+ rename: {
+ component: 'button',
+ text: 'rename',
+ on: {
+ click: function () {
+ var modal = this.parentNode.parentNode,
+ file = modal.skeleton.parent.rendered;
+
+ satus.render({
+ component: 'modal',
+
+ input: {
+ component: 'input',
+ properties: {
+ type: 'text',
+ value: file.textContent
+ },
+ on: {
+ render: function () {
+ this.focus();
+ }
+ }
+ },
+ section_align_end: {
+ component: 'section',
+ variant: 'actions',
+
+ cancel: {
+ component: 'button',
+ text: 'cancel',
+ on: {
+ click: function () {
+ this.parentNode.parentNode.parentNode.close();
+ }
+ }
+ },
+ save: {
+ component: 'button',
+ text: 'save',
+ on: {
+ click: function () {
+ var modal = this.parentNode.parentNode.parentNode;
+
+ satus.indexeddb.set({
+ files: [
+ {
+ id: file.indexId,
+ name: modal.skeleton.input.rendered.value,
+ time: new Date().getTime()
+ }
+ ]
+ }, function () {
+ skeleton.main.sidebar.list.update();
+ });
+
+ modal.close();
+ }
+ }
+ }
+ }
+ });
+
+ modal.close();
+ }
+ }
+ },
+ delete: {
+ component: 'button',
+ text: 'delete',
+ on: {
+ click: function () {
+ var modal = this.parentNode.parentNode;
+
+ functions.delete(modal.skeleton.parent.rendered.indexId);
+
+ modal.close();
+ }
+ }
+ }
+ }
+ }, list);
+ }
+ });
+ }
+ }
+ },
+ textarea: {
+ component: 'textarea',
+ properties: {
+ saved: false
+ },
+ on: {
+ input: function () {
+ this.saved = false;
+ },
+ selectionchange: function () {
+ skeleton.footer.section_align_start.span.rendered.update();
+ skeleton.footer.section_align_end.span.rendered.update();
+ }
+ }
+ }
+ },
+ footer: {
+ component: 'footer',
+
+ section_align_start: {
+ component: 'section',
+ variant: 'align-start',
+
+ span: {
+ component: 'span',
+ text: function () {
+ return satus.locale.get('line') + ' 1, ' + satus.locale.get('column') + ' 1';
+ },
+ properties: {
+ update: function () {
+ var textarea = skeleton.main.textarea.rendered,
+ message = skeleton.footer.section_align_start.span.rendered,
+ selection_start = textarea.textarea.selectionStart,
+ selection_end = textarea.textarea.selectionEnd;
+
+ if (selection_start === selection_end) {
+ if (textarea.textarea.selectionDirection === 'forward') {
+ var column = textarea.textarea.selectionEnd;
+ } else {
+ var column = textarea.textarea.selectionStart;
+ }
+
+ var lines = textarea.value.slice(0, column).split('\n');
+
+ message.textContent = satus.locale.get('line') + ' ' + lines.length + ', ' + satus.locale.get('column') + ' ' + (lines[lines.length - 1].length + 1);
+ } else {
+ var min = Math.min(selection_start, selection_end),
+ max = Math.max(selection_start, selection_end),
+ selected_text = textarea.value.slice(min, max);
+
+ message.textContent = selected_text.split('\n').length + ' ' + satus.locale.get('lines') + ', ' + selected_text.length + ' ' + satus.locale.get('characters') + ' ' + satus.locale.get('selected');
+ }
+ }
+ }
+ }
+ },
+ section_align_end: {
+ component: 'section',
+ variant: 'align-end',
+
+ span: {
+ component: 'span',
+ style: {
+ textTransform: 'capitalize'
+ },
+ text: function () {
+ return satus.locale.get('characters') + ' 0, ' + satus.locale.get('bytes') + ' 0';
+ },
+ properties: {
+ update: function () {
+ var value = skeleton.main.textarea.rendered.value,
+ message = skeleton.footer.section_align_end.span.rendered;
+
+ message.textContent = satus.locale.get('characters') + ' ' + value.length + ', ' + satus.locale.get('bytes') + ' ' + new Blob([value]).size;
+ }
+ }
+ }
+ }
+ }
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*--------------------------------------------------------------
+# KEYBOARD
+--------------------------------------------------------------*/
+
+window.addEventListener('keydown', function (event) {
+ if (event.code === 'KeyN' && event.ctrlKey === true) {
+ event.preventDefault();
+ event.stopPropagation();
+
+ functions.newFile();
+
+ return false;
+ } else if (event.code === 'KeyO' && event.ctrlKey === true) {
+ event.preventDefault();
+ event.stopPropagation();
+
+ functions.import();
+
+ return false;
+ } else if (event.code === 'KeyS' && event.ctrlKey === true && event.shiftKey === true) {
+ event.preventDefault();
+ event.stopPropagation();
+
+ functions.saveAs();
+
+ return false;
+ } else if (event.code === 'KeyS' && event.ctrlKey === true) {
+ var textarea = skeleton.main.textarea.rendered;
+
+ event.preventDefault();
+ event.stopPropagation();
+
+ functions.save(textarea.name, textarea.value, textarea.indexId);
+
+ return false;
+ } else if (event.code === 'KeyQ' && event.ctrlKey === true) {
+ event.preventDefault();
+ event.stopPropagation();
+
+ window.close();
+
+ return false;
+ }
+}, true);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*--------------------------------------------------------------
+# INITIALIZATION
+--------------------------------------------------------------*/
+
+satus.indexeddb.open('text-editor', {
+ files: {
+ indexes: [
+ 'id',
+ 'time',
+ 'name'
+ ],
+ keyOptions: {
+ keyPath: 'id',
+ autoIncrement: true
+ }
+ },
+ content: {
+ indexes: [
+ 'id',
+ 'content'
+ ],
+ keyOptions: {
+ keyPath: 'id',
+ autoIncrement: false
+ }
+ },
+ session: {
+ indexes: [
+ 'id'
+ ],
+ keyOptions: {
+ keyPath: 'id'
+ }
+ },
+ options: {
+ indexes: [
+ 'key',
+ 'value'
+ ],
+ keyOptions: {
+ keyPath: 'key'
+ }
+ }
+}, function () {
+ satus.indexeddb.get({
+ session: {},
+ options: {}
+ }, function (items) {
+ console.log('options', items);
+
+ satus.locale.import(items.options.language, '../_locales/', function () {
+ satus.render(skeleton);
+
+ if (items.session[0]) {
+ functions.openFile(items.session[0].id);
+ }
+ });
+ });
+});
\ No newline at end of file
diff --git a/ui/styles.css b/ui/styles.css
new file mode 100644
index 0000000..371ea64
--- /dev/null
+++ b/ui/styles.css
@@ -0,0 +1,134 @@
+/*--------------------------------------------------------------
+>>> TEXT EDITOR
+----------------------------------------------------------------
+# Body
+# Menubar
+# Textarea
+# Footer
+--------------------------------------------------------------*/
+
+/*--------------------------------------------------------------
+# BODY
+--------------------------------------------------------------*/
+
+body {
+ --satus-contrast: 255, 255, 255;
+ --satus-menubar-background: #1a1f23;
+ --satus-menubar-text: #8a8f93;
+ --satus-menubar-hover: rgba(var(--satus-contrast), .1);
+ --satus-textarea-background: #2f3841;
+ --satus-textarea-color: #d8dee9;
+ --satus-footer-background: #1a1f23;
+ --satus-footer-text: #8a8f93;
+ --satus-main-background: #1a1f23;
+ --satus-main-text: #8a8f93;
+ --satus-modal-background: #1a1f23;
+ --satus-modal-text: #d8dee9;
+ --satus-text-field--background: #23292f;
+ --satus-text-field--border: #272e35;
+ --satus-text-field--text: #d8dee9;
+}
+
+
+/*--------------------------------------------------------------
+# MENUBAR
+--------------------------------------------------------------*/
+
+.satus-menubar {
+ z-index: 1;
+}
+
+
+/*--------------------------------------------------------------
+# SIDEBAR
+--------------------------------------------------------------*/
+
+.satus-sidebar {
+ width: 16px;
+ background: #1e2429;
+ overflow: hidden;
+ transition: 200ms;
+}
+
+.satus-sidebar.empty {
+ width: 0;
+}
+
+.page .satus-sidebar:not(.empty) {
+ width: 256px;
+}
+
+.satus-sidebar:hover {
+ width: 256px;
+}
+
+.satus-sidebar .satus-h1 {
+ display: block;
+ font-size: 15px;
+ font-weight: 700;
+ margin: 8px 16px;
+ text-transform: uppercase;
+}
+
+.satus-sidebar .satus-ul {
+ display: block;
+ padding: 0;
+ list-style: none;
+}
+
+.satus-sidebar li {
+ display: block;
+ font-size: 14px;
+ padding: 4px 16px;
+}
+
+.satus-sidebar li.selected {
+ background: rgba(255,255,255,.05);
+}
+
+.satus-sidebar li:hover {
+ background: rgba(var(--satus-contrast), .1);
+ cursor: pointer;
+}
+
+
+/*--------------------------------------------------------------
+# TEXTAREA
+--------------------------------------------------------------*/
+
+.satus-main {
+ flex: 1;
+ display: flex;
+}
+
+.satus-textarea {
+ padding: 4px 0;
+ flex: 1;
+}
+
+
+/*--------------------------------------------------------------
+# FOOTER
+--------------------------------------------------------------*/
+
+.satus-footer {
+ font-size: 14px;
+ display: flex;
+ box-sizing: border-box;
+ height: 32px;
+ padding: 0 8px;
+ color: var(--satus-footer-text);
+ background: var(--satus-footer-background);
+ justify-content: space-between;
+ align-items: center;
+}
+
+.satus-footer .satus-section> :not(:last-child)::after {
+ margin: 0 4px 0 0;
+ content: ',';
+}
+
+.satus-footer .satus-section>*> :not(:last-child)::after {
+ margin: 0 4px 0 0;
+ content: ' ';
+}
\ No newline at end of file