From faff8e2cd8b61230d630afa7df8e3f60cb4ebcbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 16 Nov 2015 00:01:34 +0100 Subject: [PATCH 01/32] Update list.php --- htdocs/commande/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 0323bd4ec09..1530795b8dd 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -444,7 +444,7 @@ if ($resql) } $text_info .= $generic_commande->lines[$lig]->qty.' X '.$generic_commande->lines[$lig]->ref.' '.dol_trunc($generic_commande->lines[$lig]->product_label, 25); $text_stock_reel = $generic_product->stock_reel.'/'.$stock_order; - if ($generic_product->stock_reel<$generic_commande->lines[$lig]->qty) { + if (($generic_product->stock_reel < $generic_commande->lines[$lig]->qty) || ($stock_order > $generic_product->stock_reel)) { $notshippable++; $text_info.=''.$langs->trans('Available').' : '.$text_stock_reel.''; } else { From 28196a5fd92a5c6ef66c287911b2a1584519ae6a Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Wed, 18 Nov 2015 12:24:52 +0100 Subject: [PATCH 02/32] add pgsql function --- htdocs/install/pgsql/functions/functions.sql | 46 +++++++++++++++++++- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/htdocs/install/pgsql/functions/functions.sql b/htdocs/install/pgsql/functions/functions.sql index 37d5630fbea..768eb853ca2 100644 --- a/htdocs/install/pgsql/functions/functions.sql +++ b/htdocs/install/pgsql/functions/functions.sql @@ -54,38 +54,66 @@ CREATE OR REPLACE FUNCTION dol_util_triggerall(DoEnable boolean) RETURNS integer -- Add triggers for timestamp fields CREATE OR REPLACE FUNCTION update_modified_column_tms() RETURNS TRIGGER AS $$ BEGIN NEW.tms = now(); RETURN NEW; END; $$ LANGUAGE plpgsql; +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_accounting_fiscalyear FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_accountingaccount FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_accountingtransaction FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_actioncomm FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_actioncomm_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_adherent FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_adherent_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_adherent_type FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_adherent_type_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_advtargetemailing FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_askpricesupplier FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_askpricesupplier_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_askpricesupplierdet_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bank FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bank_account FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bank_account_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bordereau_cheque FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_boxes_def FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_c_email_templates FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_c_field_list FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_c_shipment_mode FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_categories_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_chargesociales FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_commande FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_commande_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_commande_fournisseur FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_commande_fournisseur_dispatch FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_commande_fournisseur_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_commande_fournisseur_log FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_commande_fournisseurdet_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_commandedet_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_const FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_contrat FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_contrat_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_contratdet FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_contratdet_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_contratdet_log FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_cotisation FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_cronjob FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_deplacement FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_don FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_don_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_ecm_documents FOR EACH ROW EXECUTE PROCEDURE update_modified_column_date_u(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_element_resources FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_entrepot FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_events FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_expedition FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_expensereport FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_facture FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_facture_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_facture_fourn FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_facture_fourn_det_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_facture_fourn_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_facturedet_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_fichinter FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_fichinter_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_fichinterdet_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_livraison FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_loan FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_localtax FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_menu FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_notify FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); @@ -96,15 +124,28 @@ CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_opensurvey_user_stud CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_paiement FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_paiementcharge FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_paiementfourn FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_payment_donation FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_payment_expensereport FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_payment_loan FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_payment_salary FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_printer_ipp FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_printing FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_product FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_product_batch FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_product_customer_price FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_product_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_product_fournisseur_price FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_product_price FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_product_stock FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_projet FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_projet_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_projet_task FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_projet_task_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_propal FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_propal_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_propal_merge_pdf_product FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_propaldet_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_resource FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_societe FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_societe_address FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_societe_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); @@ -114,12 +155,13 @@ CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_societe_rib FOR EACH CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_socpeople FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_socpeople_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_stock_mouvement FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_time_basket FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_timebasket_counter FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_tva FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_user FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_user_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_usergroup FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_cronjob FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_printing FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_usergroup_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE OR REPLACE FUNCTION update_modified_column_date_m() RETURNS TRIGGER AS $$ BEGIN NEW.date_m = now(); RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_ecm_directories FOR EACH ROW EXECUTE PROCEDURE update_modified_column_date_m(); From 3a2cb63575d84a15634e62d79d0cf9cf71367670 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 19 Nov 2015 16:20:06 +0100 Subject: [PATCH 03/32] Update list.php --- htdocs/commande/list.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 1530795b8dd..b941ba37249 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -404,6 +404,7 @@ if ($resql) // Shippable Icon if (($objp->fk_statut > 0) && ($objp->fk_statut < 3) && ! empty($conf->global->SHIPPABLE_ORDER_ICON_IN_LIST)) { $notshippable=0; + $warning = 0; $text_info=''; $nbprod=0; for ($lig=0; $lig<(count($generic_commande->lines)); $lig++) { @@ -444,7 +445,11 @@ if ($resql) } $text_info .= $generic_commande->lines[$lig]->qty.' X '.$generic_commande->lines[$lig]->ref.' '.dol_trunc($generic_commande->lines[$lig]->product_label, 25); $text_stock_reel = $generic_product->stock_reel.'/'.$stock_order; - if (($generic_product->stock_reel < $generic_commande->lines[$lig]->qty) || ($stock_order > $generic_product->stock_reel)) { + if ($stock_order > $generic_product->stock_reel && ! ($generic_product->stock_reel < $generic_commande->lines[$lig]->qty)) { + $warning++; + $text_warning.=''.$langs->trans('Available').' : '.$text_stock_reel.''; + } + if ($generic_product->stock_reel < $generic_commande->lines[$lig]->qty) { $notshippable++; $text_info.=''.$langs->trans('Available').' : '.$text_stock_reel.''; } else { @@ -469,6 +474,11 @@ if ($resql) print $form->textwithtooltip('',$text_info,2,1,$text_icon,'',2); print ''; } + if ($warning) { + print ''; + print $form->textwithtooltip('', $langs->trans('NotEnoughForAllOrders').'
'.$text_warning, 2, 1, img_picto('', 'error'),'',2); + print ''; + } } // warning late icon From 80f19de223f781ee394325e6859f421ee0a9df2f Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Thu, 19 Nov 2015 16:32:25 +0100 Subject: [PATCH 04/32] fix && vs and --- htdocs/core/class/extrafields.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 99114bfaef1..5d04b9c9317 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -258,7 +258,7 @@ class ExtraFields if (! empty($attrname) && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname) && ! is_numeric($attrname)) { - if(is_array($param) and count($param) > 0) + if(is_array($param) && count($param) > 0) { $params = $this->db->escape(serialize($param)); } From e31a8f25a216fcf88a3a9fe64ecce555ee734b95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Sat, 21 Nov 2015 10:55:23 +0100 Subject: [PATCH 05/32] FIX #4018 SQL error if trying to access the mailing/card.php page without an ID defined --- htdocs/comm/mailing/class/mailing.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/comm/mailing/class/mailing.class.php b/htdocs/comm/mailing/class/mailing.class.php index 1df5a7ad18f..a69909a1ef3 100644 --- a/htdocs/comm/mailing/class/mailing.class.php +++ b/htdocs/comm/mailing/class/mailing.class.php @@ -196,7 +196,7 @@ class Mailing extends CommonObject $sql.= ", m.date_envoi"; $sql.= ", m.extraparams"; $sql.= " FROM ".MAIN_DB_PREFIX."mailing as m"; - $sql.= " WHERE m.rowid = ".$rowid; + $sql.= " WHERE m.rowid = ".(int) $rowid; dol_syslog(get_class($this)."::fetch", LOG_DEBUG); $result=$this->db->query($sql); From eba5832d3ad9fdb7101e844b327eb3081c906978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Sat, 21 Nov 2015 10:58:58 +0100 Subject: [PATCH 06/32] FIX #4049 PHP warning when trying to access a non-existing product/service --- htdocs/product/card.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/product/card.php b/htdocs/product/card.php index b5dca48674f..dbadd69cdcb 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -1569,7 +1569,6 @@ else } else if ($action != 'create') { - header("Location: index.php"); exit; } } From e8fc5f0d3ac3f1062e48ef464177432e6027429f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Sat, 21 Nov 2015 11:00:56 +0100 Subject: [PATCH 07/32] FIX #3987 Undefined variable $newref in CommandeFournisseur::approve --- htdocs/fourn/class/fournisseur.commande.class.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 06da62fd016..0299df0dbed 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -765,7 +765,6 @@ class CommandeFournisseur extends CommonOrder if (! $error) { - $this->ref=$newref; if ($movetoapprovestatus) $this->statut = 2; else $this->statut = 1; if (empty($secondlevel)) // standard or first level approval From 4bf6cf4e65b847044036ad332e5294aabb2d271e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Sat, 21 Nov 2015 11:24:18 +0100 Subject: [PATCH 08/32] FIX #3508 Useless tooltip in 3.8 boxes --- htdocs/core/boxes/modules_boxes.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/core/boxes/modules_boxes.php b/htdocs/core/boxes/modules_boxes.php index d1d05ec28a8..808af6a68b9 100644 --- a/htdocs/core/boxes/modules_boxes.php +++ b/htdocs/core/boxes/modules_boxes.php @@ -287,7 +287,10 @@ class ModeleBoxes // Can't be abtract as it is instantiated to build "empty" // Url if (! empty($contents[$i][$j]['url']) && empty($contents[$i][$j]['logo'])) { - $out.= 'trans("Show").' '.$tooltip, 1).'" class="classfortooltip"'; + } //$out.= ' alt="'.$textwithnotags.'"'; // Pas de alt sur un "" $out.= isset($contents[$i][$j]['target'])?' target="'.$contents[$i][$j]['target'].'"':''; $out.= '>'; From 3fbe10a5784e8025020700229d46821a1ed14f9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Sat, 21 Nov 2015 12:18:29 +0100 Subject: [PATCH 09/32] FIX #3293 Login page form icons not shown --- htdocs/theme/eldy/style.css.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 8d42f6c650e..0d4e850b238 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -1053,17 +1053,17 @@ img.loginphoto { border-radius: 2px; } .span-icon-user { - background: url() no-repeat scroll 7px 7px; + background-image: url(); + background-repeat: no-repeat; } .span-icon-password { background-image: url(); background-repeat: no-repeat; } -/* + .span-icon-user input, .span-icon-password input { - margin-right: 30px; + margin-left: 25px; } -*/ /* ============================================================================== */ /* Menu gauche */ From a456d212494625d4781687da4b7c82af0bf142b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garci=CC=81a=20de=20La=20Fuente?= Date: Sat, 21 Nov 2015 13:25:09 +0100 Subject: [PATCH 10/32] FIX #3231 [Members] Public subscription page displays GeoIP error --- htdocs/core/class/dolgeoip.class.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/htdocs/core/class/dolgeoip.class.php b/htdocs/core/class/dolgeoip.class.php index 7cddd4c16f5..a57e4e844ec 100644 --- a/htdocs/core/class/dolgeoip.class.php +++ b/htdocs/core/class/dolgeoip.class.php @@ -58,18 +58,15 @@ class DolGeoIP // Here, function exists (embedded into PHP or exists because we made include) if (empty($type) || empty($datfile)) { - //dol_syslog("DolGeoIP::DolGeoIP parameter datafile not defined", LOG_ERR); - $this->errorlabel='DolGeoIP constructor was called with no datafile parameter'; - //dol_print_error('','DolGeoIP constructor was called with no datafile parameter'); - print $this->errorlabel; + $this->errorlabel='Constructor was called with no datafile parameter'; + dol_syslog('DolGeoIP '.$this->errorlabel, LOG_ERR); return 0; } if (! file_exists($datfile) || ! is_readable($datfile)) { - //dol_syslog("DolGeoIP::DolGeoIP datafile ".$datfile." can not be read", LOG_ERR); $this->error='ErrorGeoIPClassNotInitialized'; $this->errorlabel="Datafile ".$datfile." not found"; - print $this->errorlabel; // To be sure to understand when it fails on screens + dol_syslog('DolGeoIP '.$this->errorlabel, LOG_ERR); return 0; } From 3d05b53a627efde4dc3a29ff605643e91f055f6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 22 Nov 2015 19:08:38 +0100 Subject: [PATCH 11/32] Typo --- htdocs/compta/facture/class/facture.class.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 27f83a23a7f..b27bc9d2294 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -257,7 +257,7 @@ class Facture extends CommonInvoice $this->fk_incoterms = $_facrec->fk_incoterms; $this->location_incoterms= $_facrec->location_incoterms; - // Clean parametres + // Clean parameters if (! $this->type) $this->type = self::TYPE_STANDARD; $this->ref_client=trim($this->ref_client); $this->note_private=trim($this->note_private); @@ -1017,7 +1017,7 @@ class Facture extends CommonInvoice if ($this->statut == self::STATUS_DRAFT) $this->brouillon = 1; - // Retreive all extrafield for invoice + // Retrieve all extrafield for invoice // fetch optionals attributes and labels require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; $extrafields=new ExtraFields($this->db); @@ -1386,7 +1386,7 @@ class Facture extends CommonInvoice dol_syslog(get_class($this)."::delete rowid=".$rowid, LOG_DEBUG); - // TODO Test if there is at least on payment. If yes, refuse to delete. + // TODO Test if there is at least one payment. If yes, refuse to delete. $error=0; $this->db->begin(); @@ -1448,7 +1448,7 @@ class Facture extends CommonInvoice } } - // If we decrament stock on invoice validation, we increment + // If we decrement stock on invoice validation, we increment if ($this->type != self::TYPE_DEPOSIT && $result >= 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $idwarehouse!=-1) { require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; @@ -2152,7 +2152,7 @@ class Facture extends CommonInvoice $total_localtax2 = $tabprice[10]; $pu_ht = $tabprice[3]; - // Rang to use + // Rank to use $rangtouse = $rang; if ($rangtouse == -1) { From f9e82721d7daedc13ba1f8520ef8cb3a63a103a5 Mon Sep 17 00:00:00 2001 From: aspangaro Date: Sun, 22 Nov 2015 20:13:48 +0100 Subject: [PATCH 12/32] Fix: Auguria Menu & wrong table in dictionary HRM --- htdocs/core/menus/init_menu_auguria.sql | 4 ++-- htdocs/core/modules/modHRM.class.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/menus/init_menu_auguria.sql b/htdocs/core/menus/init_menu_auguria.sql index 84b9928e432..cfb5348c4c9 100644 --- a/htdocs/core/menus/init_menu_auguria.sql +++ b/htdocs/core/menus/init_menu_auguria.sql @@ -12,12 +12,12 @@ insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, left insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('societe|fournisseur', '( ! empty($conf->societe->enabled) && (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) || empty($conf->global->SOCIETE_DISABLE_CUSTOMERS))) || ! empty($conf->fournisseur->enabled)', 2__+MAX_llx_menu__, __HANDLER__, 'top', 'companies', '', 0, '/societe/index.php?mainmenu=companies&leftmenu=', 'ThirdParties', -1, 'companies', '$user->rights->societe->lire || $user->rights->societe->contact->lire', '', 2, 20, __ENTITY__); insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('product|service', '$conf->product->enabled || $conf->service->enabled', 3__+MAX_llx_menu__, __HANDLER__, 'top', 'products', '', 0, '/product/index.php?mainmenu=products&leftmenu=', 'Products/Services', -1, 'products', '$user->rights->produit->lire||$user->rights->service->lire', '', 0, 30, __ENTITY__); insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('propal|commande|fournisseur|contrat|ficheinter', '$conf->propal->enabled || $conf->commande->enabled || $conf->fournisseur->enabled || $conf->contrat->enabled || $conf->ficheinter->enabled', 5__+MAX_llx_menu__, __HANDLER__, 'top', 'commercial', '', 0, '/comm/index.php?mainmenu=commercial&leftmenu=', 'Commercial', -1, 'commercial', '$user->rights->societe->lire || $user->rights->societe->contact->lire', '', 2, 40, __ENTITY__); -insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('comptabilite|accounting|facture|deplacement|don|tax|salaries|loan', '$conf->comptabilite->enabled || $conf->accounting->enabled || $conf->facture->enabled || $conf->deplacement->enabled || $conf->don->enabled || $conf->tax->enabled || $conf->salaries->enabled || $conf->loan->enabled', 6__+MAX_llx_menu__, __HANDLER__, 'top', 'accountancy', '', 0, '/compta/index.php?mainmenu=accountancy&leftmenu=', 'MenuFinancial', -1, 'compta', '$user->rights->compta->resultat->lire || $user->rights->accounting->plancompte->lire || $user->rights->facture->lire|| $user->rights->deplacement->lire || $user->rights->don->lire || $user->rights->tax->charges->lire || $user->rights->salaries->read || $user->rights->loan->read', '', 2, 50, __ENTITY__); +insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('comptabilite|accounting|facture|don|tax|salaries|loan', '$conf->comptabilite->enabled || $conf->accounting->enabled || $conf->facture->enabled || $conf->don->enabled || $conf->tax->enabled || $conf->salaries->enabled || $conf->loan->enabled', 6__+MAX_llx_menu__, __HANDLER__, 'top', 'accountancy', '', 0, '/compta/index.php?mainmenu=accountancy&leftmenu=', 'MenuFinancial', -1, 'compta', '$user->rights->compta->resultat->lire || $user->rights->accounting->plancompte->lire || $user->rights->facture->lire|| $user->rights->don->lire || $user->rights->tax->charges->lire || $user->rights->salaries->read || $user->rights->loan->read', '', 2, 50, __ENTITY__); insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('banque|prelevement', '$conf->banque->enabled || $conf->prelevement->enabled', 14__+MAX_llx_menu__, __HANDLER__, 'top', 'bank', '', 0, '/compta/bank/index.php?mainmenu=bank&leftmenu=bank', 'MenuBankCash', -1, 'banks', '$user->rights->banque->lire || $user->rights->prelevement->bons->lire', '', 0, 60, __ENTITY__); insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('projet', '$conf->projet->enabled', 7__+MAX_llx_menu__, __HANDLER__, 'top', 'project', '', 0, '/projet/index.php?mainmenu=project&leftmenu=', 'Projects', -1, 'projects', '$user->rights->projet->lire', '', 2, 70, __ENTITY__); insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('mailing|export|import|opensurvey', '$conf->mailing->enabled || $conf->export->enabled || $conf->import->enabled || $conf->opensurvey->enabled', 8__+MAX_llx_menu__, __HANDLER__, 'top', 'tools', '', 0, '/core/tools.php?mainmenu=tools&leftmenu=', 'Tools', -1, 'other', '$user->rights->mailing->lire || $user->rights->export->lire || $user->rights->import->run || $user->rights->opensurvey->read', '', 2, 90, __ENTITY__); insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('adherent', '$conf->adherent->enabled', 13__+MAX_llx_menu__, __HANDLER__, 'top', 'members', '', 0, '/adherents/index.php?mainmenu=members&leftmenu=', 'Members', -1, 'members', '$user->rights->adherent->lire', '', 2, 110, __ENTITY__); -insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('hrm', '$conf->hrm->enabled || $conf->holiday->enabled || $conf->deplacement->enabled || $conf->expensereport->enabled', 15__+MAX_llx_menu__, __HANDLER__, 'top', 'hrm', '', 0, '/compta/hrm.php?mainmenu=hrm&leftmenu=', 'HRM', -1, 'holiday', '$user->rights->hrm->employee->read || $user->rights->holiday->write || $user->rights->deplacement->lire || $user->rights->expensereport->lire', '', 0, 80, __ENTITY__); +insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('hrm|holiday|deplacement|expensereport', '$conf->hrm->enabled || $conf->holiday->enabled || $conf->deplacement->enabled || $conf->expensereport->enabled', 15__+MAX_llx_menu__, __HANDLER__, 'top', 'hrm', '', 0, '/compta/hrm.php?mainmenu=hrm&leftmenu=', 'HRM', -1, 'holiday', '$user->rights->hrm->employee->read || $user->rights->holiday->write || $user->rights->deplacement->lire || $user->rights->expensereport->lire', '', 0, 80, __ENTITY__); -- Home - Setup insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$user->admin', __HANDLER__, 'left', 100__+MAX_llx_menu__, 'home', 'setup', 1__+MAX_llx_menu__, '/admin/index.php?leftmenu=setup', 'Setup', 0, 'admin', '', '', 2, 0, __ENTITY__); diff --git a/htdocs/core/modules/modHRM.class.php b/htdocs/core/modules/modHRM.class.php index 1dcf2b28177..20ae0f7971c 100644 --- a/htdocs/core/modules/modHRM.class.php +++ b/htdocs/core/modules/modHRM.class.php @@ -96,7 +96,7 @@ class modHRM extends DolibarrModules ), 'tabsql'=>array( 'SELECT rowid, pos, code, label, active FROM '.MAIN_DB_PREFIX.'c_hrm_department', - 'SELECT rowid, pos, code, label, c_level, active FROM '.MAIN_DB_PREFIX.'c_hrm_department' + 'SELECT rowid, pos, code, label, c_level, active FROM '.MAIN_DB_PREFIX.'c_hrm_function' ), 'tabsqlsort'=>array( 'rowid ASC', From 5bed70b04e69e756bb6386610ab7028c973f7c10 Mon Sep 17 00:00:00 2001 From: aspangaro Date: Sun, 22 Nov 2015 21:31:05 +0100 Subject: [PATCH 13/32] New: Donation complete cerfa 11580*03 Fr - Thanks Benoit21 --- htdocs/core/modules/dons/html_cerfafr.html | 466 +++++++++++------- .../modules/dons/html_cerfafr.modules.php | 190 ++++++- htdocs/don/admin/donation.php | 34 +- 3 files changed, 491 insertions(+), 199 deletions(-) diff --git a/htdocs/core/modules/dons/html_cerfafr.html b/htdocs/core/modules/dons/html_cerfafr.html index ca3f3510eee..ea9dbee01e3 100644 --- a/htdocs/core/modules/dons/html_cerfafr.html +++ b/htdocs/core/modules/dons/html_cerfafr.html @@ -1,185 +1,299 @@ - - - __DonationTitle__ - - + + + Reçu au titre des dons à certains organismes d’intérêt général + + +
+ + + + + + +
+
+ N° 11580*03
+ DGFIP +
+
+ Reçu au titre des dons
+ à certains organismes d’intérêt général

+ Articles 200, 238 bis et 885-0 V bis A du code général des impôts (CGI) +
+ Numéro d'ordre du reçu
+ __REF__ +
-
+ + + + +
+ + + + +
+ + Bénéficiaire des versements + +
- - +
+ + + + + + +
+ Nom ou dénomination :
+ __MAIN_INFO_SOCIETE_NOM__
+ Adresse :
+ __MAIN_INFO_SOCIETE_ADDRESS__
+ Code postal __MAIN_INFO_SOCIETE_ZIP__ Commune __MAIN_INFO_SOCIETE_TOWN__
+ Objet:
+ __MAIN_INFO_SOCIETE_OBJECT__ +
+
+ Cochez la case concernée (1) :
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Association ou fondation reconnue d'utilité publique par décret en date du ........./ ..... /........... publié au Journal + officiel du ......./ ....../ .......... . ou association située dans le département de la Moselle, du Bas-Rhin ou + du Haut-Rhin dont la mission a été reconnue d'utilité publique par arrêté préfectoral en date du …./.…/……..
Fondation universitaire ou fondation partenariale mentionnées respectivement aux articles L. 719-12 et + L. 719-13 du code de l'éducation
Fondation d'entreprise
Oeuvre ou organisme d'intérêt général
Musée de France
Établissement d'enseignement supérieur ou d’enseignement artistique public ou privé, d’intérêt général, à but + non lucratif
Organisme ayant pour objet exclusif de participer financièrement à la création d'entreprises
Association cultuelle ou de bienfaisance et établissement public des cultes reconnus d'Alsace-Moselle
Organisme ayant pour activité principale l'organisation de festivals
Association fournissant gratuitement une aide alimentaire ou des soins médicaux à des personnes en difficulté ou + favorisant leur logement
Fondation du patrimoine ou fondation ou association qui affecte irrévocablement les dons à la Fondation du + patrimoine, en vue de subventionner les travaux prévus par les conventions conclues entre la Fondation du + patrimoine et les propriétaires des immeubles (article L. 143-2-1 du code du patrimoine)
Établissement de recherche public ou privé, d’intérêt général, à but non lucratif
Entreprise d’insertion ou entreprise de travail temporaire d’insertion (articles L. 5132-5 et L. 5132-6 du code du + travail).
Associations intermédiaires (article L. 5132-7 du code du travail)
Ateliers et chantiers d’insertion (article L. 5132-15 du code du travail)
Entreprises adaptées (article L. 5213-13 du code du travail)
Agence nationale de la recherche (ANR)
Société ou organisme agréé de recherche scientifique ou technique (2)
Autre organisme : ………………………………………………………………………………………………
+
+
+ + (1) ou n'indiquez que les renseignements concernant l'organisme +
+ (2) dons effectués par les entreprises +
+ +
+ + + + +
+ + + + +
+ + Donateur + +
+ + + + + + + + +
+ Nom :
+ __DONATOR_SOCIETE____DONATOR_LASTNAME__ +
+ Prénoms :
+ __DONATOR_FIRSTNAME__ +
+ Adresse :
+ __DONATOR_ADDRESS__
+ Code postal __DONATOR_ZIP__ Commune __DONATOR_TOWN__ +
+
- Cerfa N° 11580*03 +
- - __DonationReceipt__
- __FrenchArticle__ - + + + + +
+ + + + +
+ Le bénéficiaire reconnaît avoir reçu au titre des dons et versements ouvrant droit à réduction d'impôt, la somme de :
+ + + + +
+ __AMOUNT__ euros +
+
+ Somme en toutes lettres : __AMOUNTLETTERS__ +
+
+ Date du versement ou du don : __DATE__ +
+
+ Le bénéficiaire certifie sur l’honneur que les dons et versements qu’il reçoit ouvrent droit à la réduction d'impôt prévue à l’article (3) :
+ + + __CodeDon__ + +
+
+ Forme du don :
+ + + + +
Acte authentique Acte sous seing privé Déclaration de don manuel Autres
+
+ Nature du don :
+ + + + +
Numéraire Titres de sociétés cotés Autres (4)
+
+ En cas de don en numéraire, mode de versement du don : + + + __ModePaiement__ + +
+
+
+ + + + + + + + + + +
(3) + L’organisme bénéficiaire peut cocher une ou plusieurs cases.
+ L’organisme bénéficiaire peut, en application de l’article L. 80 C du livre des procédures fiscales, demander à l’administration s’il relève + de l’une des catégories d’organismes mentionnées aux articles 200 et 238 bis du code général des impôts.
+ Il est rappelé que la délivrance irrégulière de reçus fiscaux par l’organisme bénéficiaire est susceptible de donner lieu, en application des + dispositions de l'article 1740 A du code général des impôts, à une amende fiscale égale à 25 % des sommes indûment mentionnées sur + ces documents. +
(4) + Notamment : abandon de revenus ou de produits ; frais engagés par les bénévoles, dont ils renoncent expressément au remboursement
+
+
+ +
+
- - __DonationRef__ - - - - -
- - - - -
__REF__
-
- - - - - - - - - -
- - - - -
- - __DonationRecipient__ - -
-
- - - - - -
- - - - -
- __Name__ :
- __MAIN_INFO_SOCIETE_NOM__
- __Address__ :
- __MAIN_INFO_SOCIETE_ADDRESS__
- __Zip__ : __MAIN_INFO_SOCIETE_ZIP__
- __Town__ : __MAIN_INFO_SOCIETE_TOWN__
-
-
- -
-
- - - - - -
- - - - -
- - __Donor__ - -
-
- - - - - -
- - - - -
- __Name__ :
- __DONATOR_FIRSTNAME__ __DONATOR_LASTNAME__
- __Address__ :
- __DONATOR_ADDRESS__
- __Zip__ : __DONATOR_ZIP__
- __Town__ : __DONATOR_TOWN__
-
-
- -
-
- - - - - - -
- - - - - - - -
- __IConfirmDonationReception__ :
- - - - -
- - __AMOUNT__ __CURRENCY__ - -
- __DonationDatePayment__ : __DATE__
- __PaymentMode__ : __PAYMENTMODE_LIB__
- - - - - -
-
- __Message__ : - __DonationMessage__
-
- - - - - - - - - -
- __FrenchEligibility__
- __ARTICLE200__ __ARTICLE238__ __ARTICLE885__ -
- - - - -
- - - - -
-
__Date__ & __Signature__
-
__NOW__
-
-
-
- -
-
- - + + + + + +
+ + + +
Date et signature

+ + +
+ + + + +
+ __NOW__ +
+
+
+
+
+ diff --git a/htdocs/core/modules/dons/html_cerfafr.modules.php b/htdocs/core/modules/dons/html_cerfafr.modules.php index ee8951864c0..7861f089cc7 100644 --- a/htdocs/core/modules/dons/html_cerfafr.modules.php +++ b/htdocs/core/modules/dons/html_cerfafr.modules.php @@ -3,7 +3,8 @@ * Copyright (C) 2005-2006 Laurent Destailleur * Copyright (C) 2012 Regis Houssin * Copyright (C) 2012 Marcos García - * Copyright (C) 2014-2015 Alexandre Spangaro + * Copyright (C) 2014-2015 Alexandre Spangaro + * Copyright (C) 2015 Benoit Bruchard * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -45,7 +46,7 @@ class html_cerfafr extends ModeleDon $this->db = $db; $this->name = "cerfafr"; - $this->description = $langs->trans('DonationsReceiptModel').' - fr_FR - Cerfa 11580*03'; + $this->description = 'Modèles de reçu de dons - fr_FR - Cerfa 11580*03'; // Dimension page for size A4 $this->type = 'html'; @@ -130,7 +131,30 @@ class html_cerfafr extends ModeleDon $paymentmode = $formclass->cache_types_paiements[$don->modepaiementid]['label']; } else $paymentmode = ''; - + + if ($don->modepaiementid==7){ + $ModePaiement = ' Remise d\'espèces Chèque Virement, prélèvement, carte bancaire'; + } + else if ($don->modepaiementid==4){ + $ModePaiement = ' Remise d\'espèces Chèque Virement, prélèvement, carte bancaire'; + } + else if ($don->modepaiementid==2 OR $don->modepaiementid==3 OR $don->modepaiementid==6){ + $ModePaiement = ' Remise d\'espèces Chèque Virement, prélèvement, carte bancaire'; + } + else + { + $ModePaiement = ' Remise d\'espèces Chèque Virement, prélèvement, carte bancaire'; + } + + if (empty($don->societe)) + { + $CodeDon = ' 200 du CGI 238 bis du CGI 885-0 V bis A du CGI'; + } + else + { + $CodeDon = ' 200 du CGI 238 bis du CGI 885-0 V bis A du CGI'; + } + // Define contents $donmodel=DOL_DOCUMENT_ROOT ."/core/modules/dons/html_cerfafr.html"; $form = implode('', file($donmodel)); @@ -138,18 +162,23 @@ class html_cerfafr extends ModeleDon $form = str_replace('__DATE__',dol_print_date($don->date,'day',false,$outputlangs),$form); //$form = str_replace('__IP__',$user->ip,$form); // TODO $user->ip not exist $form = str_replace('__AMOUNT__',$don->amount,$form); + $form = str_replace('__AMOUNTLETTERS__',chiffre_en_lettre($don->amount),$form); $form = str_replace('__CURRENCY__',$outputlangs->transnoentitiesnoconv("Currency".$conf->currency),$form); $form = str_replace('__CURRENCYCODE__',$conf->currency,$form); $form = str_replace('__MAIN_INFO_SOCIETE_NOM__',$mysoc->name,$form); $form = str_replace('__MAIN_INFO_SOCIETE_ADDRESS__',$mysoc->address,$form); $form = str_replace('__MAIN_INFO_SOCIETE_ZIP__',$mysoc->zip,$form); $form = str_replace('__MAIN_INFO_SOCIETE_TOWN__',$mysoc->town,$form); + $form = str_replace('__MAIN_INFO_SOCIETE_OBJECT__',$mysoc->object,$form); $form = str_replace('__DONATOR_FIRSTNAME__',$don->firstname,$form); $form = str_replace('__DONATOR_LASTNAME__',$don->lastname,$form); + $form = str_replace('__DONATOR_SOCIETE__',$don->societe,$form); + $form = str_replace('__DONATOR_STATUT__',$don->statut,$form); $form = str_replace('__DONATOR_ADDRESS__',$don->address,$form); $form = str_replace('__DONATOR_ZIP__',$don->zip,$form); $form = str_replace('__DONATOR_TOWN__',$don->town,$form); $form = str_replace('__PAYMENTMODE_LIB__ ', $paymentmode,$form); + $form = str_replace('__ModePaiement__', $ModePaiement,$form); $form = str_replace('__NOW__',dol_print_date($now,'day',false,$outputlangs),$form); $form = str_replace('__DonationRef__',$outputlangs->trans("DonationRef"),$form); $form = str_replace('__DonationTitle__',$outputlangs->trans("DonationTitle"),$form); @@ -157,6 +186,7 @@ class html_cerfafr extends ModeleDon $form = str_replace('__DonationRecipient__',$outputlangs->trans("DonationRecipient"),$form); $form = str_replace('__DonationDatePayment__',$outputlangs->trans("DonationDatePayment"),$form); $form = str_replace('__PaymentMode__',$outputlangs->trans("PaymentMode"),$form); + $form = str_replace('__CodeDon__',$CodeDon,$form); $form = str_replace('__Name__',$outputlangs->trans("Name"),$form); $form = str_replace('__Address__',$outputlangs->trans("Address"),$form); $form = str_replace('__Zip__',$outputlangs->trans("Zip"),$form); @@ -181,7 +211,7 @@ class html_cerfafr extends ModeleDon if (preg_match('/fr/i',$outputlangs->defaultlang)) { if ($conf->global->DONATION_ART200 >= 1) { - $art200='200 du CGI'; + $art200='200 du CGI'; } else { @@ -194,7 +224,7 @@ class html_cerfafr extends ModeleDon if (preg_match('/fr/i',$outputlangs->defaultlang)) { if ($conf->global->DONATION_ART238 >= 1) { - $art238='238 bis du CGI'; + $art238='238 bis du CGI'; } else { @@ -207,7 +237,7 @@ class html_cerfafr extends ModeleDon if (preg_match('/fr/i',$outputlangs->defaultlang)) { if ($conf->global->DONATION_ART885 >= 1) { - $art885='885-0 V bis du CGI'; + $art885='885-0 V bis du CGI'; } else { @@ -242,3 +272,151 @@ class html_cerfafr extends ModeleDon } } +function chiffre_en_lettre($montant, $devise1='', $devise2='') +{ + if(empty($devise1)) $dev1='euros'; + else $dev1=$devise1; + if(empty($devise2)) $dev2='centimes'; + else $dev2=$devise2; + $valeur_entiere=intval($montant); + $valeur_decimal=intval(round($montant-intval($montant), 2)*100); + $dix_c=intval($valeur_decimal%100/10); + $cent_c=intval($valeur_decimal%1000/100); + $unite[1]=$valeur_entiere%10; + $dix[1]=intval($valeur_entiere%100/10); + $cent[1]=intval($valeur_entiere%1000/100); + $unite[2]=intval($valeur_entiere%10000/1000); + $dix[2]=intval($valeur_entiere%100000/10000); + $cent[2]=intval($valeur_entiere%1000000/100000); + $unite[3]=intval($valeur_entiere%10000000/1000000); + $dix[3]=intval($valeur_entiere%100000000/10000000); + $cent[3]=intval($valeur_entiere%1000000000/100000000); + $chif=array('', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six', 'sept', 'huit', 'neuf', 'dix', 'onze', 'douze', 'treize', 'quatorze', 'quinze', 'seize', 'dix sept', 'dix huit', 'dix neuf'); + $secon_c=''; + $trio_c=''; + for($i=1; $i<=3; $i++){ + $prim[$i]=''; + $secon[$i]=''; + $trio[$i]=''; + if($dix[$i]==0){ + $secon[$i]=''; + $prim[$i]=$chif[$unite[$i]]; + } + else if($dix[$i]==1){ + $secon[$i]=''; + $prim[$i]=$chif[($unite[$i]+10)]; + } + else if($dix[$i]==2){ + if($unite[$i]==1){ + $secon[$i]='vingt et'; + $prim[$i]=$chif[$unite[$i]]; + } + else { + $secon[$i]='vingt'; + $prim[$i]=$chif[$unite[$i]]; + } + } + else if($dix[$i]==3){ + if($unite[$i]==1){ + $secon[$i]='trente et'; + $prim[$i]=$chif[$unite[$i]]; + } + else { + $secon[$i]='trente'; + $prim[$i]=$chif[$unite[$i]]; + } + } + else if($dix[$i]==4){ + if($unite[$i]==1){ + $secon[$i]='quarante et'; + $prim[$i]=$chif[$unite[$i]]; + } + else { + $secon[$i]='quarante'; + $prim[$i]=$chif[$unite[$i]]; + } + } + else if($dix[$i]==5){ + if($unite[$i]==1){ + $secon[$i]='cinquante et'; + $prim[$i]=$chif[$unite[$i]]; + } + else { + $secon[$i]='cinquante'; + $prim[$i]=$chif[$unite[$i]]; + } + } + else if($dix[$i]==6){ + if($unite[$i]==1){ + $secon[$i]='soixante et'; + $prim[$i]=$chif[$unite[$i]]; + } + else { + $secon[$i]='soixante'; + $prim[$i]=$chif[$unite[$i]]; + } + } + else if($dix[$i]==7){ + if($unite[$i]==1){ + $secon[$i]='soixante et'; + $prim[$i]=$chif[$unite[$i]+10]; + } + else { + $secon[$i]='soixante'; + $prim[$i]=$chif[$unite[$i]+10]; + } + } + else if($dix[$i]==8){ + if($unite[$i]==1){ + $secon[$i]='quatre-vingts et'; + $prim[$i]=$chif[$unite[$i]]; + } + else { + $secon[$i]='quatre-vingt'; + $prim[$i]=$chif[$unite[$i]]; + } + } + else if($dix[$i]==9){ + if($unite[$i]==1){ + $secon[$i]='quatre-vingts et'; + $prim[$i]=$chif[$unite[$i]+10]; + } + else { + $secon[$i]='quatre-vingts'; + $prim[$i]=$chif[$unite[$i]+10]; + } + } + if($cent[$i]==1) $trio[$i]='cent'; + else if($cent[$i]!=0 || $cent[$i]!='') $trio[$i]=$chif[$cent[$i]] .' cents'; + } + + +$chif2=array('', 'dix', 'vingt', 'trente', 'quarante', 'cinquante', 'soixante', 'soixante-dix', 'quatre-vingts', 'quatre-vingts dix'); + $secon_c=$chif2[$dix_c]; + if($cent_c==1) $trio_c='cent'; + else if($cent_c!=0 || $cent_c!='') $trio_c=$chif[$cent_c] .' cents'; + + if(($cent[3]==0 || $cent[3]=='') && ($dix[3]==0 || $dix[3]=='') && ($unite[3]==1)) + $somme = $trio[3]. ' ' .$secon[3]. ' ' . $prim[3]. ' million '; + else if(($cent[3]!=0 && $cent[3]!='') || ($dix[3]!=0 && $dix[3]!='') || ($unite[3]!=0 && $unite[3]!='')) + $somme = $trio[3]. ' ' .$secon[3]. ' ' . $prim[3]. ' millions '; + else + $somme = $trio[3]. ' ' .$secon[3]. ' ' . $prim[3]; + + if(($cent[2]==0 || $cent[2]=='') && ($dix[2]==0 || $dix[2]=='') && ($unite[2]==1)) + $somme = $somme.' mille '; + else if(($cent[2]!=0 && $cent[2]!='') || ($dix[2]!=0 && $dix[2]!='') || ($unite[2]!=0 && $unite[2]!='')) + $somme = $somme. $trio[2]. ' ' .$secon[2]. ' ' . $prim[2]. ' milles '; + else + $somme = $somme. $trio[2]. ' ' .$secon[2]. ' ' . $prim[2]; + + $somme = $somme. $trio[1]. ' ' .$secon[1]. ' ' . $prim[1]; + + $somme = $somme. ' '. $dev1 .' ' ; + + if(($cent_c=='0' || $cent_c=='') && ($dix_c=='0' || $dix_c=='')) + return $somme. ' et zéro '. $dev2; + else + return $somme. $trio_c. ' ' .$secon_c. ' ' . $dev2; + +} diff --git a/htdocs/don/admin/donation.php b/htdocs/don/admin/donation.php index 2250c27ff7c..4719bd6855a 100644 --- a/htdocs/don/admin/donation.php +++ b/htdocs/don/admin/donation.php @@ -3,6 +3,7 @@ * Copyright (C) 2012-2015 Juanjo Menent * Copyright (C) 2013-2015 Philippe Grand * Copyright (C) 2015 Alexandre Spangaro + * Copyright (C) 2015 Benoit Bruchard * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -39,6 +40,7 @@ if (!$user->admin) accessforbidden(); $typeconst=array('yesno','texte','chaine'); $action = GETPOST('action','alpha'); +$value = GETPOST('value'); $type='donation'; @@ -377,18 +379,18 @@ if (is_resource($handle)) // Active if (in_array($name, $def)) { - print "\n"; if ($conf->global->DON_ADDON_MODEL == $name) { - print img_picto($langs->trans("Enabled"),'switch_on'); - } + print "\n"; + print img_picto($langs->trans("Enabled"),'switch_on'); + print ''; + } else { - print ' '; - print ''; + print "\n"; print '
scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Enabled"),'switch_on').''; - } - print ''; + print ''; + } } else { @@ -398,16 +400,18 @@ if (is_resource($handle)) } // Defaut - print ""; if ($conf->global->DON_ADDON_MODEL == "$name") { - print img_picto($langs->trans("Default"),'on'); + print ""; + print img_picto($langs->trans("Default"),'on'); + print ''; } else { - print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').''; - } - print ''; + print ""; + print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').''; + print ''; + } // Info $htmltooltip = ''.$langs->trans("Name").': '.$module->name; @@ -437,10 +441,6 @@ if (is_resource($handle)) print ''; - -print "
"; - +llxFooter(); $db->close(); - -llxFooter(); From 71189248d91b3778db669bc0d3b1e1a6a2a21977 Mon Sep 17 00:00:00 2001 From: aspangaro Date: Sun, 22 Nov 2015 21:35:19 +0100 Subject: [PATCH 14/32] Correct description --- htdocs/core/modules/dons/html_cerfafr.modules.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/dons/html_cerfafr.modules.php b/htdocs/core/modules/dons/html_cerfafr.modules.php index 7861f089cc7..e80d97b781a 100644 --- a/htdocs/core/modules/dons/html_cerfafr.modules.php +++ b/htdocs/core/modules/dons/html_cerfafr.modules.php @@ -46,7 +46,7 @@ class html_cerfafr extends ModeleDon $this->db = $db; $this->name = "cerfafr"; - $this->description = 'Modèles de reçu de dons - fr_FR - Cerfa 11580*03'; + $this->description = $langs->trans('DonationsReceiptModel').' - fr_FR - Cerfa 11580*03'; // Dimension page for size A4 $this->type = 'html'; From 0899e7392b42fbc2e70651245de95f28f4a09ddf Mon Sep 17 00:00:00 2001 From: aspangaro Date: Sun, 22 Nov 2015 22:11:22 +0100 Subject: [PATCH 15/32] Fix: typo on finance journal --- htdocs/accountancy/journal/bankjournal.php | 12 ++++++------ htdocs/langs/en_US/accountancy.lang | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php index cd0c5d06ce5..be136a38b98 100644 --- a/htdocs/accountancy/journal/bankjournal.php +++ b/htdocs/accountancy/journal/bankjournal.php @@ -57,7 +57,7 @@ $langs->load("bank"); $langs->load('bills'); $langs->load("accountancy"); -$id_accountancy_journal = GETPOST('id_account'); +$id_accountancy_journal = GETPOST('id_account','int'); $date_startmonth = GETPOST('date_startmonth'); $date_startday = GETPOST('date_startday'); @@ -470,7 +470,7 @@ if ($action == 'export_csv') if ($mt) { print $date . $sep; - print $bank_journal . $sep; + print $journal . $sep; if ($val["lib"] == '(SupplierInvoicePayment)') { print length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER) . $sep; } else { @@ -492,8 +492,8 @@ if ($action == 'export_csv') if (1) { print $date . $sep; - print $bank_journal . $sep; - print $conf->global->ACCOUNTING_ACCOUNT_SUSPENSE . $sep; + print $journal . $sep; + print length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE) . $sep; print $sep; print ($mt < 0 ? 'D' : 'C') . $sep; print ($mt <= 0 ? price(- $mt) : $mt) . $sep; @@ -547,7 +547,7 @@ if ($action == 'export_csv') { print '"' . $date . '"' . $sep; print '"' . $val["ref"] . '"' . $sep; - print '"' . $conf->global->ACCOUNTING_ACCOUNT_SUSPENSE . '"' . $sep; + print '"' . length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE) . '"' . $sep; print '"' . $langs->trans("Bank") . '"' . $sep; print '"' . ($mt < 0 ? price(- $mt) : '') . '"' . $sep; print '"' . ($mt >= 0 ? price($mt) : '') . '"'; @@ -696,7 +696,7 @@ else print ""; print "" . $date . ""; print "" . $reflabel . ""; - print "" . $conf->global->ACCOUNTING_ACCOUNT_SUSPENSE . ""; + print "" . length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE) . ""; print "" . $langs->trans('ThirdParty') . ""; print " "; print "" . ($mt < 0 ? price(- $mt) : '') . ""; diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index 8882a6f96b8..edc0a8d512d 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -125,7 +125,7 @@ PurchasesJournal=Purchases journal DescSellsJournal=Sells journal DescPurchasesJournal=Purchases journal BankJournal=Bank journal -DescBankJournal=Bank journal including all the types of payments other than cash +DescBankJournal=Bank journal including all the types of payments other than cash CashJournal=Cash journal DescCashJournal=Cash journal including the type of payment cash From 231196437c9f5e0e1ccde78b142a84d057d13fdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Doursenaud?= Date: Mon, 23 Nov 2015 14:21:25 +0100 Subject: [PATCH 16/32] Fix #4074 Properly save user theme settings --- htdocs/user/param_ihm.php | 85 +++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 35 deletions(-) diff --git a/htdocs/user/param_ihm.php b/htdocs/user/param_ihm.php index 724f2572be2..58d0f282b10 100644 --- a/htdocs/user/param_ihm.php +++ b/htdocs/user/param_ihm.php @@ -85,47 +85,62 @@ $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); if (empty($reshook)) { - if ($action == 'update' && ($caneditfield || !empty($user->admin))) { - if (!$_POST["cancel"]) { - $tabparam = array(); + if ($action == 'update' && ($caneditfield || !empty($user->admin))) { + if (!$_POST["cancel"]) { + $tabparam = array(); - if ($_POST["check_MAIN_LANG_DEFAULT"] == "on") { - $tabparam["MAIN_LANG_DEFAULT"] = $_POST["main_lang_default"]; - } else { - $tabparam["MAIN_LANG_DEFAULT"] = ''; - } + if (GETPOST("check_MAIN_LANG_DEFAULT") == "on") { + $tabparam["MAIN_LANG_DEFAULT"] = $_POST["main_lang_default"]; + } else { + $tabparam["MAIN_LANG_DEFAULT"] = ''; + } - if ($_POST["check_SIZE_LISTE_LIMIT"] == "on") { - $tabparam["MAIN_SIZE_LISTE_LIMIT"] = $_POST["main_size_liste_limit"]; - } else { - $tabparam["MAIN_SIZE_LISTE_LIMIT"] = ''; - } + if (GETPOST("check_SIZE_LISTE_LIMIT") == "on") { + $tabparam["MAIN_SIZE_LISTE_LIMIT"] = $_POST["main_size_liste_limit"]; + } else { + $tabparam["MAIN_SIZE_LISTE_LIMIT"] = ''; + } - $val=(join(',',(colorStringToArray(GETPOST('THEME_ELDY_TOPMENU_BACK1'),array())))); - if ($val == '') $tabparam['THEME_ELDY_TOPMENU_BACK1']=''; - else $tabparam['THEME_ELDY_TOPMENU_BACK1']=join(',',colorStringToArray(GETPOST('THEME_ELDY_TOPMENU_BACK1'),array())); - - $val=(join(',',(colorStringToArray(GETPOST('THEME_ELDY_BACKTITLE1'),array())))); - if ($val == '') $tabparam['THEME_ELDY_BACKTITLE1']=''; - else $tabparam['THEME_ELDY_BACKTITLE1']=join(',',colorStringToArray(GETPOST('THEME_ELDY_BACKTITLE1'),array())); - - if (GETPOST('check_THEME_ELDY_USE_HOVER') == 'on') $tabparam["THEME_ELDY_USE_HOVER"]=1; - else $tabparam["THEME_ELDY_USE_HOVER"]=0; - - $tabparam["MAIN_SEARCHFORM_CONTACT"]=$_POST["main_searchform_contact"]; - $tabparam["MAIN_SEARCHFORM_SOCIETE"]=$_POST["main_searchform_societe"]; - $tabparam["MAIN_SEARCHFORM_PRODUITSERVICE"]=$_POST["main_searchform_produitservice"]; + if (GETPOST("check_MAIN_THEME") == "on") { + $tabparam["MAIN_THEME"] = $_POST["main_theme"]; + } else { + $tabparam["MAIN_THEME"] = ''; + } - $tabparam["MAIN_SEARCHFORM_CONTACT"] = $_POST["main_searchform_contact"]; - $tabparam["MAIN_SEARCHFORM_SOCIETE"] = $_POST["main_searchform_societe"]; - $tabparam["MAIN_SEARCHFORM_PRODUITSERVICE"] = $_POST["main_searchform_produitservice"]; + $tabparam["MAIN_SEARCHFORM_CONTACT"] = $_POST["main_searchform_contact"]; - $result = dol_set_user_param($db, $conf, $object, $tabparam); + $val = (implode(',', (colorStringToArray(GETPOST('THEME_ELDY_TOPMENU_BACK1'), array())))); + if ($val == '') { + $tabparam['THEME_ELDY_TOPMENU_BACK1'] = ''; + } else { + $tabparam['THEME_ELDY_TOPMENU_BACK1'] = join(',', + colorStringToArray(GETPOST('THEME_ELDY_TOPMENU_BACK1'), array())); + } - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id); - exit; - } - } + $val = (implode(',', (colorStringToArray(GETPOST('THEME_ELDY_BACKTITLE1'), array())))); + if ($val == '') { + $tabparam['THEME_ELDY_BACKTITLE1'] = ''; + } else { + $tabparam['THEME_ELDY_BACKTITLE1'] = join(',', + colorStringToArray(GETPOST('THEME_ELDY_BACKTITLE1'), array())); + } + + if (GETPOST('check_THEME_ELDY_USE_HOVER') == 'on') { + $tabparam["THEME_ELDY_USE_HOVER"] = 1; + } else { + $tabparam["THEME_ELDY_USE_HOVER"] = 0; + } + + $tabparam["MAIN_SEARCHFORM_SOCIETE"] = $_POST["main_searchform_societe"]; + + $tabparam["MAIN_SEARCHFORM_PRODUITSERVICE"] = $_POST["main_searchform_produitservice"]; + + $result = dol_set_user_param($db, $conf, $object, $tabparam); + + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id); + exit; + } + } } /* From a30f7d543a225567e903a75d579f893ac9db074b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garc=C3=ADa?= Date: Wed, 25 Nov 2015 10:19:11 +0100 Subject: [PATCH 17/32] Corrected fix --- htdocs/fourn/class/fournisseur.commande.class.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 0299df0dbed..c791a4a9b83 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -765,6 +765,8 @@ class CommandeFournisseur extends CommonOrder if (! $error) { + $this->ref = $this->newref; + if ($movetoapprovestatus) $this->statut = 2; else $this->statut = 1; if (empty($secondlevel)) // standard or first level approval From 5568ff1c54e7d39952f36c679abbaf887e94898a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 25 Nov 2015 16:41:40 +0100 Subject: [PATCH 18/32] Fix bad picto on export --- htdocs/core/modules/modExpedition.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/modExpedition.class.php b/htdocs/core/modules/modExpedition.class.php index 7a8d014f120..314536c28b5 100644 --- a/htdocs/core/modules/modExpedition.class.php +++ b/htdocs/core/modules/modExpedition.class.php @@ -221,7 +221,7 @@ class modExpedition extends DolibarrModules $this->export_fields_array[$r]=array('s.rowid'=>"IdCompany",'s.nom'=>'CompanyName','s.address'=>'Address','s.zip'=>'Zip','s.town'=>'Town','co.label'=>'Country','co.code'=>'CountryCode','s.phone'=>'Phone','s.siren'=>'ProfId1','s.siret'=>'ProfId2','s.ape'=>'ProfId3','s.idprof4'=>'ProfId4','s.idprof5'=>'ProfId5','s.idprof6'=>'ProfId6','c.rowid'=>"Id",'c.ref'=>"Ref",'c.ref_customer'=>"RefCustomer",'c.fk_soc'=>"IdCompany",'c.date_creation'=>"DateCreation",'c.date_delivery'=>"DateSending",'c.tracking_number'=>"TrackingNumber",'c.height'=>"Height",'c.width'=>"Width",'c.size'=>"Depth",'c.size_units'=>'SizeUnits','c.weight'=>"Weight",'c.weight_units'=>"WeightUnits",'c.fk_statut'=>'Status','c.note_public'=>"NotePublic",'ed.rowid'=>'LineId','cd.description'=>'Description','ed.qty'=>"Qty",'p.rowid'=>'ProductId','p.ref'=>'ProductRef','p.label'=>'ProductLabel'); //$this->export_TypeFields_array[$r]=array('s.rowid'=>"List:societe:nom",'s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','co.label'=>'List:c_country:label:label','co.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','c.ref'=>"Text",'c.ref_client'=>"Text",'c.date_creation'=>"Date",'c.date_commande'=>"Date",'c.amount_ht'=>"Numeric",'c.remise_percent'=>"Numeric",'c.total_ht'=>"Numeric",'c.total_ttc'=>"Numeric",'c.facture'=>"Boolean",'c.fk_statut'=>'Status','c.note_public'=>"Text",'c.date_livraison'=>'Date','ed.qty'=>"Text"); $this->export_TypeFields_array[$r]=array('s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','co.label'=>'List:c_country:label:label','co.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','c.ref'=>"Text",'c.ref_customer'=>"Text",'c.date_creation'=>"Date",'c.date_delivery'=>"Date",'c.tracking_number'=>"Numeric",'c.height'=>"Numeric",'c.width'=>"Numeric",'c.weight'=>"Numeric",'c.fk_statut'=>'Status','c.note_public'=>"Text",'ed.qty'=>"Numeric"); - $this->export_entities_array[$r]=array('s.rowid'=>"company",'s.nom'=>'company','s.address'=>'company','s.zip'=>'company','s.town'=>'company','s.fk_pays'=>'company','s.phone'=>'company','s.siren'=>'company','s.ape'=>'company','s.siret'=>'company','s.idprof4'=>'company','s.idprof5'=>'company','s.idprof6'=>'company','c.rowid'=>"shipment",'c.ref'=>"shipment",'c.ref_customer'=>"shipment",'c.fk_soc'=>"shipment",'c.date_creation'=>"shipment",'c.date_delivery'=>"shipment",'c.tracking_number'=>'shipment','c.height'=>"shipment",'c.width'=>"shipment",'c.size'=>'shipment','c.size_units'=>'shipment','c.weight'=>"shipment",'c.weight_units'=>'shipment','c.fk_statut'=>"shipment",'c.note_public'=>"shipment",'ed.rowid'=>'shipment_line','cd.description'=>'shipment_line','ed.qty'=>"shipment_line",'p.rowid'=>'product','p.ref'=>'product','p.label'=>'product'); + $this->export_entities_array[$r]=array('s.rowid'=>"company",'s.nom'=>'company','s.address'=>'company','s.zip'=>'company','s.town'=>'company','co.label'=>'company','co.code'=>'company','s.fk_pays'=>'company','s.phone'=>'company','s.siren'=>'company','s.ape'=>'company','s.siret'=>'company','s.idprof4'=>'company','s.idprof5'=>'company','s.idprof6'=>'company','c.rowid'=>"shipment",'c.ref'=>"shipment",'c.ref_customer'=>"shipment",'c.fk_soc'=>"shipment",'c.date_creation'=>"shipment",'c.date_delivery'=>"shipment",'c.tracking_number'=>'shipment','c.height'=>"shipment",'c.width'=>"shipment",'c.size'=>'shipment','c.size_units'=>'shipment','c.weight'=>"shipment",'c.weight_units'=>'shipment','c.fk_statut'=>"shipment",'c.note_public'=>"shipment",'ed.rowid'=>'shipment_line','cd.description'=>'shipment_line','ed.qty'=>"shipment_line",'p.rowid'=>'product','p.ref'=>'product','p.label'=>'product'); $this->export_dependencies_array[$r]=array('shipment_line'=>'ed.rowid','product'=>'ed.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them $this->export_sql_start[$r]='SELECT DISTINCT '; From 2593022684c5f79017ac77667657584a27aaf83c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 25 Nov 2015 16:45:25 +0100 Subject: [PATCH 19/32] Fix bad css --- htdocs/theme/eldy/style.css.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 899e8340543..761220ced17 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -2620,6 +2620,7 @@ div.warning { } /* Error message */ +div.error { background: #EFCFCF; } From cf98c7a6f550e23f4ab52c27bc51256d0cdaa171 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 25 Nov 2015 17:11:08 +0100 Subject: [PATCH 20/32] Police plus grande --- htdocs/theme/eldy/style.css.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 761220ced17..67d30dc9d04 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -94,7 +94,7 @@ $colortexttitlenotab='80,80,0'; $colortexttitle='0,0,0'; $colortext='0,0,0'; $colortextlink='0,0,120'; -$fontsize='12'; +$fontsize='13'; $fontsizesmaller='11'; $usegradient=1; $useboldtitle=1; @@ -118,7 +118,7 @@ if (empty($conf->global->THEME_ELDY_ENABLE_PERSONALIZED)) $conf->global->THEME_ELDY_LINEPAIR2='248,248,248'; $conf->global->THEME_ELDY_LINEPAIRHOVER='238,246,252'; $conf->global->THEME_ELDY_TEXT='0,0,0'; - $conf->global->THEME_ELDY_FONT_SIZE1='12'; + $conf->global->THEME_ELDY_FONT_SIZE1='13'; $conf->global->THEME_ELDY_FONT_SIZE2='11'; } //var_dump($conf->global->THEME_ELDY_BACKBODY); @@ -210,6 +210,7 @@ print 'dol_no_mouse_hover='.$dol_no_mouse_hover."\n"; print 'dol_use_jmobile='.$dol_use_jmobile."\n"; print 'dol_screenwidth='.$_SESSION['dol_screenwidth']."\n"; print 'dol_screenheight='.$_SESSION['dol_screenheight']."\n"; +print 'fontsize='.$fontsize."\n"; print '*/'."\n"; if (! empty($conf->dol_optimize_smallscreen)) $fontsize=11; @@ -1142,7 +1143,7 @@ div.vmenu, td.vmenu { padding: 0px; padding-bottom: 0px; padding-top: 1px; - width: 174px; + width: 190px; } .vmenu { @@ -1153,7 +1154,7 @@ div.vmenu, td.vmenu { } .vmenusearchselectcombo { - width: 172px; + width: 188px; } .menu_contenu { @@ -3895,7 +3896,7 @@ border-top-right-radius: 6px; } -@media only screen and (max-width: px) +@media only screen and (max-width: px) { .mainmenuaspan { display: none; From 1d9e9ccaba9d7f865dd6c6d10fd6ec8feec5b296 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 25 Nov 2015 17:34:26 +0100 Subject: [PATCH 21/32] NEW Add filter on status on shipments --- htdocs/expedition/list.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/expedition/list.php b/htdocs/expedition/list.php index 6435b02bd43..6d8dc1d22df 100644 --- a/htdocs/expedition/list.php +++ b/htdocs/expedition/list.php @@ -61,6 +61,7 @@ if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter")) // Both $search_ref_exp=''; $search_ref_liv=''; $search_company=''; + $viewstatut=''; } /* @@ -159,7 +160,9 @@ if ($resql) print ' '; } // Status - print ''; + print ''; + print $form->selectarray('viewstatut', array('0'=>$langs->trans('StatusSendingDraftShort'),'1'=>$langs->trans('StatusSendingValidatedShort'),'2'=>$langs->trans('StatusSendingProcessedShort')),$viewstatut,1); + print ''; // Search print ''; print ''; From ce18cda92a4414c7d809fb7df33a81a4a8efa5bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 25 Nov 2015 18:29:14 +0100 Subject: [PATCH 22/32] remove a tab --- htdocs/langs/en_US/accountancy.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index 8882a6f96b8..edc0a8d512d 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -125,7 +125,7 @@ PurchasesJournal=Purchases journal DescSellsJournal=Sells journal DescPurchasesJournal=Purchases journal BankJournal=Bank journal -DescBankJournal=Bank journal including all the types of payments other than cash +DescBankJournal=Bank journal including all the types of payments other than cash CashJournal=Cash journal DescCashJournal=Cash journal including the type of payment cash From 677cba01cee6298a98105b0e06d67258459974d6 Mon Sep 17 00:00:00 2001 From: braito4 Date: Wed, 25 Nov 2015 18:58:47 +0100 Subject: [PATCH 23/32] Part solution bug #4095 It allow us to deactivate the link to a project queries to lower the page workload. --- htdocs/projet/element.php | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index ef3f62d98a2..1be43fe94dd 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -510,24 +510,27 @@ foreach ($listofreferent as $key => $value) $idtofilterthirdparty=0; if (! in_array($tablename, array('facture_fourn', 'commande_fourn'))) $idtofilterthirdparty=$object->thirdparty->id; - $selectList=$formproject->select_element($tablename, $idtofilterthirdparty, 'minwidth200'); - if (! $selectList || ($selectList<0)) - { - setEventMessages($formproject->error,$formproject->errors,'errors'); - } - elseif($selectList) - { - // Define form with the combo list of elements to link - $addform.='
'; - $addform.=''; - $addform.=''; - $addform.=''; - $addform.=''; - $addform.=''; - $addform.=''; - $addform.=''; - $addform.='
'.$langs->trans("SelectElement").''.$selectList.'
'; - $addform.='
'; + if (empty($conf->global->PROJECT_LINK_DISABLE)) + { + $selectList=$formproject->select_element($tablename, $idtofilterthirdparty, 'minwidth200'); + if (! $selectList || ($selectList<0)) + { + setEventMessages($formproject->error,$formproject->errors,'errors'); + } + elseif($selectList) + { + // Define form with the combo list of elements to link + $addform.='
'; + $addform.=''; + $addform.=''; + $addform.=''; + $addform.=''; + $addform.=''; + $addform.=''; + $addform.=''; + $addform.='
'.$langs->trans("SelectElement").''.$selectList.'
'; + $addform.='
'; + } } print_fiche_titre($langs->trans($title), $addform, ''); From 2d8c2221d862acaf0eebc293d235bf3ca1a677e4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 25 Nov 2015 23:20:41 +0100 Subject: [PATCH 24/32] NEW Provide an easier way to understand if an order can be shipped. --- htdocs/commande/list.php | 162 +++++++++++++++++++++++---------------- 1 file changed, 94 insertions(+), 68 deletions(-) diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 6d90794dbd0..fa695dbaa50 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -8,7 +8,7 @@ * Copyright (C) 2013 Cédric Salvador * Copyright (C) 2015 Frederic France * Copyright (C) 2015 Marcos García - * Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2015 Jean-François Ferry * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -402,88 +402,114 @@ if ($resql) print $generic_commande->getNomUrl(1,($viewstatut != 2?0:$objp->fk_statut)); print ''; - // Shippable Icon - if (($objp->fk_statut > 0) && ($objp->fk_statut < 3) && ! empty($conf->global->SHIPPABLE_ORDER_ICON_IN_LIST)) { - $notshippable=0; - $warning = 0; - $text_info=''; - $nbprod=0; - for ($lig=0; $lig<(count($generic_commande->lines)); $lig++) { - if ($generic_commande->lines[$lig]->product_type==0) { - $nbprod++; // order contains real products - $generic_product->id = $generic_commande->lines[$lig]->fk_product; - if (empty($productstat_cache[$generic_commande->lines[$lig]->fk_product])) { - $generic_product->load_stock(); - $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_reel; - } else { - $generic_product->stock_reel = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel']; - } - // stock order and stock order_supplier - $stock_order=0; - $stock_order_supplier=0; - if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT)) + // Show shippable Icon (create subloop, so may be slow) + if ($conf->stock->enabled) + { + $langs->load("stocks"); + if (($objp->fk_statut > 0) && ($objp->fk_statut < 3)) + { + $notshippable=0; + $warning = 0; + $text_info=''; + $nbprod=0; + + $num = count($generic_commande->lines); // Loop on each line of order + for ($lig=0; $lig < $num; $lig++) + { + if ($generic_commande->lines[$lig]->product_type == 0 && $generic_commande->lines[$lig]->fk_product > 0) // If line is a product and not a service { - if (! empty($conf->commande->enabled)) - { - if (empty($productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_customer'])) { - $generic_product->load_stats_commande(0,'1,2'); - $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_customer'] = $generic_product->stats_commande['qty']; - } else { - $generic_product->stats_commande['qty'] = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_customer']; - } - $stock_order=$generic_product->stats_commande['qty']; + $nbprod++; // order contains real products + $generic_product->id = $generic_commande->lines[$lig]->fk_product; + if (empty($productstat_cache[$generic_commande->lines[$lig]->fk_product])) { + $generic_product->load_stock(); + $generic_product->load_virtual_stock(); + $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_reel; + $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique; + } else { + $generic_product->stock_reel = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel']; + $generic_product->stock_theorique = $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique; } - if (! empty($conf->fournisseur->enabled)) + + if (empty($conf->global->SHIPPABLE_ORDER_ICON_IN_LIST)) // Default code is when this option is not set, setting it create strange result { - if (empty($productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_supplier'])) { - $generic_product->load_stats_commande_fournisseur(0,'3'); - $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_supplier'] = $generic_product->stats_commande_fournisseur['qty']; - } else { - $generic_product->stats_commande_fournisseur['qty'] = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_supplier']; + $text_info .= $generic_commande->lines[$lig]->qty.' X '.$generic_commande->lines[$lig]->ref.' '.dol_trunc($generic_commande->lines[$lig]->product_label, 25); + $text_info .= ' - '.$langs->trans("Stock").': '.$generic_product->stock_reel; + $text_info .= ' - '.$langs->trans("VirtualStock").': '.$generic_product->stock_theorique; + $text_info .= '
'; + + if ($generic_commande->lines[$lig]->qty > $generic_product->stock_reel) + { + $notshippable++; + } + } + else { // Detailed code, looks bugged + // stock order and stock order_supplier + $stock_order=0; + $stock_order_supplier=0; + if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT)) // What about other options ? + { + if (! empty($conf->commande->enabled)) + { + if (empty($productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_customer'])) { + $generic_product->load_stats_commande(0,'1,2'); + $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_customer'] = $generic_product->stats_commande['qty']; + } else { + $generic_product->stats_commande['qty'] = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_customer']; + } + $stock_order=$generic_product->stats_commande['qty']; + } + if (! empty($conf->fournisseur->enabled)) + { + if (empty($productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_supplier'])) { + $generic_product->load_stats_commande_fournisseur(0,'3'); + $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_supplier'] = $generic_product->stats_commande_fournisseur['qty']; + } else { + $generic_product->stats_commande_fournisseur['qty'] = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stats_order_supplier']; + } + $stock_order_supplier=$generic_product->stats_commande_fournisseur['qty']; + } + } + $text_info .= $generic_commande->lines[$lig]->qty.' X '.$generic_commande->lines[$lig]->ref.' '.dol_trunc($generic_commande->lines[$lig]->product_label, 25); + $text_stock_reel = $generic_product->stock_reel.'/'.$stock_order; + if ($stock_order > $generic_product->stock_reel && ! ($generic_product->stock_reel < $generic_commande->lines[$lig]->qty)) { + $warning++; + $text_warning.=''.$langs->trans('Available').' : '.$text_stock_reel.''; + } + if ($generic_product->stock_reel < $generic_commande->lines[$lig]->qty) { + $notshippable++; + $text_info.=''.$langs->trans('Available').' : '.$text_stock_reel.''; + } else { + $text_info.=''.$langs->trans('Available').' : '.$text_stock_reel.''; + } + if (! empty($conf->fournisseur->enabled)) { + $text_info.= ' '.$langs->trans('SupplierOrder').' : '.$stock_order_supplier.'
'; + } else { + $text_info.= '
'; } - $stock_order_supplier=$generic_product->stats_commande_fournisseur['qty']; } - } - $text_info .= $generic_commande->lines[$lig]->qty.' X '.$generic_commande->lines[$lig]->ref.' '.dol_trunc($generic_commande->lines[$lig]->product_label, 25); - $text_stock_reel = $generic_product->stock_reel.'/'.$stock_order; - if ($stock_order > $generic_product->stock_reel && ! ($generic_product->stock_reel < $generic_commande->lines[$lig]->qty)) { - $warning++; - $text_warning.=''.$langs->trans('Available').' : '.$text_stock_reel.''; - } - if ($generic_product->stock_reel < $generic_commande->lines[$lig]->qty) { - $notshippable++; - $text_info.=''.$langs->trans('Available').' : '.$text_stock_reel.''; - } else { - $text_info.=''.$langs->trans('Available').' : '.$text_stock_reel.''; - } - if ($stock_order_supplier>0) { - $text_info.= ' '.$langs->trans('SupplierOrder').' : '.$stock_order_supplier.'
'; - } else { - $text_info.= '
'; } } + if ($notshippable==0) { + $text_icon = img_picto('', 'object_sending'); + $text_info = $langs->trans('Shippable').'
'.$text_info; + } else { + $text_icon = img_picto('', 'error'); + $text_info = $langs->trans('NonShippable').'
'.$text_info; + } } - if ($notshippable==0) { - $text_icon = img_picto('', 'object_sending'); - $text_info = $langs->trans('Shippable').'
'.$text_info; - } else { - $text_icon = img_picto('', 'error'); - $text_info = $langs->trans('NonShippable').'
'.$text_info; - } - if ($nbprod>0) { - print ''; + print ''; + if ($nbprod) + { print $form->textwithtooltip('',$text_info,2,1,$text_icon,'',2); - print ''; } if ($warning) { - print ''; print $form->textwithtooltip('', $langs->trans('NotEnoughForAllOrders').'
'.$text_warning, 2, 1, img_picto('', 'error'),'',2); - print ''; } + print ''; } - // warning late icon - print ''; + // Warning late icon + print ''; if ($generic_commande->hasDelay()) { print img_picto($langs->trans("Late"), "warning"); } From 85d788d43a1298716c1d1f69ed8a39f4ae519873 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 25 Nov 2015 23:26:31 +0100 Subject: [PATCH 25/32] Fix crazy phpcs test --- dev/codesniffer/ruleset.xml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/dev/codesniffer/ruleset.xml b/dev/codesniffer/ruleset.xml index 9b5c0931650..321560ff6f9 100755 --- a/dev/codesniffer/ruleset.xml +++ b/dev/codesniffer/ruleset.xml @@ -289,6 +289,15 @@ + + 0 + + + 0 + + + 0 + 0 @@ -304,12 +313,6 @@ 0 - - 0 - - - 0 - From ad087a75e620e31bf1822bd1cff91d692e99c70f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 25 Nov 2015 23:32:00 +0100 Subject: [PATCH 26/32] Fix missing php --- htdocs/theme/eldy/style.css.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 0d4e850b238..58f62405c25 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -648,7 +648,7 @@ div#tmenu_tooltip { display:none; - padding-: px; + padding-: px; } From ddd0f8224fd9d12529de61a71f085d94eb1b479d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 26 Nov 2015 00:08:24 +0100 Subject: [PATCH 27/32] Picto was not visible onto login page, we keep this behaviour. --- htdocs/theme/eldy/style.css.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 58f62405c25..0dc4b3f4c36 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -1053,16 +1053,17 @@ img.loginphoto { border-radius: 2px; } .span-icon-user { - background-image: url(); + /* background-image: url(); */ background-repeat: no-repeat; } .span-icon-password { - background-image: url(); + /* background-image: url(); */ background-repeat: no-repeat; } .span-icon-user input, .span-icon-password input { - margin-left: 25px; + /* margin-left: 18px; */ + margin-left: 0px; } /* ============================================================================== */ From bc6d04e495590add4cbf93d56ea301d75378ab6f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 26 Nov 2015 00:08:34 +0100 Subject: [PATCH 28/32] Typo --- htdocs/langs/en_US/mails.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/mails.lang b/htdocs/langs/en_US/mails.lang index 9d9b1e24c51..db8b013240f 100644 --- a/htdocs/langs/en_US/mails.lang +++ b/htdocs/langs/en_US/mails.lang @@ -97,7 +97,7 @@ MailingModuleDescEmailsFromUser=EMails from user input (email;lastname;firstname MailingModuleDescContactsCategories=Third parties (by category) MailingModuleDescDolibarrContractsLinesExpired=Third parties with expired contract's lines MailingModuleDescContactsByCompanyCategory=Contacts/addresses of third parties (by third parties category) -MailingModuleDescContactsByCategory=Contacts/addresses of third parties by category +MailingModuleDescContactsByCategory=Contacts/addresses of third parties (by category) MailingModuleDescMembersCategories=Foundation members (by categories) MailingModuleDescContactsByFunction=Contacts/addresses of third parties (by position/function) LineInFile=Line %s in file From a454e926560ef1c61fe3a0ed011f96a3537b671f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 26 Nov 2015 00:31:12 +0100 Subject: [PATCH 29/32] Increase size of combo list --- htdocs/projet/element.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index a51e93ee228..451b454477a 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -510,7 +510,7 @@ foreach ($listofreferent as $key => $value) $idtofilterthirdparty=0; if (! in_array($tablename, array('facture_fourn', 'commande_fourn'))) $idtofilterthirdparty=$object->thirdparty->id; - $selectList=$formproject->select_element($tablename, $idtofilterthirdparty, 'minwidth200'); + $selectList=$formproject->select_element($tablename, $idtofilterthirdparty, 'minwidth300'); if (! $selectList || ($selectList<0)) { setEventMessages($formproject->error,$formproject->errors,'errors'); From f353464bce1fe2698459672c0e97cfb1341c6930 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 26 Nov 2015 00:47:17 +0100 Subject: [PATCH 30/32] Prepare code to fix #4095 --- htdocs/core/class/html.formprojet.class.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/html.formprojet.class.php b/htdocs/core/class/html.formprojet.class.php index 5486d19858b..b44a30dcd05 100644 --- a/htdocs/core/class/html.formprojet.class.php +++ b/htdocs/core/class/html.formprojet.class.php @@ -422,9 +422,10 @@ class FormProjets * @param string $table_element Table of the element to update * @param int $socid If of thirdparty to use as filter * @param string $morecss More CSS + * @param int $limitonstatus Add filters to limit length of list to opened status (for example to avoid ERR_RESPONSE_HEADERS_TOO_BIG on project/element.php page). TODO To implement * @return int|string The HTML select list of element or '' if nothing or -1 if KO */ - function select_element($table_element, $socid=0, $morecss='') + function select_element($table_element, $socid=0, $morecss='', $limitonstatus=-2) { global $conf, $langs; @@ -433,7 +434,9 @@ class FormProjets $linkedtothirdparty=false; if (! in_array($table_element, array('don','expensereport_det','expensereport'))) $linkedtothirdparty=true; + $sqlfilter=''; $projectkey="fk_projet"; + //print $table_element; switch ($table_element) { case "facture": @@ -443,7 +446,8 @@ class FormProjets $sql = "SELECT t.rowid, t.ref, t.ref_supplier"; break; case "commande_fourn": - $sql = "SELECT t.rowid, t.ref, t.ref_supplier"; + case "commande_fournisseur": + $sql = "SELECT t.rowid, t.ref, t.ref_supplier"; break; case "facture_rec": $sql = "SELECT t.rowid, t.titre as ref"; @@ -457,6 +461,11 @@ class FormProjets /*$sql = "SELECT rowid, '' as ref"; // table is llx_expensereport_det $projectkey="fk_projet"; break;*/ + case "commande": + case "contrat": + case "fichinter": + $sql = "SELECT t.rowid, t.ref"; + break; default: $sql = "SELECT t.rowid, t.ref"; break; @@ -468,6 +477,7 @@ class FormProjets if (! empty($socid) && $linkedtothirdparty) $sql.= " AND t.fk_soc=".$socid; if (! in_array($table_element, array('expensereport_det'))) $sql.= ' AND t.entity='.getEntity('project'); if ($linkedtothirdparty) $sql.=" AND s.rowid = t.fk_soc"; + if ($sqlfilter) $sql.= " AND ".$sqlfilter; $sql.= " ORDER BY ref DESC"; dol_syslog(get_class($this).'::select_element', LOG_DEBUG); From 4f3196edf2a04ff4db9d252f789ffa2e47c55fab Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 26 Nov 2015 01:18:54 +0100 Subject: [PATCH 31/32] Removed lib that are luxuary components. --- COPYRIGHT | 3 - .../includes/firephp/firephp-core/.gitignore | 1 - .../firephp/firephp-core/CHANGELOG.md | 171 - .../includes/firephp/firephp-core/README.md | 75 - .../firephp/firephp-core/composer.json | 26 - .../firephp/firephp-core/examples/oo.php | 82 - .../firephp/firephp-core/examples/oo.php4 | 72 - .../firephp-core/examples/procedural.php | 79 - .../firephp-core/examples/procedural.php4 | 69 - .../lib/FirePHPCore/FirePHP.class.php | 1828 ------ .../lib/FirePHPCore/FirePHP.class.php4 | 1327 ----- .../firephp-core/lib/FirePHPCore/fb.php | 275 - .../firephp-core/lib/FirePHPCore/fb.php4 | 245 - .../firephp/firephp-core/package.json | 43 - .../firephp/firephp-core/program.json | 5 - .../firephp-core/tests/API/newlines.php | 12 - .../tests/FirePHPCore/FirePHPTest.php | 181 - .../firephp/firephp-core/tests/TestHelper.php | 55 - .../firephp/firephp-core/tests/phpunit.xml | 2 - .../firephp/firephp-core/workspace/README.md | 19 - .../firephp-core/workspace/lib/project.js | 5 - .../firephp-core/workspace/package.json | 28 - .../firephp-core/workspace/program.json | 78 - .../firephp-core/workspace/scripts/build.js | 164 - .../firephp-core/workspace/scripts/publish.js | 65 - .../firephp-core/workspace/tpl/license.tpl.md | 21 - .../workspace/tpl/pear.package.tpl.xml | 61 - .../firephp-core/workspace/tpl/readme.tpl.md | 17 - htdocs/includes/raven-js/.bower.json | 18 - htdocs/includes/raven-js/.gitignore | 22 - htdocs/includes/raven-js/.jshintrc | 9 - htdocs/includes/raven-js/.travis.yml | 8 - htdocs/includes/raven-js/AUTHORS | 1 - htdocs/includes/raven-js/Gruntfile.js | 254 - htdocs/includes/raven-js/LICENSE | 9 - htdocs/includes/raven-js/Makefile | 20 - htdocs/includes/raven-js/README.md | 13 - htdocs/includes/raven-js/bower.json | 7 - htdocs/includes/raven-js/dist/raven.js | 1909 ------ htdocs/includes/raven-js/dist/raven.min.js | 3 - htdocs/includes/raven-js/dist/raven.min.map | 1 - htdocs/includes/raven-js/docs/Makefile | 153 - .../raven-js/docs/changelog/index.rst | 138 - htdocs/includes/raven-js/docs/conf.py | 244 - .../includes/raven-js/docs/config/index.rst | 220 - .../raven-js/docs/contributing/index.rst | 99 - htdocs/includes/raven-js/docs/index.rst | 42 - .../includes/raven-js/docs/install/index.rst | 61 - htdocs/includes/raven-js/docs/make.bat | 190 - .../includes/raven-js/docs/plugins/index.rst | 20 - htdocs/includes/raven-js/docs/tips/index.rst | 79 - htdocs/includes/raven-js/docs/usage/index.rst | 156 - htdocs/includes/raven-js/example/Makefile | 3 - htdocs/includes/raven-js/example/file.min.js | 2 - .../raven-js/example/file.sourcemap.js | 1 - htdocs/includes/raven-js/example/file1.js | 4 - htdocs/includes/raven-js/example/file2.js | 12 - htdocs/includes/raven-js/example/index.html | 41 - htdocs/includes/raven-js/example/scratch.js | 42 - htdocs/includes/raven-js/package.json | 32 - htdocs/includes/raven-js/plugins/angular.js | 36 - htdocs/includes/raven-js/plugins/backbone.js | 55 - htdocs/includes/raven-js/plugins/console.js | 43 - htdocs/includes/raven-js/plugins/ember.js | 29 - htdocs/includes/raven-js/plugins/jquery.js | 75 - htdocs/includes/raven-js/plugins/native.js | 33 - htdocs/includes/raven-js/plugins/require.js | 14 - htdocs/includes/raven-js/src/raven.js | 830 --- .../includes/raven-js/template/_copyright.js | 11 - htdocs/includes/raven-js/template/_footer.js | 19 - htdocs/includes/raven-js/template/_header.js | 2 - htdocs/includes/raven-js/test/index.html | 62 - htdocs/includes/raven-js/test/raven.test.js | 1773 ------ .../raven-js/vendor/TraceKit/tracekit.js | 1044 ---- htdocs/includes/raven/raven/.gitignore | 5 - htdocs/includes/raven/raven/.php_cs | 12 - htdocs/includes/raven/raven/.travis.yml | 30 - htdocs/includes/raven/raven/AUTHORS | 4 - htdocs/includes/raven/raven/CHANGES | 45 - htdocs/includes/raven/raven/LICENSE | 12 - htdocs/includes/raven/raven/Makefile | 17 - htdocs/includes/raven/raven/README.rst | 273 - htdocs/includes/raven/raven/bin/raven | 88 - htdocs/includes/raven/raven/composer.json | 35 - .../raven/raven/lib/Raven/Autoloader.php | 43 - .../includes/raven/raven/lib/Raven/Client.php | 915 --- .../includes/raven/raven/lib/Raven/Compat.php | 136 - .../raven/raven/lib/Raven/Context.php | 23 - .../raven/raven/lib/Raven/CurlHandler.php | 117 - .../raven/raven/lib/Raven/ErrorHandler.php | 175 - .../raven/raven/lib/Raven/Processor.php | 20 - .../raven/lib/Raven/SanitizeDataProcessor.php | 102 - .../raven/raven/lib/Raven/Serializer.php | 77 - .../raven/raven/lib/Raven/Stacktrace.php | 252 - .../includes/raven/raven/lib/Raven/Util.php | 33 - .../raven/raven/lib/Raven/data/cacert.pem | 5134 ----------------- htdocs/includes/raven/raven/phpunit.xml | 25 - .../raven/test/Raven/Tests/ClientTest.php | 635 -- .../raven/test/Raven/Tests/CompatTest.php | 46 - .../test/Raven/Tests/ErrorHandlerTest.php | 87 - .../Raven/Tests/SanitizeDataProcessorTest.php | 180 - .../raven/test/Raven/Tests/SerializerTest.php | 48 - .../raven/test/Raven/Tests/StacktraceTest.php | 223 - .../raven/raven/test/Raven/Tests/UtilTest.php | 32 - .../raven/test/Raven/Tests/resources/a.php | 11 - .../raven/test/Raven/Tests/resources/b.php | 3 - .../includes/raven/raven/test/bootstrap.php | 17 - 107 files changed, 21703 deletions(-) delete mode 100644 htdocs/includes/firephp/firephp-core/.gitignore delete mode 100644 htdocs/includes/firephp/firephp-core/CHANGELOG.md delete mode 100644 htdocs/includes/firephp/firephp-core/README.md delete mode 100644 htdocs/includes/firephp/firephp-core/composer.json delete mode 100644 htdocs/includes/firephp/firephp-core/examples/oo.php delete mode 100644 htdocs/includes/firephp/firephp-core/examples/oo.php4 delete mode 100644 htdocs/includes/firephp/firephp-core/examples/procedural.php delete mode 100644 htdocs/includes/firephp/firephp-core/examples/procedural.php4 delete mode 100644 htdocs/includes/firephp/firephp-core/lib/FirePHPCore/FirePHP.class.php delete mode 100644 htdocs/includes/firephp/firephp-core/lib/FirePHPCore/FirePHP.class.php4 delete mode 100644 htdocs/includes/firephp/firephp-core/lib/FirePHPCore/fb.php delete mode 100644 htdocs/includes/firephp/firephp-core/lib/FirePHPCore/fb.php4 delete mode 100644 htdocs/includes/firephp/firephp-core/package.json delete mode 100644 htdocs/includes/firephp/firephp-core/program.json delete mode 100644 htdocs/includes/firephp/firephp-core/tests/API/newlines.php delete mode 100644 htdocs/includes/firephp/firephp-core/tests/FirePHPCore/FirePHPTest.php delete mode 100644 htdocs/includes/firephp/firephp-core/tests/TestHelper.php delete mode 100644 htdocs/includes/firephp/firephp-core/tests/phpunit.xml delete mode 100644 htdocs/includes/firephp/firephp-core/workspace/README.md delete mode 100644 htdocs/includes/firephp/firephp-core/workspace/lib/project.js delete mode 100644 htdocs/includes/firephp/firephp-core/workspace/package.json delete mode 100644 htdocs/includes/firephp/firephp-core/workspace/program.json delete mode 100644 htdocs/includes/firephp/firephp-core/workspace/scripts/build.js delete mode 100644 htdocs/includes/firephp/firephp-core/workspace/scripts/publish.js delete mode 100644 htdocs/includes/firephp/firephp-core/workspace/tpl/license.tpl.md delete mode 100644 htdocs/includes/firephp/firephp-core/workspace/tpl/pear.package.tpl.xml delete mode 100644 htdocs/includes/firephp/firephp-core/workspace/tpl/readme.tpl.md delete mode 100644 htdocs/includes/raven-js/.bower.json delete mode 100644 htdocs/includes/raven-js/.gitignore delete mode 100644 htdocs/includes/raven-js/.jshintrc delete mode 100644 htdocs/includes/raven-js/.travis.yml delete mode 100644 htdocs/includes/raven-js/AUTHORS delete mode 100644 htdocs/includes/raven-js/Gruntfile.js delete mode 100644 htdocs/includes/raven-js/LICENSE delete mode 100644 htdocs/includes/raven-js/Makefile delete mode 100644 htdocs/includes/raven-js/README.md delete mode 100644 htdocs/includes/raven-js/bower.json delete mode 100644 htdocs/includes/raven-js/dist/raven.js delete mode 100644 htdocs/includes/raven-js/dist/raven.min.js delete mode 100644 htdocs/includes/raven-js/dist/raven.min.map delete mode 100644 htdocs/includes/raven-js/docs/Makefile delete mode 100644 htdocs/includes/raven-js/docs/changelog/index.rst delete mode 100644 htdocs/includes/raven-js/docs/conf.py delete mode 100644 htdocs/includes/raven-js/docs/config/index.rst delete mode 100644 htdocs/includes/raven-js/docs/contributing/index.rst delete mode 100644 htdocs/includes/raven-js/docs/index.rst delete mode 100644 htdocs/includes/raven-js/docs/install/index.rst delete mode 100644 htdocs/includes/raven-js/docs/make.bat delete mode 100644 htdocs/includes/raven-js/docs/plugins/index.rst delete mode 100644 htdocs/includes/raven-js/docs/tips/index.rst delete mode 100644 htdocs/includes/raven-js/docs/usage/index.rst delete mode 100644 htdocs/includes/raven-js/example/Makefile delete mode 100644 htdocs/includes/raven-js/example/file.min.js delete mode 100644 htdocs/includes/raven-js/example/file.sourcemap.js delete mode 100644 htdocs/includes/raven-js/example/file1.js delete mode 100644 htdocs/includes/raven-js/example/file2.js delete mode 100644 htdocs/includes/raven-js/example/index.html delete mode 100644 htdocs/includes/raven-js/example/scratch.js delete mode 100644 htdocs/includes/raven-js/package.json delete mode 100644 htdocs/includes/raven-js/plugins/angular.js delete mode 100644 htdocs/includes/raven-js/plugins/backbone.js delete mode 100644 htdocs/includes/raven-js/plugins/console.js delete mode 100644 htdocs/includes/raven-js/plugins/ember.js delete mode 100644 htdocs/includes/raven-js/plugins/jquery.js delete mode 100644 htdocs/includes/raven-js/plugins/native.js delete mode 100644 htdocs/includes/raven-js/plugins/require.js delete mode 100644 htdocs/includes/raven-js/src/raven.js delete mode 100644 htdocs/includes/raven-js/template/_copyright.js delete mode 100644 htdocs/includes/raven-js/template/_footer.js delete mode 100644 htdocs/includes/raven-js/template/_header.js delete mode 100644 htdocs/includes/raven-js/test/index.html delete mode 100644 htdocs/includes/raven-js/test/raven.test.js delete mode 100644 htdocs/includes/raven-js/vendor/TraceKit/tracekit.js delete mode 100644 htdocs/includes/raven/raven/.gitignore delete mode 100644 htdocs/includes/raven/raven/.php_cs delete mode 100644 htdocs/includes/raven/raven/.travis.yml delete mode 100644 htdocs/includes/raven/raven/AUTHORS delete mode 100644 htdocs/includes/raven/raven/CHANGES delete mode 100644 htdocs/includes/raven/raven/LICENSE delete mode 100644 htdocs/includes/raven/raven/Makefile delete mode 100644 htdocs/includes/raven/raven/README.rst delete mode 100755 htdocs/includes/raven/raven/bin/raven delete mode 100644 htdocs/includes/raven/raven/composer.json delete mode 100644 htdocs/includes/raven/raven/lib/Raven/Autoloader.php delete mode 100644 htdocs/includes/raven/raven/lib/Raven/Client.php delete mode 100644 htdocs/includes/raven/raven/lib/Raven/Compat.php delete mode 100644 htdocs/includes/raven/raven/lib/Raven/Context.php delete mode 100644 htdocs/includes/raven/raven/lib/Raven/CurlHandler.php delete mode 100644 htdocs/includes/raven/raven/lib/Raven/ErrorHandler.php delete mode 100644 htdocs/includes/raven/raven/lib/Raven/Processor.php delete mode 100644 htdocs/includes/raven/raven/lib/Raven/SanitizeDataProcessor.php delete mode 100644 htdocs/includes/raven/raven/lib/Raven/Serializer.php delete mode 100644 htdocs/includes/raven/raven/lib/Raven/Stacktrace.php delete mode 100644 htdocs/includes/raven/raven/lib/Raven/Util.php delete mode 100644 htdocs/includes/raven/raven/lib/Raven/data/cacert.pem delete mode 100644 htdocs/includes/raven/raven/phpunit.xml delete mode 100644 htdocs/includes/raven/raven/test/Raven/Tests/ClientTest.php delete mode 100644 htdocs/includes/raven/raven/test/Raven/Tests/CompatTest.php delete mode 100644 htdocs/includes/raven/raven/test/Raven/Tests/ErrorHandlerTest.php delete mode 100644 htdocs/includes/raven/raven/test/Raven/Tests/SanitizeDataProcessorTest.php delete mode 100644 htdocs/includes/raven/raven/test/Raven/Tests/SerializerTest.php delete mode 100644 htdocs/includes/raven/raven/test/Raven/Tests/StacktraceTest.php delete mode 100644 htdocs/includes/raven/raven/test/Raven/Tests/UtilTest.php delete mode 100644 htdocs/includes/raven/raven/test/Raven/Tests/resources/a.php delete mode 100644 htdocs/includes/raven/raven/test/Raven/Tests/resources/b.php delete mode 100644 htdocs/includes/raven/raven/test/bootstrap.php diff --git a/COPYRIGHT b/COPYRIGHT index b89c5d23e60..9b848744a69 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -17,7 +17,6 @@ ChromePHP 4.1.0 Apache Software License 2.0 Yes CKEditor 4.3.3 LGPL-2.1+ Yes Editor WYSIWYG EvalMath 1.0 BSD Yes Safe math expressions evaluation Escpos-php MIT License Yes Thermal receipt printer library, for use with ESC/POS compatible printers -FirePHPCore 0.4.0 MIT License Yes Send logs to Firefox Firebug console FPDI 1.5.2 Apache Software License 2.0 Yes PDF templates management GeoIP 1.4 LGPL-2.1+ Yes Sample code to make geoip convert (not into deb package) Mobiledetect 2.8.3 MIT License Yes Detect mobile devices browsers @@ -28,7 +27,6 @@ PHPExcel 1.8.1 LGPL-2.1+ Yes php-iban 1.4.7 LGPL-3+ Yes Parse and validate IBAN (and IIBAN) bank account information in PHP PHPoAuthLib 0.8.2 MIT License Yes Library to provide oauth1 and oauth2 to different service PHPPrintIPP 1.3 GPL-2+ Yes Library to send print IPP requests -Raven-php 0.12.1 MIT License Yes Used for server-side error logging with Sentry logger Restler 3.0 LGPL-3+ Yes Library to develop REST Web services TCPDF 6.2.6 LGPL-3+ Yes PDF generation TCPDI 1.0.0 LGPL-3+ / Apache 2.0 Yes FPDI replacement @@ -55,7 +53,6 @@ jQuery Timepicker 1.1.0 GPL and MIT License Yes jQuery Tiptip 1.3 GPL and MIT License Yes JS library for tooltips jsGantt 1.2 BSD License Yes JS library (to build Gantt reports) JsTimezoneDetect 1.0.6 MIT License Yes JS library to detect user timezone -Raven.js 1.1.19 MIT License Yes Used for client-side error logging with Sentry logger For licenses compatibility informations: http://www.gnu.org/licenses/licenses.en.html diff --git a/htdocs/includes/firephp/firephp-core/.gitignore b/htdocs/includes/firephp/firephp-core/.gitignore deleted file mode 100644 index d16386367f7..00000000000 --- a/htdocs/includes/firephp/firephp-core/.gitignore +++ /dev/null @@ -1 +0,0 @@ -build/ \ No newline at end of file diff --git a/htdocs/includes/firephp/firephp-core/CHANGELOG.md b/htdocs/includes/firephp/firephp-core/CHANGELOG.md deleted file mode 100644 index d8b0f86df5b..00000000000 --- a/htdocs/includes/firephp/firephp-core/CHANGELOG.md +++ /dev/null @@ -1,171 +0,0 @@ - -TODO: - - * Fix code indenting in PHP 4 code - * Port maxDepth option to PHP 4 code - -2013-04-23 - Release Version: 0.4.0 - - * No changes - -2011-06-22 - Release Version: 0.4.0rc3 - - * Build fixes - -2011-06-20 - Release Version: 0.4.0rc1 - - * (Issue 163) PHP5 class_exists() throws Exception without second parameter - * (Issue 166) Non-utf8 array values replaced with null - * Cleaned up code formatting [sokolov.innokenty@gmail.com] - * Ensure JSON keys are never NULL (due to NULL key in some arrays) - * Better UTF-8 encoding detection - * Code style cleanup (qbbr) - * Changed license to MIT - * Refactored project - -2010-10-26 - Release Version: 0.3.2 - -2010-10-12 - Release Version: 0.3.2rc6 - - * (Issue 154) getRequestHeader uses "getallheaders" even though it doesn't always exist. [25m] - -2010-10-09 - Release Version: 0.3.2rc5 - - * (Issue 153) FirePHP incorrectly double-encodes UTF8 when mbstring.func_overload is enabled - -2010-10-08 - Release Version: 0.3.2rc4 - - * Trigger upgrade message if part of FirePHP 1.0 - * Removed FirePHP/Init.php inclusion logic and only load FirePHP.class.php if not already loaded - -2010-07-19 - Release Version: 0.3.2rc3 - - * Fixed FirePHP/Init.php inclusion logic - -2010-07-19 - Release Version: 0.3.2rc2 - - * (Issue 145) maxDepth option - * Changed maxObjectDepth and maxArrayDepth option defaults to 5 - * Fixed code indentation - -2010-03-05 - Release Version: 0.3.2rc1 - - * (Issue 114) Allow options to be passed on to basic logging wrappers - * (Issue 122) Filter objectStack property of FirePHP class - * (Issue 123) registerErrorHandler(false) by default - * Added setOption() and getOption() methods - * (Issue 117) dump() method argument validation - * Started adding PHPUnit tests - * Some refactoring to support unit testing - * Deprecated setProcessorUrl() and setRendererUrl() - * Check User-Agent and X-FirePHP-Version header to detect FirePHP on client - * (Issue 135) FirePHP 0.4.3 with Firebug 1.5 changes user agent on the fly - * (Issue 112) Error Predefined Constants Not available for PHP 5.x versions - -2008-06-14 - Release Version: 0.3.1 - - * (Issue 108) ignore class name case in object filter - -2009-05-11 - Release Version: 0.3 -2009-05-01 - Release Version: 0.3.rc.1 - - * (Issue 90) PHP4 compatible version of FirePHPCore - * (Issue 98) Thrown exceptions don't send an HTTP 500 if the FirePHP exception handler is enabled - * (Issue 85) Support associative arrays in encodeTable method in FirePHP.class.php - * (Issue 66) Add a new getOptions() public method in API - * (Issue 82) Define $this->options outside of __construct - * (Issue 72) Message error if group name is null - * (Issue 68) registerErrorHandler() and registerExceptionHandler() should returns previous handlers defined - * (Issue 69) Add the missing register handler in the triumvirate (error, exception, assert) - * (Issue 75) [Error & Exception Handling] Option to not exit script execution - * (Issue 83) Exception handler can't throw exceptions - * (Issue 80) Auto/Pre collapsing groups AND Custom group row colors - -2008-11-09 - Release Version: 0.2.1 - - * (Issue 70) Problem when logging resources - -2008-10-21 - Release Version: 0.2.0 - - * Updated version to 0.2.0 - * Switched to using __sleep instead of __wakeup - * Added support to exclude object members when encoding - * Add support to enable/disable logging - -2008-10-17 - Release Version: 0.2.b.8 - - * New implementation for is_utf8() - * (Issue 55) maxObjectDepth Option not working correctly when using TABLE and EXCEPTION Type - * Bugfix for max[Object|Array]Depth when encoding nested array/object graphs - * Bugfix for FB::setOptions() - -2008-10-16 - Release Version: 0.2.b.7 - - * (Issue 45) Truncate dump when string have non utf8 cars - * (Issue 52) logging will not work when firephp object gets stored in the session. - -2008-10-16 - Release Version: 0.2.b.6 - - * (Issue 37) Display file and line information for each log message - * (Issue 51) Limit output of object graphs - * Bugfix for encoding object members set to NULL|false|'' - -2008-10-14 - Release Version: 0.2.b.5 - - * Updated JsonStream wildfire protocol to be more robust - * (Issue 33) PHP error notices running demos - * (Issue 48) Warning: ReflectionProperty::getValue() expects exactly 1 parameter, 0 given - -2008-10-08 - Release Version: 0.2.b.4 - - * Bugfix for logging objects with recursion - -2008-10-08 - Release Version: 0.2.b.3 - - * (Issue 43) Notice message in 0.2b2 - * Added support for PHP's native json_encode() if available - * Revised object encoder to detect object recursion - -2008-10-07 - Release Version: 0.2.b.2 - - * (Issue 28) Need solution for logging private and protected object variables - * Added trace() and table() aliases in FirePHP class - * (Issue 41) Use PHP doc in FirePHP - * (Issue 39) Static logging method for object oriented API - -2008-10-01 - Release Version: 0.2.b.1 - - * Added support for error and exception handling - * Updated min PHP version for PEAR package to 5.2 - * Added version constant for library - * Gave server library it's own wildfire plugin namespace - * Migrated communication protocol to Wildfire JsonStream - * Added support for console groups using "group" and "groupEnd" - * Added support for log, info, warn and error logging aliases - * (Issue 29) problem with TRACE when using with error_handler - * (Issue 33) PHP error notices running demos - * (Issue 12) undefined index php notice - * Removed closing ?> php tags - * (Issue 13) the code in the fb() function has a second return statement that will never be reached - -2008-07-30 - Release Version: 0.1.1.3 - - * Include __className property in JSON string if variable was an object - * Bugfix - Mis-spelt "Exception" in JSON encoding code - -2008-06-13 - Release Version: 0.1.1.1 - - * Bugfix - Standardize windows paths in stack traces - * Bugfix - Display correct stack trace info in windows environments - * Bugfix - Check $_SERVER['HTTP_USER_AGENT'] before returning - -2008-06-13 - Release Version: 0.1.1 - - * Added support for FirePHP::TRACE log style - * Changed license to New BSD License - -2008-06-06 - Release Version: 0.0.2 - - * Bugfix - Added usleep() to header writing loop to ensure unique index - * Bugfix - Ensure chunk_split does not generate trailing "\n" with empty data header - * Added support for FirePHP::TABLE log style diff --git a/htdocs/includes/firephp/firephp-core/README.md b/htdocs/includes/firephp/firephp-core/README.md deleted file mode 100644 index b1b32f842ff..00000000000 --- a/htdocs/includes/firephp/firephp-core/README.md +++ /dev/null @@ -1,75 +0,0 @@ -FirePHPCore -=========== - -**Status: stable** - -> **FirePHP is an advanced logging system that can display PHP variables in the browser as an application is navigated.** -> All communication is out of band to the application meaning that the logging data will not interfere with the normal functioning of the application. - -This project contains the *FirePHPCore* PHP server library and provides a development environment (see `./workspace/`) for working on *FirePHPCore*. - - -Usage -===== - -See [Install/Traditional: FirePHPCore](http://docs.sourcemint.org/firephp.org/firephp/1/-docs/Configuration/Traditional) in the -[FirePHP 1.0 Documentation](http://docs.sourcemint.org/firephp.org/firephp/1/-docs/). - - -Testing -======= - - cd tests - phpunit . - - -Support & Feedback -================== - -See [Support](http://docs.sourcemint.org/firephp.org/firephp/1/-docs/OpenSource#support) in the [FirePHP 1.0 Documentation](http://docs.sourcemint.org/firephp.org/firephp/1/-docs/). - - -Contribute -========== - -See [Contribute](http://docs.sourcemint.org/firephp.org/firephp/1/-docs/OpenSource#contribute) in the [FirePHP 1.0 Documentation](http://docs.sourcemint.org/firephp.org/firephp/1/-docs/). - - -Author -====== - -This project is authored and maintained by [Christoph Dorn](http://www.christophdorn.com/). - - -Documentation License -===================== - -[Creative Commons Attribution-NonCommercial-ShareAlike 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/) - -Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/) - - -Code License -============ - -[MIT License](http://www.opensource.org/licenses/mit-license.php) - -Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/htdocs/includes/firephp/firephp-core/composer.json b/htdocs/includes/firephp/firephp-core/composer.json deleted file mode 100644 index 7cab85a9f8b..00000000000 --- a/htdocs/includes/firephp/firephp-core/composer.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "firephp/firephp-core", - "description": "Traditional FirePHPCore library for sending PHP variables to the browser.", - "type": "library", - "homepage": "https://github.com/firephp/firephp-core", - "license": "MIT", - "authors": [ - { - "name": "Christoph Dorn", - "email": "christoph@christophdorn.com", - "homepage": "http://christophdorn.com" - } - ], - "support": { - "forum": "http://groups.google.com/group/firephp-dev", - "issues": "https://github.com/firephp/firephp-core/issues", - "source": "https://github.com/firephp/firephp-core" - }, - "autoload": { - "classmap": [ - "lib/FirePHPCore/FirePHP.class.php", - "lib/FirePHPCore/fb.php" - ] - } -} - diff --git a/htdocs/includes/firephp/firephp-core/examples/oo.php b/htdocs/includes/firephp/firephp-core/examples/oo.php deleted file mode 100644 index f5f39875c94..00000000000 --- a/htdocs/includes/firephp/firephp-core/examples/oo.php +++ /dev/null @@ -1,82 +0,0 @@ -, Copyright 2007, New BSD License -// - cadorn, Christoph Dorn , Copyright 2011, MIT License - -/* *** BEGIN LICENSE BLOCK ***** - * - * [MIT License](http://www.opensource.org/licenses/mit-license.php) - * - * Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * ***** END LICENSE BLOCK ***** */ - - -/* NOTE: You must have the FirePHPCore library in your include path */ - -set_include_path(dirname(dirname(__FILE__)).'/lib'.PATH_SEPARATOR.get_include_path()); - - -require('FirePHPCore/FirePHP.class.php'); - -/* NOTE: You must have Output Buffering enabled via - ob_start() or output_buffering ini directive. */ - - -$firephp = FirePHP::getInstance(true); - - -$firephp->fb('Hello World'); /* Defaults to FirePHP::LOG */ - -$firephp->fb('Log message' ,FirePHP::LOG); -$firephp->fb('Info message' ,FirePHP::INFO); -$firephp->fb('Warn message' ,FirePHP::WARN); -$firephp->fb('Error message',FirePHP::ERROR); - -$firephp->fb('Message with label','Label',FirePHP::LOG); - -$firephp->fb(array('key1'=>'val1', - 'key2'=>array(array('v1','v2'),'v3')), - 'TestArray',FirePHP::LOG); - -function test($Arg1) { - throw new Exception('Test Exception'); -} -try { - test(array('Hello'=>'World')); -} catch(Exception $e) { - /* Log exception including stack trace & variables */ - $firephp->fb($e); -} - -$firephp->fb('Backtrace to here',FirePHP::TRACE); - -$firephp->fb(array('2 SQL queries took 0.06 seconds',array( - array('SQL Statement','Time','Result'), - array('SELECT * FROM Foo','0.02',array('row1','row2')), - array('SELECT * FROM Bar','0.04',array('row1','row2')) - )),FirePHP::TABLE); - -/* Will show only in "Server" tab for the request */ -$firephp->fb(apache_request_headers(),'RequestHeaders',FirePHP::DUMP); - - -print 'Hello World'; diff --git a/htdocs/includes/firephp/firephp-core/examples/oo.php4 b/htdocs/includes/firephp/firephp-core/examples/oo.php4 deleted file mode 100644 index 75ec1ee3f9e..00000000000 --- a/htdocs/includes/firephp/firephp-core/examples/oo.php4 +++ /dev/null @@ -1,72 +0,0 @@ -, Copyright 2007, New BSD License -// - cadorn, Christoph Dorn , Copyright 2011, MIT License - -/* *** BEGIN LICENSE BLOCK ***** - * - * [MIT License](http://www.opensource.org/licenses/mit-license.php) - * - * Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * ***** END LICENSE BLOCK ***** */ - - -/* NOTE: You must have the FirePHPCore library in your include path */ - -set_include_path(dirname(dirname(__FILE__)).'/lib'.PATH_SEPARATOR.get_include_path()); - - -require('FirePHPCore/FirePHP.class.php4'); - -/* NOTE: You must have Output Buffering enabled via - ob_start() or output_buffering ini directive. */ - - -$firephp =& FirePHP::getInstance(true); - - -$firephp->fb('Hello World'); /* Defaults to FirePHP::LOG */ - -$firephp->fb('Log message' ,FirePHP_LOG); -$firephp->fb('Info message' ,FirePHP_INFO); -$firephp->fb('Warn message' ,FirePHP_WARN); -$firephp->fb('Error message',FirePHP_ERROR); - -$firephp->fb('Message with label','Label',FirePHP_LOG); - -$firephp->fb(array('key1'=>'val1', - 'key2'=>array(array('v1','v2'),'v3')), - 'TestArray',FirePHP_LOG); - -$firephp->fb('Backtrace to here',FirePHP_TRACE); - -$firephp->fb(array('2 SQL queries took 0.06 seconds',array( - array('SQL Statement','Time','Result'), - array('SELECT * FROM Foo','0.02',array('row1','row2')), - array('SELECT * FROM Bar','0.04',array('row1','row2')) - )),FirePHP_TABLE); - -/* Will show only in "Server" tab for the request */ -$firephp->fb(apache_request_headers(),'RequestHeaders',FirePHP_DUMP); - - -print 'Hello World'; diff --git a/htdocs/includes/firephp/firephp-core/examples/procedural.php b/htdocs/includes/firephp/firephp-core/examples/procedural.php deleted file mode 100644 index d1d3920bf4a..00000000000 --- a/htdocs/includes/firephp/firephp-core/examples/procedural.php +++ /dev/null @@ -1,79 +0,0 @@ -, Copyright 2007, New BSD License -// - cadorn, Christoph Dorn , Copyright 2011, MIT License - -/* *** BEGIN LICENSE BLOCK ***** - * - * [MIT License](http://www.opensource.org/licenses/mit-license.php) - * - * Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * ***** END LICENSE BLOCK ***** */ - - -/* NOTE: You must have the FirePHPCore library in your include path */ - -set_include_path(dirname(dirname(__FILE__)).'/lib'.PATH_SEPARATOR.get_include_path()); - - -require('FirePHPCore/fb.php'); - -/* NOTE: You must have Output Buffering enabled via - ob_start() or output_buffering ini directive. */ - -fb('Hello World'); /* Defaults to FirePHP::LOG */ - -fb('Log message' ,FirePHP::LOG); -fb('Info message' ,FirePHP::INFO); -fb('Warn message' ,FirePHP::WARN); -fb('Error message',FirePHP::ERROR); - -fb('Message with label','Label',FirePHP::LOG); - -fb(array('key1'=>'val1', - 'key2'=>array(array('v1','v2'),'v3')), - 'TestArray',FirePHP::LOG); - -function test($Arg1) { - throw new Exception('Test Exception'); -} -try { - test(array('Hello'=>'World')); -} catch(Exception $e) { - /* Log exception including stack trace & variables */ - fb($e); -} - -fb('Backtrace to here',FirePHP::TRACE); - -fb(array('2 SQL queries took 0.06 seconds',array( - array('SQL Statement','Time','Result'), - array('SELECT * FROM Foo','0.02',array('row1','row2')), - array('SELECT * FROM Bar','0.04',array('row1','row2')) - )),FirePHP::TABLE); - -/* Will show only in "Server" tab for the request */ -fb(apache_request_headers(),'RequestHeaders',FirePHP::DUMP); - - -print 'Hello World'; - diff --git a/htdocs/includes/firephp/firephp-core/examples/procedural.php4 b/htdocs/includes/firephp/firephp-core/examples/procedural.php4 deleted file mode 100644 index 28eb7dc17e8..00000000000 --- a/htdocs/includes/firephp/firephp-core/examples/procedural.php4 +++ /dev/null @@ -1,69 +0,0 @@ -, Copyright 2007, New BSD License -// - cadorn, Christoph Dorn , Copyright 2011, MIT License - -/* *** BEGIN LICENSE BLOCK ***** - * - * [MIT License](http://www.opensource.org/licenses/mit-license.php) - * - * Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * ***** END LICENSE BLOCK ***** */ - - -/* NOTE: You must have the FirePHPCore library in your include path */ - -set_include_path(dirname(dirname(__FILE__)).'/lib'.PATH_SEPARATOR.get_include_path()); - - -require('FirePHPCore/fb.php'); - -/* NOTE: You must have Output Buffering enabled via - ob_start() or output_buffering ini directive. */ - -fb('Hello World'); /* Defaults to FirePHP::LOG */ - -fb('Log message' ,FirePHP_LOG); -fb('Info message' ,FirePHP_INFO); -fb('Warn message' ,FirePHP_WARN); -fb('Error message',FirePHP_ERROR); - -fb('Message with label','Label',FirePHP_LOG); - -fb(array('key1'=>'val1', - 'key2'=>array(array('v1','v2'),'v3')), - 'TestArray',FirePHP_LOG); - -fb('Backtrace to here',FirePHP_TRACE); - -fb(array('2 SQL queries took 0.06 seconds',array( - array('SQL Statement','Time','Result'), - array('SELECT * FROM Foo','0.02',array('row1','row2')), - array('SELECT * FROM Bar','0.04',array('row1','row2')) - )),FirePHP_TABLE); - -/* Will show only in "Server" tab for the request */ -fb(apache_request_headers(),'RequestHeaders',FirePHP_DUMP); - - -print 'Hello World'; - diff --git a/htdocs/includes/firephp/firephp-core/lib/FirePHPCore/FirePHP.class.php b/htdocs/includes/firephp/firephp-core/lib/FirePHPCore/FirePHP.class.php deleted file mode 100644 index 65d83b56dca..00000000000 --- a/htdocs/includes/firephp/firephp-core/lib/FirePHPCore/FirePHP.class.php +++ /dev/null @@ -1,1828 +0,0 @@ -, Copyright 2007, New BSD License -// - qbbr, Sokolov Innokenty , Copyright 2011, New BSD License -// - cadorn, Christoph Dorn , Copyright 2011, MIT License - -/** - * *** BEGIN LICENSE BLOCK ***** - * - * [MIT License](http://www.opensource.org/licenses/mit-license.php) - * - * Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * ***** END LICENSE BLOCK ***** - * - * @copyright Copyright (C) 2007+ Christoph Dorn - * @author Christoph Dorn - * @license [MIT License](http://www.opensource.org/licenses/mit-license.php) - * @package FirePHPCore - */ - -/** - * @see http://code.google.com/p/firephp/issues/detail?id=112 - */ -if (!defined('E_STRICT')) { - define('E_STRICT', 2048); -} -if (!defined('E_RECOVERABLE_ERROR')) { - define('E_RECOVERABLE_ERROR', 4096); -} -if (!defined('E_DEPRECATED')) { - define('E_DEPRECATED', 8192); -} -if (!defined('E_USER_DEPRECATED')) { - define('E_USER_DEPRECATED', 16384); -} - -/** - * Sends the given data to the FirePHP Firefox Extension. - * The data can be displayed in the Firebug Console or in the - * "Server" request tab. - * - * For more information see: http://www.firephp.org/ - * - * @copyright Copyright (C) 2007+ Christoph Dorn - * @author Christoph Dorn - * @license [MIT License](http://www.opensource.org/licenses/mit-license.php) - * @package FirePHPCore - */ -class FirePHP { - - /** - * FirePHP version - * - * @var string - */ - const VERSION = '0.3'; // @pinf replace '0.3' with '%%VERSION%%' - - /** - * Firebug LOG level - * - * Logs a message to firebug console. - * - * @var string - */ - const LOG = 'LOG'; - - /** - * Firebug INFO level - * - * Logs a message to firebug console and displays an info icon before the message. - * - * @var string - */ - const INFO = 'INFO'; - - /** - * Firebug WARN level - * - * Logs a message to firebug console, displays an warning icon before the message and colors the line turquoise. - * - * @var string - */ - const WARN = 'WARN'; - - /** - * Firebug ERROR level - * - * Logs a message to firebug console, displays an error icon before the message and colors the line yellow. Also increments the firebug error count. - * - * @var string - */ - const ERROR = 'ERROR'; - - /** - * Dumps a variable to firebug's server panel - * - * @var string - */ - const DUMP = 'DUMP'; - - /** - * Displays a stack trace in firebug console - * - * @var string - */ - const TRACE = 'TRACE'; - - /** - * Displays an exception in firebug console - * - * Increments the firebug error count. - * - * @var string - */ - const EXCEPTION = 'EXCEPTION'; - - /** - * Displays an table in firebug console - * - * @var string - */ - const TABLE = 'TABLE'; - - /** - * Starts a group in firebug console - * - * @var string - */ - const GROUP_START = 'GROUP_START'; - - /** - * Ends a group in firebug console - * - * @var string - */ - const GROUP_END = 'GROUP_END'; - - /** - * Singleton instance of FirePHP - * - * @var FirePHP - */ - protected static $instance = null; - - /** - * Flag whether we are logging from within the exception handler - * - * @var boolean - */ - protected $inExceptionHandler = false; - - /** - * Flag whether to throw PHP errors that have been converted to ErrorExceptions - * - * @var boolean - */ - protected $throwErrorExceptions = true; - - /** - * Flag whether to convert PHP assertion errors to Exceptions - * - * @var boolean - */ - protected $convertAssertionErrorsToExceptions = true; - - /** - * Flag whether to throw PHP assertion errors that have been converted to Exceptions - * - * @var boolean - */ - protected $throwAssertionExceptions = false; - - /** - * Wildfire protocol message index - * - * @var integer - */ - protected $messageIndex = 1; - - /** - * Options for the library - * - * @var array - */ - protected $options = array('maxDepth' => 10, - 'maxObjectDepth' => 5, - 'maxArrayDepth' => 5, - 'useNativeJsonEncode' => true, - 'includeLineNumbers' => true); - - /** - * Filters used to exclude object members when encoding - * - * @var array - */ - protected $objectFilters = array( - 'firephp' => array('objectStack', 'instance', 'json_objectStack'), - 'firephp_test_class' => array('objectStack', 'instance', 'json_objectStack') - ); - - /** - * A stack of objects used to detect recursion during object encoding - * - * @var object - */ - protected $objectStack = array(); - - /** - * Flag to enable/disable logging - * - * @var boolean - */ - protected $enabled = true; - - /** - * The insight console to log to if applicable - * - * @var object - */ - protected $logToInsightConsole = null; - - /** - * When the object gets serialized only include specific object members. - * - * @return array - */ - public function __sleep() - { - return array('options', 'objectFilters', 'enabled'); - } - - /** - * Gets singleton instance of FirePHP - * - * @param boolean $autoCreate - * @return FirePHP - */ - public static function getInstance($autoCreate = false) - { - if ($autoCreate === true && !self::$instance) { - self::init(); - } - return self::$instance; - } - - /** - * Creates FirePHP object and stores it for singleton access - * - * @return FirePHP - */ - public static function init() - { - return self::setInstance(new self()); - } - - /** - * Set the instance of the FirePHP singleton - * - * @param FirePHP $instance The FirePHP object instance - * @return FirePHP - */ - public static function setInstance($instance) - { - return self::$instance = $instance; - } - - /** - * Set an Insight console to direct all logging calls to - * - * @param object $console The console object to log to - * @return void - */ - public function setLogToInsightConsole($console) - { - if (is_string($console)) { - if (get_class($this) != 'FirePHP_Insight' && !is_subclass_of($this, 'FirePHP_Insight')) { - throw new Exception('FirePHP instance not an instance or subclass of FirePHP_Insight!'); - } - $this->logToInsightConsole = $this->to('request')->console($console); - } else { - $this->logToInsightConsole = $console; - } - } - - /** - * Enable and disable logging to Firebug - * - * @param boolean $enabled TRUE to enable, FALSE to disable - * @return void - */ - public function setEnabled($enabled) - { - $this->enabled = $enabled; - } - - /** - * Check if logging is enabled - * - * @return boolean TRUE if enabled - */ - public function getEnabled() - { - return $this->enabled; - } - - /** - * Specify a filter to be used when encoding an object - * - * Filters are used to exclude object members. - * - * @param string $class The class name of the object - * @param array $filter An array of members to exclude - * @return void - */ - public function setObjectFilter($class, $filter) - { - $this->objectFilters[strtolower($class)] = $filter; - } - - /** - * Set some options for the library - * - * Options: - * - maxDepth: The maximum depth to traverse (default: 10) - * - maxObjectDepth: The maximum depth to traverse objects (default: 5) - * - maxArrayDepth: The maximum depth to traverse arrays (default: 5) - * - useNativeJsonEncode: If true will use json_encode() (default: true) - * - includeLineNumbers: If true will include line numbers and filenames (default: true) - * - * @param array $options The options to be set - * @return void - */ - public function setOptions($options) - { - $this->options = array_merge($this->options, $options); - } - - /** - * Get options from the library - * - * @return array The currently set options - */ - public function getOptions() - { - return $this->options; - } - - /** - * Set an option for the library - * - * @param string $name - * @param mixed $value - * @return void - * @throws Exception - */ - public function setOption($name, $value) - { - if (!isset($this->options[$name])) { - throw $this->newException('Unknown option: ' . $name); - } - $this->options[$name] = $value; - } - - /** - * Get an option from the library - * - * @param string $name - * @return mixed - * @throws Exception - */ - public function getOption($name) - { - if (!isset($this->options[$name])) { - throw $this->newException('Unknown option: ' . $name); - } - return $this->options[$name]; - } - - /** - * Register FirePHP as your error handler - * - * Will throw exceptions for each php error. - * - * @return mixed Returns a string containing the previously defined error handler (if any) - */ - public function registerErrorHandler($throwErrorExceptions = false) - { - //NOTE: The following errors will not be caught by this error handler: - // E_ERROR, E_PARSE, E_CORE_ERROR, - // E_CORE_WARNING, E_COMPILE_ERROR, - // E_COMPILE_WARNING, E_STRICT - - $this->throwErrorExceptions = $throwErrorExceptions; - - return set_error_handler(array($this, 'errorHandler')); - } - - /** - * FirePHP's error handler - * - * Throws exception for each php error that will occur. - * - * @param integer $errno - * @param string $errstr - * @param string $errfile - * @param integer $errline - * @param array $errcontext - */ - public function errorHandler($errno, $errstr, $errfile, $errline, $errcontext) - { - // Don't throw exception if error reporting is switched off - if (error_reporting() == 0) { - return; - } - // Only throw exceptions for errors we are asking for - if (error_reporting() & $errno) { - - $exception = new ErrorException($errstr, 0, $errno, $errfile, $errline); - if ($this->throwErrorExceptions) { - throw $exception; - } else { - $this->fb($exception); - } - } - } - - /** - * Register FirePHP as your exception handler - * - * @return mixed Returns the name of the previously defined exception handler, - * or NULL on error. - * If no previous handler was defined, NULL is also returned. - */ - public function registerExceptionHandler() - { - return set_exception_handler(array($this, 'exceptionHandler')); - } - - /** - * FirePHP's exception handler - * - * Logs all exceptions to your firebug console and then stops the script. - * - * @param Exception $exception - * @throws Exception - */ - function exceptionHandler($exception) - { - $this->inExceptionHandler = true; - - header('HTTP/1.1 500 Internal Server Error'); - - try { - $this->fb($exception); - } catch (Exception $e) { - echo 'We had an exception: ' . $e; - } - - $this->inExceptionHandler = false; - } - - /** - * Register FirePHP driver as your assert callback - * - * @param boolean $convertAssertionErrorsToExceptions - * @param boolean $throwAssertionExceptions - * @return mixed Returns the original setting or FALSE on errors - */ - public function registerAssertionHandler($convertAssertionErrorsToExceptions = true, $throwAssertionExceptions = false) - { - $this->convertAssertionErrorsToExceptions = $convertAssertionErrorsToExceptions; - $this->throwAssertionExceptions = $throwAssertionExceptions; - - if ($throwAssertionExceptions && !$convertAssertionErrorsToExceptions) { - throw $this->newException('Cannot throw assertion exceptions as assertion errors are not being converted to exceptions!'); - } - - return assert_options(ASSERT_CALLBACK, array($this, 'assertionHandler')); - } - - /** - * FirePHP's assertion handler - * - * Logs all assertions to your firebug console and then stops the script. - * - * @param string $file File source of assertion - * @param integer $line Line source of assertion - * @param mixed $code Assertion code - */ - public function assertionHandler($file, $line, $code) - { - if ($this->convertAssertionErrorsToExceptions) { - - $exception = new ErrorException('Assertion Failed - Code[ ' . $code . ' ]', 0, null, $file, $line); - - if ($this->throwAssertionExceptions) { - throw $exception; - } else { - $this->fb($exception); - } - - } else { - $this->fb($code, 'Assertion Failed', FirePHP::ERROR, array('File' => $file, 'Line' => $line)); - } - } - - /** - * Start a group for following messages. - * - * Options: - * Collapsed: [true|false] - * Color: [#RRGGBB|ColorName] - * - * @param string $name - * @param array $options OPTIONAL Instructions on how to log the group - * @return true - * @throws Exception - */ - public function group($name, $options = null) - { - - if (!$name) { - throw $this->newException('You must specify a label for the group!'); - } - - if ($options) { - if (!is_array($options)) { - throw $this->newException('Options must be defined as an array!'); - } - if (array_key_exists('Collapsed', $options)) { - $options['Collapsed'] = ($options['Collapsed']) ? 'true' : 'false'; - } - } - - return $this->fb(null, $name, FirePHP::GROUP_START, $options); - } - - /** - * Ends a group you have started before - * - * @return true - * @throws Exception - */ - public function groupEnd() - { - return $this->fb(null, null, FirePHP::GROUP_END); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::LOG - * @param mixes $object - * @param string $label - * @return true - * @throws Exception - */ - public function log($object, $label = null, $options = array()) - { - return $this->fb($object, $label, FirePHP::LOG, $options); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::INFO - * @param mixes $object - * @param string $label - * @return true - * @throws Exception - */ - public function info($object, $label = null, $options = array()) - { - return $this->fb($object, $label, FirePHP::INFO, $options); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::WARN - * @param mixes $object - * @param string $label - * @return true - * @throws Exception - */ - public function warn($object, $label = null, $options = array()) - { - return $this->fb($object, $label, FirePHP::WARN, $options); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::ERROR - * @param mixes $object - * @param string $label - * @return true - * @throws Exception - */ - public function error($object, $label = null, $options = array()) - { - return $this->fb($object, $label, FirePHP::ERROR, $options); - } - - /** - * Dumps key and variable to firebug server panel - * - * @see FirePHP::DUMP - * @param string $key - * @param mixed $variable - * @return true - * @throws Exception - */ - public function dump($key, $variable, $options = array()) - { - if (!is_string($key)) { - throw $this->newException('Key passed to dump() is not a string'); - } - if (strlen($key) > 100) { - throw $this->newException('Key passed to dump() is longer than 100 characters'); - } - if (!preg_match_all('/^[a-zA-Z0-9-_\.:]*$/', $key, $m)) { - throw $this->newException('Key passed to dump() contains invalid characters [a-zA-Z0-9-_\.:]'); - } - return $this->fb($variable, $key, FirePHP::DUMP, $options); - } - - /** - * Log a trace in the firebug console - * - * @see FirePHP::TRACE - * @param string $label - * @return true - * @throws Exception - */ - public function trace($label) - { - return $this->fb($label, FirePHP::TRACE); - } - - /** - * Log a table in the firebug console - * - * @see FirePHP::TABLE - * @param string $label - * @param string $table - * @return true - * @throws Exception - */ - public function table($label, $table, $options = array()) - { - return $this->fb($table, $label, FirePHP::TABLE, $options); - } - - /** - * Insight API wrapper - * - * @see Insight_Helper::to() - */ - public static function to() - { - $instance = self::getInstance(); - if (!method_exists($instance, '_to')) { - throw new Exception('FirePHP::to() implementation not loaded'); - } - $args = func_get_args(); - return call_user_func_array(array($instance, '_to'), $args); - } - - /** - * Insight API wrapper - * - * @see Insight_Helper::plugin() - */ - public static function plugin() - { - $instance = self::getInstance(); - if (!method_exists($instance, '_plugin')) { - throw new Exception('FirePHP::plugin() implementation not loaded'); - } - $args = func_get_args(); - return call_user_func_array(array($instance, '_plugin'), $args); - } - - /** - * Check if FirePHP is installed on client - * - * @return boolean - */ - public function detectClientExtension() - { - // Check if FirePHP is installed on client via User-Agent header - if (@preg_match_all('/\sFirePHP\/([\.\d]*)\s?/si', $this->getUserAgent(), $m) && - version_compare($m[1][0], '0.0.6', '>=')) { - return true; - } else - // Check if FirePHP is installed on client via X-FirePHP-Version header - if (@preg_match_all('/^([\.\d]*)$/si', $this->getRequestHeader('X-FirePHP-Version'), $m) && - version_compare($m[1][0], '0.0.6', '>=')) { - return true; - } - return false; - } - - /** - * Log varible to Firebug - * - * @see http://www.firephp.org/Wiki/Reference/Fb - * @param mixed $object The variable to be logged - * @return boolean Return TRUE if message was added to headers, FALSE otherwise - * @throws Exception - */ - public function fb($object) - { - if ($this instanceof FirePHP_Insight && method_exists($this, '_logUpgradeClientMessage')) { - if (!FirePHP_Insight::$upgradeClientMessageLogged) { // avoid infinite recursion as _logUpgradeClientMessage() logs a message - $this->_logUpgradeClientMessage(); - } - } - - static $insightGroupStack = array(); - - if (!$this->getEnabled()) { - return false; - } - - if ($this->headersSent($filename, $linenum)) { - // If we are logging from within the exception handler we cannot throw another exception - if ($this->inExceptionHandler) { - // Simply echo the error out to the page - echo '
FirePHP ERROR: Headers already sent in ' . $filename . ' on line ' . $linenum . '. Cannot send log data to FirePHP. You must have Output Buffering enabled via ob_start() or output_buffering ini directive.
'; - } else { - throw $this->newException('Headers already sent in ' . $filename . ' on line ' . $linenum . '. Cannot send log data to FirePHP. You must have Output Buffering enabled via ob_start() or output_buffering ini directive.'); - } - } - - $type = null; - $label = null; - $options = array(); - - if (func_num_args() == 1) { - } else if (func_num_args() == 2) { - switch (func_get_arg(1)) { - case self::LOG: - case self::INFO: - case self::WARN: - case self::ERROR: - case self::DUMP: - case self::TRACE: - case self::EXCEPTION: - case self::TABLE: - case self::GROUP_START: - case self::GROUP_END: - $type = func_get_arg(1); - break; - default: - $label = func_get_arg(1); - break; - } - } else if (func_num_args() == 3) { - $type = func_get_arg(2); - $label = func_get_arg(1); - } else if (func_num_args() == 4) { - $type = func_get_arg(2); - $label = func_get_arg(1); - $options = func_get_arg(3); - } else { - throw $this->newException('Wrong number of arguments to fb() function!'); - } - - if ($this->logToInsightConsole !== null && (get_class($this) == 'FirePHP_Insight' || is_subclass_of($this, 'FirePHP_Insight'))) { - $trace = debug_backtrace(); - if (!$trace) return false; - for ($i = 0; $i < sizeof($trace); $i++) { - if (isset($trace[$i]['class'])) { - if ($trace[$i]['class'] == 'FirePHP' || $trace[$i]['class'] == 'FB') { - continue; - } - } - if (isset($trace[$i]['file'])) { - $path = $this->_standardizePath($trace[$i]['file']); - if (substr($path, -18, 18) == 'FirePHPCore/fb.php' || substr($path, -29, 29) == 'FirePHPCore/FirePHP.class.php') { - continue; - } - } - if (isset($trace[$i]['function']) && $trace[$i]['function'] == 'fb' && - isset($trace[$i - 1]['file']) && substr($this->_standardizePath($trace[$i - 1]['file']), -18, 18) == 'FirePHPCore/fb.php') { - continue; - } - if (isset($trace[$i]['class']) && $trace[$i]['class'] == 'FB' && - isset($trace[$i - 1]['file']) && substr($this->_standardizePath($trace[$i - 1]['file']), -18, 18) == 'FirePHPCore/fb.php') { - continue; - } - break; - } - // adjust trace offset - $msg = $this->logToInsightConsole->option('encoder.trace.offsetAdjustment', $i); - - if ($object instanceof Exception) { - $type = self::EXCEPTION; - } - if ($label && $type != self::TABLE && $type != self::GROUP_START) { - $msg = $msg->label($label); - } - switch ($type) { - case self::DUMP: - case self::LOG: - return $msg->log($object); - case self::INFO: - return $msg->info($object); - case self::WARN: - return $msg->warn($object); - case self::ERROR: - return $msg->error($object); - case self::TRACE: - return $msg->trace($object); - case self::EXCEPTION: - return $this->plugin('error')->handleException($object, $msg); - case self::TABLE: - if (isset($object[0]) && !is_string($object[0]) && $label) { - $object = array($label, $object); - } - return $msg->table($object[0], array_slice($object[1], 1), $object[1][0]); - case self::GROUP_START: - $insightGroupStack[] = $msg->group(md5($label))->open(); - return $msg->log($label); - case self::GROUP_END: - if (count($insightGroupStack) == 0) { - throw new Error('Too many groupEnd() as opposed to group() calls!'); - } - $group = array_pop($insightGroupStack); - return $group->close(); - default: - return $msg->log($object); - } - } - - if (!$this->detectClientExtension()) { - return false; - } - - $meta = array(); - $skipFinalObjectEncode = false; - - if ($object instanceof Exception) { - - $meta['file'] = $this->_escapeTraceFile($object->getFile()); - $meta['line'] = $object->getLine(); - - $trace = $object->getTrace(); - if ($object instanceof ErrorException - && isset($trace[0]['function']) - && $trace[0]['function'] == 'errorHandler' - && isset($trace[0]['class']) - && $trace[0]['class'] == 'FirePHP') { - - $severity = false; - switch ($object->getSeverity()) { - case E_WARNING: - $severity = 'E_WARNING'; - break; - - case E_NOTICE: - $severity = 'E_NOTICE'; - break; - - case E_USER_ERROR: - $severity = 'E_USER_ERROR'; - break; - - case E_USER_WARNING: - $severity = 'E_USER_WARNING'; - break; - - case E_USER_NOTICE: - $severity = 'E_USER_NOTICE'; - break; - - case E_STRICT: - $severity = 'E_STRICT'; - break; - - case E_RECOVERABLE_ERROR: - $severity = 'E_RECOVERABLE_ERROR'; - break; - - case E_DEPRECATED: - $severity = 'E_DEPRECATED'; - break; - - case E_USER_DEPRECATED: - $severity = 'E_USER_DEPRECATED'; - break; - } - - $object = array('Class' => get_class($object), - 'Message' => $severity . ': ' . $object->getMessage(), - 'File' => $this->_escapeTraceFile($object->getFile()), - 'Line' => $object->getLine(), - 'Type' => 'trigger', - 'Trace' => $this->_escapeTrace(array_splice($trace, 2))); - $skipFinalObjectEncode = true; - } else { - $object = array('Class' => get_class($object), - 'Message' => $object->getMessage(), - 'File' => $this->_escapeTraceFile($object->getFile()), - 'Line' => $object->getLine(), - 'Type' => 'throw', - 'Trace' => $this->_escapeTrace($trace)); - $skipFinalObjectEncode = true; - } - $type = self::EXCEPTION; - - } else if ($type == self::TRACE) { - - $trace = debug_backtrace(); - if (!$trace) return false; - for ($i = 0; $i < sizeof($trace); $i++) { - - if (isset($trace[$i]['class']) - && isset($trace[$i]['file']) - && ($trace[$i]['class'] == 'FirePHP' - || $trace[$i]['class'] == 'FB') - && (substr($this->_standardizePath($trace[$i]['file']), -18, 18) == 'FirePHPCore/fb.php' - || substr($this->_standardizePath($trace[$i]['file']), -29, 29) == 'FirePHPCore/FirePHP.class.php')) { - /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */ - } else - if (isset($trace[$i]['class']) - && isset($trace[$i+1]['file']) - && $trace[$i]['class'] == 'FirePHP' - && substr($this->_standardizePath($trace[$i + 1]['file']), -18, 18) == 'FirePHPCore/fb.php') { - /* Skip fb() */ - } else - if ($trace[$i]['function'] == 'fb' - || $trace[$i]['function'] == 'trace' - || $trace[$i]['function'] == 'send') { - - $object = array('Class' => isset($trace[$i]['class']) ? $trace[$i]['class'] : '', - 'Type' => isset($trace[$i]['type']) ? $trace[$i]['type'] : '', - 'Function' => isset($trace[$i]['function']) ? $trace[$i]['function'] : '', - 'Message' => $trace[$i]['args'][0], - 'File' => isset($trace[$i]['file']) ? $this->_escapeTraceFile($trace[$i]['file']) : '', - 'Line' => isset($trace[$i]['line']) ? $trace[$i]['line'] : '', - 'Args' => isset($trace[$i]['args']) ? $this->encodeObject($trace[$i]['args']) : '', - 'Trace' => $this->_escapeTrace(array_splice($trace, $i + 1))); - - $skipFinalObjectEncode = true; - $meta['file'] = isset($trace[$i]['file']) ? $this->_escapeTraceFile($trace[$i]['file']) : ''; - $meta['line'] = isset($trace[$i]['line']) ? $trace[$i]['line'] : ''; - break; - } - } - - } else - if ($type == self::TABLE) { - - if (isset($object[0]) && is_string($object[0])) { - $object[1] = $this->encodeTable($object[1]); - } else { - $object = $this->encodeTable($object); - } - - $skipFinalObjectEncode = true; - - } else if ($type == self::GROUP_START) { - - if (!$label) { - throw $this->newException('You must specify a label for the group!'); - } - - } else { - if ($type === null) { - $type = self::LOG; - } - } - - if ($this->options['includeLineNumbers']) { - if (!isset($meta['file']) || !isset($meta['line'])) { - - $trace = debug_backtrace(); - for ($i = 0; $trace && $i < sizeof($trace); $i++) { - - if (isset($trace[$i]['class']) - && isset($trace[$i]['file']) - && ($trace[$i]['class'] == 'FirePHP' - || $trace[$i]['class'] == 'FB') - && (substr($this->_standardizePath($trace[$i]['file']), -18, 18) == 'FirePHPCore/fb.php' - || substr($this->_standardizePath($trace[$i]['file']), -29, 29) == 'FirePHPCore/FirePHP.class.php')) { - /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */ - } else - if (isset($trace[$i]['class']) - && isset($trace[$i + 1]['file']) - && $trace[$i]['class'] == 'FirePHP' - && substr($this->_standardizePath($trace[$i + 1]['file']), -18, 18) == 'FirePHPCore/fb.php') { - /* Skip fb() */ - } else - if (isset($trace[$i]['file']) - && substr($this->_standardizePath($trace[$i]['file']), -18, 18) == 'FirePHPCore/fb.php') { - /* Skip FB::fb() */ - } else { - $meta['file'] = isset($trace[$i]['file']) ? $this->_escapeTraceFile($trace[$i]['file']) : ''; - $meta['line'] = isset($trace[$i]['line']) ? $trace[$i]['line'] : ''; - break; - } - } - } - } else { - unset($meta['file']); - unset($meta['line']); - } - - $this->setHeader('X-Wf-Protocol-1', 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2'); - $this->setHeader('X-Wf-1-Plugin-1', 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/' . self::VERSION); - - $structureIndex = 1; - if ($type == self::DUMP) { - $structureIndex = 2; - $this->setHeader('X-Wf-1-Structure-2', 'http://meta.firephp.org/Wildfire/Structure/FirePHP/Dump/0.1'); - } else { - $this->setHeader('X-Wf-1-Structure-1', 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1'); - } - - if ($type == self::DUMP) { - $msg = '{"' . $label . '":' . $this->jsonEncode($object, $skipFinalObjectEncode) . '}'; - } else { - $msgMeta = $options; - $msgMeta['Type'] = $type; - if ($label !== null) { - $msgMeta['Label'] = $label; - } - if (isset($meta['file']) && !isset($msgMeta['File'])) { - $msgMeta['File'] = $meta['file']; - } - if (isset($meta['line']) && !isset($msgMeta['Line'])) { - $msgMeta['Line'] = $meta['line']; - } - $msg = '[' . $this->jsonEncode($msgMeta) . ',' . $this->jsonEncode($object, $skipFinalObjectEncode) . ']'; - } - - $parts = explode("\n", chunk_split($msg, 5000, "\n")); - - for ($i = 0; $i < count($parts); $i++) { - - $part = $parts[$i]; - if ($part) { - - if (count($parts) > 2) { - // Message needs to be split into multiple parts - $this->setHeader('X-Wf-1-' . $structureIndex . '-' . '1-' . $this->messageIndex, - (($i == 0) ? strlen($msg) : '') - . '|' . $part . '|' - . (($i < count($parts) - 2) ? '\\' : '')); - } else { - $this->setHeader('X-Wf-1-' . $structureIndex . '-' . '1-' . $this->messageIndex, - strlen($part) . '|' . $part . '|'); - } - - $this->messageIndex++; - - if ($this->messageIndex > 99999) { - throw $this->newException('Maximum number (99,999) of messages reached!'); - } - } - } - - $this->setHeader('X-Wf-1-Index', $this->messageIndex - 1); - - return true; - } - - /** - * Standardizes path for windows systems. - * - * @param string $path - * @return string - */ - protected function _standardizePath($path) - { - return preg_replace('/\\\\+/', '/', $path); - } - - /** - * Escape trace path for windows systems - * - * @param array $trace - * @return array - */ - protected function _escapeTrace($trace) - { - if (!$trace) return $trace; - for ($i = 0; $i < sizeof($trace); $i++) { - if (isset($trace[$i]['file'])) { - $trace[$i]['file'] = $this->_escapeTraceFile($trace[$i]['file']); - } - if (isset($trace[$i]['args'])) { - $trace[$i]['args'] = $this->encodeObject($trace[$i]['args']); - } - } - return $trace; - } - - /** - * Escape file information of trace for windows systems - * - * @param string $file - * @return string - */ - protected function _escapeTraceFile($file) - { - /* Check if we have a windows filepath */ - if (strpos($file, '\\')) { - /* First strip down to single \ */ - - $file = preg_replace('/\\\\+/', '\\', $file); - - return $file; - } - return $file; - } - - /** - * Check if headers have already been sent - * - * @param string $filename - * @param integer $linenum - */ - protected function headersSent(&$filename, &$linenum) - { - return headers_sent($filename, $linenum); - } - - /** - * Send header - * - * @param string $name - * @param string $value - */ - protected function setHeader($name, $value) - { - return header($name . ': ' . $value); - } - - /** - * Get user agent - * - * @return string|false - */ - protected function getUserAgent() - { - if (!isset($_SERVER['HTTP_USER_AGENT'])) return false; - return $_SERVER['HTTP_USER_AGENT']; - } - - /** - * Get all request headers - * - * @return array - */ - public static function getAllRequestHeaders() - { - static $_cachedHeaders = false; - if ($_cachedHeaders !== false) { - return $_cachedHeaders; - } - $headers = array(); - if (function_exists('getallheaders')) { - foreach (getallheaders() as $name => $value) { - $headers[strtolower($name)] = $value; - } - } else { - foreach ($_SERVER as $name => $value) { - if (substr($name, 0, 5) == 'HTTP_') { - $headers[strtolower(str_replace(' ', '-', str_replace('_', ' ', substr($name, 5))))] = $value; - } - } - } - return $_cachedHeaders = $headers; - } - - /** - * Get a request header - * - * @return string|false - */ - protected function getRequestHeader($name) - { - $headers = self::getAllRequestHeaders(); - if (isset($headers[strtolower($name)])) { - return $headers[strtolower($name)]; - } - return false; - } - - /** - * Returns a new exception - * - * @param string $message - * @return Exception - */ - protected function newException($message) - { - return new Exception($message); - } - - /** - * Encode an object into a JSON string - * - * Uses PHP's jeson_encode() if available - * - * @param object $object The object to be encoded - * @param boolean $skipObjectEncode - * @return string The JSON string - */ - public function jsonEncode($object, $skipObjectEncode = false) - { - if (!$skipObjectEncode) { - $object = $this->encodeObject($object); - } - - if (function_exists('json_encode') - && $this->options['useNativeJsonEncode'] != false) { - - return json_encode($object); - } else { - return $this->json_encode($object); - } - } - - /** - * Encodes a table by encoding each row and column with encodeObject() - * - * @param array $table The table to be encoded - * @return array - */ - protected function encodeTable($table) - { - if (!$table) return $table; - - $newTable = array(); - foreach ($table as $row) { - - if (is_array($row)) { - $newRow = array(); - - foreach ($row as $item) { - $newRow[] = $this->encodeObject($item); - } - - $newTable[] = $newRow; - } - } - - return $newTable; - } - - /** - * Encodes an object including members with - * protected and private visibility - * - * @param object $object The object to be encoded - * @param integer $Depth The current traversal depth - * @return array All members of the object - */ - protected function encodeObject($object, $objectDepth = 1, $arrayDepth = 1, $maxDepth = 1) - { - if ($maxDepth > $this->options['maxDepth']) { - return '** Max Depth (' . $this->options['maxDepth'] . ') **'; - } - - $return = array(); - - if (is_resource($object)) { - - return '** ' . (string) $object . ' **'; - - } else if (is_object($object)) { - - if ($objectDepth > $this->options['maxObjectDepth']) { - return '** Max Object Depth (' . $this->options['maxObjectDepth'] . ') **'; - } - - foreach ($this->objectStack as $refVal) { - if ($refVal === $object) { - return '** Recursion (' . get_class($object) . ') **'; - } - } - array_push($this->objectStack, $object); - - $return['__className'] = $class = get_class($object); - $classLower = strtolower($class); - - $reflectionClass = new ReflectionClass($class); - $properties = array(); - foreach ($reflectionClass->getProperties() as $property) { - $properties[$property->getName()] = $property; - } - - $members = (array)$object; - - foreach ($properties as $plainName => $property) { - - $name = $rawName = $plainName; - if ($property->isStatic()) { - $name = 'static:' . $name; - } - if ($property->isPublic()) { - $name = 'public:' . $name; - } else if ($property->isPrivate()) { - $name = 'private:' . $name; - $rawName = "\0" . $class . "\0" . $rawName; - } else if ($property->isProtected()) { - $name = 'protected:' . $name; - $rawName = "\0" . '*' . "\0" . $rawName; - } - - if (!(isset($this->objectFilters[$classLower]) - && is_array($this->objectFilters[$classLower]) - && in_array($plainName, $this->objectFilters[$classLower]))) { - - if (array_key_exists($rawName, $members) && !$property->isStatic()) { - $return[$name] = $this->encodeObject($members[$rawName], $objectDepth + 1, 1, $maxDepth + 1); - } else { - if (method_exists($property, 'setAccessible')) { - $property->setAccessible(true); - $return[$name] = $this->encodeObject($property->getValue($object), $objectDepth + 1, 1, $maxDepth + 1); - } else - if ($property->isPublic()) { - $return[$name] = $this->encodeObject($property->getValue($object), $objectDepth + 1, 1, $maxDepth + 1); - } else { - $return[$name] = '** Need PHP 5.3 to get value **'; - } - } - } else { - $return[$name] = '** Excluded by Filter **'; - } - } - - // Include all members that are not defined in the class - // but exist in the object - foreach ($members as $rawName => $value) { - - $name = $rawName; - - if ($name{0} == "\0") { - $parts = explode("\0", $name); - $name = $parts[2]; - } - - $plainName = $name; - - if (!isset($properties[$name])) { - $name = 'undeclared:' . $name; - - if (!(isset($this->objectFilters[$classLower]) - && is_array($this->objectFilters[$classLower]) - && in_array($plainName, $this->objectFilters[$classLower]))) { - - $return[$name] = $this->encodeObject($value, $objectDepth + 1, 1, $maxDepth + 1); - } else { - $return[$name] = '** Excluded by Filter **'; - } - } - } - - array_pop($this->objectStack); - - } elseif (is_array($object)) { - - if ($arrayDepth > $this->options['maxArrayDepth']) { - return '** Max Array Depth (' . $this->options['maxArrayDepth'] . ') **'; - } - - foreach ($object as $key => $val) { - - // Encoding the $GLOBALS PHP array causes an infinite loop - // if the recursion is not reset here as it contains - // a reference to itself. This is the only way I have come up - // with to stop infinite recursion in this case. - if ($key == 'GLOBALS' - && is_array($val) - && array_key_exists('GLOBALS', $val)) { - $val['GLOBALS'] = '** Recursion (GLOBALS) **'; - } - - if (!$this->is_utf8($key)) { - $key = utf8_encode($key); - } - - $return[$key] = $this->encodeObject($val, 1, $arrayDepth + 1, $maxDepth + 1); - } - } else { - if ($this->is_utf8($object)) { - return $object; - } else { - return utf8_encode($object); - } - } - return $return; - } - - /** - * Returns true if $string is valid UTF-8 and false otherwise. - * - * @param mixed $str String to be tested - * @return boolean - */ - protected function is_utf8($str) - { - if (function_exists('mb_detect_encoding')) { - return ( - mb_detect_encoding($str, 'UTF-8', true) == 'UTF-8' && - ($str === null || $this->jsonEncode($str, true) !== 'null') - ); - } - $c = 0; - $b = 0; - $bits = 0; - $len = strlen($str); - for ($i = 0; $i < $len; $i++) { - $c = ord($str[$i]); - if ($c > 128) { - if (($c >= 254)) return false; - elseif ($c >= 252) $bits = 6; - elseif ($c >= 248) $bits = 5; - elseif ($c >= 240) $bits = 4; - elseif ($c >= 224) $bits = 3; - elseif ($c >= 192) $bits = 2; - else return false; - if (($i + $bits) > $len) return false; - while($bits > 1) { - $i++; - $b = ord($str[$i]); - if ($b < 128 || $b > 191) return false; - $bits--; - } - } - } - return ($str === null || $this->jsonEncode($str, true) !== 'null'); - } - - /** - * Converts to and from JSON format. - * - * JSON (JavaScript Object Notation) is a lightweight data-interchange - * format. It is easy for humans to read and write. It is easy for machines - * to parse and generate. It is based on a subset of the JavaScript - * Programming Language, Standard ECMA-262 3rd Edition - December 1999. - * This feature can also be found in Python. JSON is a text format that is - * completely language independent but uses conventions that are familiar - * to programmers of the C-family of languages, including C, C++, C#, Java, - * JavaScript, Perl, TCL, and many others. These properties make JSON an - * ideal data-interchange language. - * - * This package provides a simple encoder and decoder for JSON notation. It - * is intended for use with client-side Javascript applications that make - * use of HTTPRequest to perform server communication functions - data can - * be encoded into JSON notation for use in a client-side javascript, or - * decoded from incoming Javascript requests. JSON format is native to - * Javascript, and can be directly eval()'ed with no further parsing - * overhead - * - * All strings should be in ASCII or UTF-8 format! - * - * LICENSE: Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: Redistributions of source code must retain the - * above copyright notice, this list of conditions and the following - * disclaimer. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * @category - * @package Services_JSON - * @author Michal Migurski - * @author Matt Knapp - * @author Brett Stimmerman - * @author Christoph Dorn - * @copyright 2005 Michal Migurski - * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $ - * @license http://www.opensource.org/licenses/bsd-license.php - * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 - */ - - - /** - * Keep a list of objects as we descend into the array so we can detect recursion. - */ - private $json_objectStack = array(); - - - /** - * convert a string from one UTF-8 char to one UTF-16 char - * - * Normally should be handled by mb_convert_encoding, but - * provides a slower PHP-only method for installations - * that lack the multibye string extension. - * - * @param string $utf8 UTF-8 character - * @return string UTF-16 character - * @access private - */ - private function json_utf82utf16($utf8) - { - // oh please oh please oh please oh please oh please - if (function_exists('mb_convert_encoding')) { - return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); - } - - switch (strlen($utf8)) { - case 1: - // this case should never be reached, because we are in ASCII range - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return $utf8; - - case 2: - // return a UTF-16 character from a 2-byte UTF-8 char - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr(0x07 & (ord($utf8{0}) >> 2)) - . chr((0xC0 & (ord($utf8{0}) << 6)) - | (0x3F & ord($utf8{1}))); - - case 3: - // return a UTF-16 character from a 3-byte UTF-8 char - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr((0xF0 & (ord($utf8{0}) << 4)) - | (0x0F & (ord($utf8{1}) >> 2))) - . chr((0xC0 & (ord($utf8{1}) << 6)) - | (0x7F & ord($utf8{2}))); - } - - // ignoring UTF-32 for now, sorry - return ''; - } - - /** - * encodes an arbitrary variable into JSON format - * - * @param mixed $var any number, boolean, string, array, or object to be encoded. - * see argument 1 to Services_JSON() above for array-parsing behavior. - * if var is a strng, note that encode() always expects it - * to be in ASCII or UTF-8 format! - * - * @return mixed JSON string representation of input var or an error if a problem occurs - * @access public - */ - private function json_encode($var) - { - if (is_object($var)) { - if (in_array($var, $this->json_objectStack)) { - return '"** Recursion **"'; - } - } - - switch (gettype($var)) { - case 'boolean': - return $var ? 'true' : 'false'; - - case 'NULL': - return 'null'; - - case 'integer': - return (int) $var; - - case 'double': - case 'float': - return (float) $var; - - case 'string': - // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT - $ascii = ''; - $strlen_var = strlen($var); - - /* - * Iterate over every character in the string, - * escaping with a slash or encoding to UTF-8 where necessary - */ - for ($c = 0; $c < $strlen_var; ++$c) { - - $ord_var_c = ord($var{$c}); - - switch (true) { - case $ord_var_c == 0x08: - $ascii .= '\b'; - break; - case $ord_var_c == 0x09: - $ascii .= '\t'; - break; - case $ord_var_c == 0x0A: - $ascii .= '\n'; - break; - case $ord_var_c == 0x0C: - $ascii .= '\f'; - break; - case $ord_var_c == 0x0D: - $ascii .= '\r'; - break; - - case $ord_var_c == 0x22: - case $ord_var_c == 0x2F: - case $ord_var_c == 0x5C: - // double quote, slash, slosh - $ascii .= '\\' . $var{$c}; - break; - - case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): - // characters U-00000000 - U-0000007F (same as ASCII) - $ascii .= $var{$c}; - break; - - case (($ord_var_c & 0xE0) == 0xC0): - // characters U-00000080 - U-000007FF, mask 110XXXXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, ord($var{$c + 1})); - $c += 1; - $utf16 = $this->json_utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xF0) == 0xE0): - // characters U-00000800 - U-0000FFFF, mask 1110XXXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2})); - $c += 2; - $utf16 = $this->json_utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xF8) == 0xF0): - // characters U-00010000 - U-001FFFFF, mask 11110XXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3})); - $c += 3; - $utf16 = $this->json_utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xFC) == 0xF8): - // characters U-00200000 - U-03FFFFFF, mask 111110XX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3}), - ord($var{$c + 4})); - $c += 4; - $utf16 = $this->json_utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xFE) == 0xFC): - // characters U-04000000 - U-7FFFFFFF, mask 1111110X - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3}), - ord($var{$c + 4}), - ord($var{$c + 5})); - $c += 5; - $utf16 = $this->json_utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - } - } - - return '"' . $ascii . '"'; - - case 'array': - /* - * As per JSON spec if any array key is not an integer - * we must treat the the whole array as an object. We - * also try to catch a sparsely populated associative - * array with numeric keys here because some JS engines - * will create an array with empty indexes up to - * max_index which can cause memory issues and because - * the keys, which may be relevant, will be remapped - * otherwise. - * - * As per the ECMA and JSON specification an object may - * have any string as a property. Unfortunately due to - * a hole in the ECMA specification if the key is a - * ECMA reserved word or starts with a digit the - * parameter is only accessible using ECMAScript's - * bracket notation. - */ - - // treat as a JSON object - if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { - - $this->json_objectStack[] = $var; - - $properties = array_map(array($this, 'json_name_value'), - array_keys($var), - array_values($var)); - - array_pop($this->json_objectStack); - - foreach ($properties as $property) { - if ($property instanceof Exception) { - return $property; - } - } - - return '{' . join(',', $properties) . '}'; - } - - $this->json_objectStack[] = $var; - - // treat it like a regular array - $elements = array_map(array($this, 'json_encode'), $var); - - array_pop($this->json_objectStack); - - foreach ($elements as $element) { - if ($element instanceof Exception) { - return $element; - } - } - - return '[' . join(',', $elements) . ']'; - - case 'object': - $vars = self::encodeObject($var); - - $this->json_objectStack[] = $var; - - $properties = array_map(array($this, 'json_name_value'), - array_keys($vars), - array_values($vars)); - - array_pop($this->json_objectStack); - - foreach ($properties as $property) { - if ($property instanceof Exception) { - return $property; - } - } - - return '{' . join(',', $properties) . '}'; - - default: - return null; - } - } - - /** - * array-walking function for use in generating JSON-formatted name-value pairs - * - * @param string $name name of key to use - * @param mixed $value reference to an array element to be encoded - * - * @return string JSON-formatted name-value pair, like '"name":value' - * @access private - */ - private function json_name_value($name, $value) - { - // Encoding the $GLOBALS PHP array causes an infinite loop - // if the recursion is not reset here as it contains - // a reference to itself. This is the only way I have come up - // with to stop infinite recursion in this case. - if ($name == 'GLOBALS' - && is_array($value) - && array_key_exists('GLOBALS', $value)) { - $value['GLOBALS'] = '** Recursion **'; - } - - $encodedValue = $this->json_encode($value); - - if ($encodedValue instanceof Exception) { - return $encodedValue; - } - - return $this->json_encode(strval($name)) . ':' . $encodedValue; - } - - /** - * @deprecated - */ - public function setProcessorUrl($URL) - { - trigger_error('The FirePHP::setProcessorUrl() method is no longer supported', E_USER_DEPRECATED); - } - - /** - * @deprecated - */ - public function setRendererUrl($URL) - { - trigger_error('The FirePHP::setRendererUrl() method is no longer supported', E_USER_DEPRECATED); - } -} \ No newline at end of file diff --git a/htdocs/includes/firephp/firephp-core/lib/FirePHPCore/FirePHP.class.php4 b/htdocs/includes/firephp/firephp-core/lib/FirePHPCore/FirePHP.class.php4 deleted file mode 100644 index d702cea4a35..00000000000 --- a/htdocs/includes/firephp/firephp-core/lib/FirePHPCore/FirePHP.class.php4 +++ /dev/null @@ -1,1327 +0,0 @@ -, Copyright 2007, New BSD License -// - qbbr, Michael Day , Copyright 2008, New BSD License -// - cadorn, Christoph Dorn , Copyright 2011, MIT License - -/** - * *** BEGIN LICENSE BLOCK ***** - * - * [MIT License](http://www.opensource.org/licenses/mit-license.php) - * - * Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * ***** END LICENSE BLOCK ***** - * - * This verion of FirePHPCore is for use with PHP4. If you do not require PHP4 - * compatibility, it is suggested you use FirePHPCore.class.php instead. - * - * @copyright Copyright (C) 2007+ Christoph Dorn - * @author Christoph Dorn - * @author Michael Day - * @license [MIT License](http://www.opensource.org/licenses/mit-license.php) - * @package FirePHPCore - */ - -/** - * FirePHP version - * - * @var string - */ -define('FirePHP_VERSION', '0.3'); // @pinf replace '0.3' with '%%VERSION%%' - -/** - * Firebug LOG level - * - * Logs a message to firebug console - * - * @var string - */ -define('FirePHP_LOG', 'LOG'); - -/** - * Firebug INFO level - * - * Logs a message to firebug console and displays an info icon before the message - * - * @var string - */ -define('FirePHP_INFO', 'INFO'); - -/** - * Firebug WARN level - * - * Logs a message to firebug console, displays a warning icon before the message and colors the line turquoise - * - * @var string - */ -define('FirePHP_WARN', 'WARN'); - -/** - * Firebug ERROR level - * - * Logs a message to firebug console, displays an error icon before the message and colors the line yellow. Also increments the firebug error count. - * - * @var string - */ -define('FirePHP_ERROR', 'ERROR'); - -/** - * Dumps a variable to firebug's server panel - * - * @var string - */ -define('FirePHP_DUMP', 'DUMP'); - -/** - * Displays a stack trace in firebug console - * - * @var string - */ -define('FirePHP_TRACE', 'TRACE'); - -/** - * Displays a table in firebug console - * - * @var string - */ -define('FirePHP_TABLE', 'TABLE'); - -/** - * Starts a group in firebug console - * - * @var string - */ -define('FirePHP_GROUP_START', 'GROUP_START'); - -/** - * Ends a group in firebug console - * - * @var string - */ -define('FirePHP_GROUP_END', 'GROUP_END'); - -/** - * Sends the given data to the FirePHP Firefox Extension. - * The data can be displayed in the Firebug Console or in the - * "Server" request tab. - * - * For more information see: http://www.firephp.org/ - * - * @copyright Copyright (C) 2007+ Christoph Dorn - * @author Christoph Dorn - * @author Michael Day - * @license [MIT License](http://www.opensource.org/licenses/mit-license.php) - * @package FirePHPCore - */ -class FirePHP { - /** - * Wildfire protocol message index - * - * @var int - */ - var $messageIndex = 1; - - /** - * Options for the library - * - * @var array - */ - var $options = array('maxObjectDepth' => 5, - 'maxArrayDepth' => 5, - 'useNativeJsonEncode' => true, - 'includeLineNumbers' => true); - - /** - * Filters used to exclude object members when encoding - * - * @var array - */ - var $objectFilters = array(); - - /** - * A stack of objects used to detect recursion during object encoding - * - * @var object - */ - var $objectStack = array(); - - /** - * Flag to enable/disable logging - * - * @var boolean - */ - var $enabled = true; - - /** - * The object constructor - */ - function FirePHP() { - } - - - /** - * When the object gets serialized only include specific object members. - * - * @return array - */ - function __sleep() { - return array('options','objectFilters','enabled'); - } - - /** - * Gets singleton instance of FirePHP - * - * @param boolean $AutoCreate - * @return FirePHP - */ - function &getInstance($AutoCreate=false) { - global $FirePHP_Instance; - - if($AutoCreate===true && !$FirePHP_Instance) { - $FirePHP_Instance = new FirePHP(); - } - - return $FirePHP_Instance; - } - - /** - * Enable and disable logging to Firebug - * - * @param boolean $Enabled TRUE to enable, FALSE to disable - * @return void - */ - function setEnabled($Enabled) { - $this->enabled = $Enabled; - } - - /** - * Check if logging is enabled - * - * @return boolean TRUE if enabled - */ - function getEnabled() { - return $this->enabled; - } - - /** - * Specify a filter to be used when encoding an object - * - * Filters are used to exclude object members. - * - * @param string $Class The class name of the object - * @param array $Filter An array of members to exclude - * @return void - */ - function setObjectFilter($Class, $Filter) { - $this->objectFilters[strtolower($Class)] = $Filter; - } - - /** - * Set some options for the library - * - * Options: - * - maxObjectDepth: The maximum depth to traverse objects (default: 5) - * - maxArrayDepth: The maximum depth to traverse arrays (default: 5) - * - useNativeJsonEncode: If true will use json_encode() (default: true) - * - includeLineNumbers: If true will include line numbers and filenames (default: true) - * - * @param array $Options The options to be set - * @return void - */ - function setOptions($Options) { - $this->options = array_merge($this->options,$Options); - } - - /** - * Get options from the library - * - * @return array The currently set options - */ - function getOptions() { - return $this->options; - } - - /** - * Register FirePHP as your error handler - * - * Will use FirePHP to log each php error. - * - * @return mixed Returns a string containing the previously defined error handler (if any) - */ - function registerErrorHandler() - { - //NOTE: The following errors will not be caught by this error handler: - // E_ERROR, E_PARSE, E_CORE_ERROR, - // E_CORE_WARNING, E_COMPILE_ERROR, - // E_COMPILE_WARNING, E_STRICT - - return set_error_handler(array($this,'errorHandler')); - } - - /** - * FirePHP's error handler - * - * Logs each php error that will occur. - * - * @param int $errno - * @param string $errstr - * @param string $errfile - * @param int $errline - * @param array $errcontext - */ - function errorHandler($errno, $errstr, $errfile, $errline, $errcontext) - { - global $FirePHP_Instance; - // Don't log error if error reporting is switched off - if (error_reporting() == 0) { - return; - } - // Only log error for errors we are asking for - if (error_reporting() & $errno) { - $FirePHP_Instance->group($errstr); - $FirePHP_Instance->error("{$errfile}, line $errline"); - $FirePHP_Instance->groupEnd(); - } - } - - /** - * Register FirePHP driver as your assert callback - * - * @return mixed Returns the original setting - */ - function registerAssertionHandler() - { - return assert_options(ASSERT_CALLBACK, array($this, 'assertionHandler')); - } - - /** - * FirePHP's assertion handler - * - * Logs all assertions to your firebug console and then stops the script. - * - * @param string $file File source of assertion - * @param int $line Line source of assertion - * @param mixed $code Assertion code - */ - function assertionHandler($file, $line, $code) - { - $this->fb($code, 'Assertion Failed', FirePHP_ERROR, array('File'=>$file,'Line'=>$line)); - } - - /** - * Set custom processor url for FirePHP - * - * @param string $URL - */ - function setProcessorUrl($URL) - { - $this->setHeader('X-FirePHP-ProcessorURL', $URL); - } - - /** - * Set custom renderer url for FirePHP - * - * @param string $URL - */ - function setRendererUrl($URL) - { - $this->setHeader('X-FirePHP-RendererURL', $URL); - } - - /** - * Start a group for following messages. - * - * Options: - * Collapsed: [true|false] - * Color: [#RRGGBB|ColorName] - * - * @param string $Name - * @param array $Options OPTIONAL Instructions on how to log the group - * @return true - * @throws Exception - */ - function group($Name, $Options=null) { - - if(!$Name) { - trigger_error('You must specify a label for the group!'); - } - - if($Options) { - if(!is_array($Options)) { - trigger_error('Options must be defined as an array!'); - } - if(array_key_exists('Collapsed', $Options)) { - $Options['Collapsed'] = ($Options['Collapsed'])?'true':'false'; - } - } - - return $this->fb(null, $Name, FirePHP_GROUP_START, $Options); - } - - /** - * Ends a group you have started before - * - * @return true - * @throws Exception - */ - function groupEnd() { - return $this->fb(null, null, FirePHP_GROUP_END); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::LOG - * @param mixes $Object - * @param string $Label - * @return true - * @throws Exception - */ - function log($Object, $Label=null) { - return $this->fb($Object, $Label, FirePHP_LOG); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::INFO - * @param mixes $Object - * @param string $Label - * @return true - * @throws Exception - */ - function info($Object, $Label=null) { - return $this->fb($Object, $Label, FirePHP_INFO); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::WARN - * @param mixes $Object - * @param string $Label - * @return true - * @throws Exception - */ - function warn($Object, $Label=null) { - return $this->fb($Object, $Label, FirePHP_WARN); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::ERROR - * @param mixes $Object - * @param string $Label - * @return true - * @throws Exception - */ - function error($Object, $Label=null) { - return $this->fb($Object, $Label, FirePHP_ERROR); - } - - /** - * Dumps key and variable to firebug server panel - * - * @see FirePHP::DUMP - * @param string $Key - * @param mixed $Variable - * @return true - * @throws Exception - */ - function dump($Key, $Variable) { - return $this->fb($Variable, $Key, FirePHP_DUMP); - } - - /** - * Log a trace in the firebug console - * - * @see FirePHP::TRACE - * @param string $Label - * @return true - * @throws Exception - */ - function trace($Label) { - return $this->fb($Label, FirePHP_TRACE); - } - - /** - * Log a table in the firebug console - * - * @see FirePHP::TABLE - * @param string $Label - * @param string $Table - * @return true - * @throws Exception - */ - function table($Label, $Table) { - return $this->fb($Table, $Label, FirePHP_TABLE); - } - - /** - * Check if FirePHP is installed on client - * - * @return boolean - */ - function detectClientExtension() { - // Check if FirePHP is installed on client via User-Agent header - if(@preg_match_all('/\sFirePHP\/([\.\d]*)\s?/si',$this->getUserAgent(),$m) && - version_compare($m[1][0],'0.0.6','>=')) { - return true; - } else - // Check if FirePHP is installed on client via X-FirePHP-Version header - if(@preg_match_all('/^([\.\d]*)$/si',$this->getRequestHeader("X-FirePHP-Version"),$m) && - version_compare($m[1][0],'0.0.6','>=')) { - return true; - } - return false; - } - - /** - * Log varible to Firebug - * - * @see http://www.firephp.org/Wiki/Reference/Fb - * @param mixed $Object The variable to be logged - * @return true Return TRUE if message was added to headers, FALSE otherwise - * @throws Exception - */ - function fb($Object) { - - if(!$this->enabled) { - return false; - } - - if (headers_sent($filename, $linenum)) { - trigger_error('Headers already sent in '.$filename.' on line '.$linenum.'. Cannot send log data to FirePHP. You must have Output Buffering enabled via ob_start() or output_buffering ini directive.'); - } - - $Type = null; - $Label = null; - $Options = array(); - - if(func_num_args()==1) { - } else - if(func_num_args()==2) { - switch(func_get_arg(1)) { - case FirePHP_LOG: - case FirePHP_INFO: - case FirePHP_WARN: - case FirePHP_ERROR: - case FirePHP_DUMP: - case FirePHP_TRACE: - case FirePHP_TABLE: - case FirePHP_GROUP_START: - case FirePHP_GROUP_END: - $Type = func_get_arg(1); - break; - default: - $Label = func_get_arg(1); - break; - } - } else - if(func_num_args()==3) { - $Type = func_get_arg(2); - $Label = func_get_arg(1); - } else - if(func_num_args()==4) { - $Type = func_get_arg(2); - $Label = func_get_arg(1); - $Options = func_get_arg(3); - } else { - trigger_error('Wrong number of arguments to fb() function!'); - } - - - if(!$this->detectClientExtension()) { - return false; - } - - $meta = array(); - $skipFinalObjectEncode = false; - - if($Type==FirePHP_TRACE) { - - $trace = debug_backtrace(); - if(!$trace) return false; - for( $i=0 ; $i_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php' - || substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) { - /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */ - } else - if(isset($trace[$i]['class']) - && isset($trace[$i+1]['file']) - && $trace[$i]['class']=='FirePHP' - && substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') { - /* Skip fb() */ - } else - if($trace[$i]['function']=='fb' - || $trace[$i]['function']=='trace' - || $trace[$i]['function']=='send') { - $Object = array('Class'=>isset($trace[$i]['class'])?$trace[$i]['class']:'', - 'Type'=>isset($trace[$i]['type'])?$trace[$i]['type']:'', - 'Function'=>isset($trace[$i]['function'])?$trace[$i]['function']:'', - 'Message'=>$trace[$i]['args'][0], - 'File'=>isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):'', - 'Line'=>isset($trace[$i]['line'])?$trace[$i]['line']:'', - 'Args'=>isset($trace[$i]['args'])?$this->encodeObject($trace[$i]['args']):'', - 'Trace'=>$this->_escapeTrace(array_splice($trace,$i+1))); - - $skipFinalObjectEncode = true; - $meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):''; - $meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:''; - break; - } - } - - } else - if($Type==FirePHP_TABLE) { - - if(isset($Object[0]) && is_string($Object[0])) { - $Object[1] = $this->encodeTable($Object[1]); - } else { - $Object = $this->encodeTable($Object); - } - - $skipFinalObjectEncode = true; - - } else - if($Type==FirePHP_GROUP_START) { - - if(!$Label) { - trigger_error('You must specify a label for the group!'); - } - } else { - if($Type===null) { - $Type = FirePHP_LOG; - } - } - - if($this->options['includeLineNumbers']) { - if(!isset($meta['file']) || !isset($meta['line'])) { - - $trace = debug_backtrace(); - for( $i=0 ; $trace && $i_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php' - || substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) { - /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */ - } else - if(isset($trace[$i]['class']) - && isset($trace[$i+1]['file']) - && $trace[$i]['class']=='FirePHP' - && substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') { - /* Skip fb() */ - } else - if(isset($trace[$i]['file']) - && substr($this->_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php') { - /* Skip FB::fb() */ - } else { - $meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):''; - $meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:''; - break; - } - } - - } - } else { - unset($meta['file']); - unset($meta['line']); - } - - $this->setHeader('X-Wf-Protocol-1','http://meta.wildfirehq.org/Protocol/JsonStream/0.2'); - $this->setHeader('X-Wf-1-Plugin-1','http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/'.FirePHP_VERSION); - - $structure_index = 1; - if($Type==FirePHP_DUMP) { - $structure_index = 2; - $this->setHeader('X-Wf-1-Structure-2','http://meta.firephp.org/Wildfire/Structure/FirePHP/Dump/0.1'); - } else { - $this->setHeader('X-Wf-1-Structure-1','http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1'); - } - - if($Type==FirePHP_DUMP) { - $msg = '{"'.$Label.'":'.$this->jsonEncode($Object, $skipFinalObjectEncode).'}'; - } else { - $msg_meta = $Options; - $msg_meta['Type'] = $Type; - if($Label!==null) { - $msg_meta['Label'] = $Label; - } - if(isset($meta['file']) && !isset($msg_meta['File'])) { - $msg_meta['File'] = $meta['file']; - } - if(isset($meta['line']) && !isset($msg_meta['Line'])) { - $msg_meta['Line'] = $meta['line']; - } - $msg = '['.$this->jsonEncode($msg_meta).','.$this->jsonEncode($Object, $skipFinalObjectEncode).']'; - } - - $parts = explode("\n",chunk_split($msg, 5000, "\n")); - - for( $i=0 ; $i2) { - // Message needs to be split into multiple parts - $this->setHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex, - (($i==0)?strlen($msg):'') - . '|' . $part . '|' - . (($isetHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex, - strlen($part) . '|' . $part . '|'); - } - - $this->messageIndex++; - - if ($this->messageIndex > 99999) { - trigger_error('Maximum number (99,999) of messages reached!'); - } - } - } - - $this->setHeader('X-Wf-1-Index',$this->messageIndex-1); - - return true; - } - - - /** - * Standardizes path for windows systems. - * - * @param string $Path - * @return string - */ - function _standardizePath($Path) { - return preg_replace('/\\\\+/','/',$Path); - } - - /** - * Escape trace path for windows systems - * - * @param array $Trace - * @return array - */ - function _escapeTrace($Trace) { - if(!$Trace) return $Trace; - for( $i=0 ; $i_escapeTraceFile($Trace[$i]['file']); - } - if(isset($Trace[$i]['args'])) { - $Trace[$i]['args'] = $this->encodeObject($Trace[$i]['args']); - } - } - return $Trace; - } - - /** - * Escape file information of trace for windows systems - * - * @param string $File - * @return string - */ - function _escapeTraceFile($File) { - /* Check if we have a windows filepath */ - if(strpos($File,'\\')) { - /* First strip down to single \ */ - - $file = preg_replace('/\\\\+/','\\',$File); - - return $file; - } - return $File; - } - - /** - * Send header - * - * @param string $Name - * @param string_type $Value - */ - function setHeader($Name, $Value) { - return header($Name.': '.$Value); - } - - /** - * Get user agent - * - * @return string|false - */ - function getUserAgent() { - if(!isset($_SERVER['HTTP_USER_AGENT'])) return false; - return $_SERVER['HTTP_USER_AGENT']; - } - - /** - * Get all request headers - * - * @return array - */ - function getAllRequestHeaders() { - $headers = array(); - if(function_exists('getallheaders')) { - foreach( getallheaders() as $name => $value ) { - $headers[strtolower($name)] = $value; - } - } else { - foreach($_SERVER as $name => $value) { - if(substr($name, 0, 5) == 'HTTP_') { - $headers[strtolower(str_replace(' ', '-', str_replace('_', ' ', substr($name, 5))))] = $value; - } - } - } - return $headers; - } - - /** - * Get a request header - * - * @return string|false - */ - function getRequestHeader($Name) - { - $headers = $this->getAllRequestHeaders(); - if (isset($headers[strtolower($Name)])) { - return $headers[strtolower($Name)]; - } - return false; - } - - /** - * Encode an object into a JSON string - * - * Uses PHP's jeson_encode() if available - * - * @param object $Object The object to be encoded - * @return string The JSON string - */ - function jsonEncode($Object, $skipObjectEncode=false) - { - if(!$skipObjectEncode) { - $Object = $this->encodeObject($Object); - } - - if(function_exists('json_encode') - && $this->options['useNativeJsonEncode']!=false) { - - return json_encode($Object); - } else { - return $this->json_encode($Object); - } - } - - /** - * Encodes a table by encoding each row and column with encodeObject() - * - * @param array $Table The table to be encoded - * @return array - */ - function encodeTable($Table) { - - if(!$Table) return $Table; - - $new_table = array(); - foreach($Table as $row) { - - if(is_array($row)) { - $new_row = array(); - - foreach($row as $item) { - $new_row[] = $this->encodeObject($item); - } - - $new_table[] = $new_row; - } - } - - return $new_table; - } - - /** - * Encodes an object - * - * @param Object $Object The object to be encoded - * @param int $Depth The current traversal depth - * @return array All members of the object - */ - function encodeObject($Object, $ObjectDepth = 1, $ArrayDepth = 1) - { - $return = array(); - - if (is_resource($Object)) { - - return '** '.(string)$Object.' **'; - - } else - if (is_object($Object)) { - - if ($ObjectDepth > $this->options['maxObjectDepth']) { - return '** Max Object Depth ('.$this->options['maxObjectDepth'].') **'; - } - - foreach ($this->objectStack as $refVal) { - if ($refVal === $Object) { - return '** Recursion ('.get_class($Object).') **'; - } - } - array_push($this->objectStack, $Object); - - $return['__className'] = $class = get_class($Object); - $class_lower = strtolower($class); - - $members = (array)$Object; - - // Include all members that are not defined in the class - // but exist in the object - foreach( $members as $raw_name => $value ) { - - $name = $raw_name; - - if ($name{0} == "\0") { - $parts = explode("\0", $name); - $name = $parts[2]; - } - - if(!isset($properties[$name])) { - $name = 'undeclared:'.$name; - - if(!(isset($this->objectFilters[$class_lower]) - && is_array($this->objectFilters[$class_lower]) - && in_array($raw_name,$this->objectFilters[$class_lower]))) { - - $return[$name] = $this->encodeObject($value, $ObjectDepth + 1, 1); - } else { - $return[$name] = '** Excluded by Filter **'; - } - } - } - - array_pop($this->objectStack); - - } elseif (is_array($Object)) { - - if ($ArrayDepth > $this->options['maxArrayDepth']) { - return '** Max Array Depth ('.$this->options['maxArrayDepth'].') **'; - } - - foreach ($Object as $key => $val) { - - // Encoding the $GLOBALS PHP array causes an infinite loop - // if the recursion is not reset here as it contains - // a reference to itself. This is the only way I have come up - // with to stop infinite recursion in this case. - if($key=='GLOBALS' - && is_array($val) - && array_key_exists('GLOBALS',$val)) { - $val['GLOBALS'] = '** Recursion (GLOBALS) **'; - } - - $return[$key] = $this->encodeObject($val, 1, $ArrayDepth + 1); - } - } else { - if($this->is_utf8($Object)) { - return $Object; - } else { - return utf8_encode($Object); - } - } - return $return; - - } - - /** - * Returns true if $string is valid UTF-8 and false otherwise. - * - * @param mixed $str String to be tested - * @return boolean - */ - function is_utf8($str) { - $c=0; $b=0; - $bits=0; - $len=strlen($str); - for($i=0; $i<$len; $i++){ - $c=ord($str[$i]); - if($c > 128){ - if(($c >= 254)) return false; - elseif($c >= 252) $bits=6; - elseif($c >= 248) $bits=5; - elseif($c >= 240) $bits=4; - elseif($c >= 224) $bits=3; - elseif($c >= 192) $bits=2; - else return false; - if(($i+$bits) > $len) return false; - while($bits > 1){ - $i++; - $b=ord($str[$i]); - if($b < 128 || $b > 191) return false; - $bits--; - } - } - } - return true; - } - - /** - * Converts to and from JSON format. - * - * JSON (JavaScript Object Notation) is a lightweight data-interchange - * format. It is easy for humans to read and write. It is easy for machines - * to parse and generate. It is based on a subset of the JavaScript - * Programming Language, Standard ECMA-262 3rd Edition - December 1999. - * This feature can also be found in Python. JSON is a text format that is - * completely language independent but uses conventions that are familiar - * to programmers of the C-family of languages, including C, C++, C#, Java, - * JavaScript, Perl, TCL, and many others. These properties make JSON an - * ideal data-interchange language. - * - * This package provides a simple encoder and decoder for JSON notation. It - * is intended for use with client-side Javascript applications that make - * use of HTTPRequest to perform server communication functions - data can - * be encoded into JSON notation for use in a client-side javascript, or - * decoded from incoming Javascript requests. JSON format is native to - * Javascript, and can be directly eval()'ed with no further parsing - * overhead - * - * All strings should be in ASCII or UTF-8 format! - * - * LICENSE: Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: Redistributions of source code must retain the - * above copyright notice, this list of conditions and the following - * disclaimer. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * @category - * @package Services_JSON - * @author Michal Migurski - * @author Matt Knapp - * @author Brett Stimmerman - * @author Christoph Dorn - * @copyright 2005 Michal Migurski - * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $ - * @license http://www.opensource.org/licenses/bsd-license.php - * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 - */ - - - /** - * Keep a list of objects as we descend into the array so we can detect recursion. - */ - var $json_objectStack = array(); - - - /** - * convert a string from one UTF-8 char to one UTF-16 char - * - * Normally should be handled by mb_convert_encoding, but - * provides a slower PHP-only method for installations - * that lack the multibye string extension. - * - * @param string $utf8 UTF-8 character - * @return string UTF-16 character - * @access private - */ - function json_utf82utf16($utf8) - { - // oh please oh please oh please oh please oh please - if(function_exists('mb_convert_encoding')) { - return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); - } - - switch(strlen($utf8)) { - case 1: - // this case should never be reached, because we are in ASCII range - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return $utf8; - - case 2: - // return a UTF-16 character from a 2-byte UTF-8 char - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr(0x07 & (ord($utf8{0}) >> 2)) - . chr((0xC0 & (ord($utf8{0}) << 6)) - | (0x3F & ord($utf8{1}))); - - case 3: - // return a UTF-16 character from a 3-byte UTF-8 char - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr((0xF0 & (ord($utf8{0}) << 4)) - | (0x0F & (ord($utf8{1}) >> 2))) - . chr((0xC0 & (ord($utf8{1}) << 6)) - | (0x7F & ord($utf8{2}))); - } - - // ignoring UTF-32 for now, sorry - return ''; - } - - /** - * encodes an arbitrary variable into JSON format - * - * @param mixed $var any number, boolean, string, array, or object to be encoded. - * see argument 1 to Services_JSON() above for array-parsing behavior. - * if var is a strng, note that encode() always expects it - * to be in ASCII or UTF-8 format! - * - * @return mixed JSON string representation of input var or an error if a problem occurs - * @access public - */ - function json_encode($var) - { - - if(is_object($var)) { - if(in_array($var,$this->json_objectStack)) { - return '"** Recursion **"'; - } - } - - switch (gettype($var)) { - case 'boolean': - return $var ? 'true' : 'false'; - - case 'NULL': - return 'null'; - - case 'integer': - return (int) $var; - - case 'double': - case 'float': - return (float) $var; - - case 'string': - // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT - $ascii = ''; - $strlen_var = strlen($var); - - /* - * Iterate over every character in the string, - * escaping with a slash or encoding to UTF-8 where necessary - */ - for ($c = 0; $c < $strlen_var; ++$c) { - - $ord_var_c = ord($var{$c}); - - switch (true) { - case $ord_var_c == 0x08: - $ascii .= '\b'; - break; - case $ord_var_c == 0x09: - $ascii .= '\t'; - break; - case $ord_var_c == 0x0A: - $ascii .= '\n'; - break; - case $ord_var_c == 0x0C: - $ascii .= '\f'; - break; - case $ord_var_c == 0x0D: - $ascii .= '\r'; - break; - - case $ord_var_c == 0x22: - case $ord_var_c == 0x2F: - case $ord_var_c == 0x5C: - // double quote, slash, slosh - $ascii .= '\\'.$var{$c}; - break; - - case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): - // characters U-00000000 - U-0000007F (same as ASCII) - $ascii .= $var{$c}; - break; - - case (($ord_var_c & 0xE0) == 0xC0): - // characters U-00000080 - U-000007FF, mask 110XXXXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, ord($var{$c + 1})); - $c += 1; - $utf16 = $this->json_utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xF0) == 0xE0): - // characters U-00000800 - U-0000FFFF, mask 1110XXXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2})); - $c += 2; - $utf16 = $this->json_utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xF8) == 0xF0): - // characters U-00010000 - U-001FFFFF, mask 11110XXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3})); - $c += 3; - $utf16 = $this->json_utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xFC) == 0xF8): - // characters U-00200000 - U-03FFFFFF, mask 111110XX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3}), - ord($var{$c + 4})); - $c += 4; - $utf16 = $this->json_utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xFE) == 0xFC): - // characters U-04000000 - U-7FFFFFFF, mask 1111110X - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3}), - ord($var{$c + 4}), - ord($var{$c + 5})); - $c += 5; - $utf16 = $this->json_utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - } - } - - return '"'.$ascii.'"'; - - case 'array': - /* - * As per JSON spec if any array key is not an integer - * we must treat the the whole array as an object. We - * also try to catch a sparsely populated associative - * array with numeric keys here because some JS engines - * will create an array with empty indexes up to - * max_index which can cause memory issues and because - * the keys, which may be relevant, will be remapped - * otherwise. - * - * As per the ECMA and JSON specification an object may - * have any string as a property. Unfortunately due to - * a hole in the ECMA specification if the key is a - * ECMA reserved word or starts with a digit the - * parameter is only accessible using ECMAScript's - * bracket notation. - */ - - // treat as a JSON object - if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { - - $this->json_objectStack[] = $var; - - $properties = array_map(array($this, 'json_name_value'), - array_keys($var), - array_values($var)); - - array_pop($this->json_objectStack); - - return '{' . join(',', $properties) . '}'; - } - - $this->json_objectStack[] = $var; - - // treat it like a regular array - $elements = array_map(array($this, 'json_encode'), $var); - - array_pop($this->json_objectStack); - - return '[' . join(',', $elements) . ']'; - - case 'object': - $vars = FirePHP::encodeObject($var); - - $this->json_objectStack[] = $var; - - $properties = array_map(array($this, 'json_name_value'), - array_keys($vars), - array_values($vars)); - - array_pop($this->json_objectStack); - - return '{' . join(',', $properties) . '}'; - - default: - return null; - } - } - - /** - * array-walking function for use in generating JSON-formatted name-value pairs - * - * @param string $name name of key to use - * @param mixed $value reference to an array element to be encoded - * - * @return string JSON-formatted name-value pair, like '"name":value' - * @access private - */ - function json_name_value($name, $value) - { - // Encoding the $GLOBALS PHP array causes an infinite loop - // if the recursion is not reset here as it contains - // a reference to itself. This is the only way I have come up - // with to stop infinite recursion in this case. - if($name=='GLOBALS' - && is_array($value) - && array_key_exists('GLOBALS',$value)) { - $value['GLOBALS'] = '** Recursion **'; - } - - $encoded_value = $this->json_encode($value); - - return $this->json_encode(strval($name)) . ':' . $encoded_value; - } -} - diff --git a/htdocs/includes/firephp/firephp-core/lib/FirePHPCore/fb.php b/htdocs/includes/firephp/firephp-core/lib/FirePHPCore/fb.php deleted file mode 100644 index 8827ba15d97..00000000000 --- a/htdocs/includes/firephp/firephp-core/lib/FirePHPCore/fb.php +++ /dev/null @@ -1,275 +0,0 @@ -, Copyright 2007, New BSD License -// - qbbr, Sokolov Innokenty , Copyright 2011, New BSD License -// - cadorn, Christoph Dorn , Copyright 2011, MIT License - -/** - * ***** BEGIN LICENSE BLOCK ***** - * - * [MIT License](http://www.opensource.org/licenses/mit-license.php) - * - * Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * ***** END LICENSE BLOCK ***** - * - * @copyright Copyright (C) 2007+ Christoph Dorn - * @author Christoph Dorn - * @license [MIT License](http://www.opensource.org/licenses/mit-license.php) - * @package FirePHPCore - */ - -if (!class_exists('FirePHP', false)) { - require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'FirePHP.class.php'; -} - -/** - * Sends the given data to the FirePHP Firefox Extension. - * The data can be displayed in the Firebug Console or in the - * "Server" request tab. - * - * @see http://www.firephp.org/Wiki/Reference/Fb - * @param mixed $Object - * @return true - * @throws Exception - */ -function fb() -{ - $instance = FirePHP::getInstance(true); - - $args = func_get_args(); - return call_user_func_array(array($instance, 'fb'), $args); -} - - -class FB -{ - /** - * Set an Insight console to direct all logging calls to - * - * @param object $console The console object to log to - * @return void - */ - public static function setLogToInsightConsole($console) - { - FirePHP::getInstance(true)->setLogToInsightConsole($console); - } - - /** - * Enable and disable logging to Firebug - * - * @see FirePHP->setEnabled() - * @param boolean $enabled TRUE to enable, FALSE to disable - * @return void - */ - public static function setEnabled($enabled) - { - FirePHP::getInstance(true)->setEnabled($enabled); - } - - /** - * Check if logging is enabled - * - * @see FirePHP->getEnabled() - * @return boolean TRUE if enabled - */ - public static function getEnabled() - { - return FirePHP::getInstance(true)->getEnabled(); - } - - /** - * Specify a filter to be used when encoding an object - * - * Filters are used to exclude object members. - * - * @see FirePHP->setObjectFilter() - * @param string $class The class name of the object - * @param array $filter An array or members to exclude - * @return void - */ - public static function setObjectFilter($class, $filter) - { - FirePHP::getInstance(true)->setObjectFilter($class, $filter); - } - - /** - * Set some options for the library - * - * @see FirePHP->setOptions() - * @param array $options The options to be set - * @return void - */ - public static function setOptions($options) - { - FirePHP::getInstance(true)->setOptions($options); - } - - /** - * Get options for the library - * - * @see FirePHP->getOptions() - * @return array The options - */ - public static function getOptions() - { - return FirePHP::getInstance(true)->getOptions(); - } - - /** - * Log object to firebug - * - * @see http://www.firephp.org/Wiki/Reference/Fb - * @param mixed $object - * @return true - * @throws Exception - */ - public static function send() - { - $args = func_get_args(); - return call_user_func_array(array(FirePHP::getInstance(true), 'fb'), $args); - } - - /** - * Start a group for following messages - * - * Options: - * Collapsed: [true|false] - * Color: [#RRGGBB|ColorName] - * - * @param string $name - * @param array $options OPTIONAL Instructions on how to log the group - * @return true - */ - public static function group($name, $options=null) - { - return FirePHP::getInstance(true)->group($name, $options); - } - - /** - * Ends a group you have started before - * - * @return true - * @throws Exception - */ - public static function groupEnd() - { - return self::send(null, null, FirePHP::GROUP_END); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::LOG - * @param mixes $object - * @param string $label - * @return true - * @throws Exception - */ - public static function log($object, $label=null) - { - return self::send($object, $label, FirePHP::LOG); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::INFO - * @param mixes $object - * @param string $label - * @return true - * @throws Exception - */ - public static function info($object, $label=null) - { - return self::send($object, $label, FirePHP::INFO); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::WARN - * @param mixes $object - * @param string $label - * @return true - * @throws Exception - */ - public static function warn($object, $label=null) - { - return self::send($object, $label, FirePHP::WARN); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::ERROR - * @param mixes $object - * @param string $label - * @return true - * @throws Exception - */ - public static function error($object, $label=null) - { - return self::send($object, $label, FirePHP::ERROR); - } - - /** - * Dumps key and variable to firebug server panel - * - * @see FirePHP::DUMP - * @param string $key - * @param mixed $variable - * @return true - * @throws Exception - */ - public static function dump($key, $variable) - { - return self::send($variable, $key, FirePHP::DUMP); - } - - /** - * Log a trace in the firebug console - * - * @see FirePHP::TRACE - * @param string $label - * @return true - * @throws Exception - */ - public static function trace($label) - { - return self::send($label, FirePHP::TRACE); - } - - /** - * Log a table in the firebug console - * - * @see FirePHP::TABLE - * @param string $label - * @param string $table - * @return true - * @throws Exception - */ - public static function table($label, $table) - { - return self::send($table, $label, FirePHP::TABLE); - } - -} \ No newline at end of file diff --git a/htdocs/includes/firephp/firephp-core/lib/FirePHPCore/fb.php4 b/htdocs/includes/firephp/firephp-core/lib/FirePHPCore/fb.php4 deleted file mode 100644 index eab2f0f681b..00000000000 --- a/htdocs/includes/firephp/firephp-core/lib/FirePHPCore/fb.php4 +++ /dev/null @@ -1,245 +0,0 @@ -, Copyright 2007, New BSD License -// - qbbr, Michael Day , Copyright 2008, New BSD License -// - cadorn, Christoph Dorn , Copyright 2011, MIT License - -/* ***** BEGIN LICENSE BLOCK ***** - * - * [MIT License](http://www.opensource.org/licenses/mit-license.php) - * - * Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * ***** END LICENSE BLOCK ***** - * - * @copyright Copyright (C) 2007+ Christoph Dorn - * @author Christoph Dorn - * @author Michael Day - * @license [MIT License](http://www.opensource.org/licenses/mit-license.php) - * @package FirePHPCore - */ - -require_once dirname(__FILE__).'/FirePHP.class.php4'; - -/** - * Sends the given data to the FirePHP Firefox Extension. - * The data can be displayed in the Firebug Console or in the - * "Server" request tab. - * - * @see http://www.firephp.org/Wiki/Reference/Fb - * @param mixed $Object - * @return true - * @throws Exception - */ -function fb() -{ - $instance =& FirePHP::getInstance(true); - - $args = func_get_args(); - return call_user_func_array(array(&$instance,'fb'),$args); -} - - -class FB -{ - /** - * Enable and disable logging to Firebug - * - * @see FirePHP->setEnabled() - * @param boolean $Enabled TRUE to enable, FALSE to disable - * @return void - */ - function setEnabled($Enabled) { - $instance =& FirePHP::getInstance(true); - $instance->setEnabled($Enabled); - } - - /** - * Check if logging is enabled - * - * @see FirePHP->getEnabled() - * @return boolean TRUE if enabled - */ - function getEnabled() { - $instance =& FirePHP::getInstance(true); - return $instance->getEnabled(); - } - - /** - * Specify a filter to be used when encoding an object - * - * Filters are used to exclude object members. - * - * @see FirePHP->setObjectFilter() - * @param string $Class The class name of the object - * @param array $Filter An array or members to exclude - * @return void - */ - function setObjectFilter($Class, $Filter) { - $instance =& FirePHP::getInstance(true); - $instance->setObjectFilter($Class, $Filter); - } - - /** - * Set some options for the library - * - * @see FirePHP->setOptions() - * @param array $Options The options to be set - * @return void - */ - function setOptions($Options) { - $instance =& FirePHP::getInstance(true); - $instance->setOptions($Options); - } - - /** - * Get options for the library - * - * @see FirePHP->getOptions() - * @return array The options - */ - function getOptions() { - $instance =& FirePHP::getInstance(true); - return $instance->getOptions(); - } - - /** - * Log object to firebug - * - * @see http://www.firephp.org/Wiki/Reference/Fb - * @param mixed $Object - * @return true - */ - function send() - { - $instance =& FirePHP::getInstance(true); - $args = func_get_args(); - return call_user_func_array(array(&$instance,'fb'),$args); - } - - /** - * Start a group for following messages - * - * Options: - * Collapsed: [true|false] - * Color: [#RRGGBB|ColorName] - * - * @param string $Name - * @param array $Options OPTIONAL Instructions on how to log the group - * @return true - */ - function group($Name, $Options=null) { - $instance =& FirePHP::getInstance(true); - return $instance->group($Name, $Options); - } - - /** - * Ends a group you have started before - * - * @return true - */ - function groupEnd() { - return FB::send(null, null, FirePHP_GROUP_END); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::LOG - * @param mixes $Object - * @param string $Label - * @return true - */ - function log($Object, $Label=null) { - return FB::send($Object, $Label, FirePHP_LOG); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::INFO - * @param mixes $Object - * @param string $Label - * @return true - */ - function info($Object, $Label=null) { - return FB::send($Object, $Label, FirePHP_INFO); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::WARN - * @param mixes $Object - * @param string $Label - * @return true - */ - function warn($Object, $Label=null) { - return FB::send($Object, $Label, FirePHP_WARN); - } - - /** - * Log object with label to firebug console - * - * @see FirePHP::ERROR - * @param mixes $Object - * @param string $Label - * @return true - */ - function error($Object, $Label=null) { - return FB::send($Object, $Label, FirePHP_ERROR); - } - - /** - * Dumps key and variable to firebug server panel - * - * @see FirePHP::DUMP - * @param string $Key - * @param mixed $Variable - * @return true - */ - function dump($Key, $Variable) { - return FB::send($Variable, $Key, FirePHP_DUMP); - } - - /** - * Log a trace in the firebug console - * - * @see FirePHP::TRACE - * @param string $Label - * @return true - */ - function trace($Label) { - return FB::send($Label, FirePHP_TRACE); - } - - /** - * Log a table in the firebug console - * - * @see FirePHP::TABLE - * @param string $Label - * @param string $Table - * @return true - */ - function table($Label, $Table) { - return FB::send($Table, $Label, FirePHP_TABLE); - } -} diff --git a/htdocs/includes/firephp/firephp-core/package.json b/htdocs/includes/firephp/firephp-core/package.json deleted file mode 100644 index 291a920223a..00000000000 --- a/htdocs/includes/firephp/firephp-core/package.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "uid": "https://github.com/firephp/firephp-core/", - "name": "firephp-core", - "version": "0.4.0", - "label": "FirePHP Server Library", - "repositories": [ - { - "type": "git", - "url": "git://github.com/firephp/firephp-core.git" - } - ], - "maintainers": [ - { - "name": "Christoph Dorn", - "email": "christoph@christophdorn.com", - "web": "http://www.christophdorn.com/", - "alias": { - "github": "cadorn" - } - } - ], - "contributors": [ - { - "name": "Christoph Dorn", - "email": "christoph@christophdorn.com", - "web": "http://www.christophdorn.com/", - "alias": { - "github": "cadorn" - } - }, - { - "name": "Michael Day", - "email": "manveru.alma@gmail.com" - }, - { - "name": "Sokolov Innokenty", - "email": "sokolov.innokenty@gmail.com", - "alias": { - "github": "qbbr" - } - } - ] -} \ No newline at end of file diff --git a/htdocs/includes/firephp/firephp-core/program.json b/htdocs/includes/firephp/firephp-core/program.json deleted file mode 100644 index 9889e97a36f..00000000000 --- a/htdocs/includes/firephp/firephp-core/program.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": { - "location": "./workspace/program.json" - } -} \ No newline at end of file diff --git a/htdocs/includes/firephp/firephp-core/tests/API/newlines.php b/htdocs/includes/firephp/firephp-core/tests/API/newlines.php deleted file mode 100644 index 1e5511e544d..00000000000 --- a/htdocs/includes/firephp/firephp-core/tests/API/newlines.php +++ /dev/null @@ -1,12 +0,0 @@ -dump("key", "value"); - $headers = $firephp->_getHeaders(); - $this->assertEquals('15|{"key":"value"}|', $headers['X-Wf-1-2-1-1']); - $firephp->_clearHeaders(); - - $caught = false; - try { - $firephp->dump(array(), "value"); - } catch(Exception $e) { - // Key passed to dump() is not a string - $caught = true; - } - if(!$caught) $this->fail('No exception thrown'); - - $caught = false; - try { - $firephp->dump("key \n\r value", "value"); - } catch(Exception $e) { - // Key passed to dump() contains invalid characters [a-zA-Z0-9-_\.:] - $caught = true; - } - if(!$caught) $this->fail('No exception thrown'); - - $caught = false; - try { - $firephp->dump("keykeykeykkeykeykeykkeykeykeykkeykeykeykkeykeykeykkeykeykeykkeykeykeykkeykeykeykkeykeykeykkeykeykeyk1", "value"); - } catch(Exception $e) { - // Key passed to dump() is longer than 100 characters - $caught = true; - } - if(!$caught) $this->fail('No exception thrown'); - } - - /** - * @issue http://code.google.com/p/firephp/issues/detail?id=123 - */ - public function testRegisterErrorHandler() - { - $firephp = new FirePHP_Test_Class(); - $firephp->setOption("maxObjectDepth", 1); - $firephp->setOption("maxArrayDepth", 1); - - $firephp->registerErrorHandler(); - trigger_error("Hello World"); - $headers = $firephp->_getHeaders(); - if(!isset($headers["X-Wf-1-1-1-1"])) { - $this->fail("Error not in headers"); - } - } - - /** - * @issue http://code.google.com/p/firephp/issues/detail?id=122 - */ - public function testFirePHPClassInstanceLogging() - { - $firephp = new FirePHP_Test_Class(); - - $firephp->log($firephp); - $headers = $firephp->_getHeaders(); - if(!preg_match_all('/"protected:objectStack":"\\*\\* Excluded by Filter \\*\\*"/', $headers['X-Wf-1-1-1-1'], $m)) { - $this->fail("objectStack member contains value"); - } - if(!preg_match_all('/"protected:static:instance":"\\*\\* Excluded by Filter \\*\\*"/', $headers['X-Wf-1-1-1-1'], $m)) { - $this->fail("instance member should not be logged"); - } - if(!preg_match_all('/"undeclared:json_objectStack":"\\*\\* Excluded by Filter \\*\\*"/', $headers['X-Wf-1-1-1-1'], $m)) { - $this->fail("json_objectStack member should not be logged"); - } - } - - /** - * @issue http://code.google.com/p/firephp/issues/detail?id=114 - */ - public function testCustomFileLineOptions() - { - $firephp = new FirePHP_Test_Class(); - - $firephp->log("message", "label", array("File"=>"/file/path", "Line"=>"1")); - $firephp->info("message", "label", array("File"=>"/file/path", "Line"=>"1")); - $firephp->warn("message", "label", array("File"=>"/file/path", "Line"=>"1")); - $firephp->error("message", "label", array("File"=>"/file/path", "Line"=>"1")); - $firephp->dump("key", "value", array("File"=>"/file/path", "Line"=>"1")); - $firephp->table("label", array(array("header"),array("cell")), array("File"=>"/file/path", "Line"=>"1")); - - $headers = $firephp->_getHeaders(); - - $this->assertEquals('75|[{"File":"\/file\/path","Line":"1","Type":"LOG","Label":"label"},"message"]|', $headers['X-Wf-1-1-1-1']); - $this->assertEquals('76|[{"File":"\/file\/path","Line":"1","Type":"INFO","Label":"label"},"message"]|', $headers['X-Wf-1-1-1-2']); - $this->assertEquals('76|[{"File":"\/file\/path","Line":"1","Type":"WARN","Label":"label"},"message"]|', $headers['X-Wf-1-1-1-3']); - $this->assertEquals('77|[{"File":"\/file\/path","Line":"1","Type":"ERROR","Label":"label"},"message"]|', $headers['X-Wf-1-1-1-4']); - $this->assertEquals('15|{"key":"value"}|', $headers['X-Wf-1-2-1-5']); - $this->assertEquals('89|[{"File":"\/file\/path","Line":"1","Type":"TABLE","Label":"label"},[["header"],["cell"]]]|', $headers['X-Wf-1-1-1-6']); - } - - public function testRecursiveEncode() - { - $firephp = new FirePHP_Test_Class(); - - $obj = new FirePHPCore_FirePHPTest__TestObject(); - $obj->child = $obj; - - $firephp->log($obj, "label", array("File"=>"/file/path", "Line"=>"1")); - $headers = $firephp->_getHeaders(); - $this->assertEquals('215|[{"File":"\/file\/path","Line":"1","Type":"LOG","Label":"label"},{"__className":"FirePHPCore_FirePHPTest__TestObject","public:var":"value","undeclared:child":"** Recursion (FirePHPCore_FirePHPTest__TestObject) **"}]|', $headers['X-Wf-1-1-1-1']); - } - - public function testOptions() - { - $firephp = new FirePHP_Test_Class(); - - // defaults - $this->assertEquals(5, $firephp->getOption("maxObjectDepth")); - $this->assertEquals(5, $firephp->getOption("maxArrayDepth")); - $this->assertEquals(true, $firephp->getOption("useNativeJsonEncode")); - $this->assertEquals(true, $firephp->getOption("includeLineNumbers")); - - // modify - $firephp->setOption("maxObjectDepth", 1); - $this->assertEquals(1, $firephp->getOption("maxObjectDepth")); - - // invalid - $caught = false; - try { - $firephp->setOption("invalidName", 1); - } catch(Exception $e) { - $caught = true; - } - if(!$caught) $this->fail('No exception thrown'); - - $caught = false; - try { - $firephp->getOption("invalidName"); - } catch(Exception $e) { - $caught = true; - } - if(!$caught) $this->fail('No exception thrown'); - } - - public function testDeprecatedMethods() - { - $firephp = new FirePHP_Test_Class(); - - $caught = false; - try { - $firephp->setProcessorUrl('URL'); - } catch(Exception $e) { - $caught = true; - $this->assertEquals(E_USER_DEPRECATED, $e->getCode()); - $this->assertEquals('The FirePHP::setProcessorUrl() method is no longer supported', $e->getMessage()); - } - if(!$caught) $this->fail('No deprecation error thrown'); - - $caught = false; - try { - $firephp->setRendererUrl('URL'); - } catch(Exception $e) { - $caught = true; - $this->assertEquals(E_USER_DEPRECATED, $e->getCode()); - $this->assertEquals('The FirePHP::setRendererUrl() method is no longer supported', $e->getMessage()); - } - if(!$caught) $this->fail('No deprecation error thrown'); - } - -} - - -class FirePHPCore_FirePHPTest__TestObject -{ - public $var = "value"; -} diff --git a/htdocs/includes/firephp/firephp-core/tests/TestHelper.php b/htdocs/includes/firephp/firephp-core/tests/TestHelper.php deleted file mode 100644 index bb65e73202d..00000000000 --- a/htdocs/includes/firephp/firephp-core/tests/TestHelper.php +++ /dev/null @@ -1,55 +0,0 @@ -_headers; - } - public function _clearHeaders() { - $this->_headers = array(); - } - - - // ###################### - // # Subclassed Methods # - // ###################### - - protected function setHeader($Name, $Value) { - $this->_headers[$Name] = $Value; - } - - protected function headersSent(&$Filename, &$Linenum) { - return false; - } - - public function detectClientExtension() { - return true; - } - -} diff --git a/htdocs/includes/firephp/firephp-core/tests/phpunit.xml b/htdocs/includes/firephp/firephp-core/tests/phpunit.xml deleted file mode 100644 index b0474e9d627..00000000000 --- a/htdocs/includes/firephp/firephp-core/tests/phpunit.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/htdocs/includes/firephp/firephp-core/workspace/README.md b/htdocs/includes/firephp/firephp-core/workspace/README.md deleted file mode 100644 index 999f09a9418..00000000000 --- a/htdocs/includes/firephp/firephp-core/workspace/README.md +++ /dev/null @@ -1,19 +0,0 @@ - -The [PINF JavaScript Loader](https://github.com/pinf/loader-js) is used to provide a development environment and package releases for this project. - -**NOTE:** It is assumed you have the _PINF JavaScript Loader_ mapped to the `commonjs` command and are using the `node` platform by default as explained [here](https://github.com/pinf/loader-js/blob/master/docs/Setup.md). - - -Publishing -========== - - git tag v... - - commonjs -v --script build . - - commonjs -v --script publish . - - -TODO: Auto-upload to PEAR channel server at http://pear.firephp.org/ - -NOTE: For PEAR RC releases: Change release stability to "beta" and capitalize "RC" in release version in package.xml diff --git a/htdocs/includes/firephp/firephp-core/workspace/lib/project.js b/htdocs/includes/firephp/firephp-core/workspace/lib/project.js deleted file mode 100644 index 913c6d7c60f..00000000000 --- a/htdocs/includes/firephp/firephp-core/workspace/lib/project.js +++ /dev/null @@ -1,5 +0,0 @@ - -exports.main = function(options) -{ - -} diff --git a/htdocs/includes/firephp/firephp-core/workspace/package.json b/htdocs/includes/firephp/firephp-core/workspace/package.json deleted file mode 100644 index 19e8385ee6f..00000000000 --- a/htdocs/includes/firephp/firephp-core/workspace/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "firephp-core", - "engine": [ - "node" - ], - "main": "lib/project.js", - "scripts": { - "build": { - "location": "./", - "module": "/scripts/build.js" - }, - "publish": { - "location": "./", - "module": "/scripts/publish.js" - } - }, - "mappings": { - "nodejs": { - "id": "nodejs.org/" - }, - "pinf": { - "id": "pinf.org/loader/" - }, - "modules": { - "id": "github.com/pinf/modules-js/" - } - } -} \ No newline at end of file diff --git a/htdocs/includes/firephp/firephp-core/workspace/program.json b/htdocs/includes/firephp/firephp-core/workspace/program.json deleted file mode 100644 index 9628b525c6c..00000000000 --- a/htdocs/includes/firephp/firephp-core/workspace/program.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "boot": "workspace", - "engine": [ - "node" - ], - "packages": { - "workspace": { - "locator": { - "location": "./" - } - }, - "nodejs.org/": { - "provider": "nodejs.org/" - }, - "pinf.org/loader/": { - "provider": "pinf.org/loader/" - }, - "github.com/pinf/modules-js/": { - "locator": { - "archive": "https://github.com/pinf/modules-js/zipball/master" - } - }, - "github.com/kriskowal/q/": { - "locator": { - "archive": "https://github.com/kriskowal/q/zipball/v0.3.0" - }, - "descriptor": { - "uid": "https://github.com/kriskowal/q/", - "dependencies": [ - { - "id": "github.com/pinf/modules-js/" - } - ] - } - }, - "private-registry.appspot.com/cadorn.com/github/com.cadorn.baby/projects/sourcemint/packages/client-js/": { - "locator": { - "archive": "https://github.com/cadorn/com.cadorn.baby/zipball/master", - "path": "projects/sourcemint/packages/client-js" - } - }, - "github.com/cadorn/aws-lib/": { - "locator": { - "archive": "https://github.com/cadorn/aws-lib/zipball/master" - }, - "descriptor": { - "uid": "https://github.com/cadorn/aws-lib/", - "native": true, - "dependencies": [ - { - "id": "registry.npmjs.org/sax/" - }, - { - "id": "registry.npmjs.org/xml2js/" - } - ] - } - }, - "registry.npmjs.org/sax/": { - "locator": { - "archive": "http://registry.npmjs.org/sax/-/sax-0.1.2.tgz" - }, - "descriptor": { - "uid": "http://registry.npmjs.org/sax/", - "native": true - } - }, - "registry.npmjs.org/xml2js/": { - "locator": { - "archive": "http://registry.npmjs.org/xml2js/-/xml2js-0.1.6.tgz" - }, - "descriptor": { - "uid": "http://registry.npmjs.org/xml2js/", - "native": true - } - } - } -} \ No newline at end of file diff --git a/htdocs/includes/firephp/firephp-core/workspace/scripts/build.js b/htdocs/includes/firephp/firephp-core/workspace/scripts/build.js deleted file mode 100644 index 2481d99d381..00000000000 --- a/htdocs/includes/firephp/firephp-core/workspace/scripts/build.js +++ /dev/null @@ -1,164 +0,0 @@ - -var FILE = require("modules/file"), - Q = require("modules/q"), - SYSTEM = require("modules/system"), - UTIL = require("modules/util"), - JSON = require("modules/json"); - - -var pkgPath = FILE.dirname(FILE.dirname(FILE.dirname(module.id))), - buildPath = pkgPath + "/build", - tplPath = pkgPath + "/workspace/tpl", - version = false; - -exports.getBuildPath = function() -{ - return buildPath; -} - -exports.main = function() -{ - - SYSTEM.exec("rm -Rf " + buildPath, function() - { - FILE.mkdirs(buildPath, 0775); - - SYSTEM.exec("git tag", function(stdout) - { - version = UTIL.trim(stdout).split("\n").pop().match(/^v(.*)$/)[1]; - - // TODO: Compare against version in `../../program.json ~ version` (ensure =) - - module.print("\0cyan(Building version: " + version + "\0)\n"); - - buildZipArchive(function() - { - buildPEARArchive(function() - { - done(); - }); - }); - }); - }); - - function done() - { - module.print("\0green(Done\0)\n"); - } -} - -function buildZipArchive(callback) -{ - var targetBasePath = buildPath + "/FirePHPCore-" + version; - - FILE.mkdirs(targetBasePath, 0775); - - SYSTEM.exec("rsync -r --copy-links --exclude \"- .DS_Store\" --exclude \"- .git/\" --exclude \"- .tmp_*\" " + pkgPath + "/lib " + targetBasePath, function() - { - replaceVariablesInFile(targetBasePath + "/lib/FirePHPCore/FirePHP.class.php"); - replaceVariablesInFile(targetBasePath + "/lib/FirePHPCore/FirePHP.class.php4"); - - SYSTEM.exec("cp -Rf " + pkgPath + "/examples " + targetBasePath, function() - { - next1(); - }); - }); - - function next1() - { - var content = FILE.read(tplPath + "/readme.tpl.md"); - content = content.replace(/%%VERSION%%/g, version); - FILE.write(targetBasePath + "/README.md", content); - - var content = FILE.read(tplPath + "/license.tpl.md"); - FILE.write(targetBasePath + "/LICENSE.md", content); - - FILE.write(buildPath + "/info.json", JSON.encode({ - version: version - })); - - next2(); - } - - function next2() - { - SYSTEM.exec("cd " + buildPath + " ; zip -vr FirePHPCore-" + version + ".zip FirePHPCore-" + version, function(stdout) - { - console.log(stdout); - - callback(); - }); - } -} - -function buildPEARArchive(callback) -{ - var targetBasePath = buildPath + "/pear"; - - FILE.mkdirs(targetBasePath, 0775); - - SYSTEM.exec("rsync -r --copy-links --exclude \"- .DS_Store\" --exclude \"- .git/\" --exclude \"- .tmp_*\" " + pkgPath + "/lib/FirePHPCore/* " + targetBasePath, function() - { - replaceVariablesInFile(targetBasePath + "/FirePHP.class.php"); - replaceVariablesInFile(targetBasePath + "/FirePHP.class.php4"); - - next1(); - }); - - function next1() - { - var content = FILE.read(tplPath + "/pear.package.tpl.xml"); - - var date = new Date(); - content = content.replace(/%%DATE%%/g, date.getFullYear() + "-" + UTIL.padBegin(date.getMonth()+1, 2, "0") + "-" + date.getDate()); - content = content.replace(/%%VERSION%%/g, version); - content = content.replace(/%%STABILITY%%/g, "stable"); - - FILE.write(targetBasePath + "/package.xml", content); - - next2(); - } - - function next2() - { - SYSTEM.exec("pear channel-discover pear.firephp.org", function(stdout) - { - console.log(stdout); - - SYSTEM.exec("cd " + targetBasePath + "; pear package package.xml", function(stdout) - { - console.log(stdout); - - callback(); - }); - }); - } -} - -function replaceVariablesInFile(path) -{ - var content = FILE.read(path); - - // @pinf replace '0.3' with '%%VERSION%%' - var re1 = /\n(.*)\/\/\s*@pinf\s(.*)\n/g; - var match1; - while (match1 = re1.exec(content)) { - var rule = match1[2].match(/^replace (.*?) with (.*)$/); - if(rule) { - // replace variables in rule - var re2 = /%%([^%]*)%%/g; - var match2; - while (match2 = re2.exec(rule[2])) { - var value; - if(match2[1]=="VERSION") { - value = version; - } - rule[2] = rule[2].replace(match2[0], value); - } - match1[1] = match1[1].replace(rule[1], rule[2]); - content = content.replace(match1[0], "\n"+match1[1]+"\n"); - } - } - - FILE.write(path, content); -} diff --git a/htdocs/includes/firephp/firephp-core/workspace/scripts/publish.js b/htdocs/includes/firephp/firephp-core/workspace/scripts/publish.js deleted file mode 100644 index 39106e1b3b3..00000000000 --- a/htdocs/includes/firephp/firephp-core/workspace/scripts/publish.js +++ /dev/null @@ -1,65 +0,0 @@ - -var PINF_LOADER = require("pinf/loader"), - SANDBOX = PINF_LOADER.getSandbox(), - FILE = require("modules/file"), - Q = require("modules/q"), - SYSTEM = require("modules/system"), - BUILD = require("./build"), - JSON = require("modules/json"), - SOURCEMINT_CLIENT = false; - -exports.main = function() -{ - module.load({ - id: "private-registry.appspot.com/cadorn.com/github/com.cadorn.baby/projects/sourcemint/packages/client-js/", - descriptor: { - main: "lib/client.js" - } - }, function(id) - { - SOURCEMINT_CLIENT = require(id); - - publish(); - }); -} - -function publish() -{ - var buildPath = BUILD.getBuildPath(), - info = JSON.decode(FILE.read(buildPath + "/info.json")), - descriptor = JSON.decode(FILE.read(FILE.dirname(FILE.dirname(FILE.dirname(module.id))) + "/package.json")); - - var bundles = {}; - bundles["firephp-core.zip"] = { - "type": "zip", - "options": { - "archivePath": buildPath + "/FirePHPCore-" + info.version + ".zip", - } - }; - - var packages = [ - { - "uid": descriptor.uid, - "stream": "stable", - "version": info.version, - "bundles": bundles - } - ]; - - try - { - Q.when(SOURCEMINT_CLIENT.publish(packages), function(info) - { - module.print("\0green(Published:\n"); - console.log(info); - module.print("\0)"); - }, function(e) - { - throw e; - }); - } - catch(e) - { - console.error("Error: " + e); - } -} diff --git a/htdocs/includes/firephp/firephp-core/workspace/tpl/license.tpl.md b/htdocs/includes/firephp/firephp-core/workspace/tpl/license.tpl.md deleted file mode 100644 index 1b0aaf26962..00000000000 --- a/htdocs/includes/firephp/firephp-core/workspace/tpl/license.tpl.md +++ /dev/null @@ -1,21 +0,0 @@ -[MIT License](http://www.opensource.org/licenses/mit-license.php) - -Copyright (c) 2007+ [Christoph Dorn](http://www.christophdorn.com/) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/htdocs/includes/firephp/firephp-core/workspace/tpl/pear.package.tpl.xml b/htdocs/includes/firephp/firephp-core/workspace/tpl/pear.package.tpl.xml deleted file mode 100644 index b9f3d65a43d..00000000000 --- a/htdocs/includes/firephp/firephp-core/workspace/tpl/pear.package.tpl.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - - FirePHPCore - pear.firephp.org - Log variables from PHP to the browser (Firebug Console) - Handles all communication between the PHP code on the server and the client. Also implements all core FirePHP features. - - - Christoph Dorn - cadorn - christoph@christophdorn.com - yes - - - %%DATE%% - - %%VERSION%% - 0.3 - - - - %%STABILITY%% - stable - - - MIT - - No Notes - - - - - - - - - - - - - - - - - 4.0 - - - 1.4.5 - - - - - - - diff --git a/htdocs/includes/firephp/firephp-core/workspace/tpl/readme.tpl.md b/htdocs/includes/firephp/firephp-core/workspace/tpl/readme.tpl.md deleted file mode 100644 index 01264662e85..00000000000 --- a/htdocs/includes/firephp/firephp-core/workspace/tpl/readme.tpl.md +++ /dev/null @@ -1,17 +0,0 @@ -FirePHPCore Server Library -========================== - -Status: stable - -Version: [%%VERSION%%](https://github.com/firephp/firephp-core/tree/v%%VERSION%%) - -This archive contains the *FirePHPCore* PHP server library. - -Links ------ - - * Documentation: http://docs.sourcemint.org/firephp.org/firephp/1/-docs/ - * Install: http://docs.sourcemint.org/firephp.org/firephp/1/-docs/Configuration/Traditional - * Support: http://docs.sourcemint.org/firephp.org/firephp/1/-docs/OpenSource#support - * Author: [Christoph Dorn](http://www.christophdorn.com/) - * License: [MIT License](http://www.opensource.org/licenses/mit-license.php) diff --git a/htdocs/includes/raven-js/.bower.json b/htdocs/includes/raven-js/.bower.json deleted file mode 100644 index f42bb67b949..00000000000 --- a/htdocs/includes/raven-js/.bower.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "raven-js", - "version": "1.1.19", - "dependencies": {}, - "main": "dist/raven.js", - "ignore": {}, - "homepage": "https://github.com/getsentry/raven-js", - "_release": "1.1.19", - "_resolution": { - "type": "version", - "tag": "1.1.19", - "commit": "82b9c07b7545c6c10e297709a741eaa9b75f64e8" - }, - "_source": "git://github.com/getsentry/raven-js.git", - "_target": "~1.1.19", - "_originalSource": "raven-js", - "_direct": true -} \ No newline at end of file diff --git a/htdocs/includes/raven-js/.gitignore b/htdocs/includes/raven-js/.gitignore deleted file mode 100644 index 02111f91fe4..00000000000 --- a/htdocs/includes/raven-js/.gitignore +++ /dev/null @@ -1,22 +0,0 @@ -.DS_Store - -# Thumbnails -._* - -# Files that might appear on external disk -.Spotlight-V100 -.Trashes - -docs/html -docs/doctrees - -build -node_modules -npm-debug.log - -scratch/ - -*.pyc - -.idea -aws.json diff --git a/htdocs/includes/raven-js/.jshintrc b/htdocs/includes/raven-js/.jshintrc deleted file mode 100644 index 6e4ec735331..00000000000 --- a/htdocs/includes/raven-js/.jshintrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "es3": true, - "globalstrict": true, - "browser": true, - "predef": [ - "TraceKit", - "console" - ] -} diff --git a/htdocs/includes/raven-js/.travis.yml b/htdocs/includes/raven-js/.travis.yml deleted file mode 100644 index 3b4f88c1e93..00000000000 --- a/htdocs/includes/raven-js/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -# language doesn't matter, we're only using phantom.js -language: node_js -node_js: - - "0.10" -script: - - ./node_modules/.bin/grunt test build -notifications: - irc: "irc.freenode.org#sentry" diff --git a/htdocs/includes/raven-js/AUTHORS b/htdocs/includes/raven-js/AUTHORS deleted file mode 100644 index 7f1ae423217..00000000000 --- a/htdocs/includes/raven-js/AUTHORS +++ /dev/null @@ -1 +0,0 @@ -https://github.com/getsentry/raven-js/graphs/contributors diff --git a/htdocs/includes/raven-js/Gruntfile.js b/htdocs/includes/raven-js/Gruntfile.js deleted file mode 100644 index fce8eb17272..00000000000 --- a/htdocs/includes/raven-js/Gruntfile.js +++ /dev/null @@ -1,254 +0,0 @@ -module.exports = function(grunt) { - "use strict"; - - var _ = require('lodash'); - var path = require('path'); - - var coreFiles = [ - 'template/_header.js', - 'vendor/**/*.js', - 'src/**/*.js', - 'template/_footer.js' - ]; - - var plugins = grunt.option('plugins'); - // Create plugin paths and verify hey exist - plugins = _.map(plugins ? plugins.split(',') : [], function (plugin) { - var path = 'plugins/' + plugin + '.js'; - - if(!grunt.file.exists(path)) - throw new Error("Plugin '" + plugin + "' not found in plugins directory."); - - return path; - }); - - // Taken from http://dzone.com/snippets/calculate-all-combinations - var combine = function (a) { - var fn = function (n, src, got, all) { - if (n === 0) { - all.push(got); - return; - } - - for (var j = 0; j < src.length; j++) { - fn(n - 1, src.slice(j + 1), got.concat([src[j]]), all); - } - }; - - var all = [a]; - - for (var i = 0; i < a.length; i++) { - fn(i, a, [], all); - } - - return all; - }; - - var pluginCombinations = combine(grunt.file.expand('plugins/*.js')); - var pluginConcatFiles = _.reduce(pluginCombinations, function (dict, comb) { - var key = _.map(comb, function (plugin) { - return path.basename(plugin, '.js'); - }); - key.sort(); - - var dest = path.join('build/', key.join(','), '/raven.js'); - dict[dest] = coreFiles.concat(comb); - - return dict; - }, {}); - - var gruntConfig = { - pkg: grunt.file.readJSON('package.json'), - aws: grunt.file.exists('aws.json') ? grunt.file.readJSON('aws.json'): {}, - - clean: ['build'], - concat: { - options: { - separator: '\n', - banner: grunt.file.read('template/_copyright.js'), - process: true - }, - core: { - src: coreFiles.concat(plugins), - dest: 'build/raven.js' - }, - all: { - files: pluginConcatFiles - } - }, - - uglify: { - options: { - sourceMap: function (dest) { - return path.join(path.dirname(dest), - path.basename(dest, '.js')) + - '.map'; - }, - sourceMappingURL: function (dest) { - return path.basename(dest, '.js') + '.map'; - }, - preserveComments: 'some' - }, - dist: { - src: ['build/**/*.js'], - ext: '.min.js', - expand: true - } - }, - - fixSourceMaps: { - all: ['build/**/*.map'] - }, - - jshint: { - options: { - jshintrc: '.jshintrc' - }, - all: ['Gruntfile.js', 'src/**/*.js', 'plugins/**/*.js'] - }, - - mocha: { - all: { - options: { - mocha: { - ignoreLeaks: true, - grep: grunt.option('grep') - }, - log: true, - reporter: 'Dot', - run: true - }, - src: ['test/index.html'], - nonull: true - } - }, - - release: { - options: { - npm: false, - commitMessage: 'Release <%= version %>' - } - }, - - s3: { - options: { - key: '<%= aws.key %>', - secret: '<%= aws.secret %>', - bucket: '<%= aws.bucket %>', - access: 'public-read', - // Limit concurrency - maxOperations: 20, - headers: { - // Surrogate-Key header for Fastly to purge by release - 'x-amz-meta-surrogate-key': '<%= pkg.release %>' - } - }, - all: { - upload: [{ - src: 'build/**/*', - dest: '<%= pkg.release %>/', - rel: 'build/' - }] - } - }, - - connect: { - test: { - options: { - port: 8000, - debug: true, - keepalive: true - } - }, - - docs: { - options: { - port: 8000, - debug: true, - base: 'docs/html', - keepalive: true - } - } - }, - - copy: { - dist: { - expand: true, - flatten: true, - cwd: 'build/', - src: '**', - dest: 'dist/' - } - } - }; - - grunt.initConfig(gruntConfig); - - // Custom Grunt tasks - grunt.registerTask('version', function() { - var pkg = grunt.config.get('pkg'); - if (grunt.option('dev')) { - pkg.release = 'dev'; - pkg.version = grunt.config.get('gitinfo').local.branch.current.shortSHA; - } else { - pkg.release = pkg.version; - } - grunt.config.set('pkg', pkg); - }); - - grunt.registerMultiTask('fixSourceMaps', function () { - this.files.forEach(function (f) { - var result; - var sources = f.src.filter(function (filepath) { - if (!grunt.file.exists(filepath)) { - grunt.log.warn('Source file "' + filepath + '" not found.'); - return false; - } else { - return true; - } - }).forEach(function (filepath) { - var base = path.dirname(filepath); - var sMap = grunt.file.readJSON(filepath); - sMap.file = path.relative(base, sMap.file); - sMap.sources = _.map(sMap.sources, path.relative.bind(path, base)); - - grunt.file.write(filepath, JSON.stringify(sMap)); - // Print a success message. - grunt.log.writeln('File "' + filepath + '" fixed.'); - }); - }); - }); - - // Grunt contrib tasks - grunt.loadNpmTasks('grunt-contrib-uglify'); - grunt.loadNpmTasks('grunt-contrib-concat'); - grunt.loadNpmTasks('grunt-contrib-clean'); - grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-contrib-connect'); - grunt.loadNpmTasks('grunt-contrib-copy'); - - // 3rd party Grunt tasks - grunt.loadNpmTasks('grunt-mocha'); - grunt.loadNpmTasks('grunt-release'); - grunt.loadNpmTasks('grunt-s3'); - grunt.loadNpmTasks('grunt-gitinfo'); - - // Build tasks - grunt.registerTask('_prep', ['clean', 'gitinfo', 'version']); - grunt.registerTask('concat.core', ['_prep', 'concat:core']); - grunt.registerTask('concat.all', ['_prep', 'concat:all']); - grunt.registerTask('build.core', ['concat.core', 'uglify', 'fixSourceMaps']); - grunt.registerTask('build.all', ['concat.all', 'uglify', 'fixSourceMaps']); - grunt.registerTask('build', ['build.all']); - grunt.registerTask('dist', ['build.core', 'copy:dist']); - - // Test task - grunt.registerTask('test', ['jshint', 'mocha']); - - // Webserver tasks - grunt.registerTask('run:test', ['connect:test']); - grunt.registerTask('run:docs', ['connect:docs']); - - grunt.registerTask('publish', ['test', 'build.all', 's3']); - grunt.registerTask('default', ['test']); -}; diff --git a/htdocs/includes/raven-js/LICENSE b/htdocs/includes/raven-js/LICENSE deleted file mode 100644 index 2752d4c7395..00000000000 --- a/htdocs/includes/raven-js/LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -Copyright (c) 2014 Matt Robenolt and other contributors -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/htdocs/includes/raven-js/Makefile b/htdocs/includes/raven-js/Makefile deleted file mode 100644 index f378b15f09d..00000000000 --- a/htdocs/includes/raven-js/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -develop: update-submodules - npm install . - -update-submodules: - git submodule init - git submodule update - -docs: - cd docs; $(MAKE) html - -docs-live: - while true; do \ - sleep 2; \ - $(MAKE) docs; \ - done - -clean: - rm -rf docs/html - -.PHONY: develop update-submodules docs docs-live clean diff --git a/htdocs/includes/raven-js/README.md b/htdocs/includes/raven-js/README.md deleted file mode 100644 index 058a44fe41f..00000000000 --- a/htdocs/includes/raven-js/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Raven.js [![Build Status](https://travis-ci.org/getsentry/raven-js.svg?branch=master)](https://travis-ci.org/getsentry/raven-js) - -Raven.js is a tiny standalone JavaScript client for [Sentry](https://www.getsentry.com/). - -**Raven.js v1.1 requires Sentry v6.0 or later.** - -## Resources - - * [Download](http://ravenjs.com) - * [Documentation](https://raven-js.readthedocs.org) - * [Bug Tracker](https://github.com/getsentry/raven-js/issues) - * [IRC](irc://chat.freenode.net/sentry) (chat.freenode.net, #sentry) - * Follow [@mattrobenolt](https://twitter.com/mattrobenolt) on Twitter for updates diff --git a/htdocs/includes/raven-js/bower.json b/htdocs/includes/raven-js/bower.json deleted file mode 100644 index ba54c40ac65..00000000000 --- a/htdocs/includes/raven-js/bower.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "raven-js", - "version": "1.1.19", - "dependencies": {}, - "main": "dist/raven.js", - "ignore": {} -} diff --git a/htdocs/includes/raven-js/dist/raven.js b/htdocs/includes/raven-js/dist/raven.js deleted file mode 100644 index 195d002ab65..00000000000 --- a/htdocs/includes/raven-js/dist/raven.js +++ /dev/null @@ -1,1909 +0,0 @@ -/*! Raven.js 1.1.19 (b51bc89) | github.com/getsentry/raven-js */ - -/* - * Includes TraceKit - * https://github.com/getsentry/TraceKit - * - * Copyright 2015 Matt Robenolt and other contributors - * Released under the BSD license - * https://github.com/getsentry/raven-js/blob/master/LICENSE - * - */ -;(function(window, undefined){ -'use strict'; - -/* - TraceKit - Cross brower stack traces - github.com/occ/TraceKit - MIT license -*/ - -var TraceKit = { - remoteFetching: false, - collectWindowErrors: true, - // 3 lines before, the offending line, 3 lines after - linesOfContext: 7 -}; - -// global reference to slice -var _slice = [].slice; -var UNKNOWN_FUNCTION = '?'; - - -/** - * TraceKit.wrap: Wrap any function in a TraceKit reporter - * Example: func = TraceKit.wrap(func); - * - * @param {Function} func Function to be wrapped - * @return {Function} The wrapped func - */ -TraceKit.wrap = function traceKitWrapper(func) { - function wrapped() { - try { - return func.apply(this, arguments); - } catch (e) { - TraceKit.report(e); - throw e; - } - } - return wrapped; -}; - -/** - * TraceKit.report: cross-browser processing of unhandled exceptions - * - * Syntax: - * TraceKit.report.subscribe(function(stackInfo) { ... }) - * TraceKit.report.unsubscribe(function(stackInfo) { ... }) - * TraceKit.report(exception) - * try { ...code... } catch(ex) { TraceKit.report(ex); } - * - * Supports: - * - Firefox: full stack trace with line numbers, plus column number - * on top frame; column number is not guaranteed - * - Opera: full stack trace with line and column numbers - * - Chrome: full stack trace with line and column numbers - * - Safari: line and column number for the top frame only; some frames - * may be missing, and column number is not guaranteed - * - IE: line and column number for the top frame only; some frames - * may be missing, and column number is not guaranteed - * - * In theory, TraceKit should work on all of the following versions: - * - IE5.5+ (only 8.0 tested) - * - Firefox 0.9+ (only 3.5+ tested) - * - Opera 7+ (only 10.50 tested; versions 9 and earlier may require - * Exceptions Have Stacktrace to be enabled in opera:config) - * - Safari 3+ (only 4+ tested) - * - Chrome 1+ (only 5+ tested) - * - Konqueror 3.5+ (untested) - * - * Requires TraceKit.computeStackTrace. - * - * Tries to catch all unhandled exceptions and report them to the - * subscribed handlers. Please note that TraceKit.report will rethrow the - * exception. This is REQUIRED in order to get a useful stack trace in IE. - * If the exception does not reach the top of the browser, you will only - * get a stack trace from the point where TraceKit.report was called. - * - * Handlers receive a stackInfo object as described in the - * TraceKit.computeStackTrace docs. - */ -TraceKit.report = (function reportModuleWrapper() { - var handlers = [], - lastArgs = null, - lastException = null, - lastExceptionStack = null; - - /** - * Add a crash handler. - * @param {Function} handler - */ - function subscribe(handler) { - installGlobalHandler(); - handlers.push(handler); - } - - /** - * Remove a crash handler. - * @param {Function} handler - */ - function unsubscribe(handler) { - for (var i = handlers.length - 1; i >= 0; --i) { - if (handlers[i] === handler) { - handlers.splice(i, 1); - } - } - } - - /** - * Remove all crash handlers. - */ - function unsubscribeAll() { - uninstallGlobalHandler(); - handlers = []; - } - - /** - * Dispatch stack information to all handlers. - * @param {Object.} stack - */ - function notifyHandlers(stack, isWindowError) { - var exception = null; - if (isWindowError && !TraceKit.collectWindowErrors) { - return; - } - for (var i in handlers) { - if (hasKey(handlers, i)) { - try { - handlers[i].apply(null, [stack].concat(_slice.call(arguments, 2))); - } catch (inner) { - exception = inner; - } - } - } - - if (exception) { - throw exception; - } - } - - var _oldOnerrorHandler, _onErrorHandlerInstalled; - - /** - * Ensures all global unhandled exceptions are recorded. - * Supported by Gecko and IE. - * @param {string} message Error message. - * @param {string} url URL of script that generated the exception. - * @param {(number|string)} lineNo The line number at which the error - * occurred. - * @param {?(number|string)} colNo The column number at which the error - * occurred. - * @param {?Error} ex The actual Error object. - */ - function traceKitWindowOnError(message, url, lineNo, colNo, ex) { - var stack = null; - - if (lastExceptionStack) { - TraceKit.computeStackTrace.augmentStackTraceWithInitialElement(lastExceptionStack, url, lineNo, message); - processLastException(); - } else if (ex) { - // New chrome and blink send along a real error object - // Let's just report that like a normal error. - // See: https://mikewest.org/2013/08/debugging-runtime-errors-with-window-onerror - stack = TraceKit.computeStackTrace(ex); - notifyHandlers(stack, true); - } else { - var location = { - 'url': url, - 'line': lineNo, - 'column': colNo - }; - location.func = TraceKit.computeStackTrace.guessFunctionName(location.url, location.line); - location.context = TraceKit.computeStackTrace.gatherContext(location.url, location.line); - stack = { - 'message': message, - 'url': document.location.href, - 'stack': [location] - }; - notifyHandlers(stack, true); - } - - if (_oldOnerrorHandler) { - return _oldOnerrorHandler.apply(this, arguments); - } - - return false; - } - - function installGlobalHandler () - { - if (_onErrorHandlerInstalled) { - return; - } - _oldOnerrorHandler = window.onerror; - window.onerror = traceKitWindowOnError; - _onErrorHandlerInstalled = true; - } - - function uninstallGlobalHandler () - { - if (!_onErrorHandlerInstalled) { - return; - } - window.onerror = _oldOnerrorHandler; - _onErrorHandlerInstalled = false; - _oldOnerrorHandler = undefined; - } - - function processLastException() { - var _lastExceptionStack = lastExceptionStack, - _lastArgs = lastArgs; - lastArgs = null; - lastExceptionStack = null; - lastException = null; - notifyHandlers.apply(null, [_lastExceptionStack, false].concat(_lastArgs)); - } - - /** - * Reports an unhandled Error to TraceKit. - * @param {Error} ex - * @param {?boolean} rethrow If false, do not re-throw the exception. - * Only used for window.onerror to not cause an infinite loop of - * rethrowing. - */ - function report(ex, rethrow) { - var args = _slice.call(arguments, 1); - if (lastExceptionStack) { - if (lastException === ex) { - return; // already caught by an inner catch block, ignore - } else { - processLastException(); - } - } - - var stack = TraceKit.computeStackTrace(ex); - lastExceptionStack = stack; - lastException = ex; - lastArgs = args; - - // If the stack trace is incomplete, wait for 2 seconds for - // slow slow IE to see if onerror occurs or not before reporting - // this exception; otherwise, we will end up with an incomplete - // stack trace - window.setTimeout(function () { - if (lastException === ex) { - processLastException(); - } - }, (stack.incomplete ? 2000 : 0)); - - if (rethrow !== false) { - throw ex; // re-throw to propagate to the top level (and cause window.onerror) - } - } - - report.subscribe = subscribe; - report.unsubscribe = unsubscribe; - report.uninstall = unsubscribeAll; - return report; -}()); - -/** - * TraceKit.computeStackTrace: cross-browser stack traces in JavaScript - * - * Syntax: - * s = TraceKit.computeStackTrace(exception) // consider using TraceKit.report instead (see below) - * Returns: - * s.name - exception name - * s.message - exception message - * s.stack[i].url - JavaScript or HTML file URL - * s.stack[i].func - function name, or empty for anonymous functions (if guessing did not work) - * s.stack[i].args - arguments passed to the function, if known - * s.stack[i].line - line number, if known - * s.stack[i].column - column number, if known - * s.stack[i].context - an array of source code lines; the middle element corresponds to the correct line# - * - * Supports: - * - Firefox: full stack trace with line numbers and unreliable column - * number on top frame - * - Opera 10: full stack trace with line and column numbers - * - Opera 9-: full stack trace with line numbers - * - Chrome: full stack trace with line and column numbers - * - Safari: line and column number for the topmost stacktrace element - * only - * - IE: no line numbers whatsoever - * - * Tries to guess names of anonymous functions by looking for assignments - * in the source code. In IE and Safari, we have to guess source file names - * by searching for function bodies inside all page scripts. This will not - * work for scripts that are loaded cross-domain. - * Here be dragons: some function names may be guessed incorrectly, and - * duplicate functions may be mismatched. - * - * TraceKit.computeStackTrace should only be used for tracing purposes. - * Logging of unhandled exceptions should be done with TraceKit.report, - * which builds on top of TraceKit.computeStackTrace and provides better - * IE support by utilizing the window.onerror event to retrieve information - * about the top of the stack. - * - * Note: In IE and Safari, no stack trace is recorded on the Error object, - * so computeStackTrace instead walks its *own* chain of callers. - * This means that: - * * in Safari, some methods may be missing from the stack trace; - * * in IE, the topmost function in the stack trace will always be the - * caller of computeStackTrace. - * - * This is okay for tracing (because you are likely to be calling - * computeStackTrace from the function you want to be the topmost element - * of the stack trace anyway), but not okay for logging unhandled - * exceptions (because your catch block will likely be far away from the - * inner function that actually caused the exception). - * - */ -TraceKit.computeStackTrace = (function computeStackTraceWrapper() { - var debug = false, - sourceCache = {}; - - /** - * Attempts to retrieve source code via XMLHttpRequest, which is used - * to look up anonymous function names. - * @param {string} url URL of source code. - * @return {string} Source contents. - */ - function loadSource(url) { - if (!TraceKit.remoteFetching) { //Only attempt request if remoteFetching is on. - return ''; - } - try { - var getXHR = function() { - try { - return new window.XMLHttpRequest(); - } catch (e) { - // explicitly bubble up the exception if not found - return new window.ActiveXObject('Microsoft.XMLHTTP'); - } - }; - - var request = getXHR(); - request.open('GET', url, false); - request.send(''); - return request.responseText; - } catch (e) { - return ''; - } - } - - /** - * Retrieves source code from the source code cache. - * @param {string} url URL of source code. - * @return {Array.} Source contents. - */ - function getSource(url) { - if (!isString(url)) return []; - if (!hasKey(sourceCache, url)) { - // URL needs to be able to fetched within the acceptable domain. Otherwise, - // cross-domain errors will be triggered. - var source = ''; - if (url.indexOf(document.domain) !== -1) { - source = loadSource(url); - } - sourceCache[url] = source ? source.split('\n') : []; - } - - return sourceCache[url]; - } - - /** - * Tries to use an externally loaded copy of source code to determine - * the name of a function by looking at the name of the variable it was - * assigned to, if any. - * @param {string} url URL of source code. - * @param {(string|number)} lineNo Line number in source code. - * @return {string} The function name, if discoverable. - */ - function guessFunctionName(url, lineNo) { - var reFunctionArgNames = /function ([^(]*)\(([^)]*)\)/, - reGuessFunction = /['"]?([0-9A-Za-z$_]+)['"]?\s*[:=]\s*(function|eval|new Function)/, - line = '', - maxLines = 10, - source = getSource(url), - m; - - if (!source.length) { - return UNKNOWN_FUNCTION; - } - - // Walk backwards from the first line in the function until we find the line which - // matches the pattern above, which is the function definition - for (var i = 0; i < maxLines; ++i) { - line = source[lineNo - i] + line; - - if (!isUndefined(line)) { - if ((m = reGuessFunction.exec(line))) { - return m[1]; - } else if ((m = reFunctionArgNames.exec(line))) { - return m[1]; - } - } - } - - return UNKNOWN_FUNCTION; - } - - /** - * Retrieves the surrounding lines from where an exception occurred. - * @param {string} url URL of source code. - * @param {(string|number)} line Line number in source code to centre - * around for context. - * @return {?Array.} Lines of source code. - */ - function gatherContext(url, line) { - var source = getSource(url); - - if (!source.length) { - return null; - } - - var context = [], - // linesBefore & linesAfter are inclusive with the offending line. - // if linesOfContext is even, there will be one extra line - // *before* the offending line. - linesBefore = Math.floor(TraceKit.linesOfContext / 2), - // Add one extra line if linesOfContext is odd - linesAfter = linesBefore + (TraceKit.linesOfContext % 2), - start = Math.max(0, line - linesBefore - 1), - end = Math.min(source.length, line + linesAfter - 1); - - line -= 1; // convert to 0-based index - - for (var i = start; i < end; ++i) { - if (!isUndefined(source[i])) { - context.push(source[i]); - } - } - - return context.length > 0 ? context : null; - } - - /** - * Escapes special characters, except for whitespace, in a string to be - * used inside a regular expression as a string literal. - * @param {string} text The string. - * @return {string} The escaped string literal. - */ - function escapeRegExp(text) { - return text.replace(/[\-\[\]{}()*+?.,\\\^$|#]/g, '\\$&'); - } - - /** - * Escapes special characters in a string to be used inside a regular - * expression as a string literal. Also ensures that HTML entities will - * be matched the same as their literal friends. - * @param {string} body The string. - * @return {string} The escaped string. - */ - function escapeCodeAsRegExpForMatchingInsideHTML(body) { - return escapeRegExp(body).replace('<', '(?:<|<)').replace('>', '(?:>|>)').replace('&', '(?:&|&)').replace('"', '(?:"|")').replace(/\s+/g, '\\s+'); - } - - /** - * Determines where a code fragment occurs in the source code. - * @param {RegExp} re The function definition. - * @param {Array.} urls A list of URLs to search. - * @return {?Object.} An object containing - * the url, line, and column number of the defined function. - */ - function findSourceInUrls(re, urls) { - var source, m; - for (var i = 0, j = urls.length; i < j; ++i) { - // console.log('searching', urls[i]); - if ((source = getSource(urls[i])).length) { - source = source.join('\n'); - if ((m = re.exec(source))) { - // console.log('Found function in ' + urls[i]); - - return { - 'url': urls[i], - 'line': source.substring(0, m.index).split('\n').length, - 'column': m.index - source.lastIndexOf('\n', m.index) - 1 - }; - } - } - } - - // console.log('no match'); - - return null; - } - - /** - * Determines at which column a code fragment occurs on a line of the - * source code. - * @param {string} fragment The code fragment. - * @param {string} url The URL to search. - * @param {(string|number)} line The line number to examine. - * @return {?number} The column number. - */ - function findSourceInLine(fragment, url, line) { - var source = getSource(url), - re = new RegExp('\\b' + escapeRegExp(fragment) + '\\b'), - m; - - line -= 1; - - if (source && source.length > line && (m = re.exec(source[line]))) { - return m.index; - } - - return null; - } - - /** - * Determines where a function was defined within the source code. - * @param {(Function|string)} func A function reference or serialized - * function definition. - * @return {?Object.} An object containing - * the url, line, and column number of the defined function. - */ - function findSourceByFunctionBody(func) { - var urls = [window.location.href], - scripts = document.getElementsByTagName('script'), - body, - code = '' + func, - codeRE = /^function(?:\s+([\w$]+))?\s*\(([\w\s,]*)\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/, - eventRE = /^function on([\w$]+)\s*\(event\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/, - re, - parts, - result; - - for (var i = 0; i < scripts.length; ++i) { - var script = scripts[i]; - if (script.src) { - urls.push(script.src); - } - } - - if (!(parts = codeRE.exec(code))) { - re = new RegExp(escapeRegExp(code).replace(/\s+/g, '\\s+')); - } - - // not sure if this is really necessary, but I don’t have a test - // corpus large enough to confirm that and it was in the original. - else { - var name = parts[1] ? '\\s+' + parts[1] : '', - args = parts[2].split(',').join('\\s*,\\s*'); - - body = escapeRegExp(parts[3]).replace(/;$/, ';?'); // semicolon is inserted if the function ends with a comment.replace(/\s+/g, '\\s+'); - re = new RegExp('function' + name + '\\s*\\(\\s*' + args + '\\s*\\)\\s*{\\s*' + body + '\\s*}'); - } - - // look for a normal function definition - if ((result = findSourceInUrls(re, urls))) { - return result; - } - - // look for an old-school event handler function - if ((parts = eventRE.exec(code))) { - var event = parts[1]; - body = escapeCodeAsRegExpForMatchingInsideHTML(parts[2]); - - // look for a function defined in HTML as an onXXX handler - re = new RegExp('on' + event + '=[\\\'"]\\s*' + body + '\\s*[\\\'"]', 'i'); - - if ((result = findSourceInUrls(re, urls[0]))) { - return result; - } - - // look for ??? - re = new RegExp(body); - - if ((result = findSourceInUrls(re, urls))) { - return result; - } - } - - return null; - } - - // Contents of Exception in various browsers. - // - // SAFARI: - // ex.message = Can't find variable: qq - // ex.line = 59 - // ex.sourceId = 580238192 - // ex.sourceURL = http://... - // ex.expressionBeginOffset = 96 - // ex.expressionCaretOffset = 98 - // ex.expressionEndOffset = 98 - // ex.name = ReferenceError - // - // FIREFOX: - // ex.message = qq is not defined - // ex.fileName = http://... - // ex.lineNumber = 59 - // ex.columnNumber = 69 - // ex.stack = ...stack trace... (see the example below) - // ex.name = ReferenceError - // - // CHROME: - // ex.message = qq is not defined - // ex.name = ReferenceError - // ex.type = not_defined - // ex.arguments = ['aa'] - // ex.stack = ...stack trace... - // - // INTERNET EXPLORER: - // ex.message = ... - // ex.name = ReferenceError - // - // OPERA: - // ex.message = ...message... (see the example below) - // ex.name = ReferenceError - // ex.opera#sourceloc = 11 (pretty much useless, duplicates the info in ex.message) - // ex.stacktrace = n/a; see 'opera:config#UserPrefs|Exceptions Have Stacktrace' - - /** - * Computes stack trace information from the stack property. - * Chrome and Gecko use this property. - * @param {Error} ex - * @return {?Object.} Stack trace information. - */ - function computeStackTraceFromStackProp(ex) { - if (!ex.stack) { - return null; - } - - var chrome = /^\s*at (.*?) ?\(?((?:file|https?|chrome-extension):.*?):(\d+)(?::(\d+))?\)?\s*$/i, - gecko = /^\s*(.*?)(?:\((.*?)\))?@((?:file|https?|chrome).*?):(\d+)(?::(\d+))?\s*$/i, - lines = ex.stack.split('\n'), - stack = [], - parts, - element, - reference = /^(.*) is undefined$/.exec(ex.message); - - for (var i = 0, j = lines.length; i < j; ++i) { - if ((parts = gecko.exec(lines[i]))) { - element = { - 'url': parts[3], - 'func': parts[1] || UNKNOWN_FUNCTION, - 'args': parts[2] ? parts[2].split(',') : '', - 'line': +parts[4], - 'column': parts[5] ? +parts[5] : null - }; - } else if ((parts = chrome.exec(lines[i]))) { - element = { - 'url': parts[2], - 'func': parts[1] || UNKNOWN_FUNCTION, - 'line': +parts[3], - 'column': parts[4] ? +parts[4] : null - }; - } else { - continue; - } - - if (!element.func && element.line) { - element.func = guessFunctionName(element.url, element.line); - } - - if (element.line) { - element.context = gatherContext(element.url, element.line); - } - - stack.push(element); - } - - if (!stack.length) { - return null; - } - - if (stack[0].line && !stack[0].column && reference) { - stack[0].column = findSourceInLine(reference[1], stack[0].url, stack[0].line); - } else if (!stack[0].column && !isUndefined(ex.columnNumber)) { - // FireFox uses this awesome columnNumber property for its top frame - // Also note, Firefox's column number is 0-based and everything else expects 1-based, - // so adding 1 - stack[0].column = ex.columnNumber + 1; - } - - return { - 'name': ex.name, - 'message': ex.message, - 'url': document.location.href, - 'stack': stack - }; - } - - /** - * Computes stack trace information from the stacktrace property. - * Opera 10 uses this property. - * @param {Error} ex - * @return {?Object.} Stack trace information. - */ - function computeStackTraceFromStacktraceProp(ex) { - // Access and store the stacktrace property before doing ANYTHING - // else to it because Opera is not very good at providing it - // reliably in other circumstances. - var stacktrace = ex.stacktrace; - - var testRE = / line (\d+), column (\d+) in (?:]+)>|([^\)]+))\((.*)\) in (.*):\s*$/i, - lines = stacktrace.split('\n'), - stack = [], - parts; - - for (var i = 0, j = lines.length; i < j; i += 2) { - if ((parts = testRE.exec(lines[i]))) { - var element = { - 'line': +parts[1], - 'column': +parts[2], - 'func': parts[3] || parts[4], - 'args': parts[5] ? parts[5].split(',') : [], - 'url': parts[6] - }; - - if (!element.func && element.line) { - element.func = guessFunctionName(element.url, element.line); - } - if (element.line) { - try { - element.context = gatherContext(element.url, element.line); - } catch (exc) {} - } - - if (!element.context) { - element.context = [lines[i + 1]]; - } - - stack.push(element); - } - } - - if (!stack.length) { - return null; - } - - return { - 'name': ex.name, - 'message': ex.message, - 'url': document.location.href, - 'stack': stack - }; - } - - /** - * NOT TESTED. - * Computes stack trace information from an error message that includes - * the stack trace. - * Opera 9 and earlier use this method if the option to show stack - * traces is turned on in opera:config. - * @param {Error} ex - * @return {?Object.} Stack information. - */ - function computeStackTraceFromOperaMultiLineMessage(ex) { - // Opera includes a stack trace into the exception message. An example is: - // - // Statement on line 3: Undefined variable: undefinedFunc - // Backtrace: - // Line 3 of linked script file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.js: In function zzz - // undefinedFunc(a); - // Line 7 of inline#1 script in file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.html: In function yyy - // zzz(x, y, z); - // Line 3 of inline#1 script in file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.html: In function xxx - // yyy(a, a, a); - // Line 1 of function script - // try { xxx('hi'); return false; } catch(ex) { TraceKit.report(ex); } - // ... - - var lines = ex.message.split('\n'); - if (lines.length < 4) { - return null; - } - - var lineRE1 = /^\s*Line (\d+) of linked script ((?:file|https?)\S+)(?:: in function (\S+))?\s*$/i, - lineRE2 = /^\s*Line (\d+) of inline#(\d+) script in ((?:file|https?)\S+)(?:: in function (\S+))?\s*$/i, - lineRE3 = /^\s*Line (\d+) of function script\s*$/i, - stack = [], - scripts = document.getElementsByTagName('script'), - inlineScriptBlocks = [], - parts, - i, - len, - source; - - for (i in scripts) { - if (hasKey(scripts, i) && !scripts[i].src) { - inlineScriptBlocks.push(scripts[i]); - } - } - - for (i = 2, len = lines.length; i < len; i += 2) { - var item = null; - if ((parts = lineRE1.exec(lines[i]))) { - item = { - 'url': parts[2], - 'func': parts[3], - 'line': +parts[1] - }; - } else if ((parts = lineRE2.exec(lines[i]))) { - item = { - 'url': parts[3], - 'func': parts[4] - }; - var relativeLine = (+parts[1]); // relative to the start of the - - - - - - -TraceKit specific optional settings -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Usually there is no need to touch these settings, but they exist in case you need to tweak something. - -fetchContext ------------- - -Enable TraceKit to attempt to fetch source files to look up anonymous function names, this can be useful to enable if you don't get the context for some entries in the stack trace. Default value is ``false``. - -.. code-block:: javascript - - { - fetchContext: true - } - -linesOfContext --------------- - -The count of lines surrounding the error line that should be used as context in the stack trace, default value is ``11``. Only applicable when ``fetchContext` is enabled. - -.. code-block:: javascript - - { - linesOfContext: 11 - } - -collectWindowErrors -------------------- - -Enable or disable the TraceKit ``window.onerror`` handler, default value is ``true``. - -.. code-block:: javascript - - { - collectWindowErrors: true - } diff --git a/htdocs/includes/raven-js/docs/contributing/index.rst b/htdocs/includes/raven-js/docs/contributing/index.rst deleted file mode 100644 index 2b25abf7f16..00000000000 --- a/htdocs/includes/raven-js/docs/contributing/index.rst +++ /dev/null @@ -1,99 +0,0 @@ -Contributing -============ - -Setting up an Environment -~~~~~~~~~~~~~~~~~~~~~~~~~ - -To run the test suite and run our code linter, node.js and npm are required. If you don't have node installed, `get it here `_ first. - -Installing all other dependencies is as simple as: - -.. code-block:: sh - - $ npm install - -And if you don't have `Grunt `_ already, feel free to install that globally: - -.. code-block:: sh - - $ npm install -g grunt-cli - -Running the Test Suite -~~~~~~~~~~~~~~~~~~~~~~ - -The test suite is powered by `Mocha `_ and can both run from the command line, or in the browser. - -From the command line: - -.. code-block:: sh - - $ grunt test - -From your browser: - -.. code-block:: sh - - $ grunt run:test - -Then visit: http://localhost:8000/test/ - -Compiling Raven.js -~~~~~~~~~~~~~~~~~~ - -The simplest way to compile your own version of Raven.js is with the supplied grunt command: - -.. code-block:: sh - - $ grunt build - -By default, this will compile raven.js and all of the included plugins. - -If you only want to compile the core raven.js: - -.. code-block:: sh - - $ grunt build.core - -Files are compiled into ``build/``. - -Contributing Back Code -~~~~~~~~~~~~~~~~~~~~~~ - -Please, send over suggestions and bug fixes in the form of pull requests on `GitHub `_. Any nontrivial fixes/features should include tests. -Do not include any changes to the ``dist/`` folder or bump version numbers yourself. - -Documentation -------------- - -The documentation is written using `reStructuredText `_, and compiled using `Sphinx `_. If you don't have Sphinx installed, you can do it using following command (assuming you have Python already installed in your system): - -.. code-block:: sh - - $ pip install sphinx - -Documentation can be then compiled by running: - -.. code-block:: sh - - $ make docs - -Afterwards you can view it in your browser by running following command and than pointing your browser to http://127.0.0.1:8000/: - -.. code-block:: sh - - $ grunt run:docs - - - -Releasing New Version -~~~~~~~~~~~~~~~~~~~~~ - -* Bump version numbers in both ``package.json`` and ``bower.json``. -* ``$ grunt dist`` This will compile a new version and update it in the ``dist/`` folder. -* Confirm that build was fine, etc. -* Commit new version, create a tag. Push to GitHub. -* ``$ grunt publish`` to recompile all plugins and all permutations and upload to S3. -* ``$ npm publish`` to push to npm. -* Confirm that the new version exists behind ``cdn.ravenjs.com`` -* Update version in the ``gh-pages`` branch specifically for http://ravenjs.com/. -* glhf diff --git a/htdocs/includes/raven-js/docs/index.rst b/htdocs/includes/raven-js/docs/index.rst deleted file mode 100644 index afe07bc9ab9..00000000000 --- a/htdocs/includes/raven-js/docs/index.rst +++ /dev/null @@ -1,42 +0,0 @@ -Raven.js -======== - -Raven.js is a tiny standalone JavaScript client for `Sentry `_. - -**This version of Raven.js requires Sentry 6.0 or newer.** - - -Getting Started ---------------- - -.. toctree:: - :maxdepth: 2 - - install/index - plugins/index - config/index - usage/index - tips/index - -Developers ----------- -.. toctree:: - :maxdepth: 2 - - contributing/index - -What's New? ------------ -.. toctree:: - :maxdepth: 2 - - changelog/index - -Resources ---------- -* `Download `_ -* `Bug Tracker `_ -* `Code `_ -* `IRC `_ (irc.freenode.net, #sentry) -* :doc:`Changelog ` -* Follow `@mattrobenolt `_ on Twitter for updates! diff --git a/htdocs/includes/raven-js/docs/install/index.rst b/htdocs/includes/raven-js/docs/install/index.rst deleted file mode 100644 index 17feda4e08e..00000000000 --- a/htdocs/includes/raven-js/docs/install/index.rst +++ /dev/null @@ -1,61 +0,0 @@ -Installation -============ - -Raven is distributed in a few different methods, and should get included after any other libraries are included, but before your own scripts. - -So for example: - -.. parsed-literal:: - - - - - - -This allows the ability for Raven's plugins to instrument themselves. If included before something like jQuery, it'd be impossible to use for example, the jquery plugin. - -Using our CDN -~~~~~~~~~~~~~ - -We serve our own builds off of `Fastly `_. They are accessible over both http and https, so we recommend leaving the protocol off. - -Our CDN distributes builds with and without :doc:`plugins `. - -.. parsed-literal:: - - - -**We highly recommend trying out a plugin or two since it'll greatly improve the chances that we can collect good information.** - -This version does not include any plugins. See `ravenjs.com `_ for more information about plugins and getting other builds. - -Bower -~~~~~ - -We also provide a way to deploy Raven via `bower -`_. Useful if you want serve your own scripts instead of depending on our CDN and mantain a ``bower.json`` with a list of dependencies and versions (adding the ``--save`` flag would automatically add it to ``bower.json``). - -.. code-block:: sh - - $ bower install raven-js --save - -.. code-block:: html - - - -Also note that the file is uncompresed but is ready to pass to any decent JavaScript compressor like `uglify `_. - -npm -~~~ - -Raven is published to npm as well. https://www.npmjs.com/package/raven-js - -.. code-block:: sh - - $ npm install raven-js --save - -Requirements -~~~~~~~~~~~~ - -Raven expects the browser to provide `window.JSON` and `window.JSON.stringify`. In Internet Explorer 8+ these are available in `standards mode `_. -You can also use `json2.js `_ to provide the JSON implementation in browsers/modes which doesn't support native JSON diff --git a/htdocs/includes/raven-js/docs/make.bat b/htdocs/includes/raven-js/docs/make.bat deleted file mode 100644 index 13e2848a47d..00000000000 --- a/htdocs/includes/raven-js/docs/make.bat +++ /dev/null @@ -1,190 +0,0 @@ -@ECHO OFF - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set BUILDDIR=_build -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . -set I18NSPHINXOPTS=%SPHINXOPTS% . -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% - set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% -) - -if "%1" == "" goto help - -if "%1" == "help" ( - :help - echo.Please use `make ^` where ^ is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. singlehtml to make a single large HTML file - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. devhelp to make HTML files and a Devhelp project - echo. epub to make an epub - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. text to make text files - echo. man to make manual pages - echo. texinfo to make Texinfo files - echo. gettext to make PO message catalogs - echo. changes to make an overview over all changed/added/deprecated items - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - goto end -) - -if "%1" == "clean" ( - for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i - del /q /s %BUILDDIR%\* - goto end -) - -if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end -) - -if "%1" == "singlehtml" ( - %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. - goto end -) - -if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %BUILDDIR%/htmlhelp. - goto end -) - -if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\raven-js.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\raven-js.ghc - goto end -) - -if "%1" == "devhelp" ( - %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. - goto end -) - -if "%1" == "epub" ( - %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The epub file is in %BUILDDIR%/epub. - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "text" ( - %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The text files are in %BUILDDIR%/text. - goto end -) - -if "%1" == "man" ( - %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The manual pages are in %BUILDDIR%/man. - goto end -) - -if "%1" == "texinfo" ( - %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. - goto end -) - -if "%1" == "gettext" ( - %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The message catalogs are in %BUILDDIR%/locale. - goto end -) - -if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes - if errorlevel 1 exit /b 1 - echo. - echo.The overview file is in %BUILDDIR%/changes. - goto end -) - -if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - if errorlevel 1 exit /b 1 - echo. - echo.Link check complete; look for any errors in the above output ^ -or in %BUILDDIR%/linkcheck/output.txt. - goto end -) - -if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - if errorlevel 1 exit /b 1 - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in %BUILDDIR%/doctest/output.txt. - goto end -) - -:end diff --git a/htdocs/includes/raven-js/docs/plugins/index.rst b/htdocs/includes/raven-js/docs/plugins/index.rst deleted file mode 100644 index 7a9df7b019e..00000000000 --- a/htdocs/includes/raven-js/docs/plugins/index.rst +++ /dev/null @@ -1,20 +0,0 @@ -Plugins -======= - -What are plugins? -~~~~~~~~~~~~~~~~~ - -In Raven.js, plugins are little snippets of code to augment functionality for a specific application/framework. It is highly recommended to checkout the list of plugins and use what apply to your project. - -In order to keep the core small, we have opted to only include the most basic functionality by default, and you can pick and choose which plugins are applicable for you. - -Why are plugins needed at all? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -JavaScript is pretty restrictive when it comes to exception handling, and there are a lot of things that make it difficult to get relevent information, so it's important that we inject code and wrap things magically so we can extract what we need. See :doc:`/usage/index` for tips regarding that. - - -All Plugins -~~~~~~~~~~~ -* https://github.com/getsentry/raven-js/tree/master/plugins -* `Download `_ diff --git a/htdocs/includes/raven-js/docs/tips/index.rst b/htdocs/includes/raven-js/docs/tips/index.rst deleted file mode 100644 index 8dee09eb7ef..00000000000 --- a/htdocs/includes/raven-js/docs/tips/index.rst +++ /dev/null @@ -1,79 +0,0 @@ -Pro Tips™ -========= - - -Decluttering Sentry -~~~~~~~~~~~~~~~~~~~ - -The first thing to do is to consider constructing a whitelist of domains in which might raise acceptable exceptions. - -If your scripts are loaded from ``cdn.example.com`` and your site is ``example.com`` it'd be reasonable to set ``whitelistUrls`` to: - -.. code-block:: javascript - - whitelistUrls: [ - /https?:\/\/((cdn|www)\.)?example\.com/ - ] - -Since this accepts a regular expression, that would catch anything \*.example.com or example.com exactly. See also: :ref:`Config: whitelistUrls`. - -Next, checkout the list of :doc:`plugins ` we provide and see which are applicable to you. - -The community has compiled a list of common ignore rules for common things, like Facebook, Chrome extensions, etc. So it's recommended to at least check these out and see if they apply to you. `Check out the original gist `_. - -.. code-block:: javascript - - var ravenOptions = { - ignoreErrors: [ - // Random plugins/extensions - 'top.GLOBALS', - // See: http://blog.errorception.com/2012/03/tale-of-unfindable-js-error. html - 'originalCreateNotification', - 'canvas.contentDocument', - 'MyApp_RemoveAllHighlights', - 'http://tt.epicplay.com', - 'Can\'t find variable: ZiteReader', - 'jigsaw is not defined', - 'ComboSearch is not defined', - 'http://loading.retry.widdit.com/', - 'atomicFindClose', - // Facebook borked - 'fb_xd_fragment', - // ISP "optimizing" proxy - `Cache-Control: no-transform` seems to reduce this. (thanks @acdha) - // See http://stackoverflow.com/questions/4113268/how-to-stop-javascript-injection-from-vodafone-proxy - 'bmi_SafeAddOnload', - 'EBCallBackMessageReceived', - // See http://toolbar.conduit.com/Developer/HtmlAndGadget/Methods/JSInjection.aspx - 'conduitPage' - ], - ignoreUrls: [ - // Facebook flakiness - /graph\.facebook\.com/i, - // Facebook blocked - /connect\.facebook\.net\/en_US\/all\.js/i, - // Woopra flakiness - /eatdifferent\.com\.woopra-ns\.com/i, - /static\.woopra\.com\/js\/woopra\.js/i, - // Chrome extensions - /extensions\//i, - /^chrome:\/\//i, - // Other plugins - /127\.0\.0\.1:4001\/isrunning/i, // Cacaoweb - /webappstoolbarba\.texthelp\.com\//i, - /metrics\.itunes\.apple\.com\.edgesuite\.net\//i - ] - }; - - -Sampling Data -~~~~~~~~~~~~~ - -It happens frequently that errors sent from your frontend can be overwhelming. One solution here is to only send a sample of the events that happen. You can do this via the ``shouldSendCallback`` setting: - -.. code-block:: javascript - - shouldSendCallback: function(data) { - // only send 10% of errors - var sampleRate = 10; - return (Math.random() * 100 <= sampleRate); - } diff --git a/htdocs/includes/raven-js/docs/usage/index.rst b/htdocs/includes/raven-js/docs/usage/index.rst deleted file mode 100644 index c8e01f9c801..00000000000 --- a/htdocs/includes/raven-js/docs/usage/index.rst +++ /dev/null @@ -1,156 +0,0 @@ -Usage -===== - -By default, Raven makes a few efforts to try its best to capture meaningful stack traces, but browsers make it pretty difficult. - -The easiest solution is to prevent an error from bubbling all of the way up the stack to ``window``. - -How to actually capture an error correctly -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -try...catch ------------ - -The simplest way, is to try and explicitly capture and report potentially problematic code with a ``try...catch`` block and ``Raven.captureException``. - -.. code-block:: javascript - - try { - doSomething(a[0]) - } catch(e) { - Raven.captureException(e) - } - -**Do not** throw strings! Always throw an actual ``Error`` object. For example: - -.. code-block:: javascript - - throw new Error('broken') // good - throw 'broken' // bad - -It's impossible to retrieve a stack trace from a string. If this happens, Raven transmits the error as a plain message. - -context/wrap ------------- - -``Raven.context`` allows you to wrap any function to be immediately executed. Behind the scenes, Raven is just wrapping your code in a ``try...catch`` block to record the exception before re-throwing it. - -.. code-block:: javascript - - Raven.context(function() { - doSomething(a[0]) - }) - -``Raven.wrap`` wraps a function in a similar way to ``Raven.context``, but instead of executing the function, it returns another function. This is totally awesome for use when passing around a callback. - -.. code-block:: javascript - - var doIt = function() { - // doing cool stuff - } - - setTimeout(Raven.wrap(doIt), 1000) - -Tracking authenticated users -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -While a user is logged in, you can tell Sentry to associate errors with user data. - -.. code-block:: javascript - - Raven.setUserContext({ - email: 'matt@example.com', - id: '123' - }) - -If at any point, the user becomes unauthenticated, you can call ``Raven.setUserContext()`` with no arguments to remove their data. *This would only really be useful in a large web app where the user logs in/out without a page reload.* - -Capturing a specific message -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: javascript - - Raven.captureMessage('Broken!') - -Passing additional data -~~~~~~~~~~~~~~~~~~~~~~~ - -``captureException``, ``context``, ``wrap``, and ``captureMessage`` functions all allow passing additional data to be tagged onto the error, such as ``tags`` or ``extra`` for additional context. - -.. code-block:: javascript - - Raven.captureException(e, {tags: { key: "value" }}) - - Raven.captureMessage('Broken!', {tags: { key: "value" }}) - - Raven.context({tags: { key: "value" }}, function(){ ... }) - - Raven.wrap({logger: "my.module"}, function(){ ... }) - - Raven.captureException(e, {extra: { foo: "bar" }}) - -You can also set context variables globally to be merged in with future exceptions with ``setExtraContext`` and ``setTagsContext``. - -.. code-block:: javascript - - Raven.setExtraContext({ foo: "bar" }) - Raven.setTagsContext({ key: "value" }) - - -Getting back an event id -~~~~~~~~~~~~~~~~~~~~~~~~ - -An event id is a globally unique id for the event that was just sent. This event id can be used to find the exact event from within Sentry. - -This is often used to display for the user and report an error to customer service. - -.. code-block:: javascript - - Raven.lastEventId() - -``Raven.lastEventId()`` will be undefined until an event is sent. After an event is sent, it will contain the string id. - -.. code-block:: javascript - - Raven.captureMessage('Broken!') - alert(Raven.lastEventId()) - - -Check if Raven is setup and ready to go -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: javascript - - Raven.isSetup() - - -Dealing with minified source code -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Raven and Sentry now support `Source Maps `_. - -We have provided some instructions to creating Source Maps over at https://www.getsentry.com/docs/sourcemaps/. Also, checkout our `Gruntfile `_ for a good example of what we're doing. - -You can use `Source Map Validator `_ to help verify that things are correct. - -CORS -~~~~ - -If you're hosting your scripts on another domain and things don't get caught by Raven, it's likely that the error will bubble up to ``window.onerror``. If this happens, the error will report some ugly ``Script error`` and Raven will drop it on the floor -since this is a useless error for everybody. - -To help mitigate this, we can tell the browser that these scripts are safe and we're allowing them to expose their errors to us. - -In your `` - -And set an ``Access-Control-Allow-Origin`` HTTP header on that file. - -.. code-block:: console - - Access-Control-Allow-Origin: * - -**Note: both of these steps need to be done or your scripts might not even get executed** diff --git a/htdocs/includes/raven-js/example/Makefile b/htdocs/includes/raven-js/example/Makefile deleted file mode 100644 index 87976776e90..00000000000 --- a/htdocs/includes/raven-js/example/Makefile +++ /dev/null @@ -1,3 +0,0 @@ - -build: - ../node_modules/.bin/uglifyjs --source-map=file.sourcemap.js -c -o file.min.js file1.js file2.js diff --git a/htdocs/includes/raven-js/example/file.min.js b/htdocs/includes/raven-js/example/file.min.js deleted file mode 100644 index 12b9f811b28..00000000000 --- a/htdocs/includes/raven-js/example/file.min.js +++ /dev/null @@ -1,2 +0,0 @@ -function add(a,b){"use strict";return a+b}function multiply(a,b){"use strict";return a*b}function divide(a,b){"use strict";try{return multiply(add(a,b),a,b)/c}catch(e){Raven.captureException(e)}} -//@ sourceMappingURL=file.sourcemap.js \ No newline at end of file diff --git a/htdocs/includes/raven-js/example/file.sourcemap.js b/htdocs/includes/raven-js/example/file.sourcemap.js deleted file mode 100644 index 1bd0f6510cf..00000000000 --- a/htdocs/includes/raven-js/example/file.sourcemap.js +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"file.min.js","sources":["file1.js","file2.js"],"names":["add","a","b","multiply","divide","c","e","Raven","captureException"],"mappings":"AAAA,QAASA,KAAIC,EAAGC,GACf,YACA,OAAOD,GAAIC,ECFZ,QAASC,UAASF,EAAGC,GACpB,YACA,OAAOD,GAAIC,EAEZ,QAASE,QAAOH,EAAGC,GAClB,YACA,KACC,MAAOC,UAASH,IAAIC,EAAGC,GAAID,EAAGC,GAAKG,EAClC,MAAOC,GACRC,MAAMC,iBAAiBF"} \ No newline at end of file diff --git a/htdocs/includes/raven-js/example/file1.js b/htdocs/includes/raven-js/example/file1.js deleted file mode 100644 index eed5827852d..00000000000 --- a/htdocs/includes/raven-js/example/file1.js +++ /dev/null @@ -1,4 +0,0 @@ -function add(a, b) { - "use strict"; - return a + b; -} \ No newline at end of file diff --git a/htdocs/includes/raven-js/example/file2.js b/htdocs/includes/raven-js/example/file2.js deleted file mode 100644 index 8b174356846..00000000000 --- a/htdocs/includes/raven-js/example/file2.js +++ /dev/null @@ -1,12 +0,0 @@ -function multiply(a, b) { - "use strict"; - return a * b; -} -function divide(a, b) { - "use strict"; - try { - return multiply(add(a, b), a, b) / c; - } catch (e) { - Raven.captureException(e); - } -} diff --git a/htdocs/includes/raven-js/example/index.html b/htdocs/includes/raven-js/example/index.html deleted file mode 100644 index b7ebbdd018e..00000000000 --- a/htdocs/includes/raven-js/example/index.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - Scratch Disk - - - - - - - - - - - - - - - - - - diff --git a/htdocs/includes/raven-js/example/scratch.js b/htdocs/includes/raven-js/example/scratch.js deleted file mode 100644 index f1962bbdfc1..00000000000 --- a/htdocs/includes/raven-js/example/scratch.js +++ /dev/null @@ -1,42 +0,0 @@ -function foo() { - console.log("lol, i don't do anything") -} - -function foo2() { - foo() - console.log('i called foo') -} - -function broken() { - try { - /*fkjdsahfdhskfhdsahfudshafuoidashfudsa*/ fdasfds[0]; // i throw an error h sadhf hadsfdsakf kl;dsjaklf jdklsajfk ljds;klafldsl fkhdas;hf hdsaf hdsalfhjldksahfljkdsahfjkl dhsajkfl hdklsahflkjdsahkfj hdsjakhf dkashfl diusafh kdsjahfkldsahf jkdashfj khdasjkfhdjksahflkjdhsakfhjdksahfjkdhsakf hdajskhf kjdash kjfads fjkadsh jkfdsa jkfdas jkfdjkas hfjkdsajlk fdsajk fjkdsa fjdsa fdkjlsa fjkdaslk hfjlkdsah fhdsahfui - }catch(e) { - Raven.captureException(e); - } -} - -function ready() { - document.getElementById('test').onclick = broken; -} - -function foo3() { - document.getElementById('crap').value = 'barfdasjkfhoadshflkaosfjadiosfhdaskjfasfadsfads'; -} - -function somethingelse() { - document.getElementById('somethingelse').value = 'this is some realy really long message just so our minification is largeeeeeeeeee!'; -} - -function derp() { - fdas[0]; -} - -function testOptions() { - Raven.context({tags: {foo: 'bar'}}, function() { - throw new Error('foo'); - }); -} - -function throwString() { - throw 'oops'; -} diff --git a/htdocs/includes/raven-js/package.json b/htdocs/includes/raven-js/package.json deleted file mode 100644 index 9352edcab38..00000000000 --- a/htdocs/includes/raven-js/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "raven-js", - "version": "1.1.19", - "license": "BSD-2-Clause", - "homepage": "https://getsentry.com", - "scripts": { - "pretest": "npm install", - "test": "grunt test" - }, - "repository": { - "type": "git", - "url": "git://github.com/getsentry/raven-js.git" - }, - "main": "dist/raven.js", - "devDependencies": { - "chai": "~1.8.1", - "grunt": "~0.4.1", - "grunt-cli": "~0.1.9", - "grunt-contrib-jshint": "~0.6.3", - "grunt-contrib-uglify": "~0.2.2", - "grunt-contrib-concat": "~0.3.0", - "grunt-contrib-clean": "~0.4.0", - "grunt-mocha": "~0.4.1", - "grunt-release": "~0.6.0", - "grunt-s3": "~0.2.0-alpha.3", - "grunt-gitinfo": "~0.1.1", - "grunt-contrib-connect": "~0.5.0", - "grunt-contrib-copy": "~0.4.1", - "sinon": "~1.7.3", - "lodash": "~2.4.0" - } -} diff --git a/htdocs/includes/raven-js/plugins/angular.js b/htdocs/includes/raven-js/plugins/angular.js deleted file mode 100644 index 98bf5892001..00000000000 --- a/htdocs/includes/raven-js/plugins/angular.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Angular.js plugin - * - * Provides an $exceptionHandler for Angular.js - */ -;(function(Raven, angular) { -'use strict'; - -// quit if angular isn't on the page -if (!angular) { - return; -} - -function ngRavenProvider($provide) { - $provide.decorator('$exceptionHandler', [ - 'RavenConfig', '$delegate', - ngRavenExceptionHandler - ]); -} - -function ngRavenExceptionHandler(RavenConfig, $delegate) { - if (!RavenConfig) - throw new Error('RavenConfig must be set before using this'); - - Raven.config(RavenConfig.dsn, RavenConfig.config).install(); - return function angularExceptionHandler(ex, cause) { - $delegate(ex, cause); - Raven.captureException(ex, {extra: {cause: cause}}); - }; -} - -angular.module('ngRaven', []) - .config(['$provide', ngRavenProvider]) - .value('Raven', Raven); - -})(window.Raven, window.angular); diff --git a/htdocs/includes/raven-js/plugins/backbone.js b/htdocs/includes/raven-js/plugins/backbone.js deleted file mode 100644 index 09e0f6b8c1c..00000000000 --- a/htdocs/includes/raven-js/plugins/backbone.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Backbone.js plugin - * - * Patches Backbone.Events callbacks. - */ -;(function(window, Raven, Backbone) { -'use strict'; - -// quit if Backbone isn't on the page -if (!Backbone) { - return; -} - -function makeBackboneEventsOn(oldOn) { - return function BackboneEventsOn(name, callback, context) { - var wrapCallback = function (cb) { - if (Object.prototype.toString.call(cb) === '[object Function]') { - var _callback = cb._callback || cb; - cb = Raven.wrap(cb); - cb._callback = _callback; - } - return cb; - }; - if (Object.prototype.toString.call(name) === '[object Object]') { - // Handle event maps. - for (var key in name) { - if (name.hasOwnProperty(key)) { - name[key] = wrapCallback(name[key]); - } - } - } else { - callback = wrapCallback(callback); - } - return oldOn.call(this, name, callback, context); - }; -} - -// We're too late to catch all of these by simply patching Backbone.Events.on -var affectedObjects = [ - Backbone.Events, - Backbone, - Backbone.Model.prototype, - Backbone.Collection.prototype, - Backbone.View.prototype, - Backbone.Router.prototype, - Backbone.History.prototype -], i = 0, l = affectedObjects.length; - -for (; i < l; i++) { - var affected = affectedObjects[i]; - affected.on = makeBackboneEventsOn(affected.on); - affected.bind = affected.on; -} - -}(window, window.Raven, window.Backbone)); diff --git a/htdocs/includes/raven-js/plugins/console.js b/htdocs/includes/raven-js/plugins/console.js deleted file mode 100644 index 4d5ba94090f..00000000000 --- a/htdocs/includes/raven-js/plugins/console.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * console plugin - * - * Monkey patches console.* calls into Sentry messages with - * their appropriate log levels. (Experimental) - */ -;(function(window, Raven, console) { -'use strict'; - -var originalConsole = console, - logLevels = ['debug', 'info', 'warn', 'error'], - level = logLevels.pop(); - -var logForGivenLevel = function(level) { - var originalConsoleLevel = console[level]; - - // warning level is the only level that doesn't map up - // correctly with what Sentry expects. - if (level === 'warn') level = 'warning'; - return function () { - var args = [].slice.call(arguments); - Raven.captureMessage('' + args, {level: level, logger: 'console'}); - - // this fails for some browsers. :( - if (originalConsoleLevel) { - // IE9 doesn't allow calling apply on console functions directly - // See: https://stackoverflow.com/questions/5472938/does-ie9-support-console-log-and-is-it-a-real-function#answer-5473193 - Function.prototype.bind - .call(originalConsoleLevel, originalConsole) - .apply(originalConsole, args); - } - }; -}; - - -while(level) { - console[level] = logForGivenLevel(level); - level = logLevels.pop(); -} -// export -window.console = console; - -}(window, window.Raven, window.console || {})); diff --git a/htdocs/includes/raven-js/plugins/ember.js b/htdocs/includes/raven-js/plugins/ember.js deleted file mode 100644 index c6d0551c709..00000000000 --- a/htdocs/includes/raven-js/plugins/ember.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Ember.js plugin - * - * Patches event handler callbacks and ajax callbacks. - */ -;(function(window, Raven, Ember) { -'use strict'; - -// quit if Ember isn't on the page -if (!Ember) { - return; -} - -var _oldOnError = Ember.onerror; -Ember.onerror = function EmberOnError(error) { - Raven.captureException(error); - if (typeof _oldOnError === 'function') { - _oldOnError.call(this, error); - } -}; -Ember.RSVP.on('error', function (reason) { - if (reason instanceof Error) { - Raven.captureException(reason, {extra: {context: 'Unhandled Promise error detected'}}); - } else { - Raven.captureMessage('Unhandled Promise error detected', {extra: {reason: reason}}); - } -}); - -}(window, window.Raven, window.Ember)); diff --git a/htdocs/includes/raven-js/plugins/jquery.js b/htdocs/includes/raven-js/plugins/jquery.js deleted file mode 100644 index 4a5474cdb86..00000000000 --- a/htdocs/includes/raven-js/plugins/jquery.js +++ /dev/null @@ -1,75 +0,0 @@ -/** - * jQuery plugin - * - * Patches event handler callbacks and ajax callbacks. - */ -;(function(window, Raven, $) { -'use strict'; - -// quit if jQuery isn't on the page -if (!$) { - return; -} - -var _oldEventAdd = $.event.add; -$.event.add = function ravenEventAdd(elem, types, handler, data, selector) { - var _handler; - - if (handler && handler.handler) { - _handler = handler.handler; - handler.handler = Raven.wrap(handler.handler); - } else { - _handler = handler; - handler = Raven.wrap(handler); - } - - // If the handler we are attaching doesn’t have the same guid as - // the original, it will never be removed when someone tries to - // unbind the original function later. Technically as a result of - // this our guids are no longer globally unique, but whatever, that - // never hurt anybody RIGHT?! - if (_handler.guid) { - handler.guid = _handler.guid; - } else { - handler.guid = _handler.guid = $.guid++; - } - - return _oldEventAdd.call(this, elem, types, handler, data, selector); -}; - -var _oldReady = $.fn.ready; -$.fn.ready = function ravenjQueryReadyWrapper(fn) { - return _oldReady.call(this, Raven.wrap(fn)); -}; - -var _oldAjax = $.ajax; -$.ajax = function ravenAjaxWrapper(url, options) { - var keys = ['complete', 'error', 'success'], key; - - // Taken from https://github.com/jquery/jquery/blob/eee2eaf1d7a189d99106423a4206c224ebd5b848/src/ajax.js#L311-L318 - // If url is an object, simulate pre-1.5 signature - if (typeof url === 'object') { - options = url; - url = undefined; - } - - // Force options to be an object - options = options || {}; - - /*jshint -W084*/ - while(key = keys.pop()) { - if ($.isFunction(options[key])) { - options[key] = Raven.wrap(options[key]); - } - } - /*jshint +W084*/ - - try { - return _oldAjax.call(this, url, options); - } catch (e) { - Raven.captureException(e); - throw e; - } -}; - -}(window, window.Raven, window.jQuery)); diff --git a/htdocs/includes/raven-js/plugins/native.js b/htdocs/includes/raven-js/plugins/native.js deleted file mode 100644 index c641f13a5d1..00000000000 --- a/htdocs/includes/raven-js/plugins/native.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * native plugin - * - * Extends support for global error handling for asynchronous browser - * functions. Adopted from Closure Library's errorhandler.js. - */ -;(function extendToAsynchronousCallbacks(window, Raven) { -"use strict"; - -var _helper = function _helper(fnName) { - var originalFn = window[fnName]; - window[fnName] = function ravenAsyncExtension() { - // Make a copy of the arguments - var args = [].slice.call(arguments); - var originalCallback = args[0]; - if (typeof (originalCallback) === 'function') { - args[0] = Raven.wrap(originalCallback); - } - // IE < 9 doesn't support .call/.apply on setInterval/setTimeout, but it - // also supports only two arguments and doesn't care what this is, so we - // can just call the original function directly. - if (originalFn.apply) { - return originalFn.apply(this, args); - } else { - return originalFn(args[0], args[1]); - } - }; -}; - -_helper('setTimeout'); -_helper('setInterval'); - -}(window, window.Raven)); diff --git a/htdocs/includes/raven-js/plugins/require.js b/htdocs/includes/raven-js/plugins/require.js deleted file mode 100644 index 60378a1b0b9..00000000000 --- a/htdocs/includes/raven-js/plugins/require.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * require.js plugin - * - * Automatically wrap define/require callbacks. (Experimental) - */ -;(function(window, Raven) { -'use strict'; - -if (typeof define === 'function' && define.amd) { - window.define = Raven.wrap({deep: false}, define); - window.require = Raven.wrap({deep: false}, require); -} - -}(window, window.Raven)); diff --git a/htdocs/includes/raven-js/src/raven.js b/htdocs/includes/raven-js/src/raven.js deleted file mode 100644 index a2d2b35604b..00000000000 --- a/htdocs/includes/raven-js/src/raven.js +++ /dev/null @@ -1,830 +0,0 @@ -'use strict'; - -// First, check for JSON support -// If there is no JSON, we no-op the core features of Raven -// since JSON is required to encode the payload -var _Raven = window.Raven, - hasJSON = !!(typeof JSON === 'object' && JSON.stringify), - lastCapturedException, - lastEventId, - globalServer, - globalUser, - globalKey, - globalProject, - globalOptions = { - logger: 'javascript', - ignoreErrors: [], - ignoreUrls: [], - whitelistUrls: [], - includePaths: [], - collectWindowErrors: true, - tags: {}, - maxMessageLength: 100, - extra: {} - }, - authQueryString, - isRavenInstalled = false, - - objectPrototype = Object.prototype, - startTime = now(); - -/* - * The core Raven singleton - * - * @this {Raven} - */ -var Raven = { - VERSION: '<%= pkg.version %>', - - debug: true, - - /* - * Allow multiple versions of Raven to be installed. - * Strip Raven from the global context and returns the instance. - * - * @return {Raven} - */ - noConflict: function() { - window.Raven = _Raven; - return Raven; - }, - - /* - * Configure Raven with a DSN and extra options - * - * @param {string} dsn The public Sentry DSN - * @param {object} options Optional set of of global options [optional] - * @return {Raven} - */ - config: function(dsn, options) { - if (globalServer) { - logDebug('error', 'Error: Raven has already been configured'); - return Raven; - } - if (!dsn) return Raven; - - var uri = parseDSN(dsn), - lastSlash = uri.path.lastIndexOf('/'), - path = uri.path.substr(1, lastSlash); - - // merge in options - if (options) { - each(options, function(key, value){ - globalOptions[key] = value; - }); - } - - // "Script error." is hard coded into browsers for errors that it can't read. - // this is the result of a script being pulled in from an external domain and CORS. - globalOptions.ignoreErrors.push(/^Script error\.?$/); - globalOptions.ignoreErrors.push(/^Javascript error: Script error\.? on line 0$/); - - // join regexp rules into one big rule - globalOptions.ignoreErrors = joinRegExp(globalOptions.ignoreErrors); - globalOptions.ignoreUrls = globalOptions.ignoreUrls.length ? joinRegExp(globalOptions.ignoreUrls) : false; - globalOptions.whitelistUrls = globalOptions.whitelistUrls.length ? joinRegExp(globalOptions.whitelistUrls) : false; - globalOptions.includePaths = joinRegExp(globalOptions.includePaths); - - globalKey = uri.user; - globalProject = uri.path.substr(lastSlash + 1); - - // assemble the endpoint from the uri pieces - globalServer = '//' + uri.host + - (uri.port ? ':' + uri.port : '') + - '/' + path + 'api/' + globalProject + '/store/'; - - if (uri.protocol) { - globalServer = uri.protocol + ':' + globalServer; - } - - if (globalOptions.fetchContext) { - TraceKit.remoteFetching = true; - } - - if (globalOptions.linesOfContext) { - TraceKit.linesOfContext = globalOptions.linesOfContext; - } - - TraceKit.collectWindowErrors = !!globalOptions.collectWindowErrors; - - setAuthQueryString(); - - // return for chaining - return Raven; - }, - - /* - * Installs a global window.onerror error handler - * to capture and report uncaught exceptions. - * At this point, install() is required to be called due - * to the way TraceKit is set up. - * - * @return {Raven} - */ - install: function() { - if (isSetup() && !isRavenInstalled) { - TraceKit.report.subscribe(handleStackInfo); - isRavenInstalled = true; - } - - return Raven; - }, - - /* - * Wrap code within a context so Raven can capture errors - * reliably across domains that is executed immediately. - * - * @param {object} options A specific set of options for this context [optional] - * @param {function} func The callback to be immediately executed within the context - * @param {array} args An array of arguments to be called with the callback [optional] - */ - context: function(options, func, args) { - if (isFunction(options)) { - args = func || []; - func = options; - options = undefined; - } - - return Raven.wrap(options, func).apply(this, args); - }, - - /* - * Wrap code within a context and returns back a new function to be executed - * - * @param {object} options A specific set of options for this context [optional] - * @param {function} func The function to be wrapped in a new context - * @return {function} The newly wrapped functions with a context - */ - wrap: function(options, func) { - // 1 argument has been passed, and it's not a function - // so just return it - if (isUndefined(func) && !isFunction(options)) { - return options; - } - - // options is optional - if (isFunction(options)) { - func = options; - options = undefined; - } - - // At this point, we've passed along 2 arguments, and the second one - // is not a function either, so we'll just return the second argument. - if (!isFunction(func)) { - return func; - } - - // We don't wanna wrap it twice! - if (func.__raven__) { - return func; - } - - function wrapped() { - var args = [], i = arguments.length, - deep = !options || options && options.deep !== false; - // Recursively wrap all of a function's arguments that are - // functions themselves. - - while(i--) args[i] = deep ? Raven.wrap(options, arguments[i]) : arguments[i]; - - try { - /*jshint -W040*/ - return func.apply(this, args); - } catch(e) { - Raven.captureException(e, options); - throw e; - } - } - - // copy over properties of the old function - for (var property in func) { - if (hasKey(func, property)) { - wrapped[property] = func[property]; - } - } - - // Signal that this function has been wrapped already - // for both debugging and to prevent it to being wrapped twice - wrapped.__raven__ = true; - wrapped.__inner__ = func; - - return wrapped; - }, - - /* - * Uninstalls the global error handler. - * - * @return {Raven} - */ - uninstall: function() { - TraceKit.report.uninstall(); - isRavenInstalled = false; - - return Raven; - }, - - /* - * Manually capture an exception and send it over to Sentry - * - * @param {error} ex An exception to be logged - * @param {object} options A specific set of options for this error [optional] - * @return {Raven} - */ - captureException: function(ex, options) { - // If not an Error is passed through, recall as a message instead - if (!isError(ex)) return Raven.captureMessage(ex, options); - - // Store the raw exception object for potential debugging and introspection - lastCapturedException = ex; - - // TraceKit.report will re-raise any exception passed to it, - // which means you have to wrap it in try/catch. Instead, we - // can wrap it here and only re-raise if TraceKit.report - // raises an exception different from the one we asked to - // report on. - try { - TraceKit.report(ex, options); - } catch(ex1) { - if(ex !== ex1) { - throw ex1; - } - } - - return Raven; - }, - - /* - * Manually send a message to Sentry - * - * @param {string} msg A plain message to be captured in Sentry - * @param {object} options A specific set of options for this message [optional] - * @return {Raven} - */ - captureMessage: function(msg, options) { - // config() automagically converts ignoreErrors from a list to a RegExp so we need to test for an - // early call; we'll error on the side of logging anything called before configuration since it's - // probably something you should see: - if (!!globalOptions.ignoreErrors.test && globalOptions.ignoreErrors.test(msg)) { - return; - } - - // Fire away! - send( - objectMerge({ - message: msg + '' // Make sure it's actually a string - }, options) - ); - - return Raven; - }, - - /* - * Set/clear a user to be sent along with the payload. - * - * @param {object} user An object representing user data [optional] - * @return {Raven} - */ - setUserContext: function(user) { - globalUser = user; - - return Raven; - }, - - /* - * Set extra attributes to be sent along with the payload. - * - * @param {object} extra An object representing extra data [optional] - * @return {Raven} - */ - setExtraContext: function(extra) { - globalOptions.extra = extra || {}; - - return Raven; - }, - - /* - * Set tags to be sent along with the payload. - * - * @param {object} tags An object representing tags [optional] - * @return {Raven} - */ - setTagsContext: function(tags) { - globalOptions.tags = tags || {}; - - return Raven; - }, - - /* - * Set release version of application - * - * @param {string} release Typically something like a git SHA to identify version - * @return {Raven} - */ - setReleaseContext: function(release) { - globalOptions.release = release; - - return Raven; - }, - - /* - * Set the dataCallback option - * - * @param {function} callback The callback to run which allows the - * data blob to be mutated before sending - * @return {Raven} - */ - setDataCallback: function(callback) { - globalOptions.dataCallback = callback; - - return Raven; - }, - - /* - * Set the shouldSendCallback option - * - * @param {function} callback The callback to run which allows - * introspecting the blob before sending - * @return {Raven} - */ - setShouldSendCallback: function(callback) { - globalOptions.shouldSendCallback = callback; - - return Raven; - }, - - /* - * Get the latest raw exception that was captured by Raven. - * - * @return {error} - */ - lastException: function() { - return lastCapturedException; - }, - - /* - * Get the last event id - * - * @return {string} - */ - lastEventId: function() { - return lastEventId; - }, - - /* - * Determine if Raven is setup and ready to go. - * - * @return {boolean} - */ - isSetup: function() { - return isSetup(); - } -}; - -Raven.setUser = Raven.setUserContext; // To be deprecated - -function triggerEvent(eventType, options) { - var event, key; - - options = options || {}; - - eventType = 'raven' + eventType.substr(0,1).toUpperCase() + eventType.substr(1); - - if (document.createEvent) { - event = document.createEvent('HTMLEvents'); - event.initEvent(eventType, true, true); - } else { - event = document.createEventObject(); - event.eventType = eventType; - } - - for (key in options) if (hasKey(options, key)) { - event[key] = options[key]; - } - - if (document.createEvent) { - // IE9 if standards - document.dispatchEvent(event); - } else { - // IE8 regardless of Quirks or Standards - // IE9 if quirks - try { - document.fireEvent('on' + event.eventType.toLowerCase(), event); - } catch(e) {} - } -} - -var dsnKeys = 'source protocol user pass host port path'.split(' '), - dsnPattern = /^(?:(\w+):)?\/\/(\w+)(:\w+)?@([\w\.-]+)(?::(\d+))?(\/.*)/; - -function RavenConfigError(message) { - this.name = 'RavenConfigError'; - this.message = message; -} -RavenConfigError.prototype = new Error(); -RavenConfigError.prototype.constructor = RavenConfigError; - -/**** Private functions ****/ -function parseDSN(str) { - var m = dsnPattern.exec(str), - dsn = {}, - i = 7; - - try { - while (i--) dsn[dsnKeys[i]] = m[i] || ''; - } catch(e) { - throw new RavenConfigError('Invalid DSN: ' + str); - } - - if (dsn.pass) - throw new RavenConfigError('Do not specify your private key in the DSN!'); - - return dsn; -} - -function isUndefined(what) { - return what === void 0; -} - -function isFunction(what) { - return typeof what === 'function'; -} - -function isString(what) { - return objectPrototype.toString.call(what) === '[object String]'; -} - -function isObject(what) { - return typeof what === 'object' && what !== null; -} - -function isEmptyObject(what) { - for (var k in what) return false; - return true; -} - -// Sorta yanked from https://github.com/joyent/node/blob/aa3b4b4/lib/util.js#L560 -// with some tiny modifications -function isError(what) { - return isObject(what) && - objectPrototype.toString.call(what) === '[object Error]' || - what instanceof Error; -} - -/** - * hasKey, a better form of hasOwnProperty - * Example: hasKey(MainHostObject, property) === true/false - * - * @param {Object} host object to check property - * @param {string} key to check - */ -function hasKey(object, key) { - return objectPrototype.hasOwnProperty.call(object, key); -} - -function each(obj, callback) { - var i, j; - - if (isUndefined(obj.length)) { - for (i in obj) { - if (hasKey(obj, i)) { - callback.call(null, i, obj[i]); - } - } - } else { - j = obj.length; - if (j) { - for (i = 0; i < j; i++) { - callback.call(null, i, obj[i]); - } - } - } -} - - -function setAuthQueryString() { - authQueryString = - '?sentry_version=4' + - '&sentry_client=raven-js/' + Raven.VERSION + - '&sentry_key=' + globalKey; -} - - -function handleStackInfo(stackInfo, options) { - var frames = []; - - if (stackInfo.stack && stackInfo.stack.length) { - each(stackInfo.stack, function(i, stack) { - var frame = normalizeFrame(stack); - if (frame) { - frames.push(frame); - } - }); - } - - triggerEvent('handle', { - stackInfo: stackInfo, - options: options - }); - - processException( - stackInfo.name, - stackInfo.message, - stackInfo.url, - stackInfo.lineno, - frames, - options - ); -} - -function normalizeFrame(frame) { - if (!frame.url) return; - - // normalize the frames data - var normalized = { - filename: frame.url, - lineno: frame.line, - colno: frame.column, - 'function': frame.func || '?' - }, context = extractContextFromFrame(frame), i; - - if (context) { - var keys = ['pre_context', 'context_line', 'post_context']; - i = 3; - while (i--) normalized[keys[i]] = context[i]; - } - - normalized.in_app = !( // determine if an exception came from outside of our app - // first we check the global includePaths list. - !globalOptions.includePaths.test(normalized.filename) || - // Now we check for fun, if the function name is Raven or TraceKit - /(Raven|TraceKit)\./.test(normalized['function']) || - // finally, we do a last ditch effort and check for raven.min.js - /raven\.(min\.)?js$/.test(normalized.filename) - ); - - return normalized; -} - -function extractContextFromFrame(frame) { - // immediately check if we should even attempt to parse a context - if (!frame.context || !globalOptions.fetchContext) return; - - var context = frame.context, - pivot = ~~(context.length / 2), - i = context.length, isMinified = false; - - while (i--) { - // We're making a guess to see if the source is minified or not. - // To do that, we make the assumption if *any* of the lines passed - // in are greater than 300 characters long, we bail. - // Sentry will see that there isn't a context - if (context[i].length > 300) { - isMinified = true; - break; - } - } - - if (isMinified) { - // The source is minified and we don't know which column. Fuck it. - if (isUndefined(frame.column)) return; - - // If the source is minified and has a frame column - // we take a chunk of the offending line to hopefully shed some light - return [ - [], // no pre_context - context[pivot].substr(frame.column, 50), // grab 50 characters, starting at the offending column - [] // no post_context - ]; - } - - return [ - context.slice(0, pivot), // pre_context - context[pivot], // context_line - context.slice(pivot + 1) // post_context - ]; -} - -function processException(type, message, fileurl, lineno, frames, options) { - var stacktrace, label, i; - - // In some instances message is not actually a string, no idea why, - // so we want to always coerce it to one. - message += ''; - - // Sometimes an exception is getting logged in Sentry as - // - // This can only mean that the message was falsey since this value - // is hardcoded into Sentry itself. - // At this point, if the message is falsey, we bail since it's useless - if (type === 'Error' && !message) return; - - if (globalOptions.ignoreErrors.test(message)) return; - - if (frames && frames.length) { - fileurl = frames[0].filename || fileurl; - // Sentry expects frames oldest to newest - // and JS sends them as newest to oldest - frames.reverse(); - stacktrace = {frames: frames}; - } else if (fileurl) { - stacktrace = { - frames: [{ - filename: fileurl, - lineno: lineno, - in_app: true - }] - }; - } - - // Truncate the message to a max of characters - message = truncate(message, globalOptions.maxMessageLength); - - if (globalOptions.ignoreUrls && globalOptions.ignoreUrls.test(fileurl)) return; - if (globalOptions.whitelistUrls && !globalOptions.whitelistUrls.test(fileurl)) return; - - label = lineno ? message + ' at ' + lineno : message; - - // Fire away! - send( - objectMerge({ - // sentry.interfaces.Exception - exception: { - type: type, - value: message - }, - // sentry.interfaces.Stacktrace - stacktrace: stacktrace, - culprit: fileurl, - message: label - }, options) - ); -} - -function objectMerge(obj1, obj2) { - if (!obj2) { - return obj1; - } - each(obj2, function(key, value){ - obj1[key] = value; - }); - return obj1; -} - -function truncate(str, max) { - return str.length <= max ? str : str.substr(0, max) + '\u2026'; -} - -function now() { - return +new Date(); -} - -function getHttpData() { - var http = { - url: document.location.href, - headers: { - 'User-Agent': navigator.userAgent - } - }; - - if (document.referrer) { - http.headers.Referer = document.referrer; - } - - return http; -} - -function send(data) { - if (!isSetup()) return; - - data = objectMerge({ - project: globalProject, - logger: globalOptions.logger, - platform: 'javascript', - // sentry.interfaces.Http - request: getHttpData() - }, data); - - // Merge in the tags and extra separately since objectMerge doesn't handle a deep merge - data.tags = objectMerge(objectMerge({}, globalOptions.tags), data.tags); - data.extra = objectMerge(objectMerge({}, globalOptions.extra), data.extra); - - // Send along our own collected metadata with extra - data.extra = objectMerge({ - 'session:duration': now() - startTime - }, data.extra); - - // If there are no tags/extra, strip the key from the payload alltogther. - if (isEmptyObject(data.tags)) delete data.tags; - - if (globalUser) { - // sentry.interfaces.User - data.user = globalUser; - } - - // Include the release iff it's defined in globalOptions - if (globalOptions.release) data.release = globalOptions.release; - - if (isFunction(globalOptions.dataCallback)) { - data = globalOptions.dataCallback(data) || data; - } - - // Why?????????? - if (!data || isEmptyObject(data)) { - return; - } - - // Check if the request should be filtered or not - if (isFunction(globalOptions.shouldSendCallback) && !globalOptions.shouldSendCallback(data)) { - return; - } - - // Send along an event_id if not explicitly passed. - // This event_id can be used to reference the error within Sentry itself. - // Set lastEventId after we know the error should actually be sent - lastEventId = data.event_id || (data.event_id = uuid4()); - - makeRequest(data); -} - - -function makeRequest(data) { - var img = newImage(), - src = globalServer + authQueryString + '&sentry_data=' + encodeURIComponent(JSON.stringify(data)); - - img.crossOrigin = 'anonymous'; - img.onload = function success() { - triggerEvent('success', { - data: data, - src: src - }); - }; - img.onerror = img.onabort = function failure() { - triggerEvent('failure', { - data: data, - src: src - }); - }; - img.src = src; -} - -// Note: this is shitty, but I can't figure out how to get -// sinon to stub document.createElement without breaking everything -// so this wrapper is just so I can stub it for tests. -function newImage() { - return document.createElement('img'); -} - -function isSetup() { - if (!hasJSON) return false; // needs JSON support - if (!globalServer) { - logDebug('error', 'Error: Raven has not been configured.'); - return false; - } - return true; -} - -function joinRegExp(patterns) { - // Combine an array of regular expressions and strings into one large regexp - // Be mad. - var sources = [], - i = 0, len = patterns.length, - pattern; - - for (; i < len; i++) { - pattern = patterns[i]; - if (isString(pattern)) { - // If it's a string, we need to escape it - // Taken from: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions - sources.push(pattern.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1")); - } else if (pattern && pattern.source) { - // If it's a regexp already, we want to extract the source - sources.push(pattern.source); - } - // Intentionally skip other cases - } - return new RegExp(sources.join('|'), 'i'); -} - -// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523 -function uuid4() { - return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) { - var r = Math.random()*16|0, - v = c == 'x' ? r : (r&0x3|0x8); - return v.toString(16); - }); -} - -function logDebug(level, message) { - if (window.console && console[level] && Raven.debug) { - console[level](message); - } -} - -function afterLoad() { - // Attempt to initialize Raven on load - var RavenConfig = window.RavenConfig; - if (RavenConfig) { - Raven.config(RavenConfig.dsn, RavenConfig.config).install(); - } -} -afterLoad(); diff --git a/htdocs/includes/raven-js/template/_copyright.js b/htdocs/includes/raven-js/template/_copyright.js deleted file mode 100644 index f1ee87084f8..00000000000 --- a/htdocs/includes/raven-js/template/_copyright.js +++ /dev/null @@ -1,11 +0,0 @@ -/*! Raven.js <%= pkg.release %> (<%= gitinfo.local.branch.current.shortSHA %>) | github.com/getsentry/raven-js */ - -/* - * Includes TraceKit - * https://github.com/getsentry/TraceKit - * - * Copyright <%= grunt.template.today('yyyy') %> Matt Robenolt and other contributors - * Released under the BSD license - * https://github.com/getsentry/raven-js/blob/master/LICENSE - * - */ diff --git a/htdocs/includes/raven-js/template/_footer.js b/htdocs/includes/raven-js/template/_footer.js deleted file mode 100644 index 9d102d2458d..00000000000 --- a/htdocs/includes/raven-js/template/_footer.js +++ /dev/null @@ -1,19 +0,0 @@ -// Expose Raven to the world -if (typeof define === 'function' && define.amd) { - // AMD - window.Raven = Raven; - define('raven', [], function() { - return Raven; - }); -} else if (typeof module === 'object') { - // browserify - module.exports = Raven; -} else if (typeof exports === 'object') { - // CommonJS - exports = Raven; -} else { - // Everything else - window.Raven = Raven; -} - -})(typeof window !== 'undefined' ? window : this); diff --git a/htdocs/includes/raven-js/template/_header.js b/htdocs/includes/raven-js/template/_header.js deleted file mode 100644 index 27595a61a2d..00000000000 --- a/htdocs/includes/raven-js/template/_header.js +++ /dev/null @@ -1,2 +0,0 @@ -;(function(window, undefined){ -'use strict'; diff --git a/htdocs/includes/raven-js/test/index.html b/htdocs/includes/raven-js/test/index.html deleted file mode 100644 index b5188ed0600..00000000000 --- a/htdocs/includes/raven-js/test/index.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - Raven.js Test Suite - - - - -
- - - - - - - - - - - - - - - - - - - diff --git a/htdocs/includes/raven-js/test/raven.test.js b/htdocs/includes/raven-js/test/raven.test.js deleted file mode 100644 index e26a36ef174..00000000000 --- a/htdocs/includes/raven-js/test/raven.test.js +++ /dev/null @@ -1,1773 +0,0 @@ -function flushRavenState() { - authQueryString = undefined; - hasJSON = !isUndefined(window.JSON); - lastCapturedException = undefined; - lastEventId = undefined; - globalServer = undefined; - globalUser = undefined; - globalProject = undefined; - globalOptions = { - logger: 'javascript', - release: undefined, - ignoreErrors: [], - ignoreUrls: [], - whitelistUrls: [], - includePaths: [], - collectWindowErrors: true, - maxMessageLength: 100, - tags: {}, - extra: {} - }, - startTime = 0 - ; - - Raven.uninstall(); -} - -// window.console must be stubbed in for browsers that don't have it -if (typeof window.console === 'undefined') { - console = {error: function(){}}; -} - -var SENTRY_DSN = 'http://abc@example.com:80/2'; - -function setupRaven() { - Raven.config(SENTRY_DSN); -} - -// patched to return a predictable result -function uuid4() { - return 'abc123'; -} - -// patched to be predictable -function now() { - return 100; -} - -describe('TraceKit', function(){ - describe('stacktrace info', function() { - it('should not remove anonymous functions from the stack', function() { - // mock up an error object with a stack trace that includes both - // named functions and anonymous functions - var stack_str = "" + - " Error: \n" + - " at new (http://example.com/js/test.js:63)\n" + // stack[0] - " at namedFunc0 (http://example.com/js/script.js:10)\n" + // stack[1] - " at http://example.com/js/test.js:65\n" + // stack[2] - " at namedFunc2 (http://example.com/js/script.js:20)\n" + // stack[3] - " at http://example.com/js/test.js:67\n" + // stack[4] - " at namedFunc4 (http://example.com/js/script.js:100001)"; // stack[5] - var mock_err = { stack: stack_str }; - var trace = TraceKit.computeStackTrace.computeStackTraceFromStackProp(mock_err); - - // Make sure TraceKit didn't remove the anonymous functions - // from the stack like it used to :) - assert.equal(trace.stack[0].func, 'new '); - assert.equal(trace.stack[1].func, 'namedFunc0'); - assert.equal(trace.stack[2].func, '?'); - assert.equal(trace.stack[3].func, 'namedFunc2'); - assert.equal(trace.stack[4].func, '?'); - assert.equal(trace.stack[5].func, 'namedFunc4'); - }); - }); - describe('error notifications', function(){ - var testMessage = "__mocha_ignore__"; - var subscriptionHandler; - // TraceKit waits 2000ms for window.onerror to fire, so give the tests - // some extra time. - this.timeout(3000); - - before(function() { - // Prevent the onerror call that's part of our tests from getting to - // mocha's handler, which would treat it as a test failure. - // - // We set this up here and don't ever restore the old handler, because - // we can't do that without clobbering TraceKit's handler, which can only - // be installed once. - var oldOnError = window.onerror; - window.onerror = function(message) { - if (message == testMessage) { - return true; - } - return oldOnError.apply(this, arguments); - }; - }); - - afterEach(function() { - if (subscriptionHandler) { - TraceKit.report.unsubscribe(subscriptionHandler); - subscriptionHandler = null; - } - }); - - function testErrorNotification(collectWindowErrors, callOnError, numReports, done) { - var extraVal = "foo"; - var numDone = 0; - // TraceKit's collectWindowErrors flag shouldn't affect direct calls - // to TraceKit.report, so we parameterize it for the tests. - TraceKit.collectWindowErrors = collectWindowErrors; - - subscriptionHandler = function(stackInfo, extra) { - assert.equal(extra, extraVal); - numDone++; - if (numDone == numReports) { - done(); - } - }; - TraceKit.report.subscribe(subscriptionHandler); - - // TraceKit.report always throws an exception in order to trigger - // window.onerror so it can gather more stack data. Mocha treats - // uncaught exceptions as errors, so we catch it via assert.throws - // here (and manually call window.onerror later if appropriate). - // - // We test multiple reports because TraceKit has special logic for when - // report() is called a second time before either a timeout elapses or - // window.onerror is called (which is why we always call window.onerror - // only once below, after all calls to report()). - for (var i=0; i < numReports; i++) { - var e = new Error('testing'); - assert.throws(function() { - TraceKit.report(e, extraVal); - }, e); - } - // The call to report should work whether or not window.onerror is - // triggered, so we parameterize it for the tests. We only call it - // once, regardless of numReports, because the case we want to test for - // multiple reports is when window.onerror is *not* called between them. - if (callOnError) { - window.onerror(testMessage); - } - } - - Mocha.utils.forEach([false, true], function(collectWindowErrors) { - Mocha.utils.forEach([false, true], function(callOnError) { - Mocha.utils.forEach([1, 2], function(numReports) { - it('it should receive arguments from report() when' + - ' collectWindowErrors is ' + collectWindowErrors + - ' and callOnError is ' + callOnError + - ' and numReports is ' + numReports, function(done) { - testErrorNotification(collectWindowErrors, callOnError, numReports, done); - }); - }); - }); - }); - }); -}); - -describe('globals', function() { - beforeEach(function() { - setupRaven(); - globalOptions.fetchContext = true; - }); - - afterEach(function() { - flushRavenState(); - }); - - describe('getHttpData', function() { - var data = getHttpData(); - - it('should have a url', function() { - assert.equal(data.url, window.location.href); - }); - - it('should have the user-agent header', function() { - assert.equal(data.headers['User-Agent'], navigator.userAgent); - }); - - it('should have referer header when available', function() { - // lol this test is awful - if (window.document.referrer) { - assert.equal(data.headers.Referer, window.document.referrer); - } else { - assert.isUndefined(data.headers.Referer); - } - }); - - }); - - describe('isUndefined', function() { - it('should do as advertised', function() { - assert.isTrue(isUndefined()); - assert.isFalse(isUndefined({})); - assert.isFalse(isUndefined('')); - assert.isTrue(isUndefined(undefined)); - }); - }); - - describe('isFunction', function() { - it('should do as advertised', function() { - assert.isTrue(isFunction(function(){})); - assert.isFalse(isFunction({})); - assert.isFalse(isFunction('')); - assert.isFalse(isFunction(undefined)); - }); - }); - - describe('isString', function() { - it('should do as advertised', function() { - assert.isTrue(isString('')); - assert.isTrue(isString(String(''))); - assert.isTrue(isString(new String(''))); - assert.isFalse(isString({})); - assert.isFalse(isString(undefined)); - assert.isFalse(isString(function(){})); - }); - }); - - describe('isObject', function() { - it('should do as advertised', function() { - assert.isTrue(isObject({})); - assert.isTrue(isObject(new Error())) - assert.isFalse(isObject('')); - }); - }); - - describe('isEmptyObject', function() { - it('should work as advertised', function() { - assert.isTrue(isEmptyObject({})); - assert.isFalse(isEmptyObject({foo: 1})); - }); - }); - - describe('isError', function() { - it('should work as advertised', function() { - assert.isTrue(isError(new Error())); - assert.isTrue(isError(new ReferenceError())); - assert.isTrue(isError(new RavenConfigError())); - assert.isFalse(isError({})); - assert.isFalse(isError('')); - assert.isFalse(isError(true)); - }); - }); - - describe('objectMerge', function() { - it('should work as advertised', function() { - assert.deepEqual(objectMerge({}, {}), {}); - assert.deepEqual(objectMerge({a:1}, {b:2}), {a:1, b:2}); - assert.deepEqual(objectMerge({a:1}), {a:1}); - }); - }); - - describe('truncate', function() { - it('should work as advertised', function() { - assert.equal(truncate('lolol', 3), 'lol\u2026'); - assert.equal(truncate('lolol', 10), 'lolol'); - assert.equal(truncate('lol', 3), 'lol'); - }); - }); - - describe('isSetup', function() { - it('should return false with no JSON support', function() { - globalServer = 'http://localhost/'; - hasJSON = false; - assert.isFalse(isSetup()); - }); - - it('should return false when Raven is not configured', function() { - hasJSON = true; // be explicit - globalServer = undefined; - this.sinon.stub(window, 'logDebug'); - assert.isFalse(isSetup()); - }); - - it('should return true when everything is all gravy', function() { - hasJSON = true; - assert.isTrue(isSetup()); - }); - }); - - describe('logDebug', function() { - var level = 'error', - message = 'foobar'; - - it('should not write to console when Raven.debug is false', function() { - Raven.debug = false; - this.sinon.stub(console, level); - logDebug(level, message); - assert.isFalse(console[level].called); - }); - - it('should write to console when Raven.debug is true', function() { - Raven.debug = true; - this.sinon.stub(console, level); - logDebug(level, message); - assert.isTrue(console[level].calledOnce); - }); - }); - - describe('setAuthQueryString', function() { - it('should return a properly formatted string and cache it', function() { - var expected = '?sentry_version=4&sentry_client=raven-js/<%= pkg.version %>&sentry_key=abc'; - setAuthQueryString(); - assert.strictEqual(authQueryString, expected); - }); - }); - - describe('parseDSN', function() { - it('should do what it advertises', function() { - var pieces = parseDSN('http://abc@example.com:80/2'); - assert.strictEqual(pieces.protocol, 'http'); - assert.strictEqual(pieces.user, 'abc'); - assert.strictEqual(pieces.port, '80'); - assert.strictEqual(pieces.path, '/2'); - assert.strictEqual(pieces.host, 'example.com'); - }); - - it('should parse protocol relative', function() { - var pieces = parseDSN('//user@mattrobenolt.com/'); - assert.strictEqual(pieces.protocol, ''); - assert.strictEqual(pieces.user, 'user'); - assert.strictEqual(pieces.port, ''); - assert.strictEqual(pieces.path, '/'); - assert.strictEqual(pieces.host, 'mattrobenolt.com'); - }); - - it('should parse domain with hyphen', function() { - var pieces = parseDSN('http://user@matt-robenolt.com/1'); - assert.strictEqual(pieces.protocol, 'http'); - assert.strictEqual(pieces.user, 'user'); - assert.strictEqual(pieces.port, ''); - assert.strictEqual(pieces.path, '/1'); - assert.strictEqual(pieces.host, 'matt-robenolt.com'); - }); - - it('should raise a RavenConfigError when setting a password', function() { - try { - parseDSN('http://user:pass@example.com/2'); - } catch(e) { - return assert.equal(e.name, 'RavenConfigError'); - } - // shouldn't hit this - assert.isTrue(false); - }); - - it('should raise a RavenConfigError with an invalid DSN', function() { - try { - parseDSN('lol'); - } catch(e) { - return assert.equal(e.name, 'RavenConfigError'); - } - // shouldn't hit this - assert.isTrue(false); - }); - }); - - describe('normalizeFrame', function() { - it('should handle a normal frame', function() { - var context = [ - ['line1'], // pre - 'line2', // culprit - ['line3'] // post - ]; - this.sinon.stub(window, 'extractContextFromFrame').returns(context); - var frame = { - url: 'http://example.com/path/file.js', - line: 10, - column: 11, - func: 'lol' - // context: [] context is stubbed - }; - - globalOptions.fetchContext = true; - - assert.deepEqual(normalizeFrame(frame), { - filename: 'http://example.com/path/file.js', - lineno: 10, - colno: 11, - 'function': 'lol', - pre_context: ['line1'], - context_line: 'line2', - post_context: ['line3'], - in_app: true - }); - }); - - it('should handle a frame without context', function() { - this.sinon.stub(window, 'extractContextFromFrame').returns(undefined); - var frame = { - url: 'http://example.com/path/file.js', - line: 10, - column: 11, - func: 'lol' - // context: [] context is stubbed - }; - - globalOptions.fetchContext = true; - - assert.deepEqual(normalizeFrame(frame), { - filename: 'http://example.com/path/file.js', - lineno: 10, - colno: 11, - 'function': 'lol', - in_app: true - }); - }); - - it('should not mark `in_app` if rules match', function() { - this.sinon.stub(window, 'extractContextFromFrame').returns(undefined); - var frame = { - url: 'http://example.com/path/file.js', - line: 10, - column: 11, - func: 'lol' - // context: [] context is stubbed - }; - - globalOptions.fetchContext = true; - globalOptions.includePaths = /^http:\/\/example\.com/; - - assert.deepEqual(normalizeFrame(frame), { - filename: 'http://example.com/path/file.js', - lineno: 10, - colno: 11, - 'function': 'lol', - in_app: true - }); - }); - - it('should mark `in_app` if rules do not match', function() { - this.sinon.stub(window, 'extractContextFromFrame').returns(undefined); - var frame = { - url: 'http://lol.com/path/file.js', - line: 10, - column: 11, - func: 'lol' - // context: [] context is stubbed - }; - - globalOptions.fetchContext = true; - globalOptions.includePaths = /^http:\/\/example\.com/; - - assert.deepEqual(normalizeFrame(frame), { - filename: 'http://lol.com/path/file.js', - lineno: 10, - colno: 11, - 'function': 'lol', - in_app: false - }); - }); - - it('should mark `in_app` for raven.js', function() { - this.sinon.stub(window, 'extractContextFromFrame').returns(undefined); - var frame = { - url: 'http://lol.com/path/raven.js', - line: 10, - column: 11, - func: 'lol' - // context: [] context is stubbed - }; - - assert.deepEqual(normalizeFrame(frame), { - filename: 'http://lol.com/path/raven.js', - lineno: 10, - colno: 11, - 'function': 'lol', - in_app: false - }); - }); - - it('should mark `in_app` for raven.min.js', function() { - this.sinon.stub(window, 'extractContextFromFrame').returns(undefined); - var frame = { - url: 'http://lol.com/path/raven.min.js', - line: 10, - column: 11, - func: 'lol' - // context: [] context is stubbed - }; - - assert.deepEqual(normalizeFrame(frame), { - filename: 'http://lol.com/path/raven.min.js', - lineno: 10, - colno: 11, - 'function': 'lol', - in_app: false - }); - }); - - it('should mark `in_app` for Raven', function() { - this.sinon.stub(window, 'extractContextFromFrame').returns(undefined); - var frame = { - url: 'http://lol.com/path/file.js', - line: 10, - column: 11, - func: 'Raven.wrap' - // context: [] context is stubbed - }; - - assert.deepEqual(normalizeFrame(frame), { - filename: 'http://lol.com/path/file.js', - lineno: 10, - colno: 11, - 'function': 'Raven.wrap', - in_app: false - }); - }); - - it('should mark `in_app` for TraceKit', function() { - this.sinon.stub(window, 'extractContextFromFrame').returns(undefined); - var frame = { - url: 'http://lol.com/path/file.js', - line: 10, - column: 11, - func: 'TraceKit.lol' - // context: [] context is stubbed - }; - - assert.deepEqual(normalizeFrame(frame), { - filename: 'http://lol.com/path/file.js', - lineno: 10, - colno: 11, - 'function': 'TraceKit.lol', - in_app: false - }); - }); - }); - - describe('extractContextFromFrame', function() { - it('should handle a normal frame', function() { - var frame = { - column: 2, - context: [ - 'line1', - 'line2', - 'line3', - 'line4', - 'line5', - 'culprit', - 'line7', - 'line8', - 'line9', - 'line10', - 'line11' - ] - }; - var context = extractContextFromFrame(frame); - assert.deepEqual(context, [ - ['line1', 'line2', 'line3', 'line4', 'line5'], - 'culprit', - ['line7', 'line8', 'line9', 'line10', 'line11'] - ]); - }); - - it('should return nothing if there is no context', function() { - var frame = { - column: 2 - }; - assert.isUndefined(extractContextFromFrame(frame)); - }); - - it('should reject a context if a line is too long without a column', function() { - var frame = { - context: [ - new Array(1000).join('f') // generate a line that is 1000 chars long - ] - }; - assert.isUndefined(extractContextFromFrame(frame)); - }); - - it('should reject a minified context with fetchContext disabled', function() { - var frame = { - column: 2, - context: [ - 'line1', - 'line2', - 'line3', - 'line4', - 'line5', - 'culprit', - 'line7', - 'line8', - 'line9', - 'line10', - 'line11' - ] - }; - globalOptions.fetchContext = false; - assert.isUndefined(extractContextFromFrame(frame)); - }); - - it('should truncate the minified line if there is a column number without sourcemaps enabled', function() { - // Note to future self: - // Array(51).join('f').length === 50 - var frame = { - column: 2, - context: [ - 'aa' + (new Array(51).join('f')) + (new Array(500).join('z')) - ] - }; - assert.deepEqual(extractContextFromFrame(frame), [[], new Array(51).join('f'), []]); - }); - }); - - describe('processException', function() { - it('should respect `ignoreErrors`', function() { - this.sinon.stub(window, 'send'); - - globalOptions.ignoreErrors = joinRegExp(['e1', 'e2']); - processException('Error', 'e1', 'http://example.com', []); - assert.isFalse(window.send.called); - processException('Error', 'e2', 'http://example.com', []); - assert.isFalse(window.send.called); - processException('Error', 'error', 'http://example.com', []); - assert.isTrue(window.send.calledOnce); - }); - - it('should respect `ignoreUrls`', function() { - this.sinon.stub(window, 'send'); - - globalOptions.ignoreUrls = joinRegExp([/.+?host1.+/, /.+?host2.+/]); - processException('Error', 'error', 'http://host1/', []); - assert.isFalse(window.send.called); - processException('Error', 'error', 'http://host2/', []); - assert.isFalse(window.send.called); - processException('Error', 'error', 'http://host3/', []); - assert.isTrue(window.send.calledOnce); - }); - - it('should respect `whitelistUrls`', function() { - this.sinon.stub(window, 'send'); - - globalOptions.whitelistUrls = joinRegExp([/.+?host1.+/, /.+?host2.+/]); - processException('Error', 'error', 'http://host1/', []); - assert.equal(window.send.callCount, 1); - processException('Error', 'error', 'http://host2/', []); - assert.equal(window.send.callCount, 2); - processException('Error', 'error', 'http://host3/', []); - assert.equal(window.send.callCount, 2); - }); - - it('should send a proper payload with frames', function() { - this.sinon.stub(window, 'send'); - - var frames = [ - { - filename: 'http://example.com/file1.js' - }, - { - filename: 'http://example.com/file2.js' - } - ], framesFlipped = frames.slice(0); - - framesFlipped.reverse(); - - processException('Error', 'lol', 'http://example.com/override.js', 10, frames.slice(0), {}); - assert.deepEqual(window.send.lastCall.args, [{ - exception: { - type: 'Error', - value: 'lol' - }, - stacktrace: { - frames: framesFlipped - }, - culprit: 'http://example.com/file1.js', - message: 'lol at 10' - }]); - - processException('Error', 'lol', '', 10, frames.slice(0), {}); - assert.deepEqual(window.send.lastCall.args, [{ - exception: { - type: 'Error', - value: 'lol' - }, - stacktrace: { - frames: framesFlipped - }, - culprit: 'http://example.com/file1.js', - message: 'lol at 10' - }]); - - processException('Error', 'lol', '', 10, frames.slice(0), {extra: 'awesome'}); - assert.deepEqual(window.send.lastCall.args, [{ - exception: { - type: 'Error', - value: 'lol' - }, - stacktrace: { - frames: framesFlipped - }, - culprit: 'http://example.com/file1.js', - message: 'lol at 10', - extra: 'awesome' - }]); - }); - - it('should send a proper payload without frames', function() { - this.sinon.stub(window, 'send'); - - processException('Error', 'lol', 'http://example.com/override.js', 10, [], {}); - assert.deepEqual(window.send.lastCall.args, [{ - exception: { - type: 'Error', - value: 'lol' - }, - stacktrace: { - frames: [{ - filename: 'http://example.com/override.js', - lineno: 10, - in_app: true - }] - }, - culprit: 'http://example.com/override.js', - message: 'lol at 10' - }]); - - processException('Error', 'lol', 'http://example.com/override.js', 10, [], {}); - assert.deepEqual(window.send.lastCall.args, [{ - exception: { - type: 'Error', - value: 'lol' - }, - stacktrace: { - frames: [{ - filename: 'http://example.com/override.js', - lineno: 10, - in_app: true - }] - }, - culprit: 'http://example.com/override.js', - message: 'lol at 10' - }]); - - processException('Error', 'lol', 'http://example.com/override.js', 10, [], {extra: 'awesome'}); - assert.deepEqual(window.send.lastCall.args, [{ - exception: { - type: 'Error', - value: 'lol' - }, - stacktrace: { - frames: [{ - filename: 'http://example.com/override.js', - lineno: 10, - in_app: true - }] - }, - culprit: 'http://example.com/override.js', - message: 'lol at 10', - extra: 'awesome' - }]); - }); - - it('should ignored falsey messages', function() { - this.sinon.stub(window, 'send'); - - processException('Error', '', 'http://example.com', []); - assert.isFalse(window.send.called); - - processException('TypeError', '', 'http://example.com', []); - assert.isTrue(window.send.called); - }); - - it('should not blow up with `undefined` message', function() { - this.sinon.stub(window, 'send'); - - processException('TypeError', undefined, 'http://example.com', []); - assert.isTrue(window.send.called); - }); - - it('should truncate messages to the specified length', function() { - this.sinon.stub(window, 'send'); - - processException('TypeError', new Array(500).join('a'), 'http://example.com', []); - assert.deepEqual(window.send.lastCall.args, [{ - message: new Array(101).join('a')+'\u2026 at ', - exception: { - type: 'TypeError', - value: new Array(101).join('a')+'\u2026' - }, - stacktrace: { - frames: [{ - filename: 'http://example.com', - lineno: [], - in_app: true - }] - }, - culprit: 'http://example.com', - }]); - - globalOptions.maxMessageLength = 150; - - processException('TypeError', new Array(500).join('a'), 'http://example.com', []); - assert.deepEqual(window.send.lastCall.args, [{ - message: new Array(151).join('a')+'\u2026 at ', - exception: { - type: 'TypeError', - value: new Array(151).join('a')+'\u2026' - }, - stacktrace: { - frames: [{ - filename: 'http://example.com', - lineno: [], - in_app: true - }] - }, - culprit: 'http://example.com', - }]); - }); - }); - - describe('send', function() { - it('should check `isSetup`', function() { - this.sinon.stub(window, 'isSetup').returns(false); - this.sinon.stub(window, 'makeRequest'); - - send(); - assert.isTrue(window.isSetup.calledOnce); - assert.isFalse(window.makeRequest.calledOnce); - }); - - it('should build a good data payload', function() { - this.sinon.stub(window, 'isSetup').returns(true); - this.sinon.stub(window, 'makeRequest'); - this.sinon.stub(window, 'getHttpData').returns({ - url: 'http://localhost/?a=b', - headers: {'User-Agent': 'lolbrowser'} - }); - - globalProject = '2'; - globalOptions = { - logger: 'javascript' - }; - - send({foo: 'bar'}); - assert.deepEqual(window.makeRequest.lastCall.args[0], { - project: '2', - logger: 'javascript', - platform: 'javascript', - request: { - url: 'http://localhost/?a=b', - headers: { - 'User-Agent': 'lolbrowser' - } - }, - event_id: 'abc123', - foo: 'bar', - extra: {'session:duration': 100} - }); - }); - - it('should build a good data payload with a User', function() { - this.sinon.stub(window, 'isSetup').returns(true); - this.sinon.stub(window, 'makeRequest'); - this.sinon.stub(window, 'getHttpData').returns({ - url: 'http://localhost/?a=b', - headers: {'User-Agent': 'lolbrowser'} - }); - - globalProject = '2'; - globalOptions = { - logger: 'javascript' - }; - - globalUser = {name: 'Matt'}; - - send({foo: 'bar'}); - assert.deepEqual(window.makeRequest.lastCall.args, [{ - project: '2', - logger: 'javascript', - platform: 'javascript', - request: { - url: 'http://localhost/?a=b', - headers: { - 'User-Agent': 'lolbrowser' - } - }, - event_id: 'abc123', - user: { - name: 'Matt' - }, - foo: 'bar', - extra: {'session:duration': 100} - }]); - }); - - it('should merge in global tags', function() { - this.sinon.stub(window, 'isSetup').returns(true); - this.sinon.stub(window, 'makeRequest'); - this.sinon.stub(window, 'getHttpData').returns({ - url: 'http://localhost/?a=b', - headers: {'User-Agent': 'lolbrowser'} - }); - - globalProject = '2'; - globalOptions = { - logger: 'javascript', - tags: {tag1: 'value1'} - }; - - - send({tags: {tag2: 'value2'}}); - assert.deepEqual(window.makeRequest.lastCall.args, [{ - project: '2', - logger: 'javascript', - platform: 'javascript', - request: { - url: 'http://localhost/?a=b', - headers: { - 'User-Agent': 'lolbrowser' - } - }, - event_id: 'abc123', - tags: {tag1: 'value1', tag2: 'value2'}, - extra: {'session:duration': 100} - }]); - assert.deepEqual(globalOptions, { - logger: 'javascript', - tags: {tag1: 'value1'} - }); - }); - - it('should merge in global extra', function() { - this.sinon.stub(window, 'isSetup').returns(true); - this.sinon.stub(window, 'makeRequest'); - this.sinon.stub(window, 'getHttpData').returns({ - url: 'http://localhost/?a=b', - headers: {'User-Agent': 'lolbrowser'} - }); - - globalProject = '2'; - globalOptions = { - logger: 'javascript', - extra: {key1: 'value1'} - }; - - - send({extra: {key2: 'value2'}}); - assert.deepEqual(window.makeRequest.lastCall.args, [{ - project: '2', - logger: 'javascript', - platform: 'javascript', - request: { - url: 'http://localhost/?a=b', - headers: { - 'User-Agent': 'lolbrowser' - } - }, - event_id: 'abc123', - extra: {key1: 'value1', key2: 'value2', 'session:duration': 100} - }]); - assert.deepEqual(globalOptions, { - logger: 'javascript', - extra: {key1: 'value1'} - }); - }); - - it('should let dataCallback override everything', function() { - this.sinon.stub(window, 'isSetup').returns(true); - this.sinon.stub(window, 'makeRequest'); - - globalOptions = { - projectId: 2, - logger: 'javascript', - dataCallback: function() { - return {lol: 'ibrokeit'}; - } - }; - - globalUser = {name: 'Matt'}; - - send({foo: 'bar'}); - assert.deepEqual(window.makeRequest.lastCall.args, [{ - lol: 'ibrokeit', - event_id: 'abc123', - }]); - }); - - it('should ignore dataCallback if it does not return anything', function() { - this.sinon.stub(window, 'isSetup').returns(true); - this.sinon.stub(window, 'makeRequest'); - this.sinon.stub(window, 'getHttpData').returns({ - url: 'http://localhost/?a=b', - headers: {'User-Agent': 'lolbrowser'} - }); - - globalProject = '2'; - globalOptions = { - logger: 'javascript', - dataCallback: function() { - return; - } - }; - - send({foo: 'bar'}); - assert.deepEqual(window.makeRequest.lastCall.args[0], { - project: '2', - logger: 'javascript', - platform: 'javascript', - request: { - url: 'http://localhost/?a=b', - headers: { - 'User-Agent': 'lolbrowser' - } - }, - event_id: 'abc123', - foo: 'bar', - extra: {'session:duration': 100} - }); - }); - - it('should strip empty tags', function() { - this.sinon.stub(window, 'isSetup').returns(true); - this.sinon.stub(window, 'makeRequest'); - this.sinon.stub(window, 'getHttpData').returns({ - url: 'http://localhost/?a=b', - headers: {'User-Agent': 'lolbrowser'} - }); - - globalOptions = { - projectId: 2, - logger: 'javascript', - tags: {} - }; - - send({foo: 'bar', tags: {}, extra: {}}); - assert.deepEqual(window.makeRequest.lastCall.args[0], { - project: '2', - logger: 'javascript', - platform: 'javascript', - request: { - url: 'http://localhost/?a=b', - headers: { - 'User-Agent': 'lolbrowser' - } - }, - event_id: 'abc123', - foo: 'bar', - extra: {'session:duration': 100} - }); - }); - - it('should attach release if available', function() { - this.sinon.stub(window, 'isSetup').returns(true); - this.sinon.stub(window, 'makeRequest'); - this.sinon.stub(window, 'getHttpData').returns({ - url: 'http://localhost/?a=b', - headers: {'User-Agent': 'lolbrowser'} - }); - - globalOptions = { - projectId: 2, - logger: 'javascript', - release: 'abc123', - }; - - send({foo: 'bar'}); - assert.deepEqual(window.makeRequest.lastCall.args[0], { - project: '2', - release: 'abc123', - logger: 'javascript', - platform: 'javascript', - request: { - url: 'http://localhost/?a=b', - headers: { - 'User-Agent': 'lolbrowser' - } - }, - event_id: 'abc123', - foo: 'bar', - extra: {'session:duration': 100} - }); - }); - }); - - describe('makeRequest', function() { - it('should load an Image', function() { - authQueryString = '?lol'; - globalServer = 'http://localhost/'; - var imageCache = []; - this.sinon.stub(window, 'newImage', function(){ var img = {}; imageCache.push(img); return img; }); - - makeRequest({foo: 'bar'}); - assert.equal(imageCache.length, 1); - assert.equal(imageCache[0].src, 'http://localhost/?lol&sentry_data=%7B%22foo%22%3A%22bar%22%7D'); - }); - }); - - describe('handleStackInfo', function() { - it('should work as advertised', function() { - var frame = {url: 'http://example.com'}; - this.sinon.stub(window, 'normalizeFrame').returns(frame); - this.sinon.stub(window, 'processException'); - - var stackInfo = { - name: 'Matt', - message: 'hey', - url: 'http://example.com', - lineno: 10, - stack: [ - frame, frame - ] - }; - - handleStackInfo(stackInfo, {foo: 'bar'}); - assert.deepEqual(window.processException.lastCall.args, [ - 'Matt', 'hey', 'http://example.com', 10, [frame, frame], {foo: 'bar'} - ]); - }); - - it('should work as advertised #integration', function() { - this.sinon.stub(window, 'makeRequest'); - var stackInfo = { - name: 'Error', - message: 'crap', - url: 'http://example.com', - lineno: 10, - stack: [ - { - url: 'http://example.com/file1.js', - line: 10, - column: 11, - func: 'broken', - context: [ - 'line1', - 'line2', - 'line3' - ] - }, - { - url: 'http://example.com/file2.js', - line: 12, - column: 13, - func: 'lol', - context: [ - 'line4', - 'line5', - 'line6' - ] - } - ] - }; - - handleStackInfo(stackInfo, {foo: 'bar'}); - assert.isTrue(window.makeRequest.calledOnce); - /* This is commented out because chai is broken. - - assert.deepEqual(window.makeRequest.lastCall.args, [{ - project: '2', - logger: 'javascript', - platform: 'javascript', - request: { - url: window.location.protocol + '//' + window.location.host + window.location.pathname, - querystring: window.location.search.slice(1) - }, - exception: { - type: 'Error', - value: 'crap' - }, - stacktrace: { - frames: [{ - filename: 'http://example.com/file1.js', - filename: 'file1.js', - lineno: 10, - colno: 11, - 'function': 'broken', - post_context: ['line3'], - context_line: 'line2', - pre_context: ['line1'] - }, { - filename: 'http://example.com/file2.js', - filename: 'file2.js', - lineno: 12, - colno: 13, - 'function': 'lol', - post_context: ['line6'], - context_line: 'line5', - pre_context: ['line4'] - }] - }, - culprit: 'http://example.com', - message: 'crap at 10', - foo: 'bar' - }]); - */ - }); - - it('should ignore frames that dont have a url', function() { - this.sinon.stub(window, 'normalizeFrame').returns(undefined); - this.sinon.stub(window, 'processException'); - - var stackInfo = { - name: 'Matt', - message: 'hey', - url: 'http://example.com', - lineno: 10, - stack: new Array(2) - }; - - handleStackInfo(stackInfo, {foo: 'bar'}); - assert.deepEqual(window.processException.lastCall.args, [ - 'Matt', 'hey', 'http://example.com', 10, [], {foo: 'bar'} - ]); - }); - - it('should not shit when there is no stack object from TK', function() { - this.sinon.stub(window, 'normalizeFrame').returns(undefined); - this.sinon.stub(window, 'processException'); - - var stackInfo = { - name: 'Matt', - message: 'hey', - url: 'http://example.com', - lineno: 10 - // stack: new Array(2) - }; - - handleStackInfo(stackInfo); - assert.isFalse(window.normalizeFrame.called); - assert.deepEqual(window.processException.lastCall.args, [ - 'Matt', 'hey', 'http://example.com', 10, [], undefined - ]); - }); - - it('should detect 2-words patterns (angularjs frequent case)', function() { - this.sinon.stub(window, 'normalizeFrame').returns(undefined); - this.sinon.stub(window, 'processException'); - - var stackInfo = { - name: 'new ', - message: 'hey', - url: 'http://example.com', - lineno: 10 - // stack: new Array(2) - }; - - handleStackInfo(stackInfo); - assert.isFalse(window.normalizeFrame.called); - assert.deepEqual(window.processException.lastCall.args, [ - 'new ', 'hey', 'http://example.com', 10, [], undefined - ]); - }); - }); - - describe('joinRegExp', function() { - it('should work as advertised', function() { - assert.equal(joinRegExp([ - 'a', 'b', 'a.b', /d/, /[0-9]/ - ]).source, 'a|b|a\\.b|d|[0-9]'); - }); - - it('should not process empty or undefined variables', function() { - assert.equal(joinRegExp([ - 'a', 'b', null, undefined - ]).source, 'a|b'); - }); - - it('should skip entries that are not strings or regular expressions in the passed array of patterns', function() { - assert.equal(joinRegExp([ - 'a', 'b', null, 'a.b', undefined, true, /d/, 123, {}, /[0-9]/, [] - ]).source, 'a|b|a\\.b|d|[0-9]'); - }); - }); -}); - -describe('Raven (public API)', function() { - afterEach(function() { - flushRavenState(); - }); - - describe('.VERSION', function() { - it('should have a version', function() { - assert.isString(Raven.VERSION); - }); - }); - - describe('ignore errors', function() { - it('should install default ignore errors', function() { - Raven.config('//abc@example.com/2'); - - assert.isTrue(globalOptions.ignoreErrors.test('Script error'), 'it should install "Script error" by default'); - assert.isTrue(globalOptions.ignoreErrors.test('Script error.'), 'it should install "Script error." by default'); - assert.isTrue(globalOptions.ignoreErrors.test('Javascript error: Script error on line 0'), 'it should install "Javascript error: Script error on line 0" by default'); - assert.isTrue(globalOptions.ignoreErrors.test('Javascript error: Script error. on line 0'), 'it should install "Javascript error: Script error. on line 0" by default'); - }); - }); - - describe('callback function', function() { - it('should callback a function if it is global', function() { - window.RavenConfig = { - dsn: "http://random@some.other.server:80/2", - config: {some: 'config'} - }; - - this.sinon.stub(window, 'isSetup').returns(false); - this.sinon.stub(TraceKit.report, 'subscribe'); - - afterLoad(); - - assert.equal(globalKey, 'random'); - assert.equal(globalServer, 'http://some.other.server:80/api/2/store/'); - - assert.equal(globalOptions.some, 'config'); - assert.equal(globalProject, '2'); - - assert.isTrue(window.isSetup.calledOnce); - assert.isFalse(TraceKit.report.subscribe.calledOnce); - - delete window.RavenConfig; - }); - }); - - describe('.config', function() { - it('should work with a DSN', function() { - assert.equal(Raven, Raven.config(SENTRY_DSN, {foo: 'bar'}), 'it should return Raven'); - assert.equal(globalKey, 'abc'); - assert.equal(globalServer, 'http://example.com:80/api/2/store/'); - assert.equal(globalOptions.foo, 'bar'); - assert.equal(globalProject, '2'); - assert.isTrue(isSetup()); - }); - - it('should work with a protocol relative DSN', function() { - Raven.config('//abc@example.com/2'); - assert.equal(globalKey, 'abc'); - assert.equal(globalServer, '//example.com/api/2/store/'); - assert.equal(globalProject, '2'); - assert.isTrue(isSetup()); - }); - - it('should work should work at a non root path', function() { - Raven.config('//abc@example.com/sentry/2'); - assert.equal(globalKey, 'abc'); - assert.equal(globalServer, '//example.com/sentry/api/2/store/'); - assert.equal(globalProject, '2'); - assert.isTrue(isSetup()); - }); - - it('should noop a falsey dsn', function() { - Raven.config(''); - assert.isFalse(isSetup()); - }); - - it('should return Raven for a falsey dsn', function() { - assert.equal(Raven.config(''), Raven); - }); - - it('should not set global options more than once', function() { - this.sinon.spy(window, 'parseDSN'); - this.sinon.stub(window, 'logDebug'); - setupRaven(); - setupRaven(); - assert.isTrue(parseDSN.calledOnce); - assert.isTrue(logDebug.called); - }); - - describe('whitelistUrls', function() { - it('should be false if none are passed', function() { - Raven.config('//abc@example.com/2'); - assert.equal(globalOptions.whitelistUrls, false); - }); - - it('should join into a single RegExp', function() { - Raven.config('//abc@example.com/2', { - whitelistUrls: [ - /my.app/i, - /other.app/i - ] - }); - - assert.match(globalOptions.whitelistUrls, /my.app|other.app/i); - }); - - it('should handle strings as well', function() { - Raven.config('//abc@example.com/2', { - whitelistUrls: [ - /my.app/i, - "stringy.app" - ] - }); - - assert.match(globalOptions.whitelistUrls, /my.app|stringy.app/i); - }); - }); - - describe('collectWindowErrors', function() { - it('should be true by default', function() { - Raven.config(SENTRY_DSN); - assert.isTrue(TraceKit.collectWindowErrors); - }); - - it('should be true if set to true', function() { - Raven.config(SENTRY_DSN, { - collectWindowErrors: true - }); - - assert.isTrue(TraceKit.collectWindowErrors); - }); - - it('should be false if set to false', function() { - Raven.config(SENTRY_DSN, { - collectWindowErrors: false - }); - - assert.isFalse(TraceKit.collectWindowErrors); - }); - }); - }); - - describe('.install', function() { - it('should check `isSetup`', function() { - this.sinon.stub(window, 'isSetup').returns(false); - this.sinon.stub(TraceKit.report, 'subscribe'); - Raven.install(); - assert.isTrue(window.isSetup.calledOnce); - assert.isFalse(TraceKit.report.subscribe.calledOnce); - }); - - it('should register itself with TraceKit', function() { - this.sinon.stub(window, 'isSetup').returns(true); - this.sinon.stub(TraceKit.report, 'subscribe'); - assert.equal(Raven, Raven.install()); - assert.isTrue(TraceKit.report.subscribe.calledOnce); - assert.equal(TraceKit.report.subscribe.lastCall.args[0], handleStackInfo); - }); - - it('should not register itself more than once', function() { - this.sinon.stub(window, 'isSetup').returns(true); - this.sinon.stub(TraceKit.report, 'subscribe'); - Raven.install(); - Raven.install(); - assert.isTrue(TraceKit.report.subscribe.calledOnce); - }); - }); - - describe('.wrap', function() { - it('should return a wrapped callback', function() { - var spy = this.sinon.spy(); - var wrapped = Raven.wrap(spy); - assert.isFunction(wrapped); - assert.isTrue(wrapped.__raven__); - wrapped(); - assert.isTrue(spy.calledOnce); - }); - - it('should copy property when wrapping function', function() { - var func = function() {}; - func.test = true; - var wrapped = Raven.wrap(func); - assert.isTrue(wrapped.test); - }); - - it('should not copy prototype property when wrapping function', function() { - var func = function() {}; - func.prototype.test = true; - var wrapped = Raven.wrap(func); - assert.isUndefined(new wrapped().test); - }); - - it('should return the result of a wrapped function', function() { - var func = function() { return 'foo'; }; - var wrapped = Raven.wrap(func); - assert.equal(wrapped(), 'foo'); - }); - - it('should not wrap a non-function', function() { - assert.equal(Raven.wrap('lol'), 'lol'); - assert.equal(Raven.wrap({}, 'lol'), 'lol'); - assert.equal(Raven.wrap(undefined, 'lol'), 'lol'); - var a = [1, 2]; - assert.equal(Raven.wrap(a), a); - }); - - it('should wrap function arguments', function() { - var spy = this.sinon.spy(); - var wrapped = Raven.wrap(function(f) { - assert.isTrue(f.__raven__); - f(); - }); - wrapped(spy); - assert.isTrue(spy.calledOnce); - }); - - it('should not wrap function arguments', function() { - var spy = this.sinon.spy(); - var wrapped = Raven.wrap({ deep: false }, function(f) { - assert.isUndefined(f.__raven__); - f(); - }); - wrapped(spy); - assert.isTrue(spy.calledOnce); - }); - - it('should maintain the correct scope', function() { - var foo = {}; - var bar = function() { - assert.equal(this, foo); - }; - bar.apply(foo, []); - Raven.wrap(bar).apply(foo, []); - }); - - it('should re-raise a thrown exception', function() { - var error = new Error('lol'); - assert.throws(function() { - Raven.wrap(function() { throw error; })(); - }, error); - }); - - }); - - describe('.context', function() { - it('should execute the callback with options', function() { - var spy = this.sinon.spy(); - this.sinon.stub(Raven, 'captureException'); - Raven.context({'foo': 'bar'}, spy); - assert.isTrue(spy.calledOnce); - assert.isFalse(Raven.captureException.called); - }); - - it('should execute the callback with arguments', function() { - var spy = this.sinon.spy(); - var args = [1, 2]; - Raven.context(spy, args); - assert.deepEqual(spy.lastCall.args, args); - }); - - it('should execute the callback without options', function() { - var spy = this.sinon.spy(); - this.sinon.stub(Raven, 'captureException'); - Raven.context(spy); - assert.isTrue(spy.calledOnce); - assert.isFalse(Raven.captureException.called); - }); - - it('should capture the exception with options', function() { - var error = new Error('crap'); - var broken = function() { throw error; }; - this.sinon.stub(Raven, 'captureException'); - assert.throws(function() { - Raven.context({foo: 'bar'}, broken); - }, error); - assert.isTrue(Raven.captureException.called); - assert.deepEqual(Raven.captureException.lastCall.args, [error, {'foo': 'bar'}]); - }); - - it('should capture the exception without options', function() { - var error = new Error('crap'); - var broken = function() { throw error; }; - this.sinon.stub(Raven, 'captureException'); - assert.throws(function() { - Raven.context(broken); - }, error); - assert.isTrue(Raven.captureException.called); - assert.deepEqual(Raven.captureException.lastCall.args, [error, undefined]); - }); - - it('should execute the callback without arguments', function() { - // This is only reproducable in a browser that complains about passing - // undefined to Function.apply - var spy = this.sinon.spy(); - Raven.context(spy); - assert.deepEqual(spy.lastCall.args, []); - }); - - it('should return the result of the wrapped function', function() { - var val = {}; - var func = function() { return val; }; - assert.equal(Raven.context(func), val); - }); - }); - - describe('.uninstall', function() { - it('should uninstall from TraceKit', function() { - this.sinon.stub(TraceKit.report, 'uninstall'); - Raven.uninstall(); - assert.isTrue(TraceKit.report.uninstall.calledOnce); - }); - - it('should set isRavenInstalled flag to false', function() { - isRavenInstalled = true; - this.sinon.stub(TraceKit.report, 'uninstall'); - Raven.uninstall(); - assert.isFalse(isRavenInstalled); - }); - }); - - describe('.setUserContext', function() { - it('should set the globalUser object', function() { - Raven.setUserContext({name: 'Matt'}); - assert.deepEqual(globalUser, {name: 'Matt'}); - }); - - it('should clear the globalUser with no arguments', function() { - globalUser = {name: 'Matt'}; - Raven.setUserContext(); - assert.isUndefined(globalUser); - }); - }); - - describe('.setExtraContext', function() { - it('should set the globalOptions.extra object', function() { - Raven.setExtraContext({name: 'Matt'}); - assert.deepEqual(globalOptions.extra, {name: 'Matt'}); - }); - - it('should clear globalOptions.extra with no arguments', function() { - globalOptions = {name: 'Matt'}; - Raven.setExtraContext(); - assert.deepEqual(globalOptions.extra, {}); - }); - }); - - describe('.setTagsContext', function() { - it('should set the globalOptions.tags object', function() { - Raven.setTagsContext({name: 'Matt'}); - assert.deepEqual(globalOptions.tags, {name: 'Matt'}); - }); - - it('should clear globalOptions.tags with no arguments', function() { - globalOptions = {name: 'Matt'}; - Raven.setTagsContext(); - assert.deepEqual(globalOptions.tags, {}); - }); - }); - - describe('.setReleaseContext', function() { - it('should set the globalOptions.release attribute', function() { - Raven.setReleaseContext('abc123'); - assert.equal(globalOptions.release, 'abc123'); - }); - - it('should clear globalOptions.release with no arguments', function() { - globalOptions.release = 'abc123'; - Raven.setReleaseContext(); - assert.isUndefined(globalOptions.release); - }); - }); - - describe('.setDataCallback', function() { - it('should set the globalOptions.dataCallback attribute', function() { - var foo = function(){}; - Raven.setDataCallback(foo); - assert.equal(globalOptions.dataCallback, foo); - }); - - it('should clear globalOptions.dataCallback with no arguments', function() { - var foo = function(){}; - globalOptions.dataCallback = foo; - Raven.setDataCallback(); - assert.isUndefined(globalOptions.dataCallback); - }); - }); - - describe('.setShouldSendCallback', function() { - it('should set the globalOptions.shouldSendCallback attribute', function() { - var foo = function(){}; - Raven.setShouldSendCallback(foo); - assert.equal(globalOptions.shouldSendCallback, foo); - }); - - it('should clear globalOptions.shouldSendCallback with no arguments', function() { - var foo = function(){}; - globalOptions.shouldSendCallback = foo; - Raven.setShouldSendCallback(); - assert.isUndefined(globalOptions.shouldSendCallback); - }); - }); - - describe('.captureMessage', function() { - it('should work as advertised', function() { - this.sinon.stub(window, 'send'); - Raven.captureMessage('lol', {foo: 'bar'}); - assert.deepEqual(window.send.lastCall.args, [{ - message: 'lol', - foo: 'bar' - }]); - }); - - it('should coerce message to a string', function() { - this.sinon.stub(window, 'send'); - Raven.captureMessage({}); - assert.deepEqual(window.send.lastCall.args, [{ - message: '[object Object]' - }]); - }); - - it('should work as advertised #integration', function() { - var imageCache = []; - this.sinon.stub(window, 'newImage', function(){ var img = {}; imageCache.push(img); return img; }); - - setupRaven(); - Raven.captureMessage('lol', {foo: 'bar'}); - assert.equal(imageCache.length, 1); - // It'd be hard to assert the actual payload being sent - // since it includes the generated url, which is going to - // vary between users running the tests - // Unit tests should cover that the payload was constructed properly - }); - - it('should tag lastEventId #integration', function() { - setupRaven(); - Raven.captureMessage('lol'); - assert.equal(Raven.lastEventId(), 'abc123'); - }); - - it('should respect `ignoreErrors`', function() { - this.sinon.stub(window, 'send'); - - globalOptions.ignoreErrors = joinRegExp(['e1', 'e2']); - Raven.captureMessage('e1'); - assert.isFalse(window.send.called); - Raven.captureMessage('e2'); - assert.isFalse(window.send.called); - Raven.captureMessage('Non-ignored error'); - assert.isTrue(window.send.calledOnce); - }); - }); - - describe('.captureException', function() { - it('should call TraceKit.report', function() { - var error = new Error('crap'); - this.sinon.stub(TraceKit, 'report'); - Raven.captureException(error, {foo: 'bar'}); - assert.isTrue(TraceKit.report.calledOnce); - assert.deepEqual(TraceKit.report.lastCall.args, [error, {foo: 'bar'}]); - }); - - it('should store the last exception', function() { - var error = new Error('crap'); - this.sinon.stub(TraceKit, 'report'); - Raven.captureException(error); - assert.equal(Raven.lastException(), error); - }); - - it('shouldn\'t reraise the if the error is the same error', function() { - var error = new Error('crap'); - this.sinon.stub(TraceKit, 'report').throws(error); - // this would raise if the errors didn't match - Raven.captureException(error, {foo: 'bar'}); - assert.isTrue(TraceKit.report.calledOnce); - }); - - it('should reraise a different error', function() { - var error = new Error('crap1'); - this.sinon.stub(TraceKit, 'report').throws(error); - assert.throws(function() { - Raven.captureException(new Error('crap2')); - }, error); - }); - - it('should capture as a normal message if a non-Error is passed', function() { - this.sinon.stub(Raven, 'captureMessage'); - this.sinon.stub(TraceKit, 'report'); - Raven.captureException('derp'); - assert.equal(Raven.captureMessage.lastCall.args[0], 'derp'); - assert.isFalse(TraceKit.report.called); - Raven.captureException(true); - assert.equal(Raven.captureMessage.lastCall.args[0], true); - assert.isFalse(TraceKit.report.called); - }); - }); - - describe('.isSetup', function() { - it('should work as advertised', function() { - var isSetup = this.sinon.stub(window, 'isSetup'); - isSetup.returns(true); - assert.isTrue(Raven.isSetup()); - isSetup.returns(false); - assert.isFalse(Raven.isSetup()); - }); - }); -}); diff --git a/htdocs/includes/raven-js/vendor/TraceKit/tracekit.js b/htdocs/includes/raven-js/vendor/TraceKit/tracekit.js deleted file mode 100644 index bccddabedbe..00000000000 --- a/htdocs/includes/raven-js/vendor/TraceKit/tracekit.js +++ /dev/null @@ -1,1044 +0,0 @@ -/* - TraceKit - Cross brower stack traces - github.com/occ/TraceKit - MIT license -*/ - -var TraceKit = { - remoteFetching: false, - collectWindowErrors: true, - // 3 lines before, the offending line, 3 lines after - linesOfContext: 7 -}; - -// global reference to slice -var _slice = [].slice; -var UNKNOWN_FUNCTION = '?'; - - -/** - * TraceKit.wrap: Wrap any function in a TraceKit reporter - * Example: func = TraceKit.wrap(func); - * - * @param {Function} func Function to be wrapped - * @return {Function} The wrapped func - */ -TraceKit.wrap = function traceKitWrapper(func) { - function wrapped() { - try { - return func.apply(this, arguments); - } catch (e) { - TraceKit.report(e); - throw e; - } - } - return wrapped; -}; - -/** - * TraceKit.report: cross-browser processing of unhandled exceptions - * - * Syntax: - * TraceKit.report.subscribe(function(stackInfo) { ... }) - * TraceKit.report.unsubscribe(function(stackInfo) { ... }) - * TraceKit.report(exception) - * try { ...code... } catch(ex) { TraceKit.report(ex); } - * - * Supports: - * - Firefox: full stack trace with line numbers, plus column number - * on top frame; column number is not guaranteed - * - Opera: full stack trace with line and column numbers - * - Chrome: full stack trace with line and column numbers - * - Safari: line and column number for the top frame only; some frames - * may be missing, and column number is not guaranteed - * - IE: line and column number for the top frame only; some frames - * may be missing, and column number is not guaranteed - * - * In theory, TraceKit should work on all of the following versions: - * - IE5.5+ (only 8.0 tested) - * - Firefox 0.9+ (only 3.5+ tested) - * - Opera 7+ (only 10.50 tested; versions 9 and earlier may require - * Exceptions Have Stacktrace to be enabled in opera:config) - * - Safari 3+ (only 4+ tested) - * - Chrome 1+ (only 5+ tested) - * - Konqueror 3.5+ (untested) - * - * Requires TraceKit.computeStackTrace. - * - * Tries to catch all unhandled exceptions and report them to the - * subscribed handlers. Please note that TraceKit.report will rethrow the - * exception. This is REQUIRED in order to get a useful stack trace in IE. - * If the exception does not reach the top of the browser, you will only - * get a stack trace from the point where TraceKit.report was called. - * - * Handlers receive a stackInfo object as described in the - * TraceKit.computeStackTrace docs. - */ -TraceKit.report = (function reportModuleWrapper() { - var handlers = [], - lastArgs = null, - lastException = null, - lastExceptionStack = null; - - /** - * Add a crash handler. - * @param {Function} handler - */ - function subscribe(handler) { - installGlobalHandler(); - handlers.push(handler); - } - - /** - * Remove a crash handler. - * @param {Function} handler - */ - function unsubscribe(handler) { - for (var i = handlers.length - 1; i >= 0; --i) { - if (handlers[i] === handler) { - handlers.splice(i, 1); - } - } - } - - /** - * Remove all crash handlers. - */ - function unsubscribeAll() { - uninstallGlobalHandler(); - handlers = []; - } - - /** - * Dispatch stack information to all handlers. - * @param {Object.} stack - */ - function notifyHandlers(stack, isWindowError) { - var exception = null; - if (isWindowError && !TraceKit.collectWindowErrors) { - return; - } - for (var i in handlers) { - if (hasKey(handlers, i)) { - try { - handlers[i].apply(null, [stack].concat(_slice.call(arguments, 2))); - } catch (inner) { - exception = inner; - } - } - } - - if (exception) { - throw exception; - } - } - - var _oldOnerrorHandler, _onErrorHandlerInstalled; - - /** - * Ensures all global unhandled exceptions are recorded. - * Supported by Gecko and IE. - * @param {string} message Error message. - * @param {string} url URL of script that generated the exception. - * @param {(number|string)} lineNo The line number at which the error - * occurred. - * @param {?(number|string)} colNo The column number at which the error - * occurred. - * @param {?Error} ex The actual Error object. - */ - function traceKitWindowOnError(message, url, lineNo, colNo, ex) { - var stack = null; - - if (lastExceptionStack) { - TraceKit.computeStackTrace.augmentStackTraceWithInitialElement(lastExceptionStack, url, lineNo, message); - processLastException(); - } else if (ex) { - // New chrome and blink send along a real error object - // Let's just report that like a normal error. - // See: https://mikewest.org/2013/08/debugging-runtime-errors-with-window-onerror - stack = TraceKit.computeStackTrace(ex); - notifyHandlers(stack, true); - } else { - var location = { - 'url': url, - 'line': lineNo, - 'column': colNo - }; - location.func = TraceKit.computeStackTrace.guessFunctionName(location.url, location.line); - location.context = TraceKit.computeStackTrace.gatherContext(location.url, location.line); - stack = { - 'message': message, - 'url': document.location.href, - 'stack': [location] - }; - notifyHandlers(stack, true); - } - - if (_oldOnerrorHandler) { - return _oldOnerrorHandler.apply(this, arguments); - } - - return false; - } - - function installGlobalHandler () - { - if (_onErrorHandlerInstalled) { - return; - } - _oldOnerrorHandler = window.onerror; - window.onerror = traceKitWindowOnError; - _onErrorHandlerInstalled = true; - } - - function uninstallGlobalHandler () - { - if (!_onErrorHandlerInstalled) { - return; - } - window.onerror = _oldOnerrorHandler; - _onErrorHandlerInstalled = false; - _oldOnerrorHandler = undefined; - } - - function processLastException() { - var _lastExceptionStack = lastExceptionStack, - _lastArgs = lastArgs; - lastArgs = null; - lastExceptionStack = null; - lastException = null; - notifyHandlers.apply(null, [_lastExceptionStack, false].concat(_lastArgs)); - } - - /** - * Reports an unhandled Error to TraceKit. - * @param {Error} ex - * @param {?boolean} rethrow If false, do not re-throw the exception. - * Only used for window.onerror to not cause an infinite loop of - * rethrowing. - */ - function report(ex, rethrow) { - var args = _slice.call(arguments, 1); - if (lastExceptionStack) { - if (lastException === ex) { - return; // already caught by an inner catch block, ignore - } else { - processLastException(); - } - } - - var stack = TraceKit.computeStackTrace(ex); - lastExceptionStack = stack; - lastException = ex; - lastArgs = args; - - // If the stack trace is incomplete, wait for 2 seconds for - // slow slow IE to see if onerror occurs or not before reporting - // this exception; otherwise, we will end up with an incomplete - // stack trace - window.setTimeout(function () { - if (lastException === ex) { - processLastException(); - } - }, (stack.incomplete ? 2000 : 0)); - - if (rethrow !== false) { - throw ex; // re-throw to propagate to the top level (and cause window.onerror) - } - } - - report.subscribe = subscribe; - report.unsubscribe = unsubscribe; - report.uninstall = unsubscribeAll; - return report; -}()); - -/** - * TraceKit.computeStackTrace: cross-browser stack traces in JavaScript - * - * Syntax: - * s = TraceKit.computeStackTrace(exception) // consider using TraceKit.report instead (see below) - * Returns: - * s.name - exception name - * s.message - exception message - * s.stack[i].url - JavaScript or HTML file URL - * s.stack[i].func - function name, or empty for anonymous functions (if guessing did not work) - * s.stack[i].args - arguments passed to the function, if known - * s.stack[i].line - line number, if known - * s.stack[i].column - column number, if known - * s.stack[i].context - an array of source code lines; the middle element corresponds to the correct line# - * - * Supports: - * - Firefox: full stack trace with line numbers and unreliable column - * number on top frame - * - Opera 10: full stack trace with line and column numbers - * - Opera 9-: full stack trace with line numbers - * - Chrome: full stack trace with line and column numbers - * - Safari: line and column number for the topmost stacktrace element - * only - * - IE: no line numbers whatsoever - * - * Tries to guess names of anonymous functions by looking for assignments - * in the source code. In IE and Safari, we have to guess source file names - * by searching for function bodies inside all page scripts. This will not - * work for scripts that are loaded cross-domain. - * Here be dragons: some function names may be guessed incorrectly, and - * duplicate functions may be mismatched. - * - * TraceKit.computeStackTrace should only be used for tracing purposes. - * Logging of unhandled exceptions should be done with TraceKit.report, - * which builds on top of TraceKit.computeStackTrace and provides better - * IE support by utilizing the window.onerror event to retrieve information - * about the top of the stack. - * - * Note: In IE and Safari, no stack trace is recorded on the Error object, - * so computeStackTrace instead walks its *own* chain of callers. - * This means that: - * * in Safari, some methods may be missing from the stack trace; - * * in IE, the topmost function in the stack trace will always be the - * caller of computeStackTrace. - * - * This is okay for tracing (because you are likely to be calling - * computeStackTrace from the function you want to be the topmost element - * of the stack trace anyway), but not okay for logging unhandled - * exceptions (because your catch block will likely be far away from the - * inner function that actually caused the exception). - * - */ -TraceKit.computeStackTrace = (function computeStackTraceWrapper() { - var debug = false, - sourceCache = {}; - - /** - * Attempts to retrieve source code via XMLHttpRequest, which is used - * to look up anonymous function names. - * @param {string} url URL of source code. - * @return {string} Source contents. - */ - function loadSource(url) { - if (!TraceKit.remoteFetching) { //Only attempt request if remoteFetching is on. - return ''; - } - try { - var getXHR = function() { - try { - return new window.XMLHttpRequest(); - } catch (e) { - // explicitly bubble up the exception if not found - return new window.ActiveXObject('Microsoft.XMLHTTP'); - } - }; - - var request = getXHR(); - request.open('GET', url, false); - request.send(''); - return request.responseText; - } catch (e) { - return ''; - } - } - - /** - * Retrieves source code from the source code cache. - * @param {string} url URL of source code. - * @return {Array.} Source contents. - */ - function getSource(url) { - if (!isString(url)) return []; - if (!hasKey(sourceCache, url)) { - // URL needs to be able to fetched within the acceptable domain. Otherwise, - // cross-domain errors will be triggered. - var source = ''; - if (url.indexOf(document.domain) !== -1) { - source = loadSource(url); - } - sourceCache[url] = source ? source.split('\n') : []; - } - - return sourceCache[url]; - } - - /** - * Tries to use an externally loaded copy of source code to determine - * the name of a function by looking at the name of the variable it was - * assigned to, if any. - * @param {string} url URL of source code. - * @param {(string|number)} lineNo Line number in source code. - * @return {string} The function name, if discoverable. - */ - function guessFunctionName(url, lineNo) { - var reFunctionArgNames = /function ([^(]*)\(([^)]*)\)/, - reGuessFunction = /['"]?([0-9A-Za-z$_]+)['"]?\s*[:=]\s*(function|eval|new Function)/, - line = '', - maxLines = 10, - source = getSource(url), - m; - - if (!source.length) { - return UNKNOWN_FUNCTION; - } - - // Walk backwards from the first line in the function until we find the line which - // matches the pattern above, which is the function definition - for (var i = 0; i < maxLines; ++i) { - line = source[lineNo - i] + line; - - if (!isUndefined(line)) { - if ((m = reGuessFunction.exec(line))) { - return m[1]; - } else if ((m = reFunctionArgNames.exec(line))) { - return m[1]; - } - } - } - - return UNKNOWN_FUNCTION; - } - - /** - * Retrieves the surrounding lines from where an exception occurred. - * @param {string} url URL of source code. - * @param {(string|number)} line Line number in source code to centre - * around for context. - * @return {?Array.} Lines of source code. - */ - function gatherContext(url, line) { - var source = getSource(url); - - if (!source.length) { - return null; - } - - var context = [], - // linesBefore & linesAfter are inclusive with the offending line. - // if linesOfContext is even, there will be one extra line - // *before* the offending line. - linesBefore = Math.floor(TraceKit.linesOfContext / 2), - // Add one extra line if linesOfContext is odd - linesAfter = linesBefore + (TraceKit.linesOfContext % 2), - start = Math.max(0, line - linesBefore - 1), - end = Math.min(source.length, line + linesAfter - 1); - - line -= 1; // convert to 0-based index - - for (var i = start; i < end; ++i) { - if (!isUndefined(source[i])) { - context.push(source[i]); - } - } - - return context.length > 0 ? context : null; - } - - /** - * Escapes special characters, except for whitespace, in a string to be - * used inside a regular expression as a string literal. - * @param {string} text The string. - * @return {string} The escaped string literal. - */ - function escapeRegExp(text) { - return text.replace(/[\-\[\]{}()*+?.,\\\^$|#]/g, '\\$&'); - } - - /** - * Escapes special characters in a string to be used inside a regular - * expression as a string literal. Also ensures that HTML entities will - * be matched the same as their literal friends. - * @param {string} body The string. - * @return {string} The escaped string. - */ - function escapeCodeAsRegExpForMatchingInsideHTML(body) { - return escapeRegExp(body).replace('<', '(?:<|<)').replace('>', '(?:>|>)').replace('&', '(?:&|&)').replace('"', '(?:"|")').replace(/\s+/g, '\\s+'); - } - - /** - * Determines where a code fragment occurs in the source code. - * @param {RegExp} re The function definition. - * @param {Array.} urls A list of URLs to search. - * @return {?Object.} An object containing - * the url, line, and column number of the defined function. - */ - function findSourceInUrls(re, urls) { - var source, m; - for (var i = 0, j = urls.length; i < j; ++i) { - // console.log('searching', urls[i]); - if ((source = getSource(urls[i])).length) { - source = source.join('\n'); - if ((m = re.exec(source))) { - // console.log('Found function in ' + urls[i]); - - return { - 'url': urls[i], - 'line': source.substring(0, m.index).split('\n').length, - 'column': m.index - source.lastIndexOf('\n', m.index) - 1 - }; - } - } - } - - // console.log('no match'); - - return null; - } - - /** - * Determines at which column a code fragment occurs on a line of the - * source code. - * @param {string} fragment The code fragment. - * @param {string} url The URL to search. - * @param {(string|number)} line The line number to examine. - * @return {?number} The column number. - */ - function findSourceInLine(fragment, url, line) { - var source = getSource(url), - re = new RegExp('\\b' + escapeRegExp(fragment) + '\\b'), - m; - - line -= 1; - - if (source && source.length > line && (m = re.exec(source[line]))) { - return m.index; - } - - return null; - } - - /** - * Determines where a function was defined within the source code. - * @param {(Function|string)} func A function reference or serialized - * function definition. - * @return {?Object.} An object containing - * the url, line, and column number of the defined function. - */ - function findSourceByFunctionBody(func) { - var urls = [window.location.href], - scripts = document.getElementsByTagName('script'), - body, - code = '' + func, - codeRE = /^function(?:\s+([\w$]+))?\s*\(([\w\s,]*)\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/, - eventRE = /^function on([\w$]+)\s*\(event\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/, - re, - parts, - result; - - for (var i = 0; i < scripts.length; ++i) { - var script = scripts[i]; - if (script.src) { - urls.push(script.src); - } - } - - if (!(parts = codeRE.exec(code))) { - re = new RegExp(escapeRegExp(code).replace(/\s+/g, '\\s+')); - } - - // not sure if this is really necessary, but I don’t have a test - // corpus large enough to confirm that and it was in the original. - else { - var name = parts[1] ? '\\s+' + parts[1] : '', - args = parts[2].split(',').join('\\s*,\\s*'); - - body = escapeRegExp(parts[3]).replace(/;$/, ';?'); // semicolon is inserted if the function ends with a comment.replace(/\s+/g, '\\s+'); - re = new RegExp('function' + name + '\\s*\\(\\s*' + args + '\\s*\\)\\s*{\\s*' + body + '\\s*}'); - } - - // look for a normal function definition - if ((result = findSourceInUrls(re, urls))) { - return result; - } - - // look for an old-school event handler function - if ((parts = eventRE.exec(code))) { - var event = parts[1]; - body = escapeCodeAsRegExpForMatchingInsideHTML(parts[2]); - - // look for a function defined in HTML as an onXXX handler - re = new RegExp('on' + event + '=[\\\'"]\\s*' + body + '\\s*[\\\'"]', 'i'); - - if ((result = findSourceInUrls(re, urls[0]))) { - return result; - } - - // look for ??? - re = new RegExp(body); - - if ((result = findSourceInUrls(re, urls))) { - return result; - } - } - - return null; - } - - // Contents of Exception in various browsers. - // - // SAFARI: - // ex.message = Can't find variable: qq - // ex.line = 59 - // ex.sourceId = 580238192 - // ex.sourceURL = http://... - // ex.expressionBeginOffset = 96 - // ex.expressionCaretOffset = 98 - // ex.expressionEndOffset = 98 - // ex.name = ReferenceError - // - // FIREFOX: - // ex.message = qq is not defined - // ex.fileName = http://... - // ex.lineNumber = 59 - // ex.columnNumber = 69 - // ex.stack = ...stack trace... (see the example below) - // ex.name = ReferenceError - // - // CHROME: - // ex.message = qq is not defined - // ex.name = ReferenceError - // ex.type = not_defined - // ex.arguments = ['aa'] - // ex.stack = ...stack trace... - // - // INTERNET EXPLORER: - // ex.message = ... - // ex.name = ReferenceError - // - // OPERA: - // ex.message = ...message... (see the example below) - // ex.name = ReferenceError - // ex.opera#sourceloc = 11 (pretty much useless, duplicates the info in ex.message) - // ex.stacktrace = n/a; see 'opera:config#UserPrefs|Exceptions Have Stacktrace' - - /** - * Computes stack trace information from the stack property. - * Chrome and Gecko use this property. - * @param {Error} ex - * @return {?Object.} Stack trace information. - */ - function computeStackTraceFromStackProp(ex) { - if (!ex.stack) { - return null; - } - - var chrome = /^\s*at (.*?) ?\(?((?:file|https?|chrome-extension):.*?):(\d+)(?::(\d+))?\)?\s*$/i, - gecko = /^\s*(.*?)(?:\((.*?)\))?@((?:file|https?|chrome).*?):(\d+)(?::(\d+))?\s*$/i, - lines = ex.stack.split('\n'), - stack = [], - parts, - element, - reference = /^(.*) is undefined$/.exec(ex.message); - - for (var i = 0, j = lines.length; i < j; ++i) { - if ((parts = gecko.exec(lines[i]))) { - element = { - 'url': parts[3], - 'func': parts[1] || UNKNOWN_FUNCTION, - 'args': parts[2] ? parts[2].split(',') : '', - 'line': +parts[4], - 'column': parts[5] ? +parts[5] : null - }; - } else if ((parts = chrome.exec(lines[i]))) { - element = { - 'url': parts[2], - 'func': parts[1] || UNKNOWN_FUNCTION, - 'line': +parts[3], - 'column': parts[4] ? +parts[4] : null - }; - } else { - continue; - } - - if (!element.func && element.line) { - element.func = guessFunctionName(element.url, element.line); - } - - if (element.line) { - element.context = gatherContext(element.url, element.line); - } - - stack.push(element); - } - - if (!stack.length) { - return null; - } - - if (stack[0].line && !stack[0].column && reference) { - stack[0].column = findSourceInLine(reference[1], stack[0].url, stack[0].line); - } else if (!stack[0].column && !isUndefined(ex.columnNumber)) { - // FireFox uses this awesome columnNumber property for its top frame - // Also note, Firefox's column number is 0-based and everything else expects 1-based, - // so adding 1 - stack[0].column = ex.columnNumber + 1; - } - - return { - 'name': ex.name, - 'message': ex.message, - 'url': document.location.href, - 'stack': stack - }; - } - - /** - * Computes stack trace information from the stacktrace property. - * Opera 10 uses this property. - * @param {Error} ex - * @return {?Object.} Stack trace information. - */ - function computeStackTraceFromStacktraceProp(ex) { - // Access and store the stacktrace property before doing ANYTHING - // else to it because Opera is not very good at providing it - // reliably in other circumstances. - var stacktrace = ex.stacktrace; - - var testRE = / line (\d+), column (\d+) in (?:]+)>|([^\)]+))\((.*)\) in (.*):\s*$/i, - lines = stacktrace.split('\n'), - stack = [], - parts; - - for (var i = 0, j = lines.length; i < j; i += 2) { - if ((parts = testRE.exec(lines[i]))) { - var element = { - 'line': +parts[1], - 'column': +parts[2], - 'func': parts[3] || parts[4], - 'args': parts[5] ? parts[5].split(',') : [], - 'url': parts[6] - }; - - if (!element.func && element.line) { - element.func = guessFunctionName(element.url, element.line); - } - if (element.line) { - try { - element.context = gatherContext(element.url, element.line); - } catch (exc) {} - } - - if (!element.context) { - element.context = [lines[i + 1]]; - } - - stack.push(element); - } - } - - if (!stack.length) { - return null; - } - - return { - 'name': ex.name, - 'message': ex.message, - 'url': document.location.href, - 'stack': stack - }; - } - - /** - * NOT TESTED. - * Computes stack trace information from an error message that includes - * the stack trace. - * Opera 9 and earlier use this method if the option to show stack - * traces is turned on in opera:config. - * @param {Error} ex - * @return {?Object.} Stack information. - */ - function computeStackTraceFromOperaMultiLineMessage(ex) { - // Opera includes a stack trace into the exception message. An example is: - // - // Statement on line 3: Undefined variable: undefinedFunc - // Backtrace: - // Line 3 of linked script file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.js: In function zzz - // undefinedFunc(a); - // Line 7 of inline#1 script in file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.html: In function yyy - // zzz(x, y, z); - // Line 3 of inline#1 script in file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.html: In function xxx - // yyy(a, a, a); - // Line 1 of function script - // try { xxx('hi'); return false; } catch(ex) { TraceKit.report(ex); } - // ... - - var lines = ex.message.split('\n'); - if (lines.length < 4) { - return null; - } - - var lineRE1 = /^\s*Line (\d+) of linked script ((?:file|https?)\S+)(?:: in function (\S+))?\s*$/i, - lineRE2 = /^\s*Line (\d+) of inline#(\d+) script in ((?:file|https?)\S+)(?:: in function (\S+))?\s*$/i, - lineRE3 = /^\s*Line (\d+) of function script\s*$/i, - stack = [], - scripts = document.getElementsByTagName('script'), - inlineScriptBlocks = [], - parts, - i, - len, - source; - - for (i in scripts) { - if (hasKey(scripts, i) && !scripts[i].src) { - inlineScriptBlocks.push(scripts[i]); - } - } - - for (i = 2, len = lines.length; i < len; i += 2) { - var item = null; - if ((parts = lineRE1.exec(lines[i]))) { - item = { - 'url': parts[2], - 'func': parts[3], - 'line': +parts[1] - }; - } else if ((parts = lineRE2.exec(lines[i]))) { - item = { - 'url': parts[3], - 'func': parts[4] - }; - var relativeLine = (+parts[1]); // relative to the start of the - - - - - - -TraceKit specific optional settings -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Usually there is no need to touch these settings, but they exist in case you need to tweak something. - -fetchContext ------------- - -Enable TraceKit to attempt to fetch source files to look up anonymous function names, this can be useful to enable if you don't get the context for some entries in the stack trace. Default value is ``false``. - -.. code-block:: javascript - - { - fetchContext: true - } - -linesOfContext --------------- - -The count of lines surrounding the error line that should be used as context in the stack trace, default value is ``11``. Only applicable when ``fetchContext` is enabled. - -.. code-block:: javascript - - { - linesOfContext: 11 - } - -collectWindowErrors -------------------- - -Enable or disable the TraceKit ``window.onerror`` handler, default value is ``true``. - -.. code-block:: javascript - - { - collectWindowErrors: true - } diff --git a/htdocs/includes/raven-js/docs/contributing/index.rst b/htdocs/includes/raven-js/docs/contributing/index.rst deleted file mode 100644 index 2b25abf7f16..00000000000 --- a/htdocs/includes/raven-js/docs/contributing/index.rst +++ /dev/null @@ -1,99 +0,0 @@ -Contributing -============ - -Setting up an Environment -~~~~~~~~~~~~~~~~~~~~~~~~~ - -To run the test suite and run our code linter, node.js and npm are required. If you don't have node installed, `get it here `_ first. - -Installing all other dependencies is as simple as: - -.. code-block:: sh - - $ npm install - -And if you don't have `Grunt `_ already, feel free to install that globally: - -.. code-block:: sh - - $ npm install -g grunt-cli - -Running the Test Suite -~~~~~~~~~~~~~~~~~~~~~~ - -The test suite is powered by `Mocha `_ and can both run from the command line, or in the browser. - -From the command line: - -.. code-block:: sh - - $ grunt test - -From your browser: - -.. code-block:: sh - - $ grunt run:test - -Then visit: http://localhost:8000/test/ - -Compiling Raven.js -~~~~~~~~~~~~~~~~~~ - -The simplest way to compile your own version of Raven.js is with the supplied grunt command: - -.. code-block:: sh - - $ grunt build - -By default, this will compile raven.js and all of the included plugins. - -If you only want to compile the core raven.js: - -.. code-block:: sh - - $ grunt build.core - -Files are compiled into ``build/``. - -Contributing Back Code -~~~~~~~~~~~~~~~~~~~~~~ - -Please, send over suggestions and bug fixes in the form of pull requests on `GitHub `_. Any nontrivial fixes/features should include tests. -Do not include any changes to the ``dist/`` folder or bump version numbers yourself. - -Documentation -------------- - -The documentation is written using `reStructuredText `_, and compiled using `Sphinx `_. If you don't have Sphinx installed, you can do it using following command (assuming you have Python already installed in your system): - -.. code-block:: sh - - $ pip install sphinx - -Documentation can be then compiled by running: - -.. code-block:: sh - - $ make docs - -Afterwards you can view it in your browser by running following command and than pointing your browser to http://127.0.0.1:8000/: - -.. code-block:: sh - - $ grunt run:docs - - - -Releasing New Version -~~~~~~~~~~~~~~~~~~~~~ - -* Bump version numbers in both ``package.json`` and ``bower.json``. -* ``$ grunt dist`` This will compile a new version and update it in the ``dist/`` folder. -* Confirm that build was fine, etc. -* Commit new version, create a tag. Push to GitHub. -* ``$ grunt publish`` to recompile all plugins and all permutations and upload to S3. -* ``$ npm publish`` to push to npm. -* Confirm that the new version exists behind ``cdn.ravenjs.com`` -* Update version in the ``gh-pages`` branch specifically for http://ravenjs.com/. -* glhf diff --git a/htdocs/includes/raven-js/docs/index.rst b/htdocs/includes/raven-js/docs/index.rst deleted file mode 100644 index afe07bc9ab9..00000000000 --- a/htdocs/includes/raven-js/docs/index.rst +++ /dev/null @@ -1,42 +0,0 @@ -Raven.js -======== - -Raven.js is a tiny standalone JavaScript client for `Sentry `_. - -**This version of Raven.js requires Sentry 6.0 or newer.** - - -Getting Started ---------------- - -.. toctree:: - :maxdepth: 2 - - install/index - plugins/index - config/index - usage/index - tips/index - -Developers ----------- -.. toctree:: - :maxdepth: 2 - - contributing/index - -What's New? ------------ -.. toctree:: - :maxdepth: 2 - - changelog/index - -Resources ---------- -* `Download `_ -* `Bug Tracker `_ -* `Code `_ -* `IRC `_ (irc.freenode.net, #sentry) -* :doc:`Changelog ` -* Follow `@mattrobenolt `_ on Twitter for updates! diff --git a/htdocs/includes/raven-js/docs/install/index.rst b/htdocs/includes/raven-js/docs/install/index.rst deleted file mode 100644 index 17feda4e08e..00000000000 --- a/htdocs/includes/raven-js/docs/install/index.rst +++ /dev/null @@ -1,61 +0,0 @@ -Installation -============ - -Raven is distributed in a few different methods, and should get included after any other libraries are included, but before your own scripts. - -So for example: - -.. parsed-literal:: - - - - - - -This allows the ability for Raven's plugins to instrument themselves. If included before something like jQuery, it'd be impossible to use for example, the jquery plugin. - -Using our CDN -~~~~~~~~~~~~~ - -We serve our own builds off of `Fastly `_. They are accessible over both http and https, so we recommend leaving the protocol off. - -Our CDN distributes builds with and without :doc:`plugins `. - -.. parsed-literal:: - - - -**We highly recommend trying out a plugin or two since it'll greatly improve the chances that we can collect good information.** - -This version does not include any plugins. See `ravenjs.com `_ for more information about plugins and getting other builds. - -Bower -~~~~~ - -We also provide a way to deploy Raven via `bower -`_. Useful if you want serve your own scripts instead of depending on our CDN and mantain a ``bower.json`` with a list of dependencies and versions (adding the ``--save`` flag would automatically add it to ``bower.json``). - -.. code-block:: sh - - $ bower install raven-js --save - -.. code-block:: html - - - -Also note that the file is uncompresed but is ready to pass to any decent JavaScript compressor like `uglify `_. - -npm -~~~ - -Raven is published to npm as well. https://www.npmjs.com/package/raven-js - -.. code-block:: sh - - $ npm install raven-js --save - -Requirements -~~~~~~~~~~~~ - -Raven expects the browser to provide `window.JSON` and `window.JSON.stringify`. In Internet Explorer 8+ these are available in `standards mode `_. -You can also use `json2.js `_ to provide the JSON implementation in browsers/modes which doesn't support native JSON diff --git a/htdocs/includes/raven-js/docs/make.bat b/htdocs/includes/raven-js/docs/make.bat deleted file mode 100644 index 13e2848a47d..00000000000 --- a/htdocs/includes/raven-js/docs/make.bat +++ /dev/null @@ -1,190 +0,0 @@ -@ECHO OFF - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set BUILDDIR=_build -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . -set I18NSPHINXOPTS=%SPHINXOPTS% . -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% - set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% -) - -if "%1" == "" goto help - -if "%1" == "help" ( - :help - echo.Please use `make ^` where ^ is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. singlehtml to make a single large HTML file - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. devhelp to make HTML files and a Devhelp project - echo. epub to make an epub - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. text to make text files - echo. man to make manual pages - echo. texinfo to make Texinfo files - echo. gettext to make PO message catalogs - echo. changes to make an overview over all changed/added/deprecated items - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - goto end -) - -if "%1" == "clean" ( - for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i - del /q /s %BUILDDIR%\* - goto end -) - -if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end -) - -if "%1" == "singlehtml" ( - %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. - goto end -) - -if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %BUILDDIR%/htmlhelp. - goto end -) - -if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\raven-js.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\raven-js.ghc - goto end -) - -if "%1" == "devhelp" ( - %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. - goto end -) - -if "%1" == "epub" ( - %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The epub file is in %BUILDDIR%/epub. - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "text" ( - %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The text files are in %BUILDDIR%/text. - goto end -) - -if "%1" == "man" ( - %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The manual pages are in %BUILDDIR%/man. - goto end -) - -if "%1" == "texinfo" ( - %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. - goto end -) - -if "%1" == "gettext" ( - %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The message catalogs are in %BUILDDIR%/locale. - goto end -) - -if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes - if errorlevel 1 exit /b 1 - echo. - echo.The overview file is in %BUILDDIR%/changes. - goto end -) - -if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - if errorlevel 1 exit /b 1 - echo. - echo.Link check complete; look for any errors in the above output ^ -or in %BUILDDIR%/linkcheck/output.txt. - goto end -) - -if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - if errorlevel 1 exit /b 1 - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in %BUILDDIR%/doctest/output.txt. - goto end -) - -:end diff --git a/htdocs/includes/raven-js/docs/plugins/index.rst b/htdocs/includes/raven-js/docs/plugins/index.rst deleted file mode 100644 index 7a9df7b019e..00000000000 --- a/htdocs/includes/raven-js/docs/plugins/index.rst +++ /dev/null @@ -1,20 +0,0 @@ -Plugins -======= - -What are plugins? -~~~~~~~~~~~~~~~~~ - -In Raven.js, plugins are little snippets of code to augment functionality for a specific application/framework. It is highly recommended to checkout the list of plugins and use what apply to your project. - -In order to keep the core small, we have opted to only include the most basic functionality by default, and you can pick and choose which plugins are applicable for you. - -Why are plugins needed at all? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -JavaScript is pretty restrictive when it comes to exception handling, and there are a lot of things that make it difficult to get relevent information, so it's important that we inject code and wrap things magically so we can extract what we need. See :doc:`/usage/index` for tips regarding that. - - -All Plugins -~~~~~~~~~~~ -* https://github.com/getsentry/raven-js/tree/master/plugins -* `Download `_ diff --git a/htdocs/includes/raven-js/docs/tips/index.rst b/htdocs/includes/raven-js/docs/tips/index.rst deleted file mode 100644 index 8dee09eb7ef..00000000000 --- a/htdocs/includes/raven-js/docs/tips/index.rst +++ /dev/null @@ -1,79 +0,0 @@ -Pro Tips™ -========= - - -Decluttering Sentry -~~~~~~~~~~~~~~~~~~~ - -The first thing to do is to consider constructing a whitelist of domains in which might raise acceptable exceptions. - -If your scripts are loaded from ``cdn.example.com`` and your site is ``example.com`` it'd be reasonable to set ``whitelistUrls`` to: - -.. code-block:: javascript - - whitelistUrls: [ - /https?:\/\/((cdn|www)\.)?example\.com/ - ] - -Since this accepts a regular expression, that would catch anything \*.example.com or example.com exactly. See also: :ref:`Config: whitelistUrls`. - -Next, checkout the list of :doc:`plugins ` we provide and see which are applicable to you. - -The community has compiled a list of common ignore rules for common things, like Facebook, Chrome extensions, etc. So it's recommended to at least check these out and see if they apply to you. `Check out the original gist `_. - -.. code-block:: javascript - - var ravenOptions = { - ignoreErrors: [ - // Random plugins/extensions - 'top.GLOBALS', - // See: http://blog.errorception.com/2012/03/tale-of-unfindable-js-error. html - 'originalCreateNotification', - 'canvas.contentDocument', - 'MyApp_RemoveAllHighlights', - 'http://tt.epicplay.com', - 'Can\'t find variable: ZiteReader', - 'jigsaw is not defined', - 'ComboSearch is not defined', - 'http://loading.retry.widdit.com/', - 'atomicFindClose', - // Facebook borked - 'fb_xd_fragment', - // ISP "optimizing" proxy - `Cache-Control: no-transform` seems to reduce this. (thanks @acdha) - // See http://stackoverflow.com/questions/4113268/how-to-stop-javascript-injection-from-vodafone-proxy - 'bmi_SafeAddOnload', - 'EBCallBackMessageReceived', - // See http://toolbar.conduit.com/Developer/HtmlAndGadget/Methods/JSInjection.aspx - 'conduitPage' - ], - ignoreUrls: [ - // Facebook flakiness - /graph\.facebook\.com/i, - // Facebook blocked - /connect\.facebook\.net\/en_US\/all\.js/i, - // Woopra flakiness - /eatdifferent\.com\.woopra-ns\.com/i, - /static\.woopra\.com\/js\/woopra\.js/i, - // Chrome extensions - /extensions\//i, - /^chrome:\/\//i, - // Other plugins - /127\.0\.0\.1:4001\/isrunning/i, // Cacaoweb - /webappstoolbarba\.texthelp\.com\//i, - /metrics\.itunes\.apple\.com\.edgesuite\.net\//i - ] - }; - - -Sampling Data -~~~~~~~~~~~~~ - -It happens frequently that errors sent from your frontend can be overwhelming. One solution here is to only send a sample of the events that happen. You can do this via the ``shouldSendCallback`` setting: - -.. code-block:: javascript - - shouldSendCallback: function(data) { - // only send 10% of errors - var sampleRate = 10; - return (Math.random() * 100 <= sampleRate); - } diff --git a/htdocs/includes/raven-js/docs/usage/index.rst b/htdocs/includes/raven-js/docs/usage/index.rst deleted file mode 100644 index c8e01f9c801..00000000000 --- a/htdocs/includes/raven-js/docs/usage/index.rst +++ /dev/null @@ -1,156 +0,0 @@ -Usage -===== - -By default, Raven makes a few efforts to try its best to capture meaningful stack traces, but browsers make it pretty difficult. - -The easiest solution is to prevent an error from bubbling all of the way up the stack to ``window``. - -How to actually capture an error correctly -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -try...catch ------------ - -The simplest way, is to try and explicitly capture and report potentially problematic code with a ``try...catch`` block and ``Raven.captureException``. - -.. code-block:: javascript - - try { - doSomething(a[0]) - } catch(e) { - Raven.captureException(e) - } - -**Do not** throw strings! Always throw an actual ``Error`` object. For example: - -.. code-block:: javascript - - throw new Error('broken') // good - throw 'broken' // bad - -It's impossible to retrieve a stack trace from a string. If this happens, Raven transmits the error as a plain message. - -context/wrap ------------- - -``Raven.context`` allows you to wrap any function to be immediately executed. Behind the scenes, Raven is just wrapping your code in a ``try...catch`` block to record the exception before re-throwing it. - -.. code-block:: javascript - - Raven.context(function() { - doSomething(a[0]) - }) - -``Raven.wrap`` wraps a function in a similar way to ``Raven.context``, but instead of executing the function, it returns another function. This is totally awesome for use when passing around a callback. - -.. code-block:: javascript - - var doIt = function() { - // doing cool stuff - } - - setTimeout(Raven.wrap(doIt), 1000) - -Tracking authenticated users -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -While a user is logged in, you can tell Sentry to associate errors with user data. - -.. code-block:: javascript - - Raven.setUserContext({ - email: 'matt@example.com', - id: '123' - }) - -If at any point, the user becomes unauthenticated, you can call ``Raven.setUserContext()`` with no arguments to remove their data. *This would only really be useful in a large web app where the user logs in/out without a page reload.* - -Capturing a specific message -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: javascript - - Raven.captureMessage('Broken!') - -Passing additional data -~~~~~~~~~~~~~~~~~~~~~~~ - -``captureException``, ``context``, ``wrap``, and ``captureMessage`` functions all allow passing additional data to be tagged onto the error, such as ``tags`` or ``extra`` for additional context. - -.. code-block:: javascript - - Raven.captureException(e, {tags: { key: "value" }}) - - Raven.captureMessage('Broken!', {tags: { key: "value" }}) - - Raven.context({tags: { key: "value" }}, function(){ ... }) - - Raven.wrap({logger: "my.module"}, function(){ ... }) - - Raven.captureException(e, {extra: { foo: "bar" }}) - -You can also set context variables globally to be merged in with future exceptions with ``setExtraContext`` and ``setTagsContext``. - -.. code-block:: javascript - - Raven.setExtraContext({ foo: "bar" }) - Raven.setTagsContext({ key: "value" }) - - -Getting back an event id -~~~~~~~~~~~~~~~~~~~~~~~~ - -An event id is a globally unique id for the event that was just sent. This event id can be used to find the exact event from within Sentry. - -This is often used to display for the user and report an error to customer service. - -.. code-block:: javascript - - Raven.lastEventId() - -``Raven.lastEventId()`` will be undefined until an event is sent. After an event is sent, it will contain the string id. - -.. code-block:: javascript - - Raven.captureMessage('Broken!') - alert(Raven.lastEventId()) - - -Check if Raven is setup and ready to go -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: javascript - - Raven.isSetup() - - -Dealing with minified source code -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Raven and Sentry now support `Source Maps `_. - -We have provided some instructions to creating Source Maps over at https://www.getsentry.com/docs/sourcemaps/. Also, checkout our `Gruntfile `_ for a good example of what we're doing. - -You can use `Source Map Validator `_ to help verify that things are correct. - -CORS -~~~~ - -If you're hosting your scripts on another domain and things don't get caught by Raven, it's likely that the error will bubble up to ``window.onerror``. If this happens, the error will report some ugly ``Script error`` and Raven will drop it on the floor -since this is a useless error for everybody. - -To help mitigate this, we can tell the browser that these scripts are safe and we're allowing them to expose their errors to us. - -In your `` - -And set an ``Access-Control-Allow-Origin`` HTTP header on that file. - -.. code-block:: console - - Access-Control-Allow-Origin: * - -**Note: both of these steps need to be done or your scripts might not even get executed** diff --git a/htdocs/includes/raven-js/example/Makefile b/htdocs/includes/raven-js/example/Makefile deleted file mode 100644 index 87976776e90..00000000000 --- a/htdocs/includes/raven-js/example/Makefile +++ /dev/null @@ -1,3 +0,0 @@ - -build: - ../node_modules/.bin/uglifyjs --source-map=file.sourcemap.js -c -o file.min.js file1.js file2.js diff --git a/htdocs/includes/raven-js/example/file.min.js b/htdocs/includes/raven-js/example/file.min.js deleted file mode 100644 index 12b9f811b28..00000000000 --- a/htdocs/includes/raven-js/example/file.min.js +++ /dev/null @@ -1,2 +0,0 @@ -function add(a,b){"use strict";return a+b}function multiply(a,b){"use strict";return a*b}function divide(a,b){"use strict";try{return multiply(add(a,b),a,b)/c}catch(e){Raven.captureException(e)}} -//@ sourceMappingURL=file.sourcemap.js \ No newline at end of file diff --git a/htdocs/includes/raven-js/example/file.sourcemap.js b/htdocs/includes/raven-js/example/file.sourcemap.js deleted file mode 100644 index 1bd0f6510cf..00000000000 --- a/htdocs/includes/raven-js/example/file.sourcemap.js +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"file.min.js","sources":["file1.js","file2.js"],"names":["add","a","b","multiply","divide","c","e","Raven","captureException"],"mappings":"AAAA,QAASA,KAAIC,EAAGC,GACf,YACA,OAAOD,GAAIC,ECFZ,QAASC,UAASF,EAAGC,GACpB,YACA,OAAOD,GAAIC,EAEZ,QAASE,QAAOH,EAAGC,GAClB,YACA,KACC,MAAOC,UAASH,IAAIC,EAAGC,GAAID,EAAGC,GAAKG,EAClC,MAAOC,GACRC,MAAMC,iBAAiBF"} \ No newline at end of file diff --git a/htdocs/includes/raven-js/example/file1.js b/htdocs/includes/raven-js/example/file1.js deleted file mode 100644 index eed5827852d..00000000000 --- a/htdocs/includes/raven-js/example/file1.js +++ /dev/null @@ -1,4 +0,0 @@ -function add(a, b) { - "use strict"; - return a + b; -} \ No newline at end of file diff --git a/htdocs/includes/raven-js/example/file2.js b/htdocs/includes/raven-js/example/file2.js deleted file mode 100644 index 8b174356846..00000000000 --- a/htdocs/includes/raven-js/example/file2.js +++ /dev/null @@ -1,12 +0,0 @@ -function multiply(a, b) { - "use strict"; - return a * b; -} -function divide(a, b) { - "use strict"; - try { - return multiply(add(a, b), a, b) / c; - } catch (e) { - Raven.captureException(e); - } -} diff --git a/htdocs/includes/raven-js/example/index.html b/htdocs/includes/raven-js/example/index.html deleted file mode 100644 index b7ebbdd018e..00000000000 --- a/htdocs/includes/raven-js/example/index.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - Scratch Disk - - - - - - - - - - - - - - - - - - diff --git a/htdocs/includes/raven-js/example/scratch.js b/htdocs/includes/raven-js/example/scratch.js deleted file mode 100644 index f1962bbdfc1..00000000000 --- a/htdocs/includes/raven-js/example/scratch.js +++ /dev/null @@ -1,42 +0,0 @@ -function foo() { - console.log("lol, i don't do anything") -} - -function foo2() { - foo() - console.log('i called foo') -} - -function broken() { - try { - /*fkjdsahfdhskfhdsahfudshafuoidashfudsa*/ fdasfds[0]; // i throw an error h sadhf hadsfdsakf kl;dsjaklf jdklsajfk ljds;klafldsl fkhdas;hf hdsaf hdsalfhjldksahfljkdsahfjkl dhsajkfl hdklsahflkjdsahkfj hdsjakhf dkashfl diusafh kdsjahfkldsahf jkdashfj khdasjkfhdjksahflkjdhsakfhjdksahfjkdhsakf hdajskhf kjdash kjfads fjkadsh jkfdsa jkfdas jkfdjkas hfjkdsajlk fdsajk fjkdsa fjdsa fdkjlsa fjkdaslk hfjlkdsah fhdsahfui - }catch(e) { - Raven.captureException(e); - } -} - -function ready() { - document.getElementById('test').onclick = broken; -} - -function foo3() { - document.getElementById('crap').value = 'barfdasjkfhoadshflkaosfjadiosfhdaskjfasfadsfads'; -} - -function somethingelse() { - document.getElementById('somethingelse').value = 'this is some realy really long message just so our minification is largeeeeeeeeee!'; -} - -function derp() { - fdas[0]; -} - -function testOptions() { - Raven.context({tags: {foo: 'bar'}}, function() { - throw new Error('foo'); - }); -} - -function throwString() { - throw 'oops'; -} diff --git a/htdocs/includes/raven-js/package.json b/htdocs/includes/raven-js/package.json deleted file mode 100644 index 9352edcab38..00000000000 --- a/htdocs/includes/raven-js/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "raven-js", - "version": "1.1.19", - "license": "BSD-2-Clause", - "homepage": "https://getsentry.com", - "scripts": { - "pretest": "npm install", - "test": "grunt test" - }, - "repository": { - "type": "git", - "url": "git://github.com/getsentry/raven-js.git" - }, - "main": "dist/raven.js", - "devDependencies": { - "chai": "~1.8.1", - "grunt": "~0.4.1", - "grunt-cli": "~0.1.9", - "grunt-contrib-jshint": "~0.6.3", - "grunt-contrib-uglify": "~0.2.2", - "grunt-contrib-concat": "~0.3.0", - "grunt-contrib-clean": "~0.4.0", - "grunt-mocha": "~0.4.1", - "grunt-release": "~0.6.0", - "grunt-s3": "~0.2.0-alpha.3", - "grunt-gitinfo": "~0.1.1", - "grunt-contrib-connect": "~0.5.0", - "grunt-contrib-copy": "~0.4.1", - "sinon": "~1.7.3", - "lodash": "~2.4.0" - } -} diff --git a/htdocs/includes/raven-js/plugins/angular.js b/htdocs/includes/raven-js/plugins/angular.js deleted file mode 100644 index 98bf5892001..00000000000 --- a/htdocs/includes/raven-js/plugins/angular.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Angular.js plugin - * - * Provides an $exceptionHandler for Angular.js - */ -;(function(Raven, angular) { -'use strict'; - -// quit if angular isn't on the page -if (!angular) { - return; -} - -function ngRavenProvider($provide) { - $provide.decorator('$exceptionHandler', [ - 'RavenConfig', '$delegate', - ngRavenExceptionHandler - ]); -} - -function ngRavenExceptionHandler(RavenConfig, $delegate) { - if (!RavenConfig) - throw new Error('RavenConfig must be set before using this'); - - Raven.config(RavenConfig.dsn, RavenConfig.config).install(); - return function angularExceptionHandler(ex, cause) { - $delegate(ex, cause); - Raven.captureException(ex, {extra: {cause: cause}}); - }; -} - -angular.module('ngRaven', []) - .config(['$provide', ngRavenProvider]) - .value('Raven', Raven); - -})(window.Raven, window.angular); diff --git a/htdocs/includes/raven-js/plugins/backbone.js b/htdocs/includes/raven-js/plugins/backbone.js deleted file mode 100644 index 09e0f6b8c1c..00000000000 --- a/htdocs/includes/raven-js/plugins/backbone.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Backbone.js plugin - * - * Patches Backbone.Events callbacks. - */ -;(function(window, Raven, Backbone) { -'use strict'; - -// quit if Backbone isn't on the page -if (!Backbone) { - return; -} - -function makeBackboneEventsOn(oldOn) { - return function BackboneEventsOn(name, callback, context) { - var wrapCallback = function (cb) { - if (Object.prototype.toString.call(cb) === '[object Function]') { - var _callback = cb._callback || cb; - cb = Raven.wrap(cb); - cb._callback = _callback; - } - return cb; - }; - if (Object.prototype.toString.call(name) === '[object Object]') { - // Handle event maps. - for (var key in name) { - if (name.hasOwnProperty(key)) { - name[key] = wrapCallback(name[key]); - } - } - } else { - callback = wrapCallback(callback); - } - return oldOn.call(this, name, callback, context); - }; -} - -// We're too late to catch all of these by simply patching Backbone.Events.on -var affectedObjects = [ - Backbone.Events, - Backbone, - Backbone.Model.prototype, - Backbone.Collection.prototype, - Backbone.View.prototype, - Backbone.Router.prototype, - Backbone.History.prototype -], i = 0, l = affectedObjects.length; - -for (; i < l; i++) { - var affected = affectedObjects[i]; - affected.on = makeBackboneEventsOn(affected.on); - affected.bind = affected.on; -} - -}(window, window.Raven, window.Backbone)); diff --git a/htdocs/includes/raven-js/plugins/console.js b/htdocs/includes/raven-js/plugins/console.js deleted file mode 100644 index 4d5ba94090f..00000000000 --- a/htdocs/includes/raven-js/plugins/console.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * console plugin - * - * Monkey patches console.* calls into Sentry messages with - * their appropriate log levels. (Experimental) - */ -;(function(window, Raven, console) { -'use strict'; - -var originalConsole = console, - logLevels = ['debug', 'info', 'warn', 'error'], - level = logLevels.pop(); - -var logForGivenLevel = function(level) { - var originalConsoleLevel = console[level]; - - // warning level is the only level that doesn't map up - // correctly with what Sentry expects. - if (level === 'warn') level = 'warning'; - return function () { - var args = [].slice.call(arguments); - Raven.captureMessage('' + args, {level: level, logger: 'console'}); - - // this fails for some browsers. :( - if (originalConsoleLevel) { - // IE9 doesn't allow calling apply on console functions directly - // See: https://stackoverflow.com/questions/5472938/does-ie9-support-console-log-and-is-it-a-real-function#answer-5473193 - Function.prototype.bind - .call(originalConsoleLevel, originalConsole) - .apply(originalConsole, args); - } - }; -}; - - -while(level) { - console[level] = logForGivenLevel(level); - level = logLevels.pop(); -} -// export -window.console = console; - -}(window, window.Raven, window.console || {})); diff --git a/htdocs/includes/raven-js/plugins/ember.js b/htdocs/includes/raven-js/plugins/ember.js deleted file mode 100644 index c6d0551c709..00000000000 --- a/htdocs/includes/raven-js/plugins/ember.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Ember.js plugin - * - * Patches event handler callbacks and ajax callbacks. - */ -;(function(window, Raven, Ember) { -'use strict'; - -// quit if Ember isn't on the page -if (!Ember) { - return; -} - -var _oldOnError = Ember.onerror; -Ember.onerror = function EmberOnError(error) { - Raven.captureException(error); - if (typeof _oldOnError === 'function') { - _oldOnError.call(this, error); - } -}; -Ember.RSVP.on('error', function (reason) { - if (reason instanceof Error) { - Raven.captureException(reason, {extra: {context: 'Unhandled Promise error detected'}}); - } else { - Raven.captureMessage('Unhandled Promise error detected', {extra: {reason: reason}}); - } -}); - -}(window, window.Raven, window.Ember)); diff --git a/htdocs/includes/raven-js/plugins/jquery.js b/htdocs/includes/raven-js/plugins/jquery.js deleted file mode 100644 index 4a5474cdb86..00000000000 --- a/htdocs/includes/raven-js/plugins/jquery.js +++ /dev/null @@ -1,75 +0,0 @@ -/** - * jQuery plugin - * - * Patches event handler callbacks and ajax callbacks. - */ -;(function(window, Raven, $) { -'use strict'; - -// quit if jQuery isn't on the page -if (!$) { - return; -} - -var _oldEventAdd = $.event.add; -$.event.add = function ravenEventAdd(elem, types, handler, data, selector) { - var _handler; - - if (handler && handler.handler) { - _handler = handler.handler; - handler.handler = Raven.wrap(handler.handler); - } else { - _handler = handler; - handler = Raven.wrap(handler); - } - - // If the handler we are attaching doesn’t have the same guid as - // the original, it will never be removed when someone tries to - // unbind the original function later. Technically as a result of - // this our guids are no longer globally unique, but whatever, that - // never hurt anybody RIGHT?! - if (_handler.guid) { - handler.guid = _handler.guid; - } else { - handler.guid = _handler.guid = $.guid++; - } - - return _oldEventAdd.call(this, elem, types, handler, data, selector); -}; - -var _oldReady = $.fn.ready; -$.fn.ready = function ravenjQueryReadyWrapper(fn) { - return _oldReady.call(this, Raven.wrap(fn)); -}; - -var _oldAjax = $.ajax; -$.ajax = function ravenAjaxWrapper(url, options) { - var keys = ['complete', 'error', 'success'], key; - - // Taken from https://github.com/jquery/jquery/blob/eee2eaf1d7a189d99106423a4206c224ebd5b848/src/ajax.js#L311-L318 - // If url is an object, simulate pre-1.5 signature - if (typeof url === 'object') { - options = url; - url = undefined; - } - - // Force options to be an object - options = options || {}; - - /*jshint -W084*/ - while(key = keys.pop()) { - if ($.isFunction(options[key])) { - options[key] = Raven.wrap(options[key]); - } - } - /*jshint +W084*/ - - try { - return _oldAjax.call(this, url, options); - } catch (e) { - Raven.captureException(e); - throw e; - } -}; - -}(window, window.Raven, window.jQuery)); diff --git a/htdocs/includes/raven-js/plugins/native.js b/htdocs/includes/raven-js/plugins/native.js deleted file mode 100644 index c641f13a5d1..00000000000 --- a/htdocs/includes/raven-js/plugins/native.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * native plugin - * - * Extends support for global error handling for asynchronous browser - * functions. Adopted from Closure Library's errorhandler.js. - */ -;(function extendToAsynchronousCallbacks(window, Raven) { -"use strict"; - -var _helper = function _helper(fnName) { - var originalFn = window[fnName]; - window[fnName] = function ravenAsyncExtension() { - // Make a copy of the arguments - var args = [].slice.call(arguments); - var originalCallback = args[0]; - if (typeof (originalCallback) === 'function') { - args[0] = Raven.wrap(originalCallback); - } - // IE < 9 doesn't support .call/.apply on setInterval/setTimeout, but it - // also supports only two arguments and doesn't care what this is, so we - // can just call the original function directly. - if (originalFn.apply) { - return originalFn.apply(this, args); - } else { - return originalFn(args[0], args[1]); - } - }; -}; - -_helper('setTimeout'); -_helper('setInterval'); - -}(window, window.Raven)); diff --git a/htdocs/includes/raven-js/plugins/require.js b/htdocs/includes/raven-js/plugins/require.js deleted file mode 100644 index 60378a1b0b9..00000000000 --- a/htdocs/includes/raven-js/plugins/require.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * require.js plugin - * - * Automatically wrap define/require callbacks. (Experimental) - */ -;(function(window, Raven) { -'use strict'; - -if (typeof define === 'function' && define.amd) { - window.define = Raven.wrap({deep: false}, define); - window.require = Raven.wrap({deep: false}, require); -} - -}(window, window.Raven)); diff --git a/htdocs/includes/raven-js/src/raven.js b/htdocs/includes/raven-js/src/raven.js deleted file mode 100644 index a2d2b35604b..00000000000 --- a/htdocs/includes/raven-js/src/raven.js +++ /dev/null @@ -1,830 +0,0 @@ -'use strict'; - -// First, check for JSON support -// If there is no JSON, we no-op the core features of Raven -// since JSON is required to encode the payload -var _Raven = window.Raven, - hasJSON = !!(typeof JSON === 'object' && JSON.stringify), - lastCapturedException, - lastEventId, - globalServer, - globalUser, - globalKey, - globalProject, - globalOptions = { - logger: 'javascript', - ignoreErrors: [], - ignoreUrls: [], - whitelistUrls: [], - includePaths: [], - collectWindowErrors: true, - tags: {}, - maxMessageLength: 100, - extra: {} - }, - authQueryString, - isRavenInstalled = false, - - objectPrototype = Object.prototype, - startTime = now(); - -/* - * The core Raven singleton - * - * @this {Raven} - */ -var Raven = { - VERSION: '<%= pkg.version %>', - - debug: true, - - /* - * Allow multiple versions of Raven to be installed. - * Strip Raven from the global context and returns the instance. - * - * @return {Raven} - */ - noConflict: function() { - window.Raven = _Raven; - return Raven; - }, - - /* - * Configure Raven with a DSN and extra options - * - * @param {string} dsn The public Sentry DSN - * @param {object} options Optional set of of global options [optional] - * @return {Raven} - */ - config: function(dsn, options) { - if (globalServer) { - logDebug('error', 'Error: Raven has already been configured'); - return Raven; - } - if (!dsn) return Raven; - - var uri = parseDSN(dsn), - lastSlash = uri.path.lastIndexOf('/'), - path = uri.path.substr(1, lastSlash); - - // merge in options - if (options) { - each(options, function(key, value){ - globalOptions[key] = value; - }); - } - - // "Script error." is hard coded into browsers for errors that it can't read. - // this is the result of a script being pulled in from an external domain and CORS. - globalOptions.ignoreErrors.push(/^Script error\.?$/); - globalOptions.ignoreErrors.push(/^Javascript error: Script error\.? on line 0$/); - - // join regexp rules into one big rule - globalOptions.ignoreErrors = joinRegExp(globalOptions.ignoreErrors); - globalOptions.ignoreUrls = globalOptions.ignoreUrls.length ? joinRegExp(globalOptions.ignoreUrls) : false; - globalOptions.whitelistUrls = globalOptions.whitelistUrls.length ? joinRegExp(globalOptions.whitelistUrls) : false; - globalOptions.includePaths = joinRegExp(globalOptions.includePaths); - - globalKey = uri.user; - globalProject = uri.path.substr(lastSlash + 1); - - // assemble the endpoint from the uri pieces - globalServer = '//' + uri.host + - (uri.port ? ':' + uri.port : '') + - '/' + path + 'api/' + globalProject + '/store/'; - - if (uri.protocol) { - globalServer = uri.protocol + ':' + globalServer; - } - - if (globalOptions.fetchContext) { - TraceKit.remoteFetching = true; - } - - if (globalOptions.linesOfContext) { - TraceKit.linesOfContext = globalOptions.linesOfContext; - } - - TraceKit.collectWindowErrors = !!globalOptions.collectWindowErrors; - - setAuthQueryString(); - - // return for chaining - return Raven; - }, - - /* - * Installs a global window.onerror error handler - * to capture and report uncaught exceptions. - * At this point, install() is required to be called due - * to the way TraceKit is set up. - * - * @return {Raven} - */ - install: function() { - if (isSetup() && !isRavenInstalled) { - TraceKit.report.subscribe(handleStackInfo); - isRavenInstalled = true; - } - - return Raven; - }, - - /* - * Wrap code within a context so Raven can capture errors - * reliably across domains that is executed immediately. - * - * @param {object} options A specific set of options for this context [optional] - * @param {function} func The callback to be immediately executed within the context - * @param {array} args An array of arguments to be called with the callback [optional] - */ - context: function(options, func, args) { - if (isFunction(options)) { - args = func || []; - func = options; - options = undefined; - } - - return Raven.wrap(options, func).apply(this, args); - }, - - /* - * Wrap code within a context and returns back a new function to be executed - * - * @param {object} options A specific set of options for this context [optional] - * @param {function} func The function to be wrapped in a new context - * @return {function} The newly wrapped functions with a context - */ - wrap: function(options, func) { - // 1 argument has been passed, and it's not a function - // so just return it - if (isUndefined(func) && !isFunction(options)) { - return options; - } - - // options is optional - if (isFunction(options)) { - func = options; - options = undefined; - } - - // At this point, we've passed along 2 arguments, and the second one - // is not a function either, so we'll just return the second argument. - if (!isFunction(func)) { - return func; - } - - // We don't wanna wrap it twice! - if (func.__raven__) { - return func; - } - - function wrapped() { - var args = [], i = arguments.length, - deep = !options || options && options.deep !== false; - // Recursively wrap all of a function's arguments that are - // functions themselves. - - while(i--) args[i] = deep ? Raven.wrap(options, arguments[i]) : arguments[i]; - - try { - /*jshint -W040*/ - return func.apply(this, args); - } catch(e) { - Raven.captureException(e, options); - throw e; - } - } - - // copy over properties of the old function - for (var property in func) { - if (hasKey(func, property)) { - wrapped[property] = func[property]; - } - } - - // Signal that this function has been wrapped already - // for both debugging and to prevent it to being wrapped twice - wrapped.__raven__ = true; - wrapped.__inner__ = func; - - return wrapped; - }, - - /* - * Uninstalls the global error handler. - * - * @return {Raven} - */ - uninstall: function() { - TraceKit.report.uninstall(); - isRavenInstalled = false; - - return Raven; - }, - - /* - * Manually capture an exception and send it over to Sentry - * - * @param {error} ex An exception to be logged - * @param {object} options A specific set of options for this error [optional] - * @return {Raven} - */ - captureException: function(ex, options) { - // If not an Error is passed through, recall as a message instead - if (!isError(ex)) return Raven.captureMessage(ex, options); - - // Store the raw exception object for potential debugging and introspection - lastCapturedException = ex; - - // TraceKit.report will re-raise any exception passed to it, - // which means you have to wrap it in try/catch. Instead, we - // can wrap it here and only re-raise if TraceKit.report - // raises an exception different from the one we asked to - // report on. - try { - TraceKit.report(ex, options); - } catch(ex1) { - if(ex !== ex1) { - throw ex1; - } - } - - return Raven; - }, - - /* - * Manually send a message to Sentry - * - * @param {string} msg A plain message to be captured in Sentry - * @param {object} options A specific set of options for this message [optional] - * @return {Raven} - */ - captureMessage: function(msg, options) { - // config() automagically converts ignoreErrors from a list to a RegExp so we need to test for an - // early call; we'll error on the side of logging anything called before configuration since it's - // probably something you should see: - if (!!globalOptions.ignoreErrors.test && globalOptions.ignoreErrors.test(msg)) { - return; - } - - // Fire away! - send( - objectMerge({ - message: msg + '' // Make sure it's actually a string - }, options) - ); - - return Raven; - }, - - /* - * Set/clear a user to be sent along with the payload. - * - * @param {object} user An object representing user data [optional] - * @return {Raven} - */ - setUserContext: function(user) { - globalUser = user; - - return Raven; - }, - - /* - * Set extra attributes to be sent along with the payload. - * - * @param {object} extra An object representing extra data [optional] - * @return {Raven} - */ - setExtraContext: function(extra) { - globalOptions.extra = extra || {}; - - return Raven; - }, - - /* - * Set tags to be sent along with the payload. - * - * @param {object} tags An object representing tags [optional] - * @return {Raven} - */ - setTagsContext: function(tags) { - globalOptions.tags = tags || {}; - - return Raven; - }, - - /* - * Set release version of application - * - * @param {string} release Typically something like a git SHA to identify version - * @return {Raven} - */ - setReleaseContext: function(release) { - globalOptions.release = release; - - return Raven; - }, - - /* - * Set the dataCallback option - * - * @param {function} callback The callback to run which allows the - * data blob to be mutated before sending - * @return {Raven} - */ - setDataCallback: function(callback) { - globalOptions.dataCallback = callback; - - return Raven; - }, - - /* - * Set the shouldSendCallback option - * - * @param {function} callback The callback to run which allows - * introspecting the blob before sending - * @return {Raven} - */ - setShouldSendCallback: function(callback) { - globalOptions.shouldSendCallback = callback; - - return Raven; - }, - - /* - * Get the latest raw exception that was captured by Raven. - * - * @return {error} - */ - lastException: function() { - return lastCapturedException; - }, - - /* - * Get the last event id - * - * @return {string} - */ - lastEventId: function() { - return lastEventId; - }, - - /* - * Determine if Raven is setup and ready to go. - * - * @return {boolean} - */ - isSetup: function() { - return isSetup(); - } -}; - -Raven.setUser = Raven.setUserContext; // To be deprecated - -function triggerEvent(eventType, options) { - var event, key; - - options = options || {}; - - eventType = 'raven' + eventType.substr(0,1).toUpperCase() + eventType.substr(1); - - if (document.createEvent) { - event = document.createEvent('HTMLEvents'); - event.initEvent(eventType, true, true); - } else { - event = document.createEventObject(); - event.eventType = eventType; - } - - for (key in options) if (hasKey(options, key)) { - event[key] = options[key]; - } - - if (document.createEvent) { - // IE9 if standards - document.dispatchEvent(event); - } else { - // IE8 regardless of Quirks or Standards - // IE9 if quirks - try { - document.fireEvent('on' + event.eventType.toLowerCase(), event); - } catch(e) {} - } -} - -var dsnKeys = 'source protocol user pass host port path'.split(' '), - dsnPattern = /^(?:(\w+):)?\/\/(\w+)(:\w+)?@([\w\.-]+)(?::(\d+))?(\/.*)/; - -function RavenConfigError(message) { - this.name = 'RavenConfigError'; - this.message = message; -} -RavenConfigError.prototype = new Error(); -RavenConfigError.prototype.constructor = RavenConfigError; - -/**** Private functions ****/ -function parseDSN(str) { - var m = dsnPattern.exec(str), - dsn = {}, - i = 7; - - try { - while (i--) dsn[dsnKeys[i]] = m[i] || ''; - } catch(e) { - throw new RavenConfigError('Invalid DSN: ' + str); - } - - if (dsn.pass) - throw new RavenConfigError('Do not specify your private key in the DSN!'); - - return dsn; -} - -function isUndefined(what) { - return what === void 0; -} - -function isFunction(what) { - return typeof what === 'function'; -} - -function isString(what) { - return objectPrototype.toString.call(what) === '[object String]'; -} - -function isObject(what) { - return typeof what === 'object' && what !== null; -} - -function isEmptyObject(what) { - for (var k in what) return false; - return true; -} - -// Sorta yanked from https://github.com/joyent/node/blob/aa3b4b4/lib/util.js#L560 -// with some tiny modifications -function isError(what) { - return isObject(what) && - objectPrototype.toString.call(what) === '[object Error]' || - what instanceof Error; -} - -/** - * hasKey, a better form of hasOwnProperty - * Example: hasKey(MainHostObject, property) === true/false - * - * @param {Object} host object to check property - * @param {string} key to check - */ -function hasKey(object, key) { - return objectPrototype.hasOwnProperty.call(object, key); -} - -function each(obj, callback) { - var i, j; - - if (isUndefined(obj.length)) { - for (i in obj) { - if (hasKey(obj, i)) { - callback.call(null, i, obj[i]); - } - } - } else { - j = obj.length; - if (j) { - for (i = 0; i < j; i++) { - callback.call(null, i, obj[i]); - } - } - } -} - - -function setAuthQueryString() { - authQueryString = - '?sentry_version=4' + - '&sentry_client=raven-js/' + Raven.VERSION + - '&sentry_key=' + globalKey; -} - - -function handleStackInfo(stackInfo, options) { - var frames = []; - - if (stackInfo.stack && stackInfo.stack.length) { - each(stackInfo.stack, function(i, stack) { - var frame = normalizeFrame(stack); - if (frame) { - frames.push(frame); - } - }); - } - - triggerEvent('handle', { - stackInfo: stackInfo, - options: options - }); - - processException( - stackInfo.name, - stackInfo.message, - stackInfo.url, - stackInfo.lineno, - frames, - options - ); -} - -function normalizeFrame(frame) { - if (!frame.url) return; - - // normalize the frames data - var normalized = { - filename: frame.url, - lineno: frame.line, - colno: frame.column, - 'function': frame.func || '?' - }, context = extractContextFromFrame(frame), i; - - if (context) { - var keys = ['pre_context', 'context_line', 'post_context']; - i = 3; - while (i--) normalized[keys[i]] = context[i]; - } - - normalized.in_app = !( // determine if an exception came from outside of our app - // first we check the global includePaths list. - !globalOptions.includePaths.test(normalized.filename) || - // Now we check for fun, if the function name is Raven or TraceKit - /(Raven|TraceKit)\./.test(normalized['function']) || - // finally, we do a last ditch effort and check for raven.min.js - /raven\.(min\.)?js$/.test(normalized.filename) - ); - - return normalized; -} - -function extractContextFromFrame(frame) { - // immediately check if we should even attempt to parse a context - if (!frame.context || !globalOptions.fetchContext) return; - - var context = frame.context, - pivot = ~~(context.length / 2), - i = context.length, isMinified = false; - - while (i--) { - // We're making a guess to see if the source is minified or not. - // To do that, we make the assumption if *any* of the lines passed - // in are greater than 300 characters long, we bail. - // Sentry will see that there isn't a context - if (context[i].length > 300) { - isMinified = true; - break; - } - } - - if (isMinified) { - // The source is minified and we don't know which column. Fuck it. - if (isUndefined(frame.column)) return; - - // If the source is minified and has a frame column - // we take a chunk of the offending line to hopefully shed some light - return [ - [], // no pre_context - context[pivot].substr(frame.column, 50), // grab 50 characters, starting at the offending column - [] // no post_context - ]; - } - - return [ - context.slice(0, pivot), // pre_context - context[pivot], // context_line - context.slice(pivot + 1) // post_context - ]; -} - -function processException(type, message, fileurl, lineno, frames, options) { - var stacktrace, label, i; - - // In some instances message is not actually a string, no idea why, - // so we want to always coerce it to one. - message += ''; - - // Sometimes an exception is getting logged in Sentry as - // - // This can only mean that the message was falsey since this value - // is hardcoded into Sentry itself. - // At this point, if the message is falsey, we bail since it's useless - if (type === 'Error' && !message) return; - - if (globalOptions.ignoreErrors.test(message)) return; - - if (frames && frames.length) { - fileurl = frames[0].filename || fileurl; - // Sentry expects frames oldest to newest - // and JS sends them as newest to oldest - frames.reverse(); - stacktrace = {frames: frames}; - } else if (fileurl) { - stacktrace = { - frames: [{ - filename: fileurl, - lineno: lineno, - in_app: true - }] - }; - } - - // Truncate the message to a max of characters - message = truncate(message, globalOptions.maxMessageLength); - - if (globalOptions.ignoreUrls && globalOptions.ignoreUrls.test(fileurl)) return; - if (globalOptions.whitelistUrls && !globalOptions.whitelistUrls.test(fileurl)) return; - - label = lineno ? message + ' at ' + lineno : message; - - // Fire away! - send( - objectMerge({ - // sentry.interfaces.Exception - exception: { - type: type, - value: message - }, - // sentry.interfaces.Stacktrace - stacktrace: stacktrace, - culprit: fileurl, - message: label - }, options) - ); -} - -function objectMerge(obj1, obj2) { - if (!obj2) { - return obj1; - } - each(obj2, function(key, value){ - obj1[key] = value; - }); - return obj1; -} - -function truncate(str, max) { - return str.length <= max ? str : str.substr(0, max) + '\u2026'; -} - -function now() { - return +new Date(); -} - -function getHttpData() { - var http = { - url: document.location.href, - headers: { - 'User-Agent': navigator.userAgent - } - }; - - if (document.referrer) { - http.headers.Referer = document.referrer; - } - - return http; -} - -function send(data) { - if (!isSetup()) return; - - data = objectMerge({ - project: globalProject, - logger: globalOptions.logger, - platform: 'javascript', - // sentry.interfaces.Http - request: getHttpData() - }, data); - - // Merge in the tags and extra separately since objectMerge doesn't handle a deep merge - data.tags = objectMerge(objectMerge({}, globalOptions.tags), data.tags); - data.extra = objectMerge(objectMerge({}, globalOptions.extra), data.extra); - - // Send along our own collected metadata with extra - data.extra = objectMerge({ - 'session:duration': now() - startTime - }, data.extra); - - // If there are no tags/extra, strip the key from the payload alltogther. - if (isEmptyObject(data.tags)) delete data.tags; - - if (globalUser) { - // sentry.interfaces.User - data.user = globalUser; - } - - // Include the release iff it's defined in globalOptions - if (globalOptions.release) data.release = globalOptions.release; - - if (isFunction(globalOptions.dataCallback)) { - data = globalOptions.dataCallback(data) || data; - } - - // Why?????????? - if (!data || isEmptyObject(data)) { - return; - } - - // Check if the request should be filtered or not - if (isFunction(globalOptions.shouldSendCallback) && !globalOptions.shouldSendCallback(data)) { - return; - } - - // Send along an event_id if not explicitly passed. - // This event_id can be used to reference the error within Sentry itself. - // Set lastEventId after we know the error should actually be sent - lastEventId = data.event_id || (data.event_id = uuid4()); - - makeRequest(data); -} - - -function makeRequest(data) { - var img = newImage(), - src = globalServer + authQueryString + '&sentry_data=' + encodeURIComponent(JSON.stringify(data)); - - img.crossOrigin = 'anonymous'; - img.onload = function success() { - triggerEvent('success', { - data: data, - src: src - }); - }; - img.onerror = img.onabort = function failure() { - triggerEvent('failure', { - data: data, - src: src - }); - }; - img.src = src; -} - -// Note: this is shitty, but I can't figure out how to get -// sinon to stub document.createElement without breaking everything -// so this wrapper is just so I can stub it for tests. -function newImage() { - return document.createElement('img'); -} - -function isSetup() { - if (!hasJSON) return false; // needs JSON support - if (!globalServer) { - logDebug('error', 'Error: Raven has not been configured.'); - return false; - } - return true; -} - -function joinRegExp(patterns) { - // Combine an array of regular expressions and strings into one large regexp - // Be mad. - var sources = [], - i = 0, len = patterns.length, - pattern; - - for (; i < len; i++) { - pattern = patterns[i]; - if (isString(pattern)) { - // If it's a string, we need to escape it - // Taken from: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions - sources.push(pattern.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1")); - } else if (pattern && pattern.source) { - // If it's a regexp already, we want to extract the source - sources.push(pattern.source); - } - // Intentionally skip other cases - } - return new RegExp(sources.join('|'), 'i'); -} - -// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523 -function uuid4() { - return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) { - var r = Math.random()*16|0, - v = c == 'x' ? r : (r&0x3|0x8); - return v.toString(16); - }); -} - -function logDebug(level, message) { - if (window.console && console[level] && Raven.debug) { - console[level](message); - } -} - -function afterLoad() { - // Attempt to initialize Raven on load - var RavenConfig = window.RavenConfig; - if (RavenConfig) { - Raven.config(RavenConfig.dsn, RavenConfig.config).install(); - } -} -afterLoad(); diff --git a/htdocs/includes/raven-js/template/_copyright.js b/htdocs/includes/raven-js/template/_copyright.js deleted file mode 100644 index f1ee87084f8..00000000000 --- a/htdocs/includes/raven-js/template/_copyright.js +++ /dev/null @@ -1,11 +0,0 @@ -/*! Raven.js <%= pkg.release %> (<%= gitinfo.local.branch.current.shortSHA %>) | github.com/getsentry/raven-js */ - -/* - * Includes TraceKit - * https://github.com/getsentry/TraceKit - * - * Copyright <%= grunt.template.today('yyyy') %> Matt Robenolt and other contributors - * Released under the BSD license - * https://github.com/getsentry/raven-js/blob/master/LICENSE - * - */ diff --git a/htdocs/includes/raven-js/template/_footer.js b/htdocs/includes/raven-js/template/_footer.js deleted file mode 100644 index 9d102d2458d..00000000000 --- a/htdocs/includes/raven-js/template/_footer.js +++ /dev/null @@ -1,19 +0,0 @@ -// Expose Raven to the world -if (typeof define === 'function' && define.amd) { - // AMD - window.Raven = Raven; - define('raven', [], function() { - return Raven; - }); -} else if (typeof module === 'object') { - // browserify - module.exports = Raven; -} else if (typeof exports === 'object') { - // CommonJS - exports = Raven; -} else { - // Everything else - window.Raven = Raven; -} - -})(typeof window !== 'undefined' ? window : this); diff --git a/htdocs/includes/raven-js/template/_header.js b/htdocs/includes/raven-js/template/_header.js deleted file mode 100644 index 27595a61a2d..00000000000 --- a/htdocs/includes/raven-js/template/_header.js +++ /dev/null @@ -1,2 +0,0 @@ -;(function(window, undefined){ -'use strict'; diff --git a/htdocs/includes/raven-js/test/index.html b/htdocs/includes/raven-js/test/index.html deleted file mode 100644 index b5188ed0600..00000000000 --- a/htdocs/includes/raven-js/test/index.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - Raven.js Test Suite - - - - -
- - - - - - - - - - - - - - - - - - - diff --git a/htdocs/includes/raven-js/test/raven.test.js b/htdocs/includes/raven-js/test/raven.test.js deleted file mode 100644 index e26a36ef174..00000000000 --- a/htdocs/includes/raven-js/test/raven.test.js +++ /dev/null @@ -1,1773 +0,0 @@ -function flushRavenState() { - authQueryString = undefined; - hasJSON = !isUndefined(window.JSON); - lastCapturedException = undefined; - lastEventId = undefined; - globalServer = undefined; - globalUser = undefined; - globalProject = undefined; - globalOptions = { - logger: 'javascript', - release: undefined, - ignoreErrors: [], - ignoreUrls: [], - whitelistUrls: [], - includePaths: [], - collectWindowErrors: true, - maxMessageLength: 100, - tags: {}, - extra: {} - }, - startTime = 0 - ; - - Raven.uninstall(); -} - -// window.console must be stubbed in for browsers that don't have it -if (typeof window.console === 'undefined') { - console = {error: function(){}}; -} - -var SENTRY_DSN = 'http://abc@example.com:80/2'; - -function setupRaven() { - Raven.config(SENTRY_DSN); -} - -// patched to return a predictable result -function uuid4() { - return 'abc123'; -} - -// patched to be predictable -function now() { - return 100; -} - -describe('TraceKit', function(){ - describe('stacktrace info', function() { - it('should not remove anonymous functions from the stack', function() { - // mock up an error object with a stack trace that includes both - // named functions and anonymous functions - var stack_str = "" + - " Error: \n" + - " at new (http://example.com/js/test.js:63)\n" + // stack[0] - " at namedFunc0 (http://example.com/js/script.js:10)\n" + // stack[1] - " at http://example.com/js/test.js:65\n" + // stack[2] - " at namedFunc2 (http://example.com/js/script.js:20)\n" + // stack[3] - " at http://example.com/js/test.js:67\n" + // stack[4] - " at namedFunc4 (http://example.com/js/script.js:100001)"; // stack[5] - var mock_err = { stack: stack_str }; - var trace = TraceKit.computeStackTrace.computeStackTraceFromStackProp(mock_err); - - // Make sure TraceKit didn't remove the anonymous functions - // from the stack like it used to :) - assert.equal(trace.stack[0].func, 'new '); - assert.equal(trace.stack[1].func, 'namedFunc0'); - assert.equal(trace.stack[2].func, '?'); - assert.equal(trace.stack[3].func, 'namedFunc2'); - assert.equal(trace.stack[4].func, '?'); - assert.equal(trace.stack[5].func, 'namedFunc4'); - }); - }); - describe('error notifications', function(){ - var testMessage = "__mocha_ignore__"; - var subscriptionHandler; - // TraceKit waits 2000ms for window.onerror to fire, so give the tests - // some extra time. - this.timeout(3000); - - before(function() { - // Prevent the onerror call that's part of our tests from getting to - // mocha's handler, which would treat it as a test failure. - // - // We set this up here and don't ever restore the old handler, because - // we can't do that without clobbering TraceKit's handler, which can only - // be installed once. - var oldOnError = window.onerror; - window.onerror = function(message) { - if (message == testMessage) { - return true; - } - return oldOnError.apply(this, arguments); - }; - }); - - afterEach(function() { - if (subscriptionHandler) { - TraceKit.report.unsubscribe(subscriptionHandler); - subscriptionHandler = null; - } - }); - - function testErrorNotification(collectWindowErrors, callOnError, numReports, done) { - var extraVal = "foo"; - var numDone = 0; - // TraceKit's collectWindowErrors flag shouldn't affect direct calls - // to TraceKit.report, so we parameterize it for the tests. - TraceKit.collectWindowErrors = collectWindowErrors; - - subscriptionHandler = function(stackInfo, extra) { - assert.equal(extra, extraVal); - numDone++; - if (numDone == numReports) { - done(); - } - }; - TraceKit.report.subscribe(subscriptionHandler); - - // TraceKit.report always throws an exception in order to trigger - // window.onerror so it can gather more stack data. Mocha treats - // uncaught exceptions as errors, so we catch it via assert.throws - // here (and manually call window.onerror later if appropriate). - // - // We test multiple reports because TraceKit has special logic for when - // report() is called a second time before either a timeout elapses or - // window.onerror is called (which is why we always call window.onerror - // only once below, after all calls to report()). - for (var i=0; i < numReports; i++) { - var e = new Error('testing'); - assert.throws(function() { - TraceKit.report(e, extraVal); - }, e); - } - // The call to report should work whether or not window.onerror is - // triggered, so we parameterize it for the tests. We only call it - // once, regardless of numReports, because the case we want to test for - // multiple reports is when window.onerror is *not* called between them. - if (callOnError) { - window.onerror(testMessage); - } - } - - Mocha.utils.forEach([false, true], function(collectWindowErrors) { - Mocha.utils.forEach([false, true], function(callOnError) { - Mocha.utils.forEach([1, 2], function(numReports) { - it('it should receive arguments from report() when' + - ' collectWindowErrors is ' + collectWindowErrors + - ' and callOnError is ' + callOnError + - ' and numReports is ' + numReports, function(done) { - testErrorNotification(collectWindowErrors, callOnError, numReports, done); - }); - }); - }); - }); - }); -}); - -describe('globals', function() { - beforeEach(function() { - setupRaven(); - globalOptions.fetchContext = true; - }); - - afterEach(function() { - flushRavenState(); - }); - - describe('getHttpData', function() { - var data = getHttpData(); - - it('should have a url', function() { - assert.equal(data.url, window.location.href); - }); - - it('should have the user-agent header', function() { - assert.equal(data.headers['User-Agent'], navigator.userAgent); - }); - - it('should have referer header when available', function() { - // lol this test is awful - if (window.document.referrer) { - assert.equal(data.headers.Referer, window.document.referrer); - } else { - assert.isUndefined(data.headers.Referer); - } - }); - - }); - - describe('isUndefined', function() { - it('should do as advertised', function() { - assert.isTrue(isUndefined()); - assert.isFalse(isUndefined({})); - assert.isFalse(isUndefined('')); - assert.isTrue(isUndefined(undefined)); - }); - }); - - describe('isFunction', function() { - it('should do as advertised', function() { - assert.isTrue(isFunction(function(){})); - assert.isFalse(isFunction({})); - assert.isFalse(isFunction('')); - assert.isFalse(isFunction(undefined)); - }); - }); - - describe('isString', function() { - it('should do as advertised', function() { - assert.isTrue(isString('')); - assert.isTrue(isString(String(''))); - assert.isTrue(isString(new String(''))); - assert.isFalse(isString({})); - assert.isFalse(isString(undefined)); - assert.isFalse(isString(function(){})); - }); - }); - - describe('isObject', function() { - it('should do as advertised', function() { - assert.isTrue(isObject({})); - assert.isTrue(isObject(new Error())) - assert.isFalse(isObject('')); - }); - }); - - describe('isEmptyObject', function() { - it('should work as advertised', function() { - assert.isTrue(isEmptyObject({})); - assert.isFalse(isEmptyObject({foo: 1})); - }); - }); - - describe('isError', function() { - it('should work as advertised', function() { - assert.isTrue(isError(new Error())); - assert.isTrue(isError(new ReferenceError())); - assert.isTrue(isError(new RavenConfigError())); - assert.isFalse(isError({})); - assert.isFalse(isError('')); - assert.isFalse(isError(true)); - }); - }); - - describe('objectMerge', function() { - it('should work as advertised', function() { - assert.deepEqual(objectMerge({}, {}), {}); - assert.deepEqual(objectMerge({a:1}, {b:2}), {a:1, b:2}); - assert.deepEqual(objectMerge({a:1}), {a:1}); - }); - }); - - describe('truncate', function() { - it('should work as advertised', function() { - assert.equal(truncate('lolol', 3), 'lol\u2026'); - assert.equal(truncate('lolol', 10), 'lolol'); - assert.equal(truncate('lol', 3), 'lol'); - }); - }); - - describe('isSetup', function() { - it('should return false with no JSON support', function() { - globalServer = 'http://localhost/'; - hasJSON = false; - assert.isFalse(isSetup()); - }); - - it('should return false when Raven is not configured', function() { - hasJSON = true; // be explicit - globalServer = undefined; - this.sinon.stub(window, 'logDebug'); - assert.isFalse(isSetup()); - }); - - it('should return true when everything is all gravy', function() { - hasJSON = true; - assert.isTrue(isSetup()); - }); - }); - - describe('logDebug', function() { - var level = 'error', - message = 'foobar'; - - it('should not write to console when Raven.debug is false', function() { - Raven.debug = false; - this.sinon.stub(console, level); - logDebug(level, message); - assert.isFalse(console[level].called); - }); - - it('should write to console when Raven.debug is true', function() { - Raven.debug = true; - this.sinon.stub(console, level); - logDebug(level, message); - assert.isTrue(console[level].calledOnce); - }); - }); - - describe('setAuthQueryString', function() { - it('should return a properly formatted string and cache it', function() { - var expected = '?sentry_version=4&sentry_client=raven-js/<%= pkg.version %>&sentry_key=abc'; - setAuthQueryString(); - assert.strictEqual(authQueryString, expected); - }); - }); - - describe('parseDSN', function() { - it('should do what it advertises', function() { - var pieces = parseDSN('http://abc@example.com:80/2'); - assert.strictEqual(pieces.protocol, 'http'); - assert.strictEqual(pieces.user, 'abc'); - assert.strictEqual(pieces.port, '80'); - assert.strictEqual(pieces.path, '/2'); - assert.strictEqual(pieces.host, 'example.com'); - }); - - it('should parse protocol relative', function() { - var pieces = parseDSN('//user@mattrobenolt.com/'); - assert.strictEqual(pieces.protocol, ''); - assert.strictEqual(pieces.user, 'user'); - assert.strictEqual(pieces.port, ''); - assert.strictEqual(pieces.path, '/'); - assert.strictEqual(pieces.host, 'mattrobenolt.com'); - }); - - it('should parse domain with hyphen', function() { - var pieces = parseDSN('http://user@matt-robenolt.com/1'); - assert.strictEqual(pieces.protocol, 'http'); - assert.strictEqual(pieces.user, 'user'); - assert.strictEqual(pieces.port, ''); - assert.strictEqual(pieces.path, '/1'); - assert.strictEqual(pieces.host, 'matt-robenolt.com'); - }); - - it('should raise a RavenConfigError when setting a password', function() { - try { - parseDSN('http://user:pass@example.com/2'); - } catch(e) { - return assert.equal(e.name, 'RavenConfigError'); - } - // shouldn't hit this - assert.isTrue(false); - }); - - it('should raise a RavenConfigError with an invalid DSN', function() { - try { - parseDSN('lol'); - } catch(e) { - return assert.equal(e.name, 'RavenConfigError'); - } - // shouldn't hit this - assert.isTrue(false); - }); - }); - - describe('normalizeFrame', function() { - it('should handle a normal frame', function() { - var context = [ - ['line1'], // pre - 'line2', // culprit - ['line3'] // post - ]; - this.sinon.stub(window, 'extractContextFromFrame').returns(context); - var frame = { - url: 'http://example.com/path/file.js', - line: 10, - column: 11, - func: 'lol' - // context: [] context is stubbed - }; - - globalOptions.fetchContext = true; - - assert.deepEqual(normalizeFrame(frame), { - filename: 'http://example.com/path/file.js', - lineno: 10, - colno: 11, - 'function': 'lol', - pre_context: ['line1'], - context_line: 'line2', - post_context: ['line3'], - in_app: true - }); - }); - - it('should handle a frame without context', function() { - this.sinon.stub(window, 'extractContextFromFrame').returns(undefined); - var frame = { - url: 'http://example.com/path/file.js', - line: 10, - column: 11, - func: 'lol' - // context: [] context is stubbed - }; - - globalOptions.fetchContext = true; - - assert.deepEqual(normalizeFrame(frame), { - filename: 'http://example.com/path/file.js', - lineno: 10, - colno: 11, - 'function': 'lol', - in_app: true - }); - }); - - it('should not mark `in_app` if rules match', function() { - this.sinon.stub(window, 'extractContextFromFrame').returns(undefined); - var frame = { - url: 'http://example.com/path/file.js', - line: 10, - column: 11, - func: 'lol' - // context: [] context is stubbed - }; - - globalOptions.fetchContext = true; - globalOptions.includePaths = /^http:\/\/example\.com/; - - assert.deepEqual(normalizeFrame(frame), { - filename: 'http://example.com/path/file.js', - lineno: 10, - colno: 11, - 'function': 'lol', - in_app: true - }); - }); - - it('should mark `in_app` if rules do not match', function() { - this.sinon.stub(window, 'extractContextFromFrame').returns(undefined); - var frame = { - url: 'http://lol.com/path/file.js', - line: 10, - column: 11, - func: 'lol' - // context: [] context is stubbed - }; - - globalOptions.fetchContext = true; - globalOptions.includePaths = /^http:\/\/example\.com/; - - assert.deepEqual(normalizeFrame(frame), { - filename: 'http://lol.com/path/file.js', - lineno: 10, - colno: 11, - 'function': 'lol', - in_app: false - }); - }); - - it('should mark `in_app` for raven.js', function() { - this.sinon.stub(window, 'extractContextFromFrame').returns(undefined); - var frame = { - url: 'http://lol.com/path/raven.js', - line: 10, - column: 11, - func: 'lol' - // context: [] context is stubbed - }; - - assert.deepEqual(normalizeFrame(frame), { - filename: 'http://lol.com/path/raven.js', - lineno: 10, - colno: 11, - 'function': 'lol', - in_app: false - }); - }); - - it('should mark `in_app` for raven.min.js', function() { - this.sinon.stub(window, 'extractContextFromFrame').returns(undefined); - var frame = { - url: 'http://lol.com/path/raven.min.js', - line: 10, - column: 11, - func: 'lol' - // context: [] context is stubbed - }; - - assert.deepEqual(normalizeFrame(frame), { - filename: 'http://lol.com/path/raven.min.js', - lineno: 10, - colno: 11, - 'function': 'lol', - in_app: false - }); - }); - - it('should mark `in_app` for Raven', function() { - this.sinon.stub(window, 'extractContextFromFrame').returns(undefined); - var frame = { - url: 'http://lol.com/path/file.js', - line: 10, - column: 11, - func: 'Raven.wrap' - // context: [] context is stubbed - }; - - assert.deepEqual(normalizeFrame(frame), { - filename: 'http://lol.com/path/file.js', - lineno: 10, - colno: 11, - 'function': 'Raven.wrap', - in_app: false - }); - }); - - it('should mark `in_app` for TraceKit', function() { - this.sinon.stub(window, 'extractContextFromFrame').returns(undefined); - var frame = { - url: 'http://lol.com/path/file.js', - line: 10, - column: 11, - func: 'TraceKit.lol' - // context: [] context is stubbed - }; - - assert.deepEqual(normalizeFrame(frame), { - filename: 'http://lol.com/path/file.js', - lineno: 10, - colno: 11, - 'function': 'TraceKit.lol', - in_app: false - }); - }); - }); - - describe('extractContextFromFrame', function() { - it('should handle a normal frame', function() { - var frame = { - column: 2, - context: [ - 'line1', - 'line2', - 'line3', - 'line4', - 'line5', - 'culprit', - 'line7', - 'line8', - 'line9', - 'line10', - 'line11' - ] - }; - var context = extractContextFromFrame(frame); - assert.deepEqual(context, [ - ['line1', 'line2', 'line3', 'line4', 'line5'], - 'culprit', - ['line7', 'line8', 'line9', 'line10', 'line11'] - ]); - }); - - it('should return nothing if there is no context', function() { - var frame = { - column: 2 - }; - assert.isUndefined(extractContextFromFrame(frame)); - }); - - it('should reject a context if a line is too long without a column', function() { - var frame = { - context: [ - new Array(1000).join('f') // generate a line that is 1000 chars long - ] - }; - assert.isUndefined(extractContextFromFrame(frame)); - }); - - it('should reject a minified context with fetchContext disabled', function() { - var frame = { - column: 2, - context: [ - 'line1', - 'line2', - 'line3', - 'line4', - 'line5', - 'culprit', - 'line7', - 'line8', - 'line9', - 'line10', - 'line11' - ] - }; - globalOptions.fetchContext = false; - assert.isUndefined(extractContextFromFrame(frame)); - }); - - it('should truncate the minified line if there is a column number without sourcemaps enabled', function() { - // Note to future self: - // Array(51).join('f').length === 50 - var frame = { - column: 2, - context: [ - 'aa' + (new Array(51).join('f')) + (new Array(500).join('z')) - ] - }; - assert.deepEqual(extractContextFromFrame(frame), [[], new Array(51).join('f'), []]); - }); - }); - - describe('processException', function() { - it('should respect `ignoreErrors`', function() { - this.sinon.stub(window, 'send'); - - globalOptions.ignoreErrors = joinRegExp(['e1', 'e2']); - processException('Error', 'e1', 'http://example.com', []); - assert.isFalse(window.send.called); - processException('Error', 'e2', 'http://example.com', []); - assert.isFalse(window.send.called); - processException('Error', 'error', 'http://example.com', []); - assert.isTrue(window.send.calledOnce); - }); - - it('should respect `ignoreUrls`', function() { - this.sinon.stub(window, 'send'); - - globalOptions.ignoreUrls = joinRegExp([/.+?host1.+/, /.+?host2.+/]); - processException('Error', 'error', 'http://host1/', []); - assert.isFalse(window.send.called); - processException('Error', 'error', 'http://host2/', []); - assert.isFalse(window.send.called); - processException('Error', 'error', 'http://host3/', []); - assert.isTrue(window.send.calledOnce); - }); - - it('should respect `whitelistUrls`', function() { - this.sinon.stub(window, 'send'); - - globalOptions.whitelistUrls = joinRegExp([/.+?host1.+/, /.+?host2.+/]); - processException('Error', 'error', 'http://host1/', []); - assert.equal(window.send.callCount, 1); - processException('Error', 'error', 'http://host2/', []); - assert.equal(window.send.callCount, 2); - processException('Error', 'error', 'http://host3/', []); - assert.equal(window.send.callCount, 2); - }); - - it('should send a proper payload with frames', function() { - this.sinon.stub(window, 'send'); - - var frames = [ - { - filename: 'http://example.com/file1.js' - }, - { - filename: 'http://example.com/file2.js' - } - ], framesFlipped = frames.slice(0); - - framesFlipped.reverse(); - - processException('Error', 'lol', 'http://example.com/override.js', 10, frames.slice(0), {}); - assert.deepEqual(window.send.lastCall.args, [{ - exception: { - type: 'Error', - value: 'lol' - }, - stacktrace: { - frames: framesFlipped - }, - culprit: 'http://example.com/file1.js', - message: 'lol at 10' - }]); - - processException('Error', 'lol', '', 10, frames.slice(0), {}); - assert.deepEqual(window.send.lastCall.args, [{ - exception: { - type: 'Error', - value: 'lol' - }, - stacktrace: { - frames: framesFlipped - }, - culprit: 'http://example.com/file1.js', - message: 'lol at 10' - }]); - - processException('Error', 'lol', '', 10, frames.slice(0), {extra: 'awesome'}); - assert.deepEqual(window.send.lastCall.args, [{ - exception: { - type: 'Error', - value: 'lol' - }, - stacktrace: { - frames: framesFlipped - }, - culprit: 'http://example.com/file1.js', - message: 'lol at 10', - extra: 'awesome' - }]); - }); - - it('should send a proper payload without frames', function() { - this.sinon.stub(window, 'send'); - - processException('Error', 'lol', 'http://example.com/override.js', 10, [], {}); - assert.deepEqual(window.send.lastCall.args, [{ - exception: { - type: 'Error', - value: 'lol' - }, - stacktrace: { - frames: [{ - filename: 'http://example.com/override.js', - lineno: 10, - in_app: true - }] - }, - culprit: 'http://example.com/override.js', - message: 'lol at 10' - }]); - - processException('Error', 'lol', 'http://example.com/override.js', 10, [], {}); - assert.deepEqual(window.send.lastCall.args, [{ - exception: { - type: 'Error', - value: 'lol' - }, - stacktrace: { - frames: [{ - filename: 'http://example.com/override.js', - lineno: 10, - in_app: true - }] - }, - culprit: 'http://example.com/override.js', - message: 'lol at 10' - }]); - - processException('Error', 'lol', 'http://example.com/override.js', 10, [], {extra: 'awesome'}); - assert.deepEqual(window.send.lastCall.args, [{ - exception: { - type: 'Error', - value: 'lol' - }, - stacktrace: { - frames: [{ - filename: 'http://example.com/override.js', - lineno: 10, - in_app: true - }] - }, - culprit: 'http://example.com/override.js', - message: 'lol at 10', - extra: 'awesome' - }]); - }); - - it('should ignored falsey messages', function() { - this.sinon.stub(window, 'send'); - - processException('Error', '', 'http://example.com', []); - assert.isFalse(window.send.called); - - processException('TypeError', '', 'http://example.com', []); - assert.isTrue(window.send.called); - }); - - it('should not blow up with `undefined` message', function() { - this.sinon.stub(window, 'send'); - - processException('TypeError', undefined, 'http://example.com', []); - assert.isTrue(window.send.called); - }); - - it('should truncate messages to the specified length', function() { - this.sinon.stub(window, 'send'); - - processException('TypeError', new Array(500).join('a'), 'http://example.com', []); - assert.deepEqual(window.send.lastCall.args, [{ - message: new Array(101).join('a')+'\u2026 at ', - exception: { - type: 'TypeError', - value: new Array(101).join('a')+'\u2026' - }, - stacktrace: { - frames: [{ - filename: 'http://example.com', - lineno: [], - in_app: true - }] - }, - culprit: 'http://example.com', - }]); - - globalOptions.maxMessageLength = 150; - - processException('TypeError', new Array(500).join('a'), 'http://example.com', []); - assert.deepEqual(window.send.lastCall.args, [{ - message: new Array(151).join('a')+'\u2026 at ', - exception: { - type: 'TypeError', - value: new Array(151).join('a')+'\u2026' - }, - stacktrace: { - frames: [{ - filename: 'http://example.com', - lineno: [], - in_app: true - }] - }, - culprit: 'http://example.com', - }]); - }); - }); - - describe('send', function() { - it('should check `isSetup`', function() { - this.sinon.stub(window, 'isSetup').returns(false); - this.sinon.stub(window, 'makeRequest'); - - send(); - assert.isTrue(window.isSetup.calledOnce); - assert.isFalse(window.makeRequest.calledOnce); - }); - - it('should build a good data payload', function() { - this.sinon.stub(window, 'isSetup').returns(true); - this.sinon.stub(window, 'makeRequest'); - this.sinon.stub(window, 'getHttpData').returns({ - url: 'http://localhost/?a=b', - headers: {'User-Agent': 'lolbrowser'} - }); - - globalProject = '2'; - globalOptions = { - logger: 'javascript' - }; - - send({foo: 'bar'}); - assert.deepEqual(window.makeRequest.lastCall.args[0], { - project: '2', - logger: 'javascript', - platform: 'javascript', - request: { - url: 'http://localhost/?a=b', - headers: { - 'User-Agent': 'lolbrowser' - } - }, - event_id: 'abc123', - foo: 'bar', - extra: {'session:duration': 100} - }); - }); - - it('should build a good data payload with a User', function() { - this.sinon.stub(window, 'isSetup').returns(true); - this.sinon.stub(window, 'makeRequest'); - this.sinon.stub(window, 'getHttpData').returns({ - url: 'http://localhost/?a=b', - headers: {'User-Agent': 'lolbrowser'} - }); - - globalProject = '2'; - globalOptions = { - logger: 'javascript' - }; - - globalUser = {name: 'Matt'}; - - send({foo: 'bar'}); - assert.deepEqual(window.makeRequest.lastCall.args, [{ - project: '2', - logger: 'javascript', - platform: 'javascript', - request: { - url: 'http://localhost/?a=b', - headers: { - 'User-Agent': 'lolbrowser' - } - }, - event_id: 'abc123', - user: { - name: 'Matt' - }, - foo: 'bar', - extra: {'session:duration': 100} - }]); - }); - - it('should merge in global tags', function() { - this.sinon.stub(window, 'isSetup').returns(true); - this.sinon.stub(window, 'makeRequest'); - this.sinon.stub(window, 'getHttpData').returns({ - url: 'http://localhost/?a=b', - headers: {'User-Agent': 'lolbrowser'} - }); - - globalProject = '2'; - globalOptions = { - logger: 'javascript', - tags: {tag1: 'value1'} - }; - - - send({tags: {tag2: 'value2'}}); - assert.deepEqual(window.makeRequest.lastCall.args, [{ - project: '2', - logger: 'javascript', - platform: 'javascript', - request: { - url: 'http://localhost/?a=b', - headers: { - 'User-Agent': 'lolbrowser' - } - }, - event_id: 'abc123', - tags: {tag1: 'value1', tag2: 'value2'}, - extra: {'session:duration': 100} - }]); - assert.deepEqual(globalOptions, { - logger: 'javascript', - tags: {tag1: 'value1'} - }); - }); - - it('should merge in global extra', function() { - this.sinon.stub(window, 'isSetup').returns(true); - this.sinon.stub(window, 'makeRequest'); - this.sinon.stub(window, 'getHttpData').returns({ - url: 'http://localhost/?a=b', - headers: {'User-Agent': 'lolbrowser'} - }); - - globalProject = '2'; - globalOptions = { - logger: 'javascript', - extra: {key1: 'value1'} - }; - - - send({extra: {key2: 'value2'}}); - assert.deepEqual(window.makeRequest.lastCall.args, [{ - project: '2', - logger: 'javascript', - platform: 'javascript', - request: { - url: 'http://localhost/?a=b', - headers: { - 'User-Agent': 'lolbrowser' - } - }, - event_id: 'abc123', - extra: {key1: 'value1', key2: 'value2', 'session:duration': 100} - }]); - assert.deepEqual(globalOptions, { - logger: 'javascript', - extra: {key1: 'value1'} - }); - }); - - it('should let dataCallback override everything', function() { - this.sinon.stub(window, 'isSetup').returns(true); - this.sinon.stub(window, 'makeRequest'); - - globalOptions = { - projectId: 2, - logger: 'javascript', - dataCallback: function() { - return {lol: 'ibrokeit'}; - } - }; - - globalUser = {name: 'Matt'}; - - send({foo: 'bar'}); - assert.deepEqual(window.makeRequest.lastCall.args, [{ - lol: 'ibrokeit', - event_id: 'abc123', - }]); - }); - - it('should ignore dataCallback if it does not return anything', function() { - this.sinon.stub(window, 'isSetup').returns(true); - this.sinon.stub(window, 'makeRequest'); - this.sinon.stub(window, 'getHttpData').returns({ - url: 'http://localhost/?a=b', - headers: {'User-Agent': 'lolbrowser'} - }); - - globalProject = '2'; - globalOptions = { - logger: 'javascript', - dataCallback: function() { - return; - } - }; - - send({foo: 'bar'}); - assert.deepEqual(window.makeRequest.lastCall.args[0], { - project: '2', - logger: 'javascript', - platform: 'javascript', - request: { - url: 'http://localhost/?a=b', - headers: { - 'User-Agent': 'lolbrowser' - } - }, - event_id: 'abc123', - foo: 'bar', - extra: {'session:duration': 100} - }); - }); - - it('should strip empty tags', function() { - this.sinon.stub(window, 'isSetup').returns(true); - this.sinon.stub(window, 'makeRequest'); - this.sinon.stub(window, 'getHttpData').returns({ - url: 'http://localhost/?a=b', - headers: {'User-Agent': 'lolbrowser'} - }); - - globalOptions = { - projectId: 2, - logger: 'javascript', - tags: {} - }; - - send({foo: 'bar', tags: {}, extra: {}}); - assert.deepEqual(window.makeRequest.lastCall.args[0], { - project: '2', - logger: 'javascript', - platform: 'javascript', - request: { - url: 'http://localhost/?a=b', - headers: { - 'User-Agent': 'lolbrowser' - } - }, - event_id: 'abc123', - foo: 'bar', - extra: {'session:duration': 100} - }); - }); - - it('should attach release if available', function() { - this.sinon.stub(window, 'isSetup').returns(true); - this.sinon.stub(window, 'makeRequest'); - this.sinon.stub(window, 'getHttpData').returns({ - url: 'http://localhost/?a=b', - headers: {'User-Agent': 'lolbrowser'} - }); - - globalOptions = { - projectId: 2, - logger: 'javascript', - release: 'abc123', - }; - - send({foo: 'bar'}); - assert.deepEqual(window.makeRequest.lastCall.args[0], { - project: '2', - release: 'abc123', - logger: 'javascript', - platform: 'javascript', - request: { - url: 'http://localhost/?a=b', - headers: { - 'User-Agent': 'lolbrowser' - } - }, - event_id: 'abc123', - foo: 'bar', - extra: {'session:duration': 100} - }); - }); - }); - - describe('makeRequest', function() { - it('should load an Image', function() { - authQueryString = '?lol'; - globalServer = 'http://localhost/'; - var imageCache = []; - this.sinon.stub(window, 'newImage', function(){ var img = {}; imageCache.push(img); return img; }); - - makeRequest({foo: 'bar'}); - assert.equal(imageCache.length, 1); - assert.equal(imageCache[0].src, 'http://localhost/?lol&sentry_data=%7B%22foo%22%3A%22bar%22%7D'); - }); - }); - - describe('handleStackInfo', function() { - it('should work as advertised', function() { - var frame = {url: 'http://example.com'}; - this.sinon.stub(window, 'normalizeFrame').returns(frame); - this.sinon.stub(window, 'processException'); - - var stackInfo = { - name: 'Matt', - message: 'hey', - url: 'http://example.com', - lineno: 10, - stack: [ - frame, frame - ] - }; - - handleStackInfo(stackInfo, {foo: 'bar'}); - assert.deepEqual(window.processException.lastCall.args, [ - 'Matt', 'hey', 'http://example.com', 10, [frame, frame], {foo: 'bar'} - ]); - }); - - it('should work as advertised #integration', function() { - this.sinon.stub(window, 'makeRequest'); - var stackInfo = { - name: 'Error', - message: 'crap', - url: 'http://example.com', - lineno: 10, - stack: [ - { - url: 'http://example.com/file1.js', - line: 10, - column: 11, - func: 'broken', - context: [ - 'line1', - 'line2', - 'line3' - ] - }, - { - url: 'http://example.com/file2.js', - line: 12, - column: 13, - func: 'lol', - context: [ - 'line4', - 'line5', - 'line6' - ] - } - ] - }; - - handleStackInfo(stackInfo, {foo: 'bar'}); - assert.isTrue(window.makeRequest.calledOnce); - /* This is commented out because chai is broken. - - assert.deepEqual(window.makeRequest.lastCall.args, [{ - project: '2', - logger: 'javascript', - platform: 'javascript', - request: { - url: window.location.protocol + '//' + window.location.host + window.location.pathname, - querystring: window.location.search.slice(1) - }, - exception: { - type: 'Error', - value: 'crap' - }, - stacktrace: { - frames: [{ - filename: 'http://example.com/file1.js', - filename: 'file1.js', - lineno: 10, - colno: 11, - 'function': 'broken', - post_context: ['line3'], - context_line: 'line2', - pre_context: ['line1'] - }, { - filename: 'http://example.com/file2.js', - filename: 'file2.js', - lineno: 12, - colno: 13, - 'function': 'lol', - post_context: ['line6'], - context_line: 'line5', - pre_context: ['line4'] - }] - }, - culprit: 'http://example.com', - message: 'crap at 10', - foo: 'bar' - }]); - */ - }); - - it('should ignore frames that dont have a url', function() { - this.sinon.stub(window, 'normalizeFrame').returns(undefined); - this.sinon.stub(window, 'processException'); - - var stackInfo = { - name: 'Matt', - message: 'hey', - url: 'http://example.com', - lineno: 10, - stack: new Array(2) - }; - - handleStackInfo(stackInfo, {foo: 'bar'}); - assert.deepEqual(window.processException.lastCall.args, [ - 'Matt', 'hey', 'http://example.com', 10, [], {foo: 'bar'} - ]); - }); - - it('should not shit when there is no stack object from TK', function() { - this.sinon.stub(window, 'normalizeFrame').returns(undefined); - this.sinon.stub(window, 'processException'); - - var stackInfo = { - name: 'Matt', - message: 'hey', - url: 'http://example.com', - lineno: 10 - // stack: new Array(2) - }; - - handleStackInfo(stackInfo); - assert.isFalse(window.normalizeFrame.called); - assert.deepEqual(window.processException.lastCall.args, [ - 'Matt', 'hey', 'http://example.com', 10, [], undefined - ]); - }); - - it('should detect 2-words patterns (angularjs frequent case)', function() { - this.sinon.stub(window, 'normalizeFrame').returns(undefined); - this.sinon.stub(window, 'processException'); - - var stackInfo = { - name: 'new ', - message: 'hey', - url: 'http://example.com', - lineno: 10 - // stack: new Array(2) - }; - - handleStackInfo(stackInfo); - assert.isFalse(window.normalizeFrame.called); - assert.deepEqual(window.processException.lastCall.args, [ - 'new ', 'hey', 'http://example.com', 10, [], undefined - ]); - }); - }); - - describe('joinRegExp', function() { - it('should work as advertised', function() { - assert.equal(joinRegExp([ - 'a', 'b', 'a.b', /d/, /[0-9]/ - ]).source, 'a|b|a\\.b|d|[0-9]'); - }); - - it('should not process empty or undefined variables', function() { - assert.equal(joinRegExp([ - 'a', 'b', null, undefined - ]).source, 'a|b'); - }); - - it('should skip entries that are not strings or regular expressions in the passed array of patterns', function() { - assert.equal(joinRegExp([ - 'a', 'b', null, 'a.b', undefined, true, /d/, 123, {}, /[0-9]/, [] - ]).source, 'a|b|a\\.b|d|[0-9]'); - }); - }); -}); - -describe('Raven (public API)', function() { - afterEach(function() { - flushRavenState(); - }); - - describe('.VERSION', function() { - it('should have a version', function() { - assert.isString(Raven.VERSION); - }); - }); - - describe('ignore errors', function() { - it('should install default ignore errors', function() { - Raven.config('//abc@example.com/2'); - - assert.isTrue(globalOptions.ignoreErrors.test('Script error'), 'it should install "Script error" by default'); - assert.isTrue(globalOptions.ignoreErrors.test('Script error.'), 'it should install "Script error." by default'); - assert.isTrue(globalOptions.ignoreErrors.test('Javascript error: Script error on line 0'), 'it should install "Javascript error: Script error on line 0" by default'); - assert.isTrue(globalOptions.ignoreErrors.test('Javascript error: Script error. on line 0'), 'it should install "Javascript error: Script error. on line 0" by default'); - }); - }); - - describe('callback function', function() { - it('should callback a function if it is global', function() { - window.RavenConfig = { - dsn: "http://random@some.other.server:80/2", - config: {some: 'config'} - }; - - this.sinon.stub(window, 'isSetup').returns(false); - this.sinon.stub(TraceKit.report, 'subscribe'); - - afterLoad(); - - assert.equal(globalKey, 'random'); - assert.equal(globalServer, 'http://some.other.server:80/api/2/store/'); - - assert.equal(globalOptions.some, 'config'); - assert.equal(globalProject, '2'); - - assert.isTrue(window.isSetup.calledOnce); - assert.isFalse(TraceKit.report.subscribe.calledOnce); - - delete window.RavenConfig; - }); - }); - - describe('.config', function() { - it('should work with a DSN', function() { - assert.equal(Raven, Raven.config(SENTRY_DSN, {foo: 'bar'}), 'it should return Raven'); - assert.equal(globalKey, 'abc'); - assert.equal(globalServer, 'http://example.com:80/api/2/store/'); - assert.equal(globalOptions.foo, 'bar'); - assert.equal(globalProject, '2'); - assert.isTrue(isSetup()); - }); - - it('should work with a protocol relative DSN', function() { - Raven.config('//abc@example.com/2'); - assert.equal(globalKey, 'abc'); - assert.equal(globalServer, '//example.com/api/2/store/'); - assert.equal(globalProject, '2'); - assert.isTrue(isSetup()); - }); - - it('should work should work at a non root path', function() { - Raven.config('//abc@example.com/sentry/2'); - assert.equal(globalKey, 'abc'); - assert.equal(globalServer, '//example.com/sentry/api/2/store/'); - assert.equal(globalProject, '2'); - assert.isTrue(isSetup()); - }); - - it('should noop a falsey dsn', function() { - Raven.config(''); - assert.isFalse(isSetup()); - }); - - it('should return Raven for a falsey dsn', function() { - assert.equal(Raven.config(''), Raven); - }); - - it('should not set global options more than once', function() { - this.sinon.spy(window, 'parseDSN'); - this.sinon.stub(window, 'logDebug'); - setupRaven(); - setupRaven(); - assert.isTrue(parseDSN.calledOnce); - assert.isTrue(logDebug.called); - }); - - describe('whitelistUrls', function() { - it('should be false if none are passed', function() { - Raven.config('//abc@example.com/2'); - assert.equal(globalOptions.whitelistUrls, false); - }); - - it('should join into a single RegExp', function() { - Raven.config('//abc@example.com/2', { - whitelistUrls: [ - /my.app/i, - /other.app/i - ] - }); - - assert.match(globalOptions.whitelistUrls, /my.app|other.app/i); - }); - - it('should handle strings as well', function() { - Raven.config('//abc@example.com/2', { - whitelistUrls: [ - /my.app/i, - "stringy.app" - ] - }); - - assert.match(globalOptions.whitelistUrls, /my.app|stringy.app/i); - }); - }); - - describe('collectWindowErrors', function() { - it('should be true by default', function() { - Raven.config(SENTRY_DSN); - assert.isTrue(TraceKit.collectWindowErrors); - }); - - it('should be true if set to true', function() { - Raven.config(SENTRY_DSN, { - collectWindowErrors: true - }); - - assert.isTrue(TraceKit.collectWindowErrors); - }); - - it('should be false if set to false', function() { - Raven.config(SENTRY_DSN, { - collectWindowErrors: false - }); - - assert.isFalse(TraceKit.collectWindowErrors); - }); - }); - }); - - describe('.install', function() { - it('should check `isSetup`', function() { - this.sinon.stub(window, 'isSetup').returns(false); - this.sinon.stub(TraceKit.report, 'subscribe'); - Raven.install(); - assert.isTrue(window.isSetup.calledOnce); - assert.isFalse(TraceKit.report.subscribe.calledOnce); - }); - - it('should register itself with TraceKit', function() { - this.sinon.stub(window, 'isSetup').returns(true); - this.sinon.stub(TraceKit.report, 'subscribe'); - assert.equal(Raven, Raven.install()); - assert.isTrue(TraceKit.report.subscribe.calledOnce); - assert.equal(TraceKit.report.subscribe.lastCall.args[0], handleStackInfo); - }); - - it('should not register itself more than once', function() { - this.sinon.stub(window, 'isSetup').returns(true); - this.sinon.stub(TraceKit.report, 'subscribe'); - Raven.install(); - Raven.install(); - assert.isTrue(TraceKit.report.subscribe.calledOnce); - }); - }); - - describe('.wrap', function() { - it('should return a wrapped callback', function() { - var spy = this.sinon.spy(); - var wrapped = Raven.wrap(spy); - assert.isFunction(wrapped); - assert.isTrue(wrapped.__raven__); - wrapped(); - assert.isTrue(spy.calledOnce); - }); - - it('should copy property when wrapping function', function() { - var func = function() {}; - func.test = true; - var wrapped = Raven.wrap(func); - assert.isTrue(wrapped.test); - }); - - it('should not copy prototype property when wrapping function', function() { - var func = function() {}; - func.prototype.test = true; - var wrapped = Raven.wrap(func); - assert.isUndefined(new wrapped().test); - }); - - it('should return the result of a wrapped function', function() { - var func = function() { return 'foo'; }; - var wrapped = Raven.wrap(func); - assert.equal(wrapped(), 'foo'); - }); - - it('should not wrap a non-function', function() { - assert.equal(Raven.wrap('lol'), 'lol'); - assert.equal(Raven.wrap({}, 'lol'), 'lol'); - assert.equal(Raven.wrap(undefined, 'lol'), 'lol'); - var a = [1, 2]; - assert.equal(Raven.wrap(a), a); - }); - - it('should wrap function arguments', function() { - var spy = this.sinon.spy(); - var wrapped = Raven.wrap(function(f) { - assert.isTrue(f.__raven__); - f(); - }); - wrapped(spy); - assert.isTrue(spy.calledOnce); - }); - - it('should not wrap function arguments', function() { - var spy = this.sinon.spy(); - var wrapped = Raven.wrap({ deep: false }, function(f) { - assert.isUndefined(f.__raven__); - f(); - }); - wrapped(spy); - assert.isTrue(spy.calledOnce); - }); - - it('should maintain the correct scope', function() { - var foo = {}; - var bar = function() { - assert.equal(this, foo); - }; - bar.apply(foo, []); - Raven.wrap(bar).apply(foo, []); - }); - - it('should re-raise a thrown exception', function() { - var error = new Error('lol'); - assert.throws(function() { - Raven.wrap(function() { throw error; })(); - }, error); - }); - - }); - - describe('.context', function() { - it('should execute the callback with options', function() { - var spy = this.sinon.spy(); - this.sinon.stub(Raven, 'captureException'); - Raven.context({'foo': 'bar'}, spy); - assert.isTrue(spy.calledOnce); - assert.isFalse(Raven.captureException.called); - }); - - it('should execute the callback with arguments', function() { - var spy = this.sinon.spy(); - var args = [1, 2]; - Raven.context(spy, args); - assert.deepEqual(spy.lastCall.args, args); - }); - - it('should execute the callback without options', function() { - var spy = this.sinon.spy(); - this.sinon.stub(Raven, 'captureException'); - Raven.context(spy); - assert.isTrue(spy.calledOnce); - assert.isFalse(Raven.captureException.called); - }); - - it('should capture the exception with options', function() { - var error = new Error('crap'); - var broken = function() { throw error; }; - this.sinon.stub(Raven, 'captureException'); - assert.throws(function() { - Raven.context({foo: 'bar'}, broken); - }, error); - assert.isTrue(Raven.captureException.called); - assert.deepEqual(Raven.captureException.lastCall.args, [error, {'foo': 'bar'}]); - }); - - it('should capture the exception without options', function() { - var error = new Error('crap'); - var broken = function() { throw error; }; - this.sinon.stub(Raven, 'captureException'); - assert.throws(function() { - Raven.context(broken); - }, error); - assert.isTrue(Raven.captureException.called); - assert.deepEqual(Raven.captureException.lastCall.args, [error, undefined]); - }); - - it('should execute the callback without arguments', function() { - // This is only reproducable in a browser that complains about passing - // undefined to Function.apply - var spy = this.sinon.spy(); - Raven.context(spy); - assert.deepEqual(spy.lastCall.args, []); - }); - - it('should return the result of the wrapped function', function() { - var val = {}; - var func = function() { return val; }; - assert.equal(Raven.context(func), val); - }); - }); - - describe('.uninstall', function() { - it('should uninstall from TraceKit', function() { - this.sinon.stub(TraceKit.report, 'uninstall'); - Raven.uninstall(); - assert.isTrue(TraceKit.report.uninstall.calledOnce); - }); - - it('should set isRavenInstalled flag to false', function() { - isRavenInstalled = true; - this.sinon.stub(TraceKit.report, 'uninstall'); - Raven.uninstall(); - assert.isFalse(isRavenInstalled); - }); - }); - - describe('.setUserContext', function() { - it('should set the globalUser object', function() { - Raven.setUserContext({name: 'Matt'}); - assert.deepEqual(globalUser, {name: 'Matt'}); - }); - - it('should clear the globalUser with no arguments', function() { - globalUser = {name: 'Matt'}; - Raven.setUserContext(); - assert.isUndefined(globalUser); - }); - }); - - describe('.setExtraContext', function() { - it('should set the globalOptions.extra object', function() { - Raven.setExtraContext({name: 'Matt'}); - assert.deepEqual(globalOptions.extra, {name: 'Matt'}); - }); - - it('should clear globalOptions.extra with no arguments', function() { - globalOptions = {name: 'Matt'}; - Raven.setExtraContext(); - assert.deepEqual(globalOptions.extra, {}); - }); - }); - - describe('.setTagsContext', function() { - it('should set the globalOptions.tags object', function() { - Raven.setTagsContext({name: 'Matt'}); - assert.deepEqual(globalOptions.tags, {name: 'Matt'}); - }); - - it('should clear globalOptions.tags with no arguments', function() { - globalOptions = {name: 'Matt'}; - Raven.setTagsContext(); - assert.deepEqual(globalOptions.tags, {}); - }); - }); - - describe('.setReleaseContext', function() { - it('should set the globalOptions.release attribute', function() { - Raven.setReleaseContext('abc123'); - assert.equal(globalOptions.release, 'abc123'); - }); - - it('should clear globalOptions.release with no arguments', function() { - globalOptions.release = 'abc123'; - Raven.setReleaseContext(); - assert.isUndefined(globalOptions.release); - }); - }); - - describe('.setDataCallback', function() { - it('should set the globalOptions.dataCallback attribute', function() { - var foo = function(){}; - Raven.setDataCallback(foo); - assert.equal(globalOptions.dataCallback, foo); - }); - - it('should clear globalOptions.dataCallback with no arguments', function() { - var foo = function(){}; - globalOptions.dataCallback = foo; - Raven.setDataCallback(); - assert.isUndefined(globalOptions.dataCallback); - }); - }); - - describe('.setShouldSendCallback', function() { - it('should set the globalOptions.shouldSendCallback attribute', function() { - var foo = function(){}; - Raven.setShouldSendCallback(foo); - assert.equal(globalOptions.shouldSendCallback, foo); - }); - - it('should clear globalOptions.shouldSendCallback with no arguments', function() { - var foo = function(){}; - globalOptions.shouldSendCallback = foo; - Raven.setShouldSendCallback(); - assert.isUndefined(globalOptions.shouldSendCallback); - }); - }); - - describe('.captureMessage', function() { - it('should work as advertised', function() { - this.sinon.stub(window, 'send'); - Raven.captureMessage('lol', {foo: 'bar'}); - assert.deepEqual(window.send.lastCall.args, [{ - message: 'lol', - foo: 'bar' - }]); - }); - - it('should coerce message to a string', function() { - this.sinon.stub(window, 'send'); - Raven.captureMessage({}); - assert.deepEqual(window.send.lastCall.args, [{ - message: '[object Object]' - }]); - }); - - it('should work as advertised #integration', function() { - var imageCache = []; - this.sinon.stub(window, 'newImage', function(){ var img = {}; imageCache.push(img); return img; }); - - setupRaven(); - Raven.captureMessage('lol', {foo: 'bar'}); - assert.equal(imageCache.length, 1); - // It'd be hard to assert the actual payload being sent - // since it includes the generated url, which is going to - // vary between users running the tests - // Unit tests should cover that the payload was constructed properly - }); - - it('should tag lastEventId #integration', function() { - setupRaven(); - Raven.captureMessage('lol'); - assert.equal(Raven.lastEventId(), 'abc123'); - }); - - it('should respect `ignoreErrors`', function() { - this.sinon.stub(window, 'send'); - - globalOptions.ignoreErrors = joinRegExp(['e1', 'e2']); - Raven.captureMessage('e1'); - assert.isFalse(window.send.called); - Raven.captureMessage('e2'); - assert.isFalse(window.send.called); - Raven.captureMessage('Non-ignored error'); - assert.isTrue(window.send.calledOnce); - }); - }); - - describe('.captureException', function() { - it('should call TraceKit.report', function() { - var error = new Error('crap'); - this.sinon.stub(TraceKit, 'report'); - Raven.captureException(error, {foo: 'bar'}); - assert.isTrue(TraceKit.report.calledOnce); - assert.deepEqual(TraceKit.report.lastCall.args, [error, {foo: 'bar'}]); - }); - - it('should store the last exception', function() { - var error = new Error('crap'); - this.sinon.stub(TraceKit, 'report'); - Raven.captureException(error); - assert.equal(Raven.lastException(), error); - }); - - it('shouldn\'t reraise the if the error is the same error', function() { - var error = new Error('crap'); - this.sinon.stub(TraceKit, 'report').throws(error); - // this would raise if the errors didn't match - Raven.captureException(error, {foo: 'bar'}); - assert.isTrue(TraceKit.report.calledOnce); - }); - - it('should reraise a different error', function() { - var error = new Error('crap1'); - this.sinon.stub(TraceKit, 'report').throws(error); - assert.throws(function() { - Raven.captureException(new Error('crap2')); - }, error); - }); - - it('should capture as a normal message if a non-Error is passed', function() { - this.sinon.stub(Raven, 'captureMessage'); - this.sinon.stub(TraceKit, 'report'); - Raven.captureException('derp'); - assert.equal(Raven.captureMessage.lastCall.args[0], 'derp'); - assert.isFalse(TraceKit.report.called); - Raven.captureException(true); - assert.equal(Raven.captureMessage.lastCall.args[0], true); - assert.isFalse(TraceKit.report.called); - }); - }); - - describe('.isSetup', function() { - it('should work as advertised', function() { - var isSetup = this.sinon.stub(window, 'isSetup'); - isSetup.returns(true); - assert.isTrue(Raven.isSetup()); - isSetup.returns(false); - assert.isFalse(Raven.isSetup()); - }); - }); -}); diff --git a/htdocs/includes/raven-js/vendor/TraceKit/tracekit.js b/htdocs/includes/raven-js/vendor/TraceKit/tracekit.js deleted file mode 100644 index bccddabedbe..00000000000 --- a/htdocs/includes/raven-js/vendor/TraceKit/tracekit.js +++ /dev/null @@ -1,1044 +0,0 @@ -/* - TraceKit - Cross brower stack traces - github.com/occ/TraceKit - MIT license -*/ - -var TraceKit = { - remoteFetching: false, - collectWindowErrors: true, - // 3 lines before, the offending line, 3 lines after - linesOfContext: 7 -}; - -// global reference to slice -var _slice = [].slice; -var UNKNOWN_FUNCTION = '?'; - - -/** - * TraceKit.wrap: Wrap any function in a TraceKit reporter - * Example: func = TraceKit.wrap(func); - * - * @param {Function} func Function to be wrapped - * @return {Function} The wrapped func - */ -TraceKit.wrap = function traceKitWrapper(func) { - function wrapped() { - try { - return func.apply(this, arguments); - } catch (e) { - TraceKit.report(e); - throw e; - } - } - return wrapped; -}; - -/** - * TraceKit.report: cross-browser processing of unhandled exceptions - * - * Syntax: - * TraceKit.report.subscribe(function(stackInfo) { ... }) - * TraceKit.report.unsubscribe(function(stackInfo) { ... }) - * TraceKit.report(exception) - * try { ...code... } catch(ex) { TraceKit.report(ex); } - * - * Supports: - * - Firefox: full stack trace with line numbers, plus column number - * on top frame; column number is not guaranteed - * - Opera: full stack trace with line and column numbers - * - Chrome: full stack trace with line and column numbers - * - Safari: line and column number for the top frame only; some frames - * may be missing, and column number is not guaranteed - * - IE: line and column number for the top frame only; some frames - * may be missing, and column number is not guaranteed - * - * In theory, TraceKit should work on all of the following versions: - * - IE5.5+ (only 8.0 tested) - * - Firefox 0.9+ (only 3.5+ tested) - * - Opera 7+ (only 10.50 tested; versions 9 and earlier may require - * Exceptions Have Stacktrace to be enabled in opera:config) - * - Safari 3+ (only 4+ tested) - * - Chrome 1+ (only 5+ tested) - * - Konqueror 3.5+ (untested) - * - * Requires TraceKit.computeStackTrace. - * - * Tries to catch all unhandled exceptions and report them to the - * subscribed handlers. Please note that TraceKit.report will rethrow the - * exception. This is REQUIRED in order to get a useful stack trace in IE. - * If the exception does not reach the top of the browser, you will only - * get a stack trace from the point where TraceKit.report was called. - * - * Handlers receive a stackInfo object as described in the - * TraceKit.computeStackTrace docs. - */ -TraceKit.report = (function reportModuleWrapper() { - var handlers = [], - lastArgs = null, - lastException = null, - lastExceptionStack = null; - - /** - * Add a crash handler. - * @param {Function} handler - */ - function subscribe(handler) { - installGlobalHandler(); - handlers.push(handler); - } - - /** - * Remove a crash handler. - * @param {Function} handler - */ - function unsubscribe(handler) { - for (var i = handlers.length - 1; i >= 0; --i) { - if (handlers[i] === handler) { - handlers.splice(i, 1); - } - } - } - - /** - * Remove all crash handlers. - */ - function unsubscribeAll() { - uninstallGlobalHandler(); - handlers = []; - } - - /** - * Dispatch stack information to all handlers. - * @param {Object.} stack - */ - function notifyHandlers(stack, isWindowError) { - var exception = null; - if (isWindowError && !TraceKit.collectWindowErrors) { - return; - } - for (var i in handlers) { - if (hasKey(handlers, i)) { - try { - handlers[i].apply(null, [stack].concat(_slice.call(arguments, 2))); - } catch (inner) { - exception = inner; - } - } - } - - if (exception) { - throw exception; - } - } - - var _oldOnerrorHandler, _onErrorHandlerInstalled; - - /** - * Ensures all global unhandled exceptions are recorded. - * Supported by Gecko and IE. - * @param {string} message Error message. - * @param {string} url URL of script that generated the exception. - * @param {(number|string)} lineNo The line number at which the error - * occurred. - * @param {?(number|string)} colNo The column number at which the error - * occurred. - * @param {?Error} ex The actual Error object. - */ - function traceKitWindowOnError(message, url, lineNo, colNo, ex) { - var stack = null; - - if (lastExceptionStack) { - TraceKit.computeStackTrace.augmentStackTraceWithInitialElement(lastExceptionStack, url, lineNo, message); - processLastException(); - } else if (ex) { - // New chrome and blink send along a real error object - // Let's just report that like a normal error. - // See: https://mikewest.org/2013/08/debugging-runtime-errors-with-window-onerror - stack = TraceKit.computeStackTrace(ex); - notifyHandlers(stack, true); - } else { - var location = { - 'url': url, - 'line': lineNo, - 'column': colNo - }; - location.func = TraceKit.computeStackTrace.guessFunctionName(location.url, location.line); - location.context = TraceKit.computeStackTrace.gatherContext(location.url, location.line); - stack = { - 'message': message, - 'url': document.location.href, - 'stack': [location] - }; - notifyHandlers(stack, true); - } - - if (_oldOnerrorHandler) { - return _oldOnerrorHandler.apply(this, arguments); - } - - return false; - } - - function installGlobalHandler () - { - if (_onErrorHandlerInstalled) { - return; - } - _oldOnerrorHandler = window.onerror; - window.onerror = traceKitWindowOnError; - _onErrorHandlerInstalled = true; - } - - function uninstallGlobalHandler () - { - if (!_onErrorHandlerInstalled) { - return; - } - window.onerror = _oldOnerrorHandler; - _onErrorHandlerInstalled = false; - _oldOnerrorHandler = undefined; - } - - function processLastException() { - var _lastExceptionStack = lastExceptionStack, - _lastArgs = lastArgs; - lastArgs = null; - lastExceptionStack = null; - lastException = null; - notifyHandlers.apply(null, [_lastExceptionStack, false].concat(_lastArgs)); - } - - /** - * Reports an unhandled Error to TraceKit. - * @param {Error} ex - * @param {?boolean} rethrow If false, do not re-throw the exception. - * Only used for window.onerror to not cause an infinite loop of - * rethrowing. - */ - function report(ex, rethrow) { - var args = _slice.call(arguments, 1); - if (lastExceptionStack) { - if (lastException === ex) { - return; // already caught by an inner catch block, ignore - } else { - processLastException(); - } - } - - var stack = TraceKit.computeStackTrace(ex); - lastExceptionStack = stack; - lastException = ex; - lastArgs = args; - - // If the stack trace is incomplete, wait for 2 seconds for - // slow slow IE to see if onerror occurs or not before reporting - // this exception; otherwise, we will end up with an incomplete - // stack trace - window.setTimeout(function () { - if (lastException === ex) { - processLastException(); - } - }, (stack.incomplete ? 2000 : 0)); - - if (rethrow !== false) { - throw ex; // re-throw to propagate to the top level (and cause window.onerror) - } - } - - report.subscribe = subscribe; - report.unsubscribe = unsubscribe; - report.uninstall = unsubscribeAll; - return report; -}()); - -/** - * TraceKit.computeStackTrace: cross-browser stack traces in JavaScript - * - * Syntax: - * s = TraceKit.computeStackTrace(exception) // consider using TraceKit.report instead (see below) - * Returns: - * s.name - exception name - * s.message - exception message - * s.stack[i].url - JavaScript or HTML file URL - * s.stack[i].func - function name, or empty for anonymous functions (if guessing did not work) - * s.stack[i].args - arguments passed to the function, if known - * s.stack[i].line - line number, if known - * s.stack[i].column - column number, if known - * s.stack[i].context - an array of source code lines; the middle element corresponds to the correct line# - * - * Supports: - * - Firefox: full stack trace with line numbers and unreliable column - * number on top frame - * - Opera 10: full stack trace with line and column numbers - * - Opera 9-: full stack trace with line numbers - * - Chrome: full stack trace with line and column numbers - * - Safari: line and column number for the topmost stacktrace element - * only - * - IE: no line numbers whatsoever - * - * Tries to guess names of anonymous functions by looking for assignments - * in the source code. In IE and Safari, we have to guess source file names - * by searching for function bodies inside all page scripts. This will not - * work for scripts that are loaded cross-domain. - * Here be dragons: some function names may be guessed incorrectly, and - * duplicate functions may be mismatched. - * - * TraceKit.computeStackTrace should only be used for tracing purposes. - * Logging of unhandled exceptions should be done with TraceKit.report, - * which builds on top of TraceKit.computeStackTrace and provides better - * IE support by utilizing the window.onerror event to retrieve information - * about the top of the stack. - * - * Note: In IE and Safari, no stack trace is recorded on the Error object, - * so computeStackTrace instead walks its *own* chain of callers. - * This means that: - * * in Safari, some methods may be missing from the stack trace; - * * in IE, the topmost function in the stack trace will always be the - * caller of computeStackTrace. - * - * This is okay for tracing (because you are likely to be calling - * computeStackTrace from the function you want to be the topmost element - * of the stack trace anyway), but not okay for logging unhandled - * exceptions (because your catch block will likely be far away from the - * inner function that actually caused the exception). - * - */ -TraceKit.computeStackTrace = (function computeStackTraceWrapper() { - var debug = false, - sourceCache = {}; - - /** - * Attempts to retrieve source code via XMLHttpRequest, which is used - * to look up anonymous function names. - * @param {string} url URL of source code. - * @return {string} Source contents. - */ - function loadSource(url) { - if (!TraceKit.remoteFetching) { //Only attempt request if remoteFetching is on. - return ''; - } - try { - var getXHR = function() { - try { - return new window.XMLHttpRequest(); - } catch (e) { - // explicitly bubble up the exception if not found - return new window.ActiveXObject('Microsoft.XMLHTTP'); - } - }; - - var request = getXHR(); - request.open('GET', url, false); - request.send(''); - return request.responseText; - } catch (e) { - return ''; - } - } - - /** - * Retrieves source code from the source code cache. - * @param {string} url URL of source code. - * @return {Array.} Source contents. - */ - function getSource(url) { - if (!isString(url)) return []; - if (!hasKey(sourceCache, url)) { - // URL needs to be able to fetched within the acceptable domain. Otherwise, - // cross-domain errors will be triggered. - var source = ''; - if (url.indexOf(document.domain) !== -1) { - source = loadSource(url); - } - sourceCache[url] = source ? source.split('\n') : []; - } - - return sourceCache[url]; - } - - /** - * Tries to use an externally loaded copy of source code to determine - * the name of a function by looking at the name of the variable it was - * assigned to, if any. - * @param {string} url URL of source code. - * @param {(string|number)} lineNo Line number in source code. - * @return {string} The function name, if discoverable. - */ - function guessFunctionName(url, lineNo) { - var reFunctionArgNames = /function ([^(]*)\(([^)]*)\)/, - reGuessFunction = /['"]?([0-9A-Za-z$_]+)['"]?\s*[:=]\s*(function|eval|new Function)/, - line = '', - maxLines = 10, - source = getSource(url), - m; - - if (!source.length) { - return UNKNOWN_FUNCTION; - } - - // Walk backwards from the first line in the function until we find the line which - // matches the pattern above, which is the function definition - for (var i = 0; i < maxLines; ++i) { - line = source[lineNo - i] + line; - - if (!isUndefined(line)) { - if ((m = reGuessFunction.exec(line))) { - return m[1]; - } else if ((m = reFunctionArgNames.exec(line))) { - return m[1]; - } - } - } - - return UNKNOWN_FUNCTION; - } - - /** - * Retrieves the surrounding lines from where an exception occurred. - * @param {string} url URL of source code. - * @param {(string|number)} line Line number in source code to centre - * around for context. - * @return {?Array.} Lines of source code. - */ - function gatherContext(url, line) { - var source = getSource(url); - - if (!source.length) { - return null; - } - - var context = [], - // linesBefore & linesAfter are inclusive with the offending line. - // if linesOfContext is even, there will be one extra line - // *before* the offending line. - linesBefore = Math.floor(TraceKit.linesOfContext / 2), - // Add one extra line if linesOfContext is odd - linesAfter = linesBefore + (TraceKit.linesOfContext % 2), - start = Math.max(0, line - linesBefore - 1), - end = Math.min(source.length, line + linesAfter - 1); - - line -= 1; // convert to 0-based index - - for (var i = start; i < end; ++i) { - if (!isUndefined(source[i])) { - context.push(source[i]); - } - } - - return context.length > 0 ? context : null; - } - - /** - * Escapes special characters, except for whitespace, in a string to be - * used inside a regular expression as a string literal. - * @param {string} text The string. - * @return {string} The escaped string literal. - */ - function escapeRegExp(text) { - return text.replace(/[\-\[\]{}()*+?.,\\\^$|#]/g, '\\$&'); - } - - /** - * Escapes special characters in a string to be used inside a regular - * expression as a string literal. Also ensures that HTML entities will - * be matched the same as their literal friends. - * @param {string} body The string. - * @return {string} The escaped string. - */ - function escapeCodeAsRegExpForMatchingInsideHTML(body) { - return escapeRegExp(body).replace('<', '(?:<|<)').replace('>', '(?:>|>)').replace('&', '(?:&|&)').replace('"', '(?:"|")').replace(/\s+/g, '\\s+'); - } - - /** - * Determines where a code fragment occurs in the source code. - * @param {RegExp} re The function definition. - * @param {Array.} urls A list of URLs to search. - * @return {?Object.} An object containing - * the url, line, and column number of the defined function. - */ - function findSourceInUrls(re, urls) { - var source, m; - for (var i = 0, j = urls.length; i < j; ++i) { - // console.log('searching', urls[i]); - if ((source = getSource(urls[i])).length) { - source = source.join('\n'); - if ((m = re.exec(source))) { - // console.log('Found function in ' + urls[i]); - - return { - 'url': urls[i], - 'line': source.substring(0, m.index).split('\n').length, - 'column': m.index - source.lastIndexOf('\n', m.index) - 1 - }; - } - } - } - - // console.log('no match'); - - return null; - } - - /** - * Determines at which column a code fragment occurs on a line of the - * source code. - * @param {string} fragment The code fragment. - * @param {string} url The URL to search. - * @param {(string|number)} line The line number to examine. - * @return {?number} The column number. - */ - function findSourceInLine(fragment, url, line) { - var source = getSource(url), - re = new RegExp('\\b' + escapeRegExp(fragment) + '\\b'), - m; - - line -= 1; - - if (source && source.length > line && (m = re.exec(source[line]))) { - return m.index; - } - - return null; - } - - /** - * Determines where a function was defined within the source code. - * @param {(Function|string)} func A function reference or serialized - * function definition. - * @return {?Object.} An object containing - * the url, line, and column number of the defined function. - */ - function findSourceByFunctionBody(func) { - var urls = [window.location.href], - scripts = document.getElementsByTagName('script'), - body, - code = '' + func, - codeRE = /^function(?:\s+([\w$]+))?\s*\(([\w\s,]*)\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/, - eventRE = /^function on([\w$]+)\s*\(event\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/, - re, - parts, - result; - - for (var i = 0; i < scripts.length; ++i) { - var script = scripts[i]; - if (script.src) { - urls.push(script.src); - } - } - - if (!(parts = codeRE.exec(code))) { - re = new RegExp(escapeRegExp(code).replace(/\s+/g, '\\s+')); - } - - // not sure if this is really necessary, but I don’t have a test - // corpus large enough to confirm that and it was in the original. - else { - var name = parts[1] ? '\\s+' + parts[1] : '', - args = parts[2].split(',').join('\\s*,\\s*'); - - body = escapeRegExp(parts[3]).replace(/;$/, ';?'); // semicolon is inserted if the function ends with a comment.replace(/\s+/g, '\\s+'); - re = new RegExp('function' + name + '\\s*\\(\\s*' + args + '\\s*\\)\\s*{\\s*' + body + '\\s*}'); - } - - // look for a normal function definition - if ((result = findSourceInUrls(re, urls))) { - return result; - } - - // look for an old-school event handler function - if ((parts = eventRE.exec(code))) { - var event = parts[1]; - body = escapeCodeAsRegExpForMatchingInsideHTML(parts[2]); - - // look for a function defined in HTML as an onXXX handler - re = new RegExp('on' + event + '=[\\\'"]\\s*' + body + '\\s*[\\\'"]', 'i'); - - if ((result = findSourceInUrls(re, urls[0]))) { - return result; - } - - // look for ??? - re = new RegExp(body); - - if ((result = findSourceInUrls(re, urls))) { - return result; - } - } - - return null; - } - - // Contents of Exception in various browsers. - // - // SAFARI: - // ex.message = Can't find variable: qq - // ex.line = 59 - // ex.sourceId = 580238192 - // ex.sourceURL = http://... - // ex.expressionBeginOffset = 96 - // ex.expressionCaretOffset = 98 - // ex.expressionEndOffset = 98 - // ex.name = ReferenceError - // - // FIREFOX: - // ex.message = qq is not defined - // ex.fileName = http://... - // ex.lineNumber = 59 - // ex.columnNumber = 69 - // ex.stack = ...stack trace... (see the example below) - // ex.name = ReferenceError - // - // CHROME: - // ex.message = qq is not defined - // ex.name = ReferenceError - // ex.type = not_defined - // ex.arguments = ['aa'] - // ex.stack = ...stack trace... - // - // INTERNET EXPLORER: - // ex.message = ... - // ex.name = ReferenceError - // - // OPERA: - // ex.message = ...message... (see the example below) - // ex.name = ReferenceError - // ex.opera#sourceloc = 11 (pretty much useless, duplicates the info in ex.message) - // ex.stacktrace = n/a; see 'opera:config#UserPrefs|Exceptions Have Stacktrace' - - /** - * Computes stack trace information from the stack property. - * Chrome and Gecko use this property. - * @param {Error} ex - * @return {?Object.} Stack trace information. - */ - function computeStackTraceFromStackProp(ex) { - if (!ex.stack) { - return null; - } - - var chrome = /^\s*at (.*?) ?\(?((?:file|https?|chrome-extension):.*?):(\d+)(?::(\d+))?\)?\s*$/i, - gecko = /^\s*(.*?)(?:\((.*?)\))?@((?:file|https?|chrome).*?):(\d+)(?::(\d+))?\s*$/i, - lines = ex.stack.split('\n'), - stack = [], - parts, - element, - reference = /^(.*) is undefined$/.exec(ex.message); - - for (var i = 0, j = lines.length; i < j; ++i) { - if ((parts = gecko.exec(lines[i]))) { - element = { - 'url': parts[3], - 'func': parts[1] || UNKNOWN_FUNCTION, - 'args': parts[2] ? parts[2].split(',') : '', - 'line': +parts[4], - 'column': parts[5] ? +parts[5] : null - }; - } else if ((parts = chrome.exec(lines[i]))) { - element = { - 'url': parts[2], - 'func': parts[1] || UNKNOWN_FUNCTION, - 'line': +parts[3], - 'column': parts[4] ? +parts[4] : null - }; - } else { - continue; - } - - if (!element.func && element.line) { - element.func = guessFunctionName(element.url, element.line); - } - - if (element.line) { - element.context = gatherContext(element.url, element.line); - } - - stack.push(element); - } - - if (!stack.length) { - return null; - } - - if (stack[0].line && !stack[0].column && reference) { - stack[0].column = findSourceInLine(reference[1], stack[0].url, stack[0].line); - } else if (!stack[0].column && !isUndefined(ex.columnNumber)) { - // FireFox uses this awesome columnNumber property for its top frame - // Also note, Firefox's column number is 0-based and everything else expects 1-based, - // so adding 1 - stack[0].column = ex.columnNumber + 1; - } - - return { - 'name': ex.name, - 'message': ex.message, - 'url': document.location.href, - 'stack': stack - }; - } - - /** - * Computes stack trace information from the stacktrace property. - * Opera 10 uses this property. - * @param {Error} ex - * @return {?Object.} Stack trace information. - */ - function computeStackTraceFromStacktraceProp(ex) { - // Access and store the stacktrace property before doing ANYTHING - // else to it because Opera is not very good at providing it - // reliably in other circumstances. - var stacktrace = ex.stacktrace; - - var testRE = / line (\d+), column (\d+) in (?:]+)>|([^\)]+))\((.*)\) in (.*):\s*$/i, - lines = stacktrace.split('\n'), - stack = [], - parts; - - for (var i = 0, j = lines.length; i < j; i += 2) { - if ((parts = testRE.exec(lines[i]))) { - var element = { - 'line': +parts[1], - 'column': +parts[2], - 'func': parts[3] || parts[4], - 'args': parts[5] ? parts[5].split(',') : [], - 'url': parts[6] - }; - - if (!element.func && element.line) { - element.func = guessFunctionName(element.url, element.line); - } - if (element.line) { - try { - element.context = gatherContext(element.url, element.line); - } catch (exc) {} - } - - if (!element.context) { - element.context = [lines[i + 1]]; - } - - stack.push(element); - } - } - - if (!stack.length) { - return null; - } - - return { - 'name': ex.name, - 'message': ex.message, - 'url': document.location.href, - 'stack': stack - }; - } - - /** - * NOT TESTED. - * Computes stack trace information from an error message that includes - * the stack trace. - * Opera 9 and earlier use this method if the option to show stack - * traces is turned on in opera:config. - * @param {Error} ex - * @return {?Object.} Stack information. - */ - function computeStackTraceFromOperaMultiLineMessage(ex) { - // Opera includes a stack trace into the exception message. An example is: - // - // Statement on line 3: Undefined variable: undefinedFunc - // Backtrace: - // Line 3 of linked script file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.js: In function zzz - // undefinedFunc(a); - // Line 7 of inline#1 script in file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.html: In function yyy - // zzz(x, y, z); - // Line 3 of inline#1 script in file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.html: In function xxx - // yyy(a, a, a); - // Line 1 of function script - // try { xxx('hi'); return false; } catch(ex) { TraceKit.report(ex); } - // ... - - var lines = ex.message.split('\n'); - if (lines.length < 4) { - return null; - } - - var lineRE1 = /^\s*Line (\d+) of linked script ((?:file|https?)\S+)(?:: in function (\S+))?\s*$/i, - lineRE2 = /^\s*Line (\d+) of inline#(\d+) script in ((?:file|https?)\S+)(?:: in function (\S+))?\s*$/i, - lineRE3 = /^\s*Line (\d+) of function script\s*$/i, - stack = [], - scripts = document.getElementsByTagName('script'), - inlineScriptBlocks = [], - parts, - i, - len, - source; - - for (i in scripts) { - if (hasKey(scripts, i) && !scripts[i].src) { - inlineScriptBlocks.push(scripts[i]); - } - } - - for (i = 2, len = lines.length; i < len; i += 2) { - var item = null; - if ((parts = lineRE1.exec(lines[i]))) { - item = { - 'url': parts[2], - 'func': parts[3], - 'line': +parts[1] - }; - } else if ((parts = lineRE2.exec(lines[i]))) { - item = { - 'url': parts[3], - 'func': parts[4] - }; - var relativeLine = (+parts[1]); // relative to the start of the