mirror of
https://github.com/atom/atom.git
synced 2026-04-06 03:02:13 -04:00
Merge branch 'master' of github.com:github/atom
This commit is contained in:
1
.pairs
1
.pairs
@@ -2,6 +2,7 @@ pairs:
|
||||
ns: Nathan Sobo; nathan
|
||||
cj: Corey Johnson; cj
|
||||
dg: David Graham; dgraham
|
||||
ks: Kevin Sawicki; kevin
|
||||
email:
|
||||
domain: github.com
|
||||
#global: true
|
||||
|
||||
2
Atom-Linux/.gitignore
vendored
2
Atom-Linux/.gitignore
vendored
@@ -1,2 +1,2 @@
|
||||
bin/
|
||||
/atom
|
||||
*.o
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
INSTALLDIR=/usr/share/atom
|
||||
|
||||
CXXFLAGS := -Werror \
|
||||
-pthread \
|
||||
-fno-exceptions \
|
||||
@@ -36,6 +38,7 @@ LDFLAGS := -pthread \
|
||||
-Wl,-O1 \
|
||||
-Wl,--as-needed \
|
||||
-Wl,--gc-sections \
|
||||
-Wl,-rpath=$(INSTALLDIR)
|
||||
|
||||
LIBS := -lX11 \
|
||||
-lgtk-x11-2.0 \
|
||||
@@ -56,32 +59,34 @@ LIBS := -lX11 \
|
||||
-lssl \
|
||||
-lcrypto \
|
||||
-lcef \
|
||||
-lcef_dll_wrapper
|
||||
-lcef_dll_wrapper \
|
||||
-lonig
|
||||
|
||||
SOURCES=atom.cpp native_handler.cpp client_handler.cpp
|
||||
SOURCES=atom.cpp native_handler.cpp client_handler.cpp onig_regexp_extension.cpp io_utils.cpp
|
||||
OBJECTS=$(SOURCES:.cpp=.o)
|
||||
INSTALLDIR=/usr/local/atom
|
||||
|
||||
all:
|
||||
g++ $(CXXFLAGS) -c $(SOURCES)
|
||||
mkdir -p bin
|
||||
cp chrome.pak bin/
|
||||
cp -R locales bin/
|
||||
cp atom.png bin/
|
||||
g++ -o bin/atom $(OBJECTS) $(LDFLAGS) $(LIBS)
|
||||
g++ -o atom $(OBJECTS) $(LDFLAGS) $(LIBS)
|
||||
|
||||
clean:
|
||||
rm -rf bin *.o
|
||||
rm -rf atom *.o
|
||||
|
||||
install:
|
||||
mkdir -p $(INSTALLDIR)
|
||||
cp -R bin $(INSTALLDIR)
|
||||
cp -R lib $(INSTALLDIR)
|
||||
cp atom $(INSTALLDIR)
|
||||
cp chrome.pak $(INSTALLDIR)
|
||||
cp -R locales $(INSTALLDIR)
|
||||
cp atom.png $(INSTALLDIR)
|
||||
cp lib/libcef.so $(INSTALLDIR)
|
||||
cp lib/libcef_dll_wrapper.a $(INSTALLDIR)
|
||||
cp -R ../src $(INSTALLDIR)
|
||||
cp -R ../static $(INSTALLDIR)
|
||||
cp -R ../vendor $(INSTALLDIR)
|
||||
cp -R ../bundles $(INSTALLDIR)
|
||||
cp -R ../themes $(INSTALLDIR)
|
||||
cp ../index.html $(INSTALLDIR)
|
||||
coffee -c -o $(INSTALLDIR)/src/stdlib ../src/stdlib/require.coffee
|
||||
ln -sf $(INSTALLDIR)/atom /usr/local/bin/atom
|
||||
|
||||
spec-install: install
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/bin/sh
|
||||
case $0 in
|
||||
/* )
|
||||
root=${0%atom}
|
||||
;;
|
||||
* )
|
||||
root=`pwd`/${0%atom}
|
||||
;;
|
||||
esac
|
||||
export LD_LIBRARY_PATH=$root'../atom/lib':$LD_LIBRARY_PATH
|
||||
$root'../atom/bin/atom' $@
|
||||
@@ -3,8 +3,6 @@
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include "atom.h"
|
||||
@@ -13,6 +11,8 @@
|
||||
#include "include/cef_frame.h"
|
||||
#include "include/cef_runnable.h"
|
||||
#include "client_handler.h"
|
||||
#include "onig_regexp_extension.h"
|
||||
#include "io_utils.h"
|
||||
|
||||
char* szWorkingDir; // The current working directory
|
||||
|
||||
@@ -58,9 +58,11 @@ int main(int argc, char *argv[]) {
|
||||
if (szWorkingDir == NULL)
|
||||
return -1;
|
||||
|
||||
std::string fullPath = argv[0];
|
||||
fullPath = fullPath.substr(0, fullPath.length() - 5);
|
||||
szPath = fullPath.c_str();
|
||||
std::string appDir = io_util_app_directory();
|
||||
if (appDir.empty())
|
||||
return -1;
|
||||
|
||||
szPath = appDir.c_str();
|
||||
|
||||
std::string pathToOpen;
|
||||
if (argc >= 2) {
|
||||
@@ -102,23 +104,20 @@ int main(int argc, char *argv[]) {
|
||||
g_handler->SetMainHwnd(vbox);
|
||||
g_handler->SetWindow(window);
|
||||
|
||||
new OnigRegexpExtension();
|
||||
|
||||
// Create the browser view.
|
||||
CefWindowInfo window_info;
|
||||
CefBrowserSettings browserSettings;
|
||||
|
||||
window_info.SetAsChild(vbox);
|
||||
|
||||
std::string path;
|
||||
path.append(szPath);
|
||||
path.append("/../index.html");
|
||||
char* realPath;
|
||||
realPath = realpath(path.c_str(), NULL);
|
||||
if (realPath == NULL)
|
||||
std::string path = io_utils_real_app_path("/index.html");
|
||||
if (path.empty())
|
||||
return -1;
|
||||
|
||||
std::string resolved("file://");
|
||||
resolved.append(realPath);
|
||||
free(realPath);
|
||||
resolved.append(path);
|
||||
|
||||
CefBrowser::CreateBrowserSync(window_info,
|
||||
static_cast<CefRefPtr<CefClient> >(g_handler), resolved, browserSettings);
|
||||
@@ -159,4 +158,3 @@ std::string AppPath() {
|
||||
std::string PathToOpen() {
|
||||
return szPathToOpen;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_CEFCLIENT_H_
|
||||
#define CEF_TESTS_CEFCLIENT_CEFCLIENT_H_
|
||||
#ifndef ATOM_H_
|
||||
#define ATOM_H_
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
@@ -31,4 +27,4 @@ std::string PathToOpen();
|
||||
// Returns the application settings
|
||||
void AppGetSettings(CefSettings& settings, CefRefPtr<CefApp>& app);
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_CEFCLIENT_H_
|
||||
#endif
|
||||
|
||||
@@ -11,11 +11,13 @@
|
||||
#include "include/cef_frame.h"
|
||||
#include "atom.h"
|
||||
#include "native_handler.h"
|
||||
#include "atom.h"
|
||||
#include <stdlib.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
ClientHandler::ClientHandler() :
|
||||
m_MainHwnd(NULL), m_BrowserHwnd(NULL) {
|
||||
m_nativeHandler = new NativeHandler();
|
||||
}
|
||||
|
||||
ClientHandler::~ClientHandler() {
|
||||
@@ -73,7 +75,7 @@ void ClientHandler::OnLoadStart(CefRefPtr<CefBrowser> browser,
|
||||
global->SetValue("$windowNumber", windowNumber, V8_PROPERTY_ATTRIBUTE_NONE);
|
||||
|
||||
std::string path;
|
||||
if (m_nativeHandler)
|
||||
if (m_nativeHandler && !m_nativeHandler->path.empty())
|
||||
path = m_nativeHandler->path;
|
||||
else
|
||||
path.append(PathToOpen());
|
||||
@@ -81,28 +83,14 @@ void ClientHandler::OnLoadStart(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefV8Value> pathToOpen = CefV8Value::CreateString(path);
|
||||
global->SetValue("$pathToOpen", pathToOpen, V8_PROPERTY_ATTRIBUTE_NONE);
|
||||
|
||||
CefRefPtr<NativeHandler> nativeHandler = new NativeHandler();
|
||||
nativeHandler->window = window;
|
||||
nativeHandler->path = path;
|
||||
global->SetValue("$native", nativeHandler->object,
|
||||
V8_PROPERTY_ATTRIBUTE_NONE);
|
||||
m_nativeHandler = nativeHandler;
|
||||
m_nativeHandler->window = window;
|
||||
m_nativeHandler->path = path;
|
||||
|
||||
CefRefPtr<CefV8Value> atom = CefV8Value::CreateObject(NULL, NULL);
|
||||
global->SetValue("atom", atom, V8_PROPERTY_ATTRIBUTE_NONE);
|
||||
|
||||
std::string relativePath(AppPath());
|
||||
relativePath.append("/..");
|
||||
char* realLoadPath;
|
||||
realLoadPath = realpath(relativePath.c_str(), NULL);
|
||||
if (realLoadPath != NULL) {
|
||||
std::string resolvedLoadPath(realLoadPath);
|
||||
free(realLoadPath);
|
||||
|
||||
CefRefPtr<CefV8Value> loadPath = CefV8Value::CreateString(
|
||||
resolvedLoadPath);
|
||||
atom->SetValue("loadPath", loadPath, V8_PROPERTY_ATTRIBUTE_NONE);
|
||||
}
|
||||
CefRefPtr<CefV8Value> loadPath = CefV8Value::CreateString(AppPath());
|
||||
atom->SetValue("loadPath", loadPath, V8_PROPERTY_ATTRIBUTE_NONE);
|
||||
|
||||
CefRefPtr<CefV8Value> bootstrapScript = CefV8Value::CreateString(
|
||||
"single-window-bootstrap");
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_CLIENT_HANDLER_H_
|
||||
#define CEF_TESTS_CEFCLIENT_CLIENT_HANDLER_H_
|
||||
#ifndef CLIENT_HANDLER_H_
|
||||
#define CLIENT_HANDLER_H_
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
@@ -156,4 +152,4 @@ IMPLEMENT_LOCKING(ClientHandler)
|
||||
;
|
||||
};
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_CLIENT_HANDLER_H_
|
||||
#endif
|
||||
|
||||
49
Atom-Linux/io_utils.cpp
Normal file
49
Atom-Linux/io_utils.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include "io_utils.h"
|
||||
#include "atom.h"
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define BUFFER_SIZE 8192
|
||||
|
||||
using namespace std;
|
||||
|
||||
int io_utils_read(string path, string* output) {
|
||||
int fd = open(path.c_str(), O_RDONLY);
|
||||
if (fd <= 0)
|
||||
return 0;
|
||||
|
||||
char buffer[BUFFER_SIZE];
|
||||
unsigned int bytesRead = 0;
|
||||
unsigned int totalRead = 0;
|
||||
while ((bytesRead = read(fd, buffer, BUFFER_SIZE)) > 0) {
|
||||
output->append(buffer, 0, bytesRead);
|
||||
totalRead += bytesRead;
|
||||
}
|
||||
close(fd);
|
||||
return totalRead;
|
||||
}
|
||||
|
||||
string io_utils_real_app_path(string relativePath) {
|
||||
string path = AppPath() + relativePath;
|
||||
char* realPath = realpath(path.c_str(), NULL);
|
||||
if (realPath != NULL) {
|
||||
string realAppPath(realPath);
|
||||
free(realPath);
|
||||
return realAppPath;
|
||||
} else
|
||||
return "";
|
||||
}
|
||||
|
||||
string io_util_app_directory() {
|
||||
char path[BUFFER_SIZE];
|
||||
if (readlink("/proc/self/exe", path, BUFFER_SIZE) < 2)
|
||||
return "";
|
||||
|
||||
string appPath(path);
|
||||
unsigned int lastSlash = appPath.rfind("/");
|
||||
if (lastSlash != string::npos)
|
||||
return appPath.substr(0, lastSlash);
|
||||
else
|
||||
return appPath;
|
||||
}
|
||||
22
Atom-Linux/io_utils.h
Normal file
22
Atom-Linux/io_utils.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef IO_UTILS_H_
|
||||
#define IO_UTILS_H_
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* Read file at path and append to output string
|
||||
*/
|
||||
int io_utils_read(std::string path, std::string* output);
|
||||
|
||||
/**
|
||||
* Get realpath for given path that is relative to the app path
|
||||
*/
|
||||
std::string io_utils_real_app_path(std::string relativePath);
|
||||
|
||||
/**
|
||||
* Get path to directory where atom app resides
|
||||
*/
|
||||
std::string io_util_app_directory();
|
||||
|
||||
#endif
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "include/cef_base.h"
|
||||
#include "include/cef_runnable.h"
|
||||
#include "client_handler.h"
|
||||
#include "io_utils.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
@@ -50,19 +51,11 @@ void ExecuteWatchCallback(NotifyContext notifyContext) {
|
||||
|
||||
NativeHandler::NativeHandler() :
|
||||
CefV8Handler() {
|
||||
object = CefV8Value::CreateObject(NULL, NULL);
|
||||
|
||||
const char *functionNames[] = { "exists", "alert", "read", "write",
|
||||
"absolute", "list", "isFile", "isDirectory", "remove", "asyncList",
|
||||
"open", "openDialog", "quit", "writeToPasteboard", "readFromPasteboard",
|
||||
"showDevTools", "newWindow", "saveDialog", "exit", "watchPath",
|
||||
"unwatchPath", "makeDirectory", "move", "moveToTrash", "md5ForPath" };
|
||||
int arrayLength = sizeof(functionNames) / sizeof(const char *);
|
||||
for (int i = 0; i < arrayLength; i++) {
|
||||
const char *functionName = functionNames[i];
|
||||
CefRefPtr<CefV8Value> function = CefV8Value::CreateFunction(functionName,
|
||||
this);
|
||||
object->SetValue(functionName, function, V8_PROPERTY_ATTRIBUTE_NONE);
|
||||
string nativePath = io_utils_real_app_path("/src/stdlib/native-handler.js");
|
||||
if (!nativePath.empty()) {
|
||||
string extensionCode;
|
||||
if (io_utils_read(nativePath, &extensionCode) > 0)
|
||||
CefRegisterExtension("v8/native-handler", extensionCode, this);
|
||||
}
|
||||
|
||||
notifyFd = inotify_init();
|
||||
@@ -109,16 +102,8 @@ void NativeHandler::Read(const CefString& name, CefRefPtr<CefV8Value> object,
|
||||
const CefV8ValueList& arguments, CefRefPtr<CefV8Value>& retval,
|
||||
CefString& exception) {
|
||||
string path = arguments[0]->GetStringValue().ToString();
|
||||
int fd = open(path.c_str(), O_RDONLY);
|
||||
if (fd < 0)
|
||||
return;
|
||||
|
||||
char buffer[8192];
|
||||
int r;
|
||||
string value;
|
||||
while ((r = read(fd, buffer, sizeof buffer)) > 0)
|
||||
value.append(buffer, 0, r);
|
||||
close(fd);
|
||||
io_utils_read(path, &value);
|
||||
retval = CefV8Value::CreateString(value);
|
||||
}
|
||||
|
||||
@@ -276,10 +261,10 @@ void NativeHandler::Write(const CefString& name, CefRefPtr<CefV8Value> object,
|
||||
string path = arguments[0]->GetStringValue().ToString();
|
||||
string content = arguments[1]->GetStringValue().ToString();
|
||||
|
||||
ofstream myfile;
|
||||
myfile.open(path.c_str());
|
||||
myfile << content;
|
||||
myfile.close();
|
||||
ofstream file;
|
||||
file.open(path.c_str());
|
||||
file << content;
|
||||
file.close();
|
||||
}
|
||||
|
||||
void NativeHandler::WriteToPasteboard(const CefString& name,
|
||||
@@ -457,7 +442,7 @@ void NativeHandler::Digest(const CefString& name, CefRefPtr<CefV8Value> object,
|
||||
EVP_MD_CTX_init(&context);
|
||||
EVP_DigestInit_ex(&context, md, NULL);
|
||||
|
||||
char buffer[8192];
|
||||
char buffer[BUFFER_SIZE];
|
||||
int r;
|
||||
while ((r = read(fd, buffer, sizeof buffer)) > 0)
|
||||
EVP_DigestUpdate(&context, buffer, r);
|
||||
@@ -477,6 +462,17 @@ void NativeHandler::Digest(const CefString& name, CefRefPtr<CefV8Value> object,
|
||||
retval = CefV8Value::CreateString(md5.str());
|
||||
}
|
||||
|
||||
void NativeHandler::LastModified(const CefString& name,
|
||||
CefRefPtr<CefV8Value> object, const CefV8ValueList& arguments,
|
||||
CefRefPtr<CefV8Value>& retval, CefString& exception) {
|
||||
string path = arguments[0]->GetStringValue().ToString();
|
||||
struct stat statInfo;
|
||||
if (stat(path.c_str(), &statInfo) == 0) {
|
||||
CefTime time(statInfo.st_mtime);
|
||||
retval = CefV8Value::CreateDate(time);
|
||||
}
|
||||
}
|
||||
|
||||
bool NativeHandler::Execute(const CefString& name, CefRefPtr<CefV8Value> object,
|
||||
const CefV8ValueList& arguments, CefRefPtr<CefV8Value>& retval,
|
||||
CefString& exception) {
|
||||
@@ -520,6 +516,10 @@ bool NativeHandler::Execute(const CefString& name, CefRefPtr<CefV8Value> object,
|
||||
UnwatchPath(name, object, arguments, retval, exception);
|
||||
else if (name == "md5ForPath")
|
||||
Digest(name, object, arguments, retval, exception);
|
||||
else if (name == "getPlatform")
|
||||
retval = CefV8Value::CreateString("linux");
|
||||
else if (name == "lastModified")
|
||||
LastModified(name, object, arguments, retval, exception);
|
||||
else
|
||||
cout << "Unhandled -> " + name.ToString() << " : "
|
||||
<< arguments[0]->GetStringValue().ToString() << endl;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef CEF_TESTS_CEFCLIENT_NATIVE_HANDLER_H_
|
||||
#define CEF_TESTS_CEFCLIENT_NATIVE_HANDLER_H_
|
||||
#ifndef NATIVE_HANDLER_H_
|
||||
#define NATIVE_HANDLER_H_
|
||||
|
||||
#include "include/cef_base.h"
|
||||
#include "include/cef_v8.h"
|
||||
@@ -21,8 +21,6 @@ class NativeHandler: public CefV8Handler {
|
||||
public:
|
||||
NativeHandler();
|
||||
|
||||
CefRefPtr<CefV8Value> object;
|
||||
|
||||
GtkWidget* window;
|
||||
|
||||
std::string path;
|
||||
@@ -121,6 +119,10 @@ private:
|
||||
void Digest(const CefString& name, CefRefPtr<CefV8Value> object,
|
||||
const CefV8ValueList& arguments, CefRefPtr<CefV8Value>& retval,
|
||||
CefString& exception);
|
||||
|
||||
void LastModified(const CefString& name, CefRefPtr<CefV8Value> object,
|
||||
const CefV8ValueList& arguments, CefRefPtr<CefV8Value>& retval,
|
||||
CefString& exception);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
185
Atom-Linux/onig_regexp_extension.cpp
Normal file
185
Atom-Linux/onig_regexp_extension.cpp
Normal file
@@ -0,0 +1,185 @@
|
||||
#include "onig_regexp_extension.h"
|
||||
#include "include/cef_base.h"
|
||||
#include "include/cef_runnable.h"
|
||||
#include <oniguruma.h>
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
#include "io_utils.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class OnigRegexpUserData: public CefBase {
|
||||
public:
|
||||
OnigRegexpUserData(CefRefPtr<CefV8Value> source) {
|
||||
OnigErrorInfo error;
|
||||
string input = source->GetStringValue().ToString();
|
||||
int length = input.length();
|
||||
UChar* pattern = (UChar*) input.c_str();
|
||||
int code = onig_new(®ex, pattern, pattern + length,
|
||||
ONIG_OPTION_SINGLELINE, ONIG_ENCODING_UTF8, ONIG_SYNTAX_DEFAULT,
|
||||
&error);
|
||||
if (code != ONIG_NORMAL) {
|
||||
char errorText[ONIG_MAX_ERROR_MESSAGE_LEN];
|
||||
onig_error_code_to_str((OnigUChar*) errorText, code, &error);
|
||||
cout << errorText << " for pattern: " << input << endl;
|
||||
}
|
||||
}
|
||||
|
||||
~OnigRegexpUserData() {
|
||||
onig_free(regex);
|
||||
}
|
||||
|
||||
OnigRegion* SearchRegion(string input, int index) {
|
||||
if (!regex)
|
||||
return NULL;
|
||||
|
||||
OnigRegion* region = onig_region_new();
|
||||
UChar* search = (UChar*) input.c_str();
|
||||
unsigned char* start = search + index;
|
||||
unsigned char* end = search + input.length();
|
||||
int code = onig_search(regex, search, end, start, end, region,
|
||||
ONIG_OPTION_NONE);
|
||||
if (code >= 0)
|
||||
return region;
|
||||
else {
|
||||
onig_region_free(region, 1);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
CefRefPtr<CefV8Value> Search(CefRefPtr<CefV8Value> argument,
|
||||
CefRefPtr<CefV8Value> index) {
|
||||
string input = argument->GetStringValue().ToString();
|
||||
OnigRegion* region = SearchRegion(input, index->GetIntValue());
|
||||
if (!region)
|
||||
return CefV8Value::CreateNull();
|
||||
|
||||
CefRefPtr<CefV8Value> indices;
|
||||
CefRefPtr<CefV8Value> resultArray = CefV8Value::CreateArray();
|
||||
CefRefPtr<CefV8Value> indicesArray = CefV8Value::CreateArray();
|
||||
for (int i = 0; i < region->num_regs; i++) {
|
||||
int begin = region->beg[i];
|
||||
int end = region->end[i];
|
||||
resultArray->SetValue(i,
|
||||
CefV8Value::CreateString(input.substr(begin, end - begin)));
|
||||
indicesArray->SetValue(i, CefV8Value::CreateInt(begin));
|
||||
}
|
||||
resultArray->SetValue("index", CefV8Value::CreateInt(region->beg[0]),
|
||||
V8_PROPERTY_ATTRIBUTE_NONE);
|
||||
resultArray->SetValue("indices", indicesArray, V8_PROPERTY_ATTRIBUTE_NONE);
|
||||
onig_region_free(region, 1);
|
||||
return resultArray;
|
||||
}
|
||||
|
||||
CefRefPtr<CefV8Value> Test(CefRefPtr<CefV8Value> argument,
|
||||
CefRefPtr<CefV8Value> index) {
|
||||
OnigRegion* region = SearchRegion(argument->GetStringValue().ToString(),
|
||||
index->GetIntValue());
|
||||
CefRefPtr<CefV8Value> text = CefV8Value::CreateBool(region != NULL);
|
||||
if (region)
|
||||
onig_region_free(region, 1);
|
||||
return text;
|
||||
}
|
||||
|
||||
CefRefPtr<CefV8Value> GetCaptureIndices(CefRefPtr<CefV8Value> argument,
|
||||
CefRefPtr<CefV8Value> index) {
|
||||
OnigRegion* region = SearchRegion(argument->GetStringValue().ToString(),
|
||||
index->GetIntValue());
|
||||
CefRefPtr<CefV8Value> indices;
|
||||
if (region) {
|
||||
indices = BuildCaptureIndices(region);
|
||||
onig_region_free(region, 1);
|
||||
} else
|
||||
indices = CefV8Value::CreateNull();
|
||||
return indices;
|
||||
}
|
||||
|
||||
CefRefPtr<CefV8Value> BuildCaptureIndices(OnigRegion *region) {
|
||||
CefRefPtr<CefV8Value> array = CefV8Value::CreateArray();
|
||||
int i = 0;
|
||||
for (int index = 0; index < region->num_regs; index++) {
|
||||
int begin = region->beg[index];
|
||||
int end = region->end[index];
|
||||
if (end - begin <= 0)
|
||||
continue;
|
||||
array->SetValue(i++, CefV8Value::CreateInt(index));
|
||||
array->SetValue(i++, CefV8Value::CreateInt(begin));
|
||||
array->SetValue(i++, CefV8Value::CreateInt(end));
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
CefRefPtr<CefV8Value> CaptureCount() {
|
||||
if (regex)
|
||||
return CefV8Value::CreateInt(onig_number_of_captures(regex));
|
||||
else
|
||||
return CefV8Value::CreateInt(0);
|
||||
}
|
||||
|
||||
regex_t* regex;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(OnigRegexpUserData)
|
||||
;
|
||||
}
|
||||
;
|
||||
|
||||
OnigRegexpExtension::OnigRegexpExtension() :
|
||||
CefV8Handler() {
|
||||
string realFilePath = io_utils_real_app_path(
|
||||
"/src/stdlib/onig-reg-exp-extension.js");
|
||||
if (!realFilePath.empty()) {
|
||||
string extensionCode;
|
||||
if (io_utils_read(realFilePath, &extensionCode) > 0)
|
||||
CefRegisterExtension("v8/oniguruma", extensionCode, this);
|
||||
}
|
||||
}
|
||||
|
||||
bool OnigRegexpExtension::Execute(const CefString& name,
|
||||
CefRefPtr<CefV8Value> object, const CefV8ValueList& arguments,
|
||||
CefRefPtr<CefV8Value>& retval, CefString& exception) {
|
||||
if (name == "getCaptureIndices") {
|
||||
CefRefPtr<CefV8Value> string = arguments[0];
|
||||
CefRefPtr<CefV8Value> index =
|
||||
arguments.size() > 1 ? arguments[1] : CefV8Value::CreateInt(0);
|
||||
OnigRegexpUserData *userData =
|
||||
(OnigRegexpUserData *) object->GetUserData().get();
|
||||
retval = userData->GetCaptureIndices(string, index);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (name == "search") {
|
||||
CefRefPtr<CefV8Value> string = arguments[0];
|
||||
CefRefPtr<CefV8Value> index =
|
||||
arguments.size() > 1 ? arguments[1] : CefV8Value::CreateInt(0);
|
||||
OnigRegexpUserData *userData =
|
||||
(OnigRegexpUserData *) object->GetUserData().get();
|
||||
retval = userData->Search(string, index);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (name == "test") {
|
||||
CefRefPtr<CefV8Value> string = arguments[0];
|
||||
CefRefPtr<CefV8Value> index =
|
||||
arguments.size() > 1 ? arguments[1] : CefV8Value::CreateInt(0);
|
||||
OnigRegexpUserData *userData =
|
||||
(OnigRegexpUserData *) object->GetUserData().get();
|
||||
retval = userData->Test(string, index);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (name == "buildOnigRegExp") {
|
||||
CefRefPtr<CefBase> userData = new OnigRegexpUserData(arguments[0]);
|
||||
retval = CefV8Value::CreateObject(userData, NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (name == "getCaptureCount") {
|
||||
OnigRegexpUserData *userData =
|
||||
(OnigRegexpUserData *) object->GetUserData().get();
|
||||
retval = userData->CaptureCount();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
21
Atom-Linux/onig_regexp_extension.h
Normal file
21
Atom-Linux/onig_regexp_extension.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef ONIG_REGEXP_EXTENSION_H_
|
||||
#define ONIG_REGEXP_EXTENSION_H_
|
||||
|
||||
#include "include/cef_base.h"
|
||||
#include "include/cef_v8.h"
|
||||
|
||||
class OnigRegexpExtension: public CefV8Handler {
|
||||
|
||||
public:
|
||||
OnigRegexpExtension();
|
||||
|
||||
virtual bool Execute(const CefString& name, CefRefPtr<CefV8Value> object,
|
||||
const CefV8ValueList& arguments, CefRefPtr<CefV8Value>& retval,
|
||||
CefString& exception);
|
||||
|
||||
IMPLEMENT_REFCOUNTING(OnigRegexpExtension)
|
||||
;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -2,8 +2,8 @@
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_UTIL_H_
|
||||
#define CEF_TESTS_CEFCLIENT_UTIL_H_
|
||||
#ifndef UTIL_H_
|
||||
#define UTIL_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/cef_task.h"
|
||||
@@ -19,4 +19,4 @@
|
||||
#define REQUIRE_IO_THREAD() ASSERT(CefCurrentlyOn(TID_IO));
|
||||
#define REQUIRE_FILE_THREAD() ASSERT(CefCurrentlyOn(TID_FILE));
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_UTIL_H_
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#import "PathWatcher.h"
|
||||
|
||||
#import <sys/event.h>
|
||||
#import <sys/time.h>
|
||||
#import <sys/param.h>
|
||||
#import <sys/time.h>
|
||||
#import <sys/param.h>
|
||||
#import <fcntl.h>
|
||||
|
||||
static NSMutableArray *gPathWatchers;
|
||||
@@ -13,7 +13,7 @@ static NSMutableArray *gPathWatchers;
|
||||
- (NSString *)watchPath:(NSString *)path callback:(WatchCallback)callback callbackId:(NSString *)callbackId;
|
||||
- (void)stopWatching;
|
||||
- (void)reassignFileDescriptor:(NSNumber *)fdNumber from:(NSString *)path to:(NSString *)newPath;
|
||||
- (bool)isAtomicWrite:(struct kevent)event;
|
||||
- (bool)isAtomicWrite:(struct kevent)event path:(NSString *)path;
|
||||
@end
|
||||
|
||||
@implementation PathWatcher
|
||||
@@ -28,12 +28,12 @@ static NSMutableArray *gPathWatchers;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!pathWatcher) {
|
||||
pathWatcher = [[[PathWatcher alloc] initWithContext:context] autorelease];
|
||||
[gPathWatchers addObject:pathWatcher];
|
||||
}
|
||||
|
||||
|
||||
return pathWatcher;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ static NSMutableArray *gPathWatchers;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (pathWatcher) {
|
||||
[pathWatcher stopWatching];
|
||||
[gPathWatchers removeObject:pathWatcher];
|
||||
@@ -65,17 +65,17 @@ static NSMutableArray *gPathWatchers;
|
||||
|
||||
- (id)initWithContext:(CefRefPtr<CefV8Context>)context {
|
||||
self = [super init];
|
||||
|
||||
|
||||
_keepWatching = YES;
|
||||
_callbacksByFileDescriptor = [[NSMutableDictionary alloc] init];
|
||||
_fileDescriptorsByPath = [[NSMutableDictionary alloc] init];
|
||||
_kq = kqueue();
|
||||
_context = context;
|
||||
|
||||
|
||||
if (_kq == -1) {
|
||||
[NSException raise:@"PathWatcher" format:@"Could not create kqueue"];
|
||||
}
|
||||
|
||||
|
||||
[self performSelectorInBackground:@selector(watch) withObject:NULL];
|
||||
return self;
|
||||
}
|
||||
@@ -96,27 +96,27 @@ static NSMutableArray *gPathWatchers;
|
||||
|
||||
- (NSString *)watchPath:(NSString *)path callback:(WatchCallback)callback callbackId:(NSString *)callbackId {
|
||||
path = [path stringByStandardizingPath];
|
||||
|
||||
|
||||
@synchronized(self) {
|
||||
NSNumber *fdNumber = [_fileDescriptorsByPath objectForKey:path];
|
||||
NSNumber *fdNumber = [_fileDescriptorsByPath objectForKey:path];
|
||||
if (!fdNumber) {
|
||||
int fd = open([path fileSystemRepresentation], O_EVTONLY, 0);
|
||||
int fd = open([path fileSystemRepresentation], O_EVTONLY, 0);
|
||||
if (fd < 0) return nil;
|
||||
[self watchFileDescriptor:fd];
|
||||
|
||||
|
||||
fdNumber = [NSNumber numberWithInt:fd];
|
||||
[_fileDescriptorsByPath setObject:fdNumber forKey:path];
|
||||
}
|
||||
|
||||
|
||||
NSMutableDictionary *callbacks = [_callbacksByFileDescriptor objectForKey:fdNumber];
|
||||
if (!callbacks) {
|
||||
if (!callbacks) {
|
||||
callbacks = [NSMutableDictionary dictionary];
|
||||
[_callbacksByFileDescriptor setObject:callbacks forKey:fdNumber];
|
||||
[_callbacksByFileDescriptor setObject:callbacks forKey:fdNumber];
|
||||
}
|
||||
|
||||
|
||||
[callbacks setObject:callback forKey:callbackId];
|
||||
}
|
||||
|
||||
|
||||
return callbackId;
|
||||
}
|
||||
|
||||
@@ -132,22 +132,22 @@ static NSMutableArray *gPathWatchers;
|
||||
NSError *e = [NSError errorWithDomain:@"PathWatcher" code:0 userInfo:userInfo];
|
||||
*error = e;
|
||||
}
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
NSMutableDictionary *callbacks = [_callbacksByFileDescriptor objectForKey:fdNumber];
|
||||
if (!callbacks) return;
|
||||
|
||||
if (!callbacks) return;
|
||||
|
||||
if (callbackId) {
|
||||
[callbacks removeObjectForKey:callbackId];
|
||||
}
|
||||
else {
|
||||
[callbacks removeAllObjects];
|
||||
}
|
||||
|
||||
|
||||
if (callbacks.count == 0) {
|
||||
close([fdNumber intValue]);
|
||||
[_callbacksByFileDescriptor removeObjectForKey:fdNumber];
|
||||
[_callbacksByFileDescriptor removeObjectForKey:fdNumber];
|
||||
[_fileDescriptorsByPath removeObjectForKey:path];
|
||||
}
|
||||
}
|
||||
@@ -159,7 +159,7 @@ static NSMutableArray *gPathWatchers;
|
||||
for (NSString *path in paths) {
|
||||
[self unwatchPath:path callbackId:nil error:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)watchFileDescriptor:(int)fd {
|
||||
@@ -180,24 +180,15 @@ static NSMutableArray *gPathWatchers;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (bool)isAtomicWrite:(struct kevent)event {
|
||||
- (bool)isAtomicWrite:(struct kevent)event path:(NSString *)path {
|
||||
if (!event.fflags & NOTE_DELETE) return NO;
|
||||
|
||||
[NSThread sleepForTimeInterval:0.01]; // HACK: Git deletes files only to create them again later. This is the cheap way of dealing with that
|
||||
NSFileManager *fm = [NSFileManager defaultManager];
|
||||
NSString *path = nil;
|
||||
@synchronized(self) {
|
||||
for (path in [_fileDescriptorsByPath allKeys]) {
|
||||
if ([[_fileDescriptorsByPath objectForKey:path] unsignedLongValue] == event.ident) {
|
||||
return [fm fileExistsAtPath:path];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
return [fm fileExistsAtPath:path];
|
||||
}
|
||||
|
||||
- (void)reassignFileDescriptor:(NSNumber *)fdNumber from:(NSString *)path to:(NSString *)newPath {
|
||||
@@ -211,25 +202,25 @@ static NSMutableArray *gPathWatchers;
|
||||
}
|
||||
|
||||
- (void)updatePath:(NSString *)path forFileDescriptor:(NSNumber *)fdNumber {
|
||||
// The path associated with the fd been updated. Remove references to old fd
|
||||
// The path associated with the fd been updated. Remove references to old fd
|
||||
// and make sure the path and callbacks are linked with new fd.
|
||||
@synchronized(self) {
|
||||
NSDictionary *callbacks = [NSDictionary dictionaryWithDictionary:[_callbacksByFileDescriptor objectForKey:fdNumber]];
|
||||
NSDictionary *callbacks = [NSDictionary dictionaryWithDictionary:[_callbacksByFileDescriptor objectForKey:fdNumber]];
|
||||
[self unwatchPath:path callbackId:nil error:nil];
|
||||
for (NSString *callbackId in [callbacks allKeys]) {
|
||||
[self watchPath:path callback:[callbacks objectForKey:callbackId] callbackId:callbackId];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)watch {
|
||||
struct kevent event;
|
||||
- (void)watch {
|
||||
struct kevent event;
|
||||
struct timespec timeout = { 5, 0 }; // 5 seconds timeout.
|
||||
|
||||
|
||||
while (_keepWatching) {
|
||||
@autoreleasepool {
|
||||
int numberOfEvents = kevent(_kq, NULL, 0, &event, 1, &timeout);
|
||||
|
||||
|
||||
if (numberOfEvents < 0) {
|
||||
NSLog(@"PathWatcher: error %d", numberOfEvents);
|
||||
}
|
||||
@@ -240,12 +231,12 @@ static NSMutableArray *gPathWatchers;
|
||||
NSNumber *fdNumber = [NSNumber numberWithInt:event.ident];
|
||||
NSString *eventFlag = nil;
|
||||
NSString *path = [[[self pathForFileDescriptor:fdNumber] retain] autorelease];
|
||||
NSString *newPath = nil;
|
||||
|
||||
NSString *newPath = nil;
|
||||
|
||||
if (event.fflags & NOTE_WRITE) {
|
||||
eventFlag = @"contents-change";
|
||||
}
|
||||
else if ([self isAtomicWrite:event]) {
|
||||
else if ([self isAtomicWrite:event path:path]) {
|
||||
eventFlag = @"contents-change";
|
||||
[self updatePath:path forFileDescriptor:fdNumber];
|
||||
}
|
||||
@@ -258,7 +249,7 @@ static NSMutableArray *gPathWatchers;
|
||||
fcntl((int)event.ident, F_GETPATH, &pathBuffer);
|
||||
newPath = [NSString stringWithUTF8String:pathBuffer];
|
||||
}
|
||||
|
||||
|
||||
NSDictionary *callbacks;
|
||||
@synchronized(self) {
|
||||
callbacks = [NSDictionary dictionaryWithDictionary:[_callbacksByFileDescriptor objectForKey:fdNumber]];
|
||||
@@ -266,7 +257,7 @@ static NSMutableArray *gPathWatchers;
|
||||
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
for (NSString *key in callbacks) {
|
||||
WatchCallback callback = [callbacks objectForKey:key];
|
||||
WatchCallback callback = [callbacks objectForKey:key];
|
||||
callback(eventFlag, newPath ? newPath : path);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -31,19 +31,9 @@ void throwException(const CefRefPtr<CefV8Value>& global, CefRefPtr<CefV8Exceptio
|
||||
}
|
||||
|
||||
NativeHandler::NativeHandler() : CefV8Handler() {
|
||||
std::string extensionCode = "var $native = {}; (function() {";
|
||||
|
||||
const char *functionNames[] = {"exists", "alert", "read", "write", "absolute", "list", "isFile", "isDirectory", "remove", "asyncList", "open", "openDialog", "quit", "writeToPasteboard", "readFromPasteboard", "showDevTools", "toggleDevTools", "newWindow", "saveDialog", "exit", "watchPath", "unwatchPath", "makeDirectory", "move", "moveToTrash", "reload", "lastModified", "md5ForPath", "exec"};
|
||||
NSUInteger arrayLength = sizeof(functionNames) / sizeof(const char *);
|
||||
for (NSUInteger i = 0; i < arrayLength; i++) {
|
||||
std::string functionName = std::string(functionNames[i]);
|
||||
extensionCode += "native function " + functionName + "(); $native." + functionName + " = " + functionName + ";";
|
||||
}
|
||||
|
||||
extensionCode += "})();";
|
||||
|
||||
// Register the extension.
|
||||
CefRegisterExtension("v8/test", extensionCode, this);
|
||||
NSString *filePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"src/stdlib/native-handler.js"];
|
||||
NSString *extensionCode = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
|
||||
CefRegisterExtension("v8/native-handler", [extensionCode UTF8String], this);
|
||||
}
|
||||
|
||||
bool NativeHandler::Execute(const CefString& name,
|
||||
@@ -525,5 +515,9 @@ bool NativeHandler::Execute(const CefString& name,
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (name == "getPlatform") {
|
||||
retval = CefV8Value::CreateString("mac");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
@@ -9,7 +9,7 @@
|
||||
2. Install CoffeeScript http://coffeescript.org/
|
||||
```
|
||||
brew install nodejs
|
||||
curl http://npmjs.org/install.sh | sh
|
||||
curl https://npmjs.org/install.sh | sh
|
||||
npm i -g coffee-script
|
||||
```
|
||||
|
||||
|
||||
8
Rakefile
8
Rakefile
@@ -68,9 +68,11 @@ task :"copy-files-to-bundle" => :"verify-prerequisites" do
|
||||
cp_r dir, File.join(dest, dir)
|
||||
end
|
||||
|
||||
sh "coffee -c -o #{dest}/src/stdlib src/stdlib/require.coffee"
|
||||
cp "src/stdlib/onig-reg-exp-extension.js", "#{dest}/src/stdlib"
|
||||
unless ENV['LOAD_RESOURCES_FROM_DIR']
|
||||
if ENV['LOAD_RESOURCES_FROM_DIR']
|
||||
sh "coffee -c -o #{dest}/src/stdlib src/stdlib/require.coffee"
|
||||
cp "src/stdlib/onig-reg-exp-extension.js", "#{dest}/src/stdlib"
|
||||
cp "src/stdlib/native-handler.js", "#{dest}/src/stdlib"
|
||||
else
|
||||
%w(src static vendor spec benchmark bundles themes).each do |dir|
|
||||
rm_rf File.join(dest, dir)
|
||||
cp_r dir, File.join(dest, dir)
|
||||
|
||||
18
docs/file-modification
Normal file
18
docs/file-modification
Normal file
@@ -0,0 +1,18 @@
|
||||
Buffers
|
||||
modify
|
||||
- if dirty alert user (immediately if focused, or on next focus)
|
||||
- if clean update contents
|
||||
|
||||
remove
|
||||
- mark file as unsaved (but maintains previous path)
|
||||
- only unsubscribe from KQueue
|
||||
- attempt to resubscribe after timeout (because of git weirdness)
|
||||
|
||||
move file
|
||||
- update path
|
||||
|
||||
move ancestor directory
|
||||
- update path on focus and save
|
||||
|
||||
recreated after remove (at same path)
|
||||
- resubscribe on focus or save
|
||||
@@ -48,7 +48,9 @@ describe 'File', ->
|
||||
newPath = fs.join(fs.directory(path), "atom-file-was-moved-test.txt")
|
||||
|
||||
afterEach ->
|
||||
fs.remove(newPath) if fs.exists(newPath)
|
||||
if fs.exists(newPath)
|
||||
fs.remove(newPath)
|
||||
waitsFor "remove event", (done) -> file.on 'remove', done
|
||||
|
||||
it "it updates its path", ->
|
||||
moveHandler = null
|
||||
|
||||
6
spec/app/native-spec.coffee
Normal file
6
spec/app/native-spec.coffee
Normal file
@@ -0,0 +1,6 @@
|
||||
describe 'Native', ->
|
||||
describe '$native.getPlatform()', ->
|
||||
it 'returns a non-empty value', ->
|
||||
platform = $native.getPlatform()
|
||||
expect(platform).not.toBe ''
|
||||
expect(platform.length).toBeGreaterThan(0)
|
||||
@@ -13,6 +13,7 @@ windowAdditions =
|
||||
rootViewParentSelector: 'body'
|
||||
rootView: null
|
||||
keymap: null
|
||||
platform: $native.getPlatform()
|
||||
|
||||
setUpKeymap: ->
|
||||
Keymap = require 'keymap'
|
||||
@@ -55,7 +56,8 @@ windowAdditions =
|
||||
$(@rootViewParentSelector).append @rootView
|
||||
|
||||
requireStylesheet: (path) ->
|
||||
fullPath = require.resolve(path)
|
||||
unless fullPath = require.resolve(path)
|
||||
throw new Error("requireStylesheet could not find a file at path '#{path}'")
|
||||
window.applyStylesheet(fullPath, fs.read(fullPath))
|
||||
|
||||
applyStylesheet: (id, text) ->
|
||||
@@ -106,3 +108,6 @@ require 'underscore-extensions'
|
||||
|
||||
requireStylesheet 'reset.css'
|
||||
requireStylesheet 'atom.css'
|
||||
|
||||
if nativeStylesheetPath = require.resolve("#{platform}.css")
|
||||
requireStylesheet(nativeStylesheetPath)
|
||||
|
||||
94
src/stdlib/native-handler.js
Normal file
94
src/stdlib/native-handler.js
Normal file
@@ -0,0 +1,94 @@
|
||||
var $native = {};
|
||||
(function() {
|
||||
|
||||
native function exists(path);
|
||||
$native.exists = exists;
|
||||
|
||||
native function alert(message, detailedMessage, buttonNamesAndCallbacks);
|
||||
$native.alert = alert;
|
||||
|
||||
native function read(path);
|
||||
$native.read = read;
|
||||
|
||||
native function write(path, content);
|
||||
$native.write = write;
|
||||
|
||||
native function absolute(path);
|
||||
$native.absolute = absolute;
|
||||
|
||||
native function list(path, recursive);
|
||||
$native.list = list;
|
||||
|
||||
native function isFile(path);
|
||||
$native.isFile = isFile;
|
||||
|
||||
native function isDirectory(path);
|
||||
$native.isDirectory = isDirectory;
|
||||
|
||||
native function remove(path);
|
||||
$native.remove = remove;
|
||||
|
||||
native function asyncList(path, recursive, callback);
|
||||
$native.asyncList = asyncList;
|
||||
|
||||
native function open(path);
|
||||
$native.open = open;
|
||||
|
||||
native function openDialog();
|
||||
$native.openDialog = openDialog;
|
||||
|
||||
native function quit();
|
||||
$native.quit = quit;
|
||||
|
||||
native function writeToPasteboard(text);
|
||||
$native.writeToPasteboard = writeToPasteboard;
|
||||
|
||||
native function readFromPasteboard();
|
||||
$native.readFromPasteboard = readFromPasteboard;
|
||||
|
||||
native function showDevTools();
|
||||
$native.showDevTools = showDevTools;
|
||||
|
||||
native function toggleDevTools();
|
||||
$native.toggleDevTools = toggleDevTools;
|
||||
|
||||
native function newWindow();
|
||||
$native.newWindow = newWindow;
|
||||
|
||||
native function saveDialog();
|
||||
$native.saveDialog = saveDialog;
|
||||
|
||||
native function exit(status);
|
||||
$native.exit = exit;
|
||||
|
||||
native function watchPath(path);
|
||||
$native.watchPath = watchPath;
|
||||
|
||||
native function unwatchPath(path, callbackId);
|
||||
$native.unwatchPath = unwatchPath;
|
||||
|
||||
native function makeDirectory(path);
|
||||
$native.makeDirectory = makeDirectory;
|
||||
|
||||
native function move(sourcePath, targetPath);
|
||||
$native.move = move;
|
||||
|
||||
native function moveToTrash(path);
|
||||
$native.moveToTrash = moveToTrash;
|
||||
|
||||
native function reload();
|
||||
$native.reload = reload;
|
||||
|
||||
native function lastModified(path);
|
||||
$native.lastModified = lastModified;
|
||||
|
||||
native function md5ForPath(path);
|
||||
$native.md5ForPath = md5ForPath;
|
||||
|
||||
native function exec(command, options, callback);
|
||||
$native.exec = exec;
|
||||
|
||||
native function getPlatform();
|
||||
$native.getPlatform = getPlatform;
|
||||
|
||||
})();
|
||||
@@ -19,10 +19,12 @@ nakedLoad = (file) ->
|
||||
code = __read file
|
||||
window.eval(code + "\n//@ sourceURL=" + file)
|
||||
|
||||
require = (file, cb) ->
|
||||
return cb require file if cb?
|
||||
require = (path, cb) ->
|
||||
return cb require path if cb?
|
||||
|
||||
unless file = resolve(path)
|
||||
throw new Error("Require can't find file at path '#{path}'")
|
||||
|
||||
file = resolve file
|
||||
parts = file.split '.'
|
||||
ext = parts[parts.length-1]
|
||||
|
||||
@@ -88,10 +90,10 @@ resolve = (file) ->
|
||||
else
|
||||
file = __expand(file) or file
|
||||
|
||||
if file[0] isnt '/'
|
||||
throw "require: Can't find '#{file}'"
|
||||
|
||||
return file
|
||||
if file[0] == '/'
|
||||
file
|
||||
else
|
||||
null
|
||||
|
||||
__expand = (path) ->
|
||||
return path if __isFile path
|
||||
|
||||
@@ -122,4 +122,8 @@
|
||||
|
||||
.editor .fold {
|
||||
background-color: #444;
|
||||
}
|
||||
|
||||
.editor .fold.selected {
|
||||
background-color: #244;
|
||||
}
|
||||
13
static/linux.css
Normal file
13
static/linux.css
Normal file
@@ -0,0 +1,13 @@
|
||||
::-webkit-scrollbar-corner {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
-webkit-border-radius: 2px;
|
||||
background: rgba(150, 150, 150, .33);
|
||||
}
|
||||
Reference in New Issue
Block a user