Merge branch '0.9.x' into socialbookmark
This commit is contained in:
commit
6393326557
@ -969,9 +969,11 @@ EndRevokeRole: when a role has been revoked
|
||||
|
||||
StartAtomPubNewActivity: When a new activity comes in through Atom Pub API
|
||||
- &$activity: received activity
|
||||
- $user: user publishing the entry
|
||||
|
||||
EndAtomPubNewActivity: When a new activity comes in through Atom Pub API
|
||||
- $activity: received activity
|
||||
- $user: user publishing the entry
|
||||
- $notice: notice that was created
|
||||
|
||||
StartXrdActionAliases: About to set aliases for the XRD object for a user
|
||||
|
@ -324,7 +324,7 @@ class ApiTimelineUserAction extends ApiBareAuthAction
|
||||
|
||||
$activity = new Activity($dom->documentElement);
|
||||
|
||||
if (Event::handle('StartAtomPubNewActivity', array(&$activity))) {
|
||||
if (Event::handle('StartAtomPubNewActivity', array(&$activity, $this->user))) {
|
||||
|
||||
if ($activity->verb != ActivityVerb::POST) {
|
||||
// TRANS: Client error displayed when not using the POST verb.
|
||||
@ -347,7 +347,7 @@ class ApiTimelineUserAction extends ApiBareAuthAction
|
||||
|
||||
$saved = $this->postNote($activity);
|
||||
|
||||
Event::handle('EndAtomPubNewActivity', array($activity, $saved));
|
||||
Event::handle('EndAtomPubNewActivity', array($activity, $this->user, $saved));
|
||||
}
|
||||
|
||||
if (!empty($saved)) {
|
||||
|
@ -48,6 +48,7 @@ if (!defined('STATUSNET')) {
|
||||
class RestoreaccountAction extends Action
|
||||
{
|
||||
private $success = false;
|
||||
private $inprogress = false;
|
||||
|
||||
/**
|
||||
* Returns the title of the page
|
||||
@ -208,8 +209,13 @@ class RestoreaccountAction extends Action
|
||||
$qm = QueueManager::get();
|
||||
$qm->enqueue(array(common_current_user(), $xml, false), 'feedimp');
|
||||
|
||||
if ($qm instanceof UnQueueManager) {
|
||||
// No active queuing means we've actually just completed the job!
|
||||
$this->success = true;
|
||||
|
||||
} else {
|
||||
// We've fed data into background queues, and it's probably still running.
|
||||
$this->inprogress = true;
|
||||
}
|
||||
$this->showPage();
|
||||
|
||||
} catch (Exception $e) {
|
||||
@ -228,6 +234,9 @@ class RestoreaccountAction extends Action
|
||||
function showContent()
|
||||
{
|
||||
if ($this->success) {
|
||||
$this->element('p', null,
|
||||
_('Feed has been restored. Your old posts should now appear in search and your profile page.'));
|
||||
} else if ($this->inprogress) {
|
||||
$this->element('p', null,
|
||||
_('Feed will be restored. Please wait a few minutes for results.'));
|
||||
} else {
|
||||
|
@ -1,11 +1,12 @@
|
||||
.fake: all clean
|
||||
|
||||
TARGETS=util.min.js
|
||||
SOURCES=util.js xbImportNode.js geometa.js
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
clean:
|
||||
rm -f $(TARGETS)
|
||||
|
||||
util.min.js: util.js
|
||||
yui-compressor $< -o $@
|
||||
util.min.js: $(SOURCES)
|
||||
cat $+ | yui-compressor --type js > $@
|
||||
|
217
js/geometa.js
Normal file
217
js/geometa.js
Normal file
@ -0,0 +1,217 @@
|
||||
// A shim to implement the W3C Geolocation API Specification using Gears or the Ajax API
|
||||
if (typeof navigator.geolocation == "undefined" || navigator.geolocation.shim ) { (function(){
|
||||
|
||||
// -- BEGIN GEARS_INIT
|
||||
(function() {
|
||||
// We are already defined. Hooray!
|
||||
if (window.google && google.gears) {
|
||||
return;
|
||||
}
|
||||
|
||||
var factory = null;
|
||||
|
||||
// Firefox
|
||||
if (typeof GearsFactory != 'undefined') {
|
||||
factory = new GearsFactory();
|
||||
} else {
|
||||
// IE
|
||||
try {
|
||||
factory = new ActiveXObject('Gears.Factory');
|
||||
// privateSetGlobalObject is only required and supported on WinCE.
|
||||
if (factory.getBuildInfo().indexOf('ie_mobile') != -1) {
|
||||
factory.privateSetGlobalObject(this);
|
||||
}
|
||||
} catch (e) {
|
||||
// Safari
|
||||
if ((typeof navigator.mimeTypes != 'undefined') && navigator.mimeTypes["application/x-googlegears"]) {
|
||||
factory = document.createElement("object");
|
||||
factory.style.display = "none";
|
||||
factory.width = 0;
|
||||
factory.height = 0;
|
||||
factory.type = "application/x-googlegears";
|
||||
document.documentElement.appendChild(factory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *Do not* define any objects if Gears is not installed. This mimics the
|
||||
// behavior of Gears defining the objects in the future.
|
||||
if (!factory) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Now set up the objects, being careful not to overwrite anything.
|
||||
//
|
||||
// Note: In Internet Explorer for Windows Mobile, you can't add properties to
|
||||
// the window object. However, global objects are automatically added as
|
||||
// properties of the window object in all browsers.
|
||||
if (!window.google) {
|
||||
google = {};
|
||||
}
|
||||
|
||||
if (!google.gears) {
|
||||
google.gears = {factory: factory};
|
||||
}
|
||||
})();
|
||||
// -- END GEARS_INIT
|
||||
|
||||
var GearsGeoLocation = (function() {
|
||||
// -- PRIVATE
|
||||
var geo = google.gears.factory.create('beta.geolocation');
|
||||
|
||||
var wrapSuccess = function(callback, self) { // wrap it for lastPosition love
|
||||
return function(position) {
|
||||
callback(position);
|
||||
self.lastPosition = position;
|
||||
};
|
||||
};
|
||||
|
||||
// -- PUBLIC
|
||||
return {
|
||||
shim: true,
|
||||
|
||||
type: "Gears",
|
||||
|
||||
lastPosition: null,
|
||||
|
||||
getCurrentPosition: function(successCallback, errorCallback, options) {
|
||||
var self = this;
|
||||
var sc = wrapSuccess(successCallback, self);
|
||||
geo.getCurrentPosition(sc, errorCallback, options);
|
||||
},
|
||||
|
||||
watchPosition: function(successCallback, errorCallback, options) {
|
||||
geo.watchPosition(successCallback, errorCallback, options);
|
||||
},
|
||||
|
||||
clearWatch: function(watchId) {
|
||||
geo.clearWatch(watchId);
|
||||
},
|
||||
|
||||
getPermission: function(siteName, imageUrl, extraMessage) {
|
||||
geo.getPermission(siteName, imageUrl, extraMessage);
|
||||
}
|
||||
|
||||
};
|
||||
});
|
||||
|
||||
var AjaxGeoLocation = (function() {
|
||||
// -- PRIVATE
|
||||
var loading = false;
|
||||
var loadGoogleLoader = function() {
|
||||
if (!hasGoogleLoader() && !loading) {
|
||||
loading = true;
|
||||
var s = document.createElement('script');
|
||||
s.src = (document.location.protocol == "https:"?"https://":"http://") + 'www.google.com/jsapi?callback=_google_loader_apiLoaded';
|
||||
s.type = "text/javascript";
|
||||
document.getElementsByTagName('body')[0].appendChild(s);
|
||||
}
|
||||
};
|
||||
|
||||
var queue = [];
|
||||
var addLocationQueue = function(callback) {
|
||||
queue.push(callback);
|
||||
};
|
||||
|
||||
var runLocationQueue = function() {
|
||||
if (hasGoogleLoader()) {
|
||||
while (queue.length > 0) {
|
||||
var call = queue.pop();
|
||||
call();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window['_google_loader_apiLoaded'] = function() {
|
||||
runLocationQueue();
|
||||
};
|
||||
|
||||
var hasGoogleLoader = function() {
|
||||
return (window['google'] && google['loader']);
|
||||
};
|
||||
|
||||
var checkGoogleLoader = function(callback) {
|
||||
if (hasGoogleLoader()) { return true; }
|
||||
|
||||
addLocationQueue(callback);
|
||||
|
||||
loadGoogleLoader();
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
loadGoogleLoader(); // start to load as soon as possible just in case
|
||||
|
||||
// -- PUBLIC
|
||||
return {
|
||||
shim: true,
|
||||
|
||||
type: "ClientLocation",
|
||||
|
||||
lastPosition: null,
|
||||
|
||||
getCurrentPosition: function(successCallback, errorCallback, options) {
|
||||
var self = this;
|
||||
if (!checkGoogleLoader(function() {
|
||||
self.getCurrentPosition(successCallback, errorCallback, options);
|
||||
})) { return; }
|
||||
|
||||
if (google.loader.ClientLocation) {
|
||||
var cl = google.loader.ClientLocation;
|
||||
|
||||
var position = {
|
||||
coords: {
|
||||
latitude: cl.latitude,
|
||||
longitude: cl.longitude,
|
||||
altitude: null,
|
||||
accuracy: 43000, // same as Gears accuracy over wifi?
|
||||
altitudeAccuracy: null,
|
||||
heading: null,
|
||||
speed: null
|
||||
},
|
||||
// extra info that is outside of the bounds of the core API
|
||||
address: {
|
||||
city: cl.address.city,
|
||||
country: cl.address.country,
|
||||
country_code: cl.address.country_code,
|
||||
region: cl.address.region
|
||||
},
|
||||
timestamp: new Date()
|
||||
};
|
||||
|
||||
successCallback(position);
|
||||
|
||||
this.lastPosition = position;
|
||||
} else if (errorCallback === "function") {
|
||||
errorCallback({ code: 3, message: "Using the Google ClientLocation API and it is not able to calculate a location."});
|
||||
}
|
||||
},
|
||||
|
||||
watchPosition: function(successCallback, errorCallback, options) {
|
||||
this.getCurrentPosition(successCallback, errorCallback, options);
|
||||
|
||||
var self = this;
|
||||
var watchId = setInterval(function() {
|
||||
self.getCurrentPosition(successCallback, errorCallback, options);
|
||||
}, 10000);
|
||||
|
||||
return watchId;
|
||||
},
|
||||
|
||||
clearWatch: function(watchId) {
|
||||
clearInterval(watchId);
|
||||
},
|
||||
|
||||
getPermission: function(siteName, imageUrl, extraMessage) {
|
||||
// for now just say yes :)
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
});
|
||||
|
||||
// If you have Gears installed use that, else use Ajax ClientLocation
|
||||
navigator.geolocation = (window.google && google.gears) ? GearsGeoLocation() : AjaxGeoLocation();
|
||||
|
||||
})();
|
||||
}
|
269
js/util.js
269
js/util.js
@ -1242,272 +1242,3 @@ $(document).ready(function(){
|
||||
SN.Init.Login();
|
||||
}
|
||||
});
|
||||
|
||||
// Formerly in xbImportNode.js
|
||||
// @fixme put it back there -- since we're minifying we can concat in the makefile now
|
||||
|
||||
/* is this stuff defined? */
|
||||
if (!document.ELEMENT_NODE) {
|
||||
document.ELEMENT_NODE = 1;
|
||||
document.ATTRIBUTE_NODE = 2;
|
||||
document.TEXT_NODE = 3;
|
||||
document.CDATA_SECTION_NODE = 4;
|
||||
document.ENTITY_REFERENCE_NODE = 5;
|
||||
document.ENTITY_NODE = 6;
|
||||
document.PROCESSING_INSTRUCTION_NODE = 7;
|
||||
document.COMMENT_NODE = 8;
|
||||
document.DOCUMENT_NODE = 9;
|
||||
document.DOCUMENT_TYPE_NODE = 10;
|
||||
document.DOCUMENT_FRAGMENT_NODE = 11;
|
||||
document.NOTATION_NODE = 12;
|
||||
}
|
||||
|
||||
document._importNode = function(node, allChildren) {
|
||||
/* find the node type to import */
|
||||
switch (node.nodeType) {
|
||||
case document.ELEMENT_NODE:
|
||||
/* create a new element */
|
||||
var newNode = document.createElement(node.nodeName);
|
||||
/* does the node have any attributes to add? */
|
||||
if (node.attributes && node.attributes.length > 0)
|
||||
/* add all of the attributes */
|
||||
for (var i = 0, il = node.attributes.length; i < il;) {
|
||||
if (node.attributes[i].nodeName == 'class') {
|
||||
newNode.className = node.getAttribute(node.attributes[i++].nodeName);
|
||||
} else {
|
||||
newNode.setAttribute(node.attributes[i].nodeName, node.getAttribute(node.attributes[i++].nodeName));
|
||||
}
|
||||
}
|
||||
/* are we going after children too, and does the node have any? */
|
||||
if (allChildren && node.childNodes && node.childNodes.length > 0)
|
||||
/* recursively get all of the child nodes */
|
||||
for (var i = 0, il = node.childNodes.length; i < il;)
|
||||
newNode.appendChild(document._importNode(node.childNodes[i++], allChildren));
|
||||
return newNode;
|
||||
break;
|
||||
case document.TEXT_NODE:
|
||||
case document.CDATA_SECTION_NODE:
|
||||
case document.COMMENT_NODE:
|
||||
return document.createTextNode(node.nodeValue);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
// @fixme put this next bit back too -- since we're minifying we can concat in the makefile now
|
||||
// A shim to implement the W3C Geolocation API Specification using Gears or the Ajax API
|
||||
if (typeof navigator.geolocation == "undefined" || navigator.geolocation.shim ) { (function(){
|
||||
|
||||
// -- BEGIN GEARS_INIT
|
||||
(function() {
|
||||
// We are already defined. Hooray!
|
||||
if (window.google && google.gears) {
|
||||
return;
|
||||
}
|
||||
|
||||
var factory = null;
|
||||
|
||||
// Firefox
|
||||
if (typeof GearsFactory != 'undefined') {
|
||||
factory = new GearsFactory();
|
||||
} else {
|
||||
// IE
|
||||
try {
|
||||
factory = new ActiveXObject('Gears.Factory');
|
||||
// privateSetGlobalObject is only required and supported on WinCE.
|
||||
if (factory.getBuildInfo().indexOf('ie_mobile') != -1) {
|
||||
factory.privateSetGlobalObject(this);
|
||||
}
|
||||
} catch (e) {
|
||||
// Safari
|
||||
if ((typeof navigator.mimeTypes != 'undefined') && navigator.mimeTypes["application/x-googlegears"]) {
|
||||
factory = document.createElement("object");
|
||||
factory.style.display = "none";
|
||||
factory.width = 0;
|
||||
factory.height = 0;
|
||||
factory.type = "application/x-googlegears";
|
||||
document.documentElement.appendChild(factory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *Do not* define any objects if Gears is not installed. This mimics the
|
||||
// behavior of Gears defining the objects in the future.
|
||||
if (!factory) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Now set up the objects, being careful not to overwrite anything.
|
||||
//
|
||||
// Note: In Internet Explorer for Windows Mobile, you can't add properties to
|
||||
// the window object. However, global objects are automatically added as
|
||||
// properties of the window object in all browsers.
|
||||
if (!window.google) {
|
||||
google = {};
|
||||
}
|
||||
|
||||
if (!google.gears) {
|
||||
google.gears = {factory: factory};
|
||||
}
|
||||
})();
|
||||
// -- END GEARS_INIT
|
||||
|
||||
var GearsGeoLocation = (function() {
|
||||
// -- PRIVATE
|
||||
var geo = google.gears.factory.create('beta.geolocation');
|
||||
|
||||
var wrapSuccess = function(callback, self) { // wrap it for lastPosition love
|
||||
return function(position) {
|
||||
callback(position);
|
||||
self.lastPosition = position;
|
||||
};
|
||||
};
|
||||
|
||||
// -- PUBLIC
|
||||
return {
|
||||
shim: true,
|
||||
|
||||
type: "Gears",
|
||||
|
||||
lastPosition: null,
|
||||
|
||||
getCurrentPosition: function(successCallback, errorCallback, options) {
|
||||
var self = this;
|
||||
var sc = wrapSuccess(successCallback, self);
|
||||
geo.getCurrentPosition(sc, errorCallback, options);
|
||||
},
|
||||
|
||||
watchPosition: function(successCallback, errorCallback, options) {
|
||||
geo.watchPosition(successCallback, errorCallback, options);
|
||||
},
|
||||
|
||||
clearWatch: function(watchId) {
|
||||
geo.clearWatch(watchId);
|
||||
},
|
||||
|
||||
getPermission: function(siteName, imageUrl, extraMessage) {
|
||||
geo.getPermission(siteName, imageUrl, extraMessage);
|
||||
}
|
||||
|
||||
};
|
||||
});
|
||||
|
||||
var AjaxGeoLocation = (function() {
|
||||
// -- PRIVATE
|
||||
var loading = false;
|
||||
var loadGoogleLoader = function() {
|
||||
if (!hasGoogleLoader() && !loading) {
|
||||
loading = true;
|
||||
var s = document.createElement('script');
|
||||
s.src = (document.location.protocol == "https:"?"https://":"http://") + 'www.google.com/jsapi?callback=_google_loader_apiLoaded';
|
||||
s.type = "text/javascript";
|
||||
document.getElementsByTagName('body')[0].appendChild(s);
|
||||
}
|
||||
};
|
||||
|
||||
var queue = [];
|
||||
var addLocationQueue = function(callback) {
|
||||
queue.push(callback);
|
||||
};
|
||||
|
||||
var runLocationQueue = function() {
|
||||
if (hasGoogleLoader()) {
|
||||
while (queue.length > 0) {
|
||||
var call = queue.pop();
|
||||
call();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window['_google_loader_apiLoaded'] = function() {
|
||||
runLocationQueue();
|
||||
};
|
||||
|
||||
var hasGoogleLoader = function() {
|
||||
return (window['google'] && google['loader']);
|
||||
};
|
||||
|
||||
var checkGoogleLoader = function(callback) {
|
||||
if (hasGoogleLoader()) { return true; }
|
||||
|
||||
addLocationQueue(callback);
|
||||
|
||||
loadGoogleLoader();
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
loadGoogleLoader(); // start to load as soon as possible just in case
|
||||
|
||||
// -- PUBLIC
|
||||
return {
|
||||
shim: true,
|
||||
|
||||
type: "ClientLocation",
|
||||
|
||||
lastPosition: null,
|
||||
|
||||
getCurrentPosition: function(successCallback, errorCallback, options) {
|
||||
var self = this;
|
||||
if (!checkGoogleLoader(function() {
|
||||
self.getCurrentPosition(successCallback, errorCallback, options);
|
||||
})) { return; }
|
||||
|
||||
if (google.loader.ClientLocation) {
|
||||
var cl = google.loader.ClientLocation;
|
||||
|
||||
var position = {
|
||||
coords: {
|
||||
latitude: cl.latitude,
|
||||
longitude: cl.longitude,
|
||||
altitude: null,
|
||||
accuracy: 43000, // same as Gears accuracy over wifi?
|
||||
altitudeAccuracy: null,
|
||||
heading: null,
|
||||
speed: null
|
||||
},
|
||||
// extra info that is outside of the bounds of the core API
|
||||
address: {
|
||||
city: cl.address.city,
|
||||
country: cl.address.country,
|
||||
country_code: cl.address.country_code,
|
||||
region: cl.address.region
|
||||
},
|
||||
timestamp: new Date()
|
||||
};
|
||||
|
||||
successCallback(position);
|
||||
|
||||
this.lastPosition = position;
|
||||
} else if (errorCallback === "function") {
|
||||
errorCallback({ code: 3, message: "Using the Google ClientLocation API and it is not able to calculate a location."});
|
||||
}
|
||||
},
|
||||
|
||||
watchPosition: function(successCallback, errorCallback, options) {
|
||||
this.getCurrentPosition(successCallback, errorCallback, options);
|
||||
|
||||
var self = this;
|
||||
var watchId = setInterval(function() {
|
||||
self.getCurrentPosition(successCallback, errorCallback, options);
|
||||
}, 10000);
|
||||
|
||||
return watchId;
|
||||
},
|
||||
|
||||
clearWatch: function(watchId) {
|
||||
clearInterval(watchId);
|
||||
},
|
||||
|
||||
getPermission: function(siteName, imageUrl, extraMessage) {
|
||||
// for now just say yes :)
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
});
|
||||
|
||||
// If you have Gears installed use that, else use Ajax ClientLocation
|
||||
navigator.geolocation = (window.google && google.gears) ? GearsGeoLocation() : AjaxGeoLocation();
|
||||
|
||||
})();
|
||||
}
|
||||
|
47
js/xbImportNode.js
Normal file
47
js/xbImportNode.js
Normal file
@ -0,0 +1,47 @@
|
||||
/* is this stuff defined? */
|
||||
if (!document.ELEMENT_NODE) {
|
||||
document.ELEMENT_NODE = 1;
|
||||
document.ATTRIBUTE_NODE = 2;
|
||||
document.TEXT_NODE = 3;
|
||||
document.CDATA_SECTION_NODE = 4;
|
||||
document.ENTITY_REFERENCE_NODE = 5;
|
||||
document.ENTITY_NODE = 6;
|
||||
document.PROCESSING_INSTRUCTION_NODE = 7;
|
||||
document.COMMENT_NODE = 8;
|
||||
document.DOCUMENT_NODE = 9;
|
||||
document.DOCUMENT_TYPE_NODE = 10;
|
||||
document.DOCUMENT_FRAGMENT_NODE = 11;
|
||||
document.NOTATION_NODE = 12;
|
||||
}
|
||||
|
||||
document._importNode = function(node, allChildren) {
|
||||
/* find the node type to import */
|
||||
switch (node.nodeType) {
|
||||
case document.ELEMENT_NODE:
|
||||
/* create a new element */
|
||||
var newNode = document.createElement(node.nodeName);
|
||||
/* does the node have any attributes to add? */
|
||||
if (node.attributes && node.attributes.length > 0)
|
||||
/* add all of the attributes */
|
||||
for (var i = 0, il = node.attributes.length; i < il;) {
|
||||
if (node.attributes[i].nodeName == 'class') {
|
||||
newNode.className = node.getAttribute(node.attributes[i++].nodeName);
|
||||
} else {
|
||||
newNode.setAttribute(node.attributes[i].nodeName, node.getAttribute(node.attributes[i++].nodeName));
|
||||
}
|
||||
}
|
||||
/* are we going after children too, and does the node have any? */
|
||||
if (allChildren && node.childNodes && node.childNodes.length > 0)
|
||||
/* recursively get all of the child nodes */
|
||||
for (var i = 0, il = node.childNodes.length; i < il;)
|
||||
newNode.appendChild(document._importNode(node.childNodes[i++], allChildren));
|
||||
return newNode;
|
||||
break;
|
||||
case document.TEXT_NODE:
|
||||
case document.CDATA_SECTION_NODE:
|
||||
case document.COMMENT_NODE:
|
||||
return document.createTextNode(node.nodeValue);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
@ -362,7 +362,9 @@ class MediaFile
|
||||
// we'll try detecting a type from its extension...
|
||||
$unclearTypes = array('application/octet-stream',
|
||||
'application/vnd.ms-office',
|
||||
'application/zip');
|
||||
'application/zip',
|
||||
// TODO: for XML we could do better content-based sniffing too
|
||||
'text/xml');
|
||||
|
||||
if ($originalFilename && (!$filetype || in_array($filetype, $unclearTypes))) {
|
||||
$type = $mte->getMIMEType($originalFilename);
|
||||
|
11
plugins/LinkPreview/Makefile
Normal file
11
plugins/LinkPreview/Makefile
Normal file
@ -0,0 +1,11 @@
|
||||
.fake: all clean
|
||||
|
||||
TARGETS=linkpreview.min.js
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
clean:
|
||||
rm -f $(TARGETS)
|
||||
|
||||
linkpreview.min.js: linkpreview.js
|
||||
yui-compressor $< -o $@
|
Loading…
Reference in New Issue
Block a user