Как стать автором
Обновить

Комментарии 10

(Сильно недостаточно советов.)
try{
// код скрипта
} catch(e){console.error(e)}

Хотелось бы дополнить, что это нужно в Fx и Opera, а Chrome и без того даёт качественные сообщения и ссылки на строку ошибки.
С учётом Fx лучше писать такую обёртку:
(function(){
var u ='undefined'
	, win = typeof unsafeWindow !=u ? unsafeWindow: window;
//... далее, код, не требующий контроля ошибок
try{
//...код с контролем ошибок
}catch(er){
	win.console.log("~~ER_global: "+ er +' (line '+(er.lineNumber||'')+')')}; //для оповещения об ошибках в Fx
})()

Совет 2-й: раз уж пишем функцию-обёртку, почему бы не использовать её:
(function(win, u, noConsole, FAST){ //всякие нужные константы
//...тело скрипта
})(typeof unsafeWindow !='undefined'? unsafeWindow: window,'undefined',1,1);


Совет 3-й: используйте метаданные не только в одном месте:
(function(){var alienFrame = /(plusone\.google\.com|userscripts\.org)/.test(location.host)
	, currMetaTx = !alienFrame && function(s){return(s=
//если Firefox+GreaseMonkey, требуется удалить "/*" перед "<!", чтобы читались многострочные данные!
/*<![CDATA[*//*
// ==UserScript==
// @name HabrAjax
// @version 0.82_2012-03-27
// @namespace spmbt.kodingen.com/index.htm
// @author spmbt0
// @description Cumulative script with over 20 functions for Fx-Opera-Chrome-Safari
// @include http://habrahabr.ru/*
// @include https://plusone.google.com/*
// @include http://userscripts.org/scripts/source/*
// @exclude http://habrahabr.ru/api/*
// @resource meta 121690.meta.js
// @update 0.82 механизм плагинов и модулей через CustomEvent (Fx6+, Chrome, Safari)
// @update 0.815 совместимость со скриптом переключателя режимов "Все блоги - Избранные" (HabrAllHub)
// @icon data:image/gif;base64,R0lGODlhIAAgAMMBAG6Wyv///2+NtIucstfY2b/FzpSmvY+QkM3Nzunp6fLy8qGwweDg4MbFxa2trrm6uiwAAAAAIAAgAAAE/xDISau9OM/AOe2edoHBBwqiRZodmrKhRLqXYFfrdmLCQBQGWk62swgOiERAQQgChs9iRZBMKDgEFGn...
// ==/UserScript==
*/s//]]>
)}	//-вернёт false, если не продолжать; 'false' (строку) - если Fx; иначе - строки метаданных
	, u ='undefined'
	, isUsfW = typeof unsafeWindow !=u
	, win = isUsfW ? unsafeWindow: window
	, isFxGmS = win !==window
	, isFxScr = typeof GM_getMetadata !=u
	, readMeta = function(s, isFxScr){ //парсинг многострочного текста по мета-директивам
		if(typeof s !='string') //очистка оболочки функций, выделение мн-стр-комментария
			s = typeof s=='function'
				? ((/\*/.test(function(){/**/}+1) ? s : s(!1) )+'')
						.replace(/(^[\s\S]*\*\/\/\*\r?\n?|\r?\n?\*\/s[\s\S]*$)/gm,'')
				: (typeof s !=u && s!==null && s.toString ? s.toString() :''); //здесь же- 'xml'
		var metaD ={}, j =0;
		if(s==='false' && isFxScr){ //isFxScr - получать ли данные средствами Scriptish
			metaD = GM_getMetadata();
			for(var i in metaD){ //приведение к нормальному виду
				if(metaD[i].length ==1)
					metaD[i] = metaD[i][0];
				j++;
			}
		}else{
			var meta = s.split('\n'), aa, a2;
			for(var i=0, mL = meta.length; i < mL; i++){
				if(( aa = /^.*?\/\/\s*@([\S]+)\s(\s*)(.*)/g.exec(meta[i]) )){
					a2 = aa[3] !==undefined && aa[3] || aa[2];
					if(metaD[aa[1]]===undefined)
						metaD[aa[1]] = a2;
					else{
						if(! (metaD[aa[1]] instanceof Array))
							metaD[aa[1]] = [metaD[aa[1]]];
						metaD[aa[1]].push(a2);
					}
					j++;
				}else
					if(!/^.*?\/\/\s*[\-=]*\s*\/?\s*UserScript\s*[\-=]*\s*$/i.test(meta[i]))
						metaD[j++] = meta[i];
			}
		}
		metaD._length = j; //число ключей хеша
		return j >1 && metaD || undefined; //хеш директив + нум.список простых строк + _length -чис.простых строк или und., если не найдено
	},
	metaD = readMeta(currMetaTx, isFxScr); //теперь можно читать метаданные в этом хеше (кроссбраузерно!)

простите, если «многобукв». В общем, по коду заголовка вы догадались где искать пример этой фичи.

Совет 4-й. Советует использовать в связке с советом 3 не GreaseMonkey (ещё раз, НЕ GreaseMonkey!) а Scriptish. Потому что для GreaseMonkey в этой фиче — принципиально неустранимая некроссбраузерность (я, кажется, об этом писал в статье, но не уверен, может быть лежит в черновиках).

Совет 5-й. Получайте кроссбраузерно внешние метаданные — от самого скрипта, от других скриптов, от анонсов скриптов на ваших серверах. Пример кода смотрите там же, откуда он взят для совета 3, ибо было бы ещё почти столько же.

Совет 6-й. Если в коде вы сделали синтаксическую ошибку, легко обнаружить её поможет только Хром. Запустите неработающий скрипт в Хроме, это путь к спасению, он укажет путь к просветл пропущенной запятой.

Совет 7-й. Метаться в Хром иногда лениво, поэтому озаботьтесь хорошим механизмом трассировки, она очень-очень пригодится. Уже имеется win.console.log, но это длинно и не очень удобно. Делаем так:

var wcl = function(){ //консоль как метод строки или функция, с отключением по noConsole ==1
	if(win.console && !noConsole)
		win.console.log.apply(console, this instanceof String
			? ["'=="+this+"'"].concat([].slice.call(arguments)) : arguments);
};
String.prototype.wcl = wcl;
(впрочем, это полезно и в простых скриптах).
Что получили? Можем писать

'myVar'.wcl(myWar);

Почему так? Потому что их будет много, без меток трассировочные значения будут все на одно лицо. ЗАчем там '=='+...? Чтобы лучше видеть. Зачем в апострофах? Чтобы лучше находить в коде по ctrl-F. (И теперь видно, зачем здесь константа noConsole из совета 2?)

Совет 8-й. Содержите кроссбраузерную функцию кроссдоменного обмена по postMessage, она отличается от функции для простых скриптов. (А в Хроме она и для внутридоменного понадобится.) Я об этом обещал написать, скоро напишу, статья готова, а реализацию можно увидеть опять же, в том же источнике примеров.

Совет 9-й. (Думаю, ещё не сучно.) Используйте легковесную библиотеку, не поддерживающую IE, если не собираетесь (с большой вероятностью, думается, это так) поддерживать юзерскрипты там. Zepto, AtomJs, Backbone или что-то небольшое своё — оно всегда пригодится — работа с DOM, с событиями, массивами, хешами. Впрочем, примеров и образцов нет. В моих примерах есть, но очень примитивное ядро на 2-3 К, не советовал бы брать за основу.

Совет 10-й (продожение 9-го). Среди полезных исполльзуемых функцих, кроме работы с DOM, будут и:
подгрузка стилей:
addRules: function(css){
	if(typeof GM_addStyle != "undefined"){ GM_addStyle(css);
	}else if(typeof PRO_addStyle != "undefined"){ PRO_addStyle(css);
	}else if(typeof addStyle != "undefined"){ addStyle(css);
	}else{
		var heads = document.getElementsByTagName("head");
		if(heads.length){
			var node = document.createElement("style");
			node.type = "text/css";
			node.appendChild(document.createTextNode(css));
			heads[0].appendChild(node);
	}}
}
,
подгрузка сторонних скриптов (кода многовато на все случаи, приводить не буду),
специфическое ожидание целевого условия по таймеру (очень частая функция), для примера ищите execCallback в HabrAjax,
генерация User Event и CustomEvent — полезная техника,
показ подсказок по наведению мыши (примеров нет),
открывание ссылок в фрейме, если нужно для задачи,
группа функций работы с настройками вашего скрипта.

Вот это — я понимаю, полезные советы, вполне достаточные для работы с юзерскриптами…

Очередной случай того, когда комментарии превосходят саму статью? Даже и не знаю, что теперь в избранное добавлять…
Обидно, такой хороший коммент, а я плюс поставить не могу. Ну, тогда просто спасибо)

Изначально статья задумывалась как пример эмуляции unsafeWindow под хромом — гугл не давал нормальных ответов, как это сделать. А в процессе я немного увлёкся. Так что да, статья точно неполная.

var u ='undefined'
    , win = typeof unsafeWindow !=u ? unsafeWindow: window;

Это не будет работать под хромом — там unsafeWindow есть, но нет у него того функционала.
Опять же, присвоение переменной значения this.unsafeWindow — на порядок короче, и будет работать и под лисой так же.
Кстати, @include прекрасно работает в Chrome. Проверено тысячами пользователей моих user-js.
Сейчас проверил — не работает. Но у меня не хром, хромиум под линуксом… Сейчас выберусь под винду, проверю под хромом. Тем не менее — можно пример?

Тысячи пользователей… Позвольте полюбопытствовать: что вы пишете?
Просто плагины для браузерной игрушки.

services.mib-oldbk.com/
Зашёл, попробовал открыть ваш скрипт… Хром сказал, что он будет иметь доступ ко всем сайтам.
И что с того? Вы на закладку Network смотрите. Напишите скрипт с @include и проверьте.
И правда, так include работает. Тем не менее, имхо, лучше указывать обе директивы — для большей наглядности для конечного пользователя.
Упс, забыл нажать «Ответить».
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории