MozReview-Commit-ID: E0Sr26LKcZx
This commit is contained in:
Kartikaya Gupta 2016-12-21 10:16:15 -05:00
Родитель 4dbcec85a4 0be466c8a9
Коммит 4233ee5fec
824 изменённых файлов: 132625 добавлений и 30127 удалений

Просмотреть файл

@ -75,6 +75,8 @@ browser/extensions/pdfjs/**
browser/extensions/pocket/content/panels/js/tmpl.js
browser/extensions/pocket/content/panels/js/vendor/**
browser/locales/**
# imported from chromium
browser/extensions/mortar/**
# devtools/ exclusions
devtools/client/canvasdebugger/**

Просмотреть файл

@ -85,8 +85,8 @@ tasks:
chainOfTrust: true
# Note: This task is built server side without the context or tooling that
# exist in tree so we must hard code the version
image: 'taskcluster/decision:0.1.7'
# exist in tree so we must hard code the hash
image: 'taskcluster/decision@sha256:0f59f922d86c471e208b7ea08ab077fc68c3920ed5e6895d69a23e8f3457dc24'
maxRunTime: 1800

Просмотреть файл

@ -7,7 +7,7 @@
include protocol PFileDescriptorSet;
include protocol PBrowser;
using mozilla::a11y::IAccessibleHolder from "mozilla/a11y/COMPtrTypes.h";
using mozilla::a11y::IAccessibleHolder from "mozilla/a11y/IPCTypes.h";
using mozilla::WindowsHandle from "ipc/IPCMessageUtils.h";
namespace mozilla {

Просмотреть файл

@ -124,14 +124,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753984
"Peaches", {"string": "linkAbbr"}, "Plums", {"string": "linkAbbr"},
{"string": "listAbbr"},
{"string": "cellInfoAbbr", "args": [ 1, 1]}]]
}, {
accOrElmOrID: "date",
expectedUtterance: [[{"string": "textInputType_date"},
{"string": "entry"}, "2011-09-29"], ["2011-09-29",
{"string": "textInputType_date"}, {"string": "entry"}]],
expectedBraille: [[{"string": "textInputType_date"},
{"string": "entryAbbr"}, "2011-09-29"], ["2011-09-29",
{"string": "textInputType_date"}, {"string": "entryAbbr"}]]
}, {
accOrElmOrID: "email",
expectedUtterance: [[{"string": "textInputType_email"},
@ -619,7 +611,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753984
<label for="password">Secret Password</label><input id="password" type="password"></input>
<label for="radio_unselected">any old radio button</label><input id="radio_unselected" type="radio"></input>
<label for="radio_selected">a unique radio button</label><input id="radio_selected" type="radio" checked></input>
<input id="date" type="date" value="2011-09-29" />
<input id="email" type="email" value="test@example.com" />
<input id="search" type="search" value="This is a search" />
<input id="tel" type="tel" value="555-5555" />

Просмотреть файл

@ -9,8 +9,6 @@
#include "Compatibility.h"
#include "DocAccessible-inl.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/a11y/DocAccessibleChild.h"
#include "mozilla/a11y/DocAccessibleParent.h"
#include "EnumVariant.h"
#include "nsAccUtils.h"
@ -1344,22 +1342,6 @@ AccessibleWrap::GetHWNDFor(Accessible* aAccessible)
return nullptr;
}
if (XRE_IsContentProcess()) {
DocAccessible* doc = aAccessible->Document();
if (!doc) {
return nullptr;
}
DocAccessibleChild* ipcDoc = doc->IPCDoc();
if (!ipcDoc) {
return nullptr;
}
auto tab = static_cast<dom::TabChild*>(ipcDoc->Manager());
MOZ_ASSERT(tab);
return reinterpret_cast<HWND>(tab->GetNativeWindowHandle());
}
// Accessibles in child processes are said to have the HWND of the window
// their tab is within. Popups are always in the parent process, and so
// never proxied, which means this is basically correct.

Просмотреть файл

@ -7,6 +7,7 @@
#include "DocAccessibleWrap.h"
#include "Compatibility.h"
#include "mozilla/dom/TabChild.h"
#include "DocAccessibleChild.h"
#include "nsWinUtils.h"
#include "Role.h"
@ -121,7 +122,15 @@ DocAccessibleWrap::Shutdown()
void*
DocAccessibleWrap::GetNativeWindow() const
{
return mHWND ? mHWND : DocAccessible::GetNativeWindow();
if (XRE_IsContentProcess()) {
DocAccessibleChild* ipcDoc = IPCDoc();
auto tab = static_cast<dom::TabChild*>(ipcDoc->Manager());
MOZ_ASSERT(tab);
return reinterpret_cast<HWND>(tab->GetNativeWindowHandle());
} else if (mHWND) {
return mHWND;
}
return DocAccessible::GetNativeWindow();
}
////////////////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -684,9 +684,6 @@ pref("dom.ipc.systemMessageCPULockTimeoutSec", 30);
// Ignore the "dialog=1" feature in window.open.
pref("dom.disable_window_open_dialog_feature", true);
// Enable before keyboard events and after keyboard events.
pref("dom.beforeAfterKeyboardEvent.enabled", true);
// Screen reader support
pref("accessibility.accessfu.activate", 2);
pref("accessibility.accessfu.quicknav_modes", "Link,Heading,FormElement,Landmark,ListItem");
@ -846,10 +843,6 @@ pref("media.webspeech.synth.enabled", true);
// Enable Web Speech recognition API
pref("media.webspeech.recognition.enable", true);
// Downloads API
pref("dom.mozDownloads.enabled", true);
pref("dom.downloads.max_retention_days", 7);
// External Helper Application Handling
//
// All external helper application handling can require the docshell to be

Просмотреть файл

@ -2759,6 +2759,11 @@
<pluginItem blockID="p28">
<match exp="NPFFAddOn.dll" name="filename"/>
</pluginItem>
<pluginItem blockID="p1421" os="Linux">
<match exp="libflashplayer\.so" name="filename"/>
<infoURL>https://get.adobe.com/flashplayer/</infoURL>
<versionRange maxVersion="23.0.0.207" minVersion="11.2.202.643" severity="0" vulnerabilitystatus="1"/>
</pluginItem>
<pluginItem blockID="p302">
<match exp="Java\(TM\) Plug-in 1\.6\.0_(39|40|41)([^\d\._]|$)" name="name"/>
<match exp="libnpjp2\.so" name="filename"/>
@ -2951,6 +2956,11 @@
<infoURL>https://get.adobe.com/reader</infoURL>
<versionRange maxVersion="15.006.30174" minVersion="15.006.30174" severity="0" vulnerabilitystatus="1"/>
</pluginItem>
<pluginItem blockID="p1422">
<match exp="(NPSWF32.*\.dll)|(NPSWF64.*\.dll)|(Flash\ Player\.plugin)" name="filename"/>
<infoURL>https://get.adobe.com/flashplayer/</infoURL>
<versionRange maxVersion="23.0.0.207" minVersion="23.0.0.205" severity="0" vulnerabilitystatus="1"/>
</pluginItem>
<pluginItem blockID="p418">
<match exp="Java\(TM\) Plug-in 1\.7\.0_(1[6-9]|2[0-4])([^\d\._]|$)" name="name"/>
<match exp="libnpjp2\.so" name="filename"/>

Просмотреть файл

@ -49,6 +49,7 @@ pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LO
pref("extensions.webservice.discoverURL", "https://discovery.addons.mozilla.org/%LOCALE%/firefox/discovery/pane/%VERSION%/%OS%/%COMPATIBILITY_MODE%");
pref("extensions.getAddons.recommended.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/list/recommended/all/%MAX_RESULTS%/%OS%/%VERSION%?src=firefox");
pref("extensions.getAddons.link.url", "https://addons.mozilla.org/%LOCALE%/firefox/");
pref("extensions.getAddons.themes.browseURL", "https://addons.mozilla.org/%LOCALE%/firefox/themes/?src=firefox");
pref("extensions.update.autoUpdateDefault", true);
@ -501,6 +502,8 @@ pref("privacy.cpd.offlineApps", false);
pref("privacy.cpd.siteSettings", false);
pref("privacy.cpd.openWindows", false);
pref("privacy.history.custom", false);
// What default should we use for the time span in the sanitizer:
// 0 - Clear everything
// 1 - Last Hour

Просмотреть файл

@ -65,10 +65,6 @@ function ContentSearchUIController(inputElement, tableParent, healthReportKey,
ContentSearchUIController.prototype = {
// The timeout (ms) of the remote suggestions. Corresponds to
// SearchSuggestionController.remoteTimeout. Uses
// SearchSuggestionController's default timeout if falsey.
remoteTimeout: undefined,
_oneOffButtons: [],
// Setting up the one off buttons causes an uninterruptible reflow. If we
// receive the list of engines while the newtab page is loading, this reflow
@ -716,7 +712,6 @@ ContentSearchUIController.prototype = {
this._sendMsg("GetSuggestions", {
engineName: this.defaultEngine.name,
searchString: this.input.value,
remoteTimeout: this.remoteTimeout,
});
}
},

Просмотреть файл

@ -11,7 +11,12 @@ var gPermURI;
var gPermPrincipal;
var gUsageRequest;
var gPermissions = SitePermissions.listPermissions();
// Array of permissionIDs sorted alphabetically by label.
var gPermissions = SitePermissions.listPermissions().sort((a, b) => {
let firstLabel = SitePermissions.getPermissionLabel(a);
let secondLabel = SitePermissions.getPermissionLabel(b);
return firstLabel.localeCompare(secondLabel);
});
gPermissions.push("plugins");
var permissionObserver = {

Просмотреть файл

@ -316,9 +316,6 @@ add_task(function* () {
yield p;
yield ContentTask.spawn(browser, null, function* () {
// Avoid intermittent failures.
content.wrappedJSObject.gContentSearchController.remoteTimeout = 5000;
// Type an X in the search input.
let input = content.document.getElementById("searchText");
input.focus();

Просмотреть файл

@ -79,7 +79,11 @@ function openSelectPopup(selectPopup, withMouse, selector = "select", win = win
function hideSelectPopup(selectPopup, mode = "enter", win = window)
{
let popupHiddenPromise = BrowserTestUtils.waitForEvent(selectPopup, "popuphidden");
let browser = win.gBrowser.selectedBrowser;
let selectClosedPromise = ContentTask.spawn(browser, null, function*() {
Cu.import("resource://gre/modules/SelectContentHelper.jsm");
return ContentTaskUtils.waitForCondition(() => !SelectContentHelper.open);
});
if (mode == "escape") {
EventUtils.synthesizeKey("KEY_Escape", { code: "Escape" }, win);
@ -91,7 +95,7 @@ function hideSelectPopup(selectPopup, mode = "enter", win = window)
EventUtils.synthesizeMouseAtCenter(selectPopup.lastChild, { }, win);
}
return popupHiddenPromise;
return selectClosedPromise;
}
function getInputEvents()
@ -559,3 +563,4 @@ add_task(function* test_somehidden() {
yield hideSelectPopup(selectPopup, "escape");
yield BrowserTestUtils.removeTab(tab);
});

Просмотреть файл

@ -27,7 +27,6 @@ var messageHandlers = {
ack("init");
}
});
gController.remoteTimeout = 5000;
},
key: function(arg) {

Просмотреть файл

@ -125,11 +125,6 @@ add_task(function* () {
yield searchEventsPromise;
yield* checkCurrentEngine(ENGINE_SUGGESTIONS);
// Avoid intermittent failures.
yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
content.gSearch._contentSearchController.remoteTimeout = 5000;
});
// Type an X in the search input. This is only a smoke test. See
// browser_searchSuggestionUI.js for comprehensive content search suggestion
// UI tests.

Просмотреть файл

@ -697,18 +697,6 @@ nsDefaultCommandLineHandler.prototype = {
/* nsICommandLineHandler */
handle : function dch_handle(cmdLine) {
// The -url flag is inserted by the operating system when the default
// application handler is used. We check for default browser to remove
// instances where users explicitly decide to "open with" the browser.
// Note that users who launch firefox manually with the -url flag will
// get erroneously counted.
try {
if (cmdLine.findFlag("url", false) &&
ShellService.isDefaultBrowser(false, false)) {
Services.telemetry.getHistogramById("FX_STARTUP_EXTERNAL_CONTENT_HANDLER").add();
}
} catch (e) {}
var urilist = [];
if (AppConstants.platform == "win") {

Просмотреть файл

@ -121,6 +121,16 @@ var gAdvancedPane = {
return;
var advancedPrefs = document.getElementById("advancedPrefs");
var preference = document.getElementById("browser.preferences.advanced.selectedTabIndex");
// tabSelectionChanged gets called twice due to the selectedIndex being set
// by both the selectedItem and selectedPanel callstacks. This guard is used
// to prevent double-counting in Telemetry.
if (preference.valueFromPreferences != advancedPrefs.selectedIndex) {
Services.telemetry
.getHistogramById("FX_PREFERENCES_CATEGORY_OPENED")
.add(telemetryBucketForCategory("advanced"));
}
preference.valueFromPreferences = advancedPrefs.selectedIndex;
},

Просмотреть файл

@ -123,6 +123,36 @@ function init_dynamic_padding() {
document.documentElement.appendChild(mediaStyle);
}
function telemetryBucketForCategory(category) {
switch (category) {
case "general":
case "search":
case "content":
case "applications":
case "privacy":
case "security":
case "sync":
return category;
case "advanced":
let advancedPaneTabs = document.getElementById("advancedPrefs");
switch (advancedPaneTabs.selectedTab.id) {
case "generalTab":
return "advancedGeneral";
case "dataChoicesTab":
return "advancedDataChoices";
case "networkTab":
return "advancedNetwork";
case "updateTab":
return "advancedUpdates";
case "encryptionTab":
return "advancedCerts";
}
// fall-through for unknown.
default:
return "unknown";
}
}
function onHashChange() {
gotoPref();
}
@ -151,9 +181,9 @@ function gotoPref(aCategory) {
throw ex;
}
let newHash = internalPrefCategoryNameToFriendlyName(category);
let friendlyName = internalPrefCategoryNameToFriendlyName(category);
if (gLastHash || category != kDefaultCategoryInternalName) {
document.location.hash = newHash;
document.location.hash = friendlyName;
}
// Need to set the gLastHash before setting categories.selectedItem since
// the categories 'select' event will re-enter the gotoPref codepath.
@ -163,6 +193,10 @@ function gotoPref(aCategory) {
search(category, "data-category");
let mainContent = document.querySelector(".main-content");
mainContent.scrollTop = 0;
Services.telemetry
.getHistogramById("FX_PREFERENCES_CATEGORY_OPENED")
.add(telemetryBucketForCategory(friendlyName));
}
function search(aQuery, aAttribute) {

Просмотреть файл

@ -287,7 +287,9 @@ var gPrivacyPane = {
let mode;
let getVal = aPref => document.getElementById(aPref).value;
if (this._checkHistoryValues(this.prefsForKeepingHistory)) {
if (getVal("privacy.history.custom"))
mode = "custom";
else if (this._checkHistoryValues(this.prefsForKeepingHistory)) {
if (getVal("browser.privatebrowsing.autostart"))
mode = "dontremember";
else
@ -317,6 +319,7 @@ var gPrivacyPane = {
break;
}
document.getElementById("historyPane").selectedIndex = selectedIndex;
document.getElementById("privacy.history.custom").value = selectedIndex == 2;
},
/**

Просмотреть файл

@ -52,6 +52,9 @@
<preference id="browser.formfill.enable"
name="browser.formfill.enable"
type="bool"/>
<preference id="privacy.history.custom"
name="privacy.history.custom"
type="bool"/>
<!-- Cookies -->
<preference id="network.cookie.cookieBehavior"
name="network.cookie.cookieBehavior"

Просмотреть файл

@ -331,6 +331,10 @@ var testRunner = {
},
};
registerCleanupFunction(function() {
Services.prefs.clearUserPref("privacy.history.custom");
});
openPreferencesViaOpenPreferencesAPI("panePrivacy", null, {leaveOpen: true}).then(function() {
let doc = gBrowser.contentDocument;
let historyMode = doc.getElementById("historyMode");

Просмотреть файл

@ -11,7 +11,7 @@ loader.loadSubScript(rootDir + "privacypane_tests_perwindow.js", this);
run_test_subset([
test_custom_retention("rememberHistory", "remember"),
test_custom_retention("rememberHistory", "custom"),
test_custom_retention("rememberForms", "remember"),
test_custom_retention("rememberForms", "custom"),
test_historymode_retention("remember", "remember"),
test_custom_retention("rememberForms", "custom"),
test_historymode_retention("remember", "custom"),
]);

Просмотреть файл

@ -14,12 +14,12 @@ let runtime = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
run_test_subset([
test_custom_retention("acceptCookies", "remember"),
test_custom_retention("acceptCookies", "custom"),
test_custom_retention("acceptThirdPartyMenu", "remember", "visited"),
test_custom_retention("acceptThirdPartyMenu", "custom", "visited"),
test_custom_retention("acceptThirdPartyMenu", "custom", "always"),
test_custom_retention("keepCookiesUntil", "remember", 1),
test_custom_retention("keepCookiesUntil", "custom", 1),
test_custom_retention("keepCookiesUntil", "custom", 2),
test_custom_retention("keepCookiesUntil", "custom", 0),
test_custom_retention("alwaysClear", "remember"),
test_custom_retention("alwaysClear", "custom"),
test_historymode_retention("remember", "remember"),
test_custom_retention("alwaysClear", "custom"),
test_historymode_retention("remember", "custom"),
]);

Просмотреть файл

@ -16,12 +16,14 @@ function testPrefStateMatchesLockedState() {
let preference = doc.getElementById("privacy.sanitize.sanitizeOnShutdown");
is(checkbox.disabled, preference.locked, "Always Clear checkbox should be enabled when preference is not locked.");
Services.prefs.clearUserPref("privacy.history.custom");
gBrowser.removeCurrentTab();
}
add_task(function setup() {
registerCleanupFunction(function resetPreferences() {
Services.prefs.unlockPref("privacy.sanitize.sanitizeOnShutdown");
Services.prefs.clearUserPref("privacy.history.custom");
});
});

Просмотреть файл

@ -0,0 +1,54 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# We keep the Makefile until the mortar is integrated into gecko build system.
ifeq ($(shell uname), Darwin)
DLL_SUFFIX = .dylib
CXX = g++
CXX_FLAGS = -std=c++11 -g -fPIC
LD_FLAGS = -dynamiclib
ifdef DEBUG
CXX_FLAGS += -DDEBUG
endif
else ifeq ($(shell uname), Linux)
DLL_SUFFIX = .so
CXX = g++
CXX_FLAGS = -std=c++11 -g -fPIC
LD_FLAGS = -shared
ifdef DEBUG
CXX_FLAGS += -DDEBUG
endif
else
DLL_SUFFIX = .dll
CXX = cl
CXX_FLAGS = -nologo -EHsc -Oy-
ifdef DEBUG
CXX_FLAGS += -LDd -DDEBUG -Od
else
CXX_FLAGS += -LD
endif
LD_FLAGS = -link -dll
endif
all : ppapi/out/rpc$(DLL_SUFFIX) ppapi/out/interpose$(DLL_SUFFIX)
ppapi/out/rpc$(DLL_SUFFIX): ppapi/out/rpc.cc host/rpc.h host/rpc.cc
$(CXX) $(CXX_FLAGS) -I. -o $@ host/rpc.cc $(LD_FLAGS)
ppapi/out/interpose$(DLL_SUFFIX): ppapi/out/rpc.cc host/rpc.h host/interpose.cc
$(CXX) -DINTERPOSE $(CXX_FLAGS) -I. -o $@ host/interpose.cc $(LD_FLAGS)
ppapi/out/rpc.cc: $(shell find . -name *.idl) $(shell find . -name *.py)
cd ppapi/generators; python idl_gen_rpc.py --out ../out/rpc.cc ; cd ../..
json/test: json/json.cpp json/json.h json/test.cpp
$(CXX) -I./json -o $@ json/test.cpp
test-json: json/test
@./json/test && echo "OK"
clean:
rm -rf ppapi/generators/*.pyc ppapi/generators/*~ *~ ppapi/out/* json/*~ json/test *.obj
.PHONY: all test-json test clean

Просмотреть файл

@ -0,0 +1,70 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let GLES2Utils = {
bytesPerElement: function(context, type) {
switch (type) {
case context.FLOAT:
case context.INT:
case context.UNSIGNED_INT:
return 4;
case context.SHORT:
case context.UNSIGNED_SHORT:
case context.UNSIGNED_SHORT_5_6_5:
case context.UNSIGNED_SHORT_4_4_4_4:
case context.UNSIGNED_SHORT_5_5_5_1:
return 2;
case context.BYTE:
case context.UNSIGNED_BYTE:
return 1;
default:
throw new Error("Don't know this type.");
}
},
elementsPerGroup: function(context, format, type) {
switch (type) {
case context.UNSIGNED_SHORT_5_6_5:
case context.UNSIGNED_SHORT_4_4_4_4:
case context.UNSIGNED_SHORT_5_5_5_1:
return 1;
default:
break;
}
switch (format) {
case context.RGB:
return 3;
case context.LUMINANCE_ALPHA:
return 2;
case context.RGBA:
return 4;
case context.ALPHA:
case context.LUMINANCE:
case context.DEPTH_COMPONENT:
case context.DEPTH_COMPONENT16:
return 1;
default:
throw new Error("Don't know this format.");
}
},
computeImageGroupSize: function(context, format, type) {
return this.bytesPerElement(context, type) * this.elementsPerGroup(context, format, type);
},
computeImageDataSize: function(context, width, height, format, type) {
const unpackAlignment = 4;
let bytesPerGroup = this.computeImageGroupSize(context, format, type);
let rowSize = width * bytesPerGroup;
if (height == 1) {
return rowSize;
}
let temp = rowSize + unpackAlignment - 1;
let paddedRowSize = Math.floor(temp / unpackAlignment) * unpackAlignment;
let sizeOfAllButLastRow = (height - 1) * paddedRowSize;
return sizeOfAllButLastRow + rowSize;
},
};
var EXPORTED_SYMBOLS = ["GLES2Utils"];

Просмотреть файл

@ -0,0 +1,33 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/Services.jsm");
let rt;
function getRuntime(type) {
if (!rt) {
let process = Cc["@mozilla.org/plugin/ppapi.js-process;1"].getService(Ci.nsIPPAPIJSProcess);
Cu.import("resource://ppapi.js/ppapi-runtime.jsm");
rt = new PPAPIRuntime(process);
process.launch(rt.callback);
}
return rt;
}
addMessageListener("ppapi.js:createInstance", ({ target, data: { type, info }, objects: { pluginWindow } }) => {
dump("ppapi.js:createInstance\n");
let rt = getRuntime(type);
let instance = rt.createInstance(info, content, docShell.chromeEventHandler, pluginWindow, target);
addEventListener("unload", () => {
rt.destroyInstance(instance);
});
});
addEventListener("DOMContentLoaded", () => {
// Passing an object here forces the creation of the CPOW manager in the
// parent.
sendRpcMessage("ppapi.js:frameLoaded", undefined, {});
});

Разница между файлами не показана из-за своего большого размера Загрузить разницу

74
browser/extensions/mortar/host/flash/bootstrap.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,74 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
Cu.import("resource://gre/modules/Services.jsm");
function sandboxScript(sandbox)
{
dump("sandboxScript " + sandbox.pluginElement + "\n");
Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader).loadSubScript("resource://ppapiflash.js/ppapi-content-sandbox.js", sandbox);
}
let plugins;
function startup(data) {
dump(">>>STARTED!!!\n");
let root = data.installPath.parent.parent;
let rpclib = root.clone();
let pluginlib = root.clone();
let os = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS;
if (os == "Darwin") {
rpclib.appendRelativePath("ppapi/out/rpc.dylib");
pluginlib.appendRelativePath("plugin/PepperFlashPlayer-debug");
} else if (os == "Linux") {
rpclib.appendRelativePath("ppapi/out/rpc.so");
pluginlib.appendRelativePath("plugin/libpepflashplayer.so");
} else if (os == "WINNT") {
rpclib.appendRelativePath("ppapi\\out\\rpc.dll");
pluginlib.appendRelativePath("plugin\\pepflashplayer.dll");
} else {
throw("Don't know the path to the libraries for this OS!");
}
rpclib = rpclib.path;
pluginlib = pluginlib.path;
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
let plugin = pluginHost.registerFakePlugin({
handlerURI: "chrome://ppapiflash.js/content/viewer.html",
mimeEntries: [{ type: "application/x-shockwave-flash", extension: "swf" }],
name: "Shockwave Flash",
niceName: "PPAPI Flash plugin",
description: "10",
version: "1.0",
sandboxScript : `(${sandboxScript.toSource()})(this);`,
ppapiProcessArgs: [ rpclib, pluginlib ],
});
plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
let rng = Cc["@mozilla.org/security/random-generator;1"].createInstance(Ci.nsIRandomGenerator);
Services.ppmm.addMessageListener("ppapi.js:generateRandomBytes", ({ data }) => {
return rng.generateRandomBytes(data);
});
let moduleLocalFiles = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
moduleLocalFiles.append("Flash PPAPI Data");
try {
moduleLocalFiles.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
} catch (e) {
if (e.result != Cr.NS_ERROR_FILE_ALREADY_EXISTS) {
throw e;
}
}
Services.ppmm.addMessageListener("ppapiflash.js:getModuleLocalFilesPath", () => {
return moduleLocalFiles.path;
});
dump("<<<STARTED!!!\n");
}
function shutdown() {
dump("SHUTDOWN!!!\n");
}

Просмотреть файл

@ -0,0 +1,3 @@
resource ppapiflash.js .
content ppapiflash.js chrome/
resource ppapi.js ../common/

Просмотреть файл

@ -0,0 +1,35 @@
<!DOCTYPE html>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<style>
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
background-color: transparent;
}
canvas {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
overflow: hidden;
line-height: 0;
border: 0px none;
}
</style>
</head>
<body>
</body>
</html>

Просмотреть файл

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>ppapiflash.js@mozilla.org</em:id>
<em:name>ppapiflash.js</em:name>
<em:description>ppapiflash.js</em:description>
<em:version>0.1</em:version>
<em:type>2</em:type>
<em:bootstrap>true</em:bootstrap>
<em:multiprocessCompatible>true</em:multiprocessCompatible>
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <!--Firefox-->
<em:minVersion>37.0</em:minVersion>
<em:maxVersion>45.*</em:maxVersion>
</Description>
</em:targetApplication>
<em:strictCompatibility>false</em:strictCompatibility>
</Description>
</RDF>

Просмотреть файл

@ -0,0 +1,226 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* This code runs in the sandbox in the content process where the page that
* loaded the plugin lives. It communicates with the process where the PPAPI
* implementation lives.
*/
const { utils: Cu } = Components;
let mm = pluginElement.frameLoader.messageManager;
let containerWindow = pluginElement.ownerDocument.defaultView;
function mapValue(v, instance) {
return instance.rt.toPP_Var(v, instance);
}
dump("<>>>>>>>>>>>>>>>>>>>> AHA <<<<<<<<<<<<<<<<<<<<<>\n");
dump(`pluginElement: ${pluginElement.toSource()}\n`);
dump(`pluginElement.frameLoader: ${pluginElement.frameLoader.toSource()}\n`);
dump(`pluginElement.frameLoader.messageManager: ${pluginElement.frameLoader.messageManager.toSource()}\n`);
dump("<>>>>>>>>>>>>>>>>>>>> AHA2 <<<<<<<<<<<<<<<<<<<<<>\n");
mm.addMessageListener("ppapi.js:frameLoaded", ({ target }) => {
let tagName = pluginElement.nodeName;
// Getting absolute URL from the EMBED tag
let url = pluginElement.srcURI.spec;
let objectParams = new Map();
for (let i = 0; i < pluginElement.attributes.length; ++i) {
let paramName = pluginElement.attributes[i].localName;
objectParams.set(paramName, pluginElement.attributes[i].value);
}
if (tagName == "OBJECT") {
let params = pluginElement.getElementsByTagName("param");
Array.prototype.forEach.call(params, (p) => {
var paramName = p.getAttribute("name").toLowerCase();
objectParams.set(paramName, p.getAttribute("value"));
});
}
let documentURL = pluginElement.ownerDocument.location.href;
let baseUrl = documentURL;
if (objectParams.base) {
try {
let parsedDocumentUrl = Services.io.newURI(documentURL);
baseUrl = Services.io.newURI(objectParams.base, null, parsedDocumentUrl).spec;
} catch (e) { /* ignore */ }
}
let info = {
url,
documentURL,
isFullFrame: pluginElement.ownerDocument.mozSyntheticDocument,
setupJSInstanceObject: true,
arguments: {
keys: Array.from(objectParams.keys()),
values: Array.from(objectParams.values()),
},
};
mm.sendAsyncMessage("ppapi.js:createInstance", { type: "flash", info },
{ pluginWindow: containerWindow });
});
mm.addMessageListener("ppapiflash.js:executeScript", ({ data, objects: { instance } }) => {
return mapValue(containerWindow.eval(data), instance);
});
let jsInterfaceObjects = new WeakMap();
mm.addMessageListener("ppapiflash.js:createObject", ({ data: { objectClass, objectData }, objects: { instance, call: callRemote } }) => {
dump("ppapiflash.js:createObject\n");
let call = (name, args) => {
/*
let metaData = target[Symbol.for("metaData")];
let callObj = { __interface: "PPP_Class_Deprecated;1.0", __instance: metaData.objectClass, __member: name, object: metaData.objectData };
*/
dump("ppapiflash.js:createObject -> call\n");
try {
let result = callRemote(name, JSON.stringify(args));
} catch (e) {
dump("FIXME: we rely on CPOWs!\n");
return undefined;
}
dump("RESULT: " + result[0] + "\n");
dump("EXCEPTION: " + result[1] + "\n");
return result[0];
};
const handler = {
// getPrototypeOf -> target (see bug 888969)
// setPrototypeOf -> target (see bug 888969)
// isExtensible -> target
// preventExtensions -> target
getOwnPropertyDescriptor: function(target, name) {
let value = this.get(target, name);
if (this._hasProperty(target, name)) {
return {
"writable": true,
"enumerable": true,
"configurable": true,
"get": this.get.bind(this, target, name),
"set": this.set.bind(this, target, name),
};
}
if (this._hasMethod(target, name)) {
return {
"value": (...args) => {
//call("Call", { name, argc, argv, exception });
},
"writable": true,
"enumerable": true,
"configurable": true,
};
}
return undefined;
},
// defineProperty -> target
has: function(target, name) {
return this._hasProperty(target, name) || this._hasMethod(target, name);
},
get: function(target, name, receiver) {
dump(`Calling GetProperty for ${name.toSource()}\n`);
let prop = call("GetProperty", { name });
if (!prop || PP_VarType[prop.type] == PP_VarType.PP_VARTYPE_UNDEFINED) {
// FIXME Need to get the exception!
return undefined;
}
return prop;
},
set: function(target, name, value, receiver) {
call("SetProperty", { name, value });
// FIXME Need to get the exception!
return true;
},
deleteProperty: function(target, name) {
call("RemoveProperty", { name });
// FIXME Need to get the exception!
return true;
},
enumerate: function(target) {
let keys = this.ownKeys(target);
return keys[Symbol.iterator];
},
ownKeys: function(target) {
let result = call("GetAllPropertyNames");
dump(result.toSource() + "\n");
dump(typeof result.properties + "\n");
return result.properties;
},
apply: function(target, thisArg, args) {
},
construct: function(target, args) {
//call("Construct", { argc, argv, exception });
},
_hasProperty: function(target, name) {
return call("HasProperty", { name }) == 1 /* PP_Bool.PP_TRUE */;
},
_hasMethod: function(target, name) {
return call("HasMethod", { name }) == 1 /* PP_Bool.PP_TRUE */;
},
};
let metaData = {
objectClass,
objectData,
};
let clonedHandler = Cu.cloneInto(handler, containerWindow, { cloneFunctions: true });
let clonedMetaData = Cu.cloneInto(metaData, containerWindow, { cloneFunctions: true });
let target = Cu.createObjectIn(containerWindow);
target[Symbol.for("metaData")] = clonedMetaData;
dump("IN CREATEOBJECT\n");
let proxy = new containerWindow.Proxy(target, clonedHandler);
jsInterfaceObjects.set(proxy, metaData);
let foo = mapValue(proxy.wrappedJSObject, instance);
dump("CREATEDOBJECT: " + foo.toSource() + "\n");
return foo;
});
mm.addMessageListener("ppapiflash.js:isInstanceOf", ({ data: { objectClass }, objects: { object, instance } }) => {
let metaData = jsInterfaceObjects.get(object);
if (!metaData || metaData.objectClass != objectClass) {
return [false];
}
return [true, metaData.objectData];
});
mm.addMessageListener("ppapiflash.js:getProperty", ({ data: { name }, objects: { object, instance } }) => {
try {
return [mapValue(object[name], instance), { exception: null }];
} catch (e) {
return [mapValue(null, instance), { exception: mapValue(e, instance) }];
}
});
mm.addMessageListener("ppapiflash.js:log", ({ data }) => {
containerWindow.console.log(data);
});
mm.addMessageListener("ppapiflash.js:setInstancePrototype", ({ objects: { proto } }) => {
Object.setPrototypeOf(proto.wrappedJSObject, Object.getPrototypeOf(pluginElement.wrappedJSObject));
Object.setPrototypeOf(pluginElement.wrappedJSObject, proto.wrappedJSObject);
});
mm.addMessageListener("ppapi.js:isFullscreen", () => {
return containerWindow.document.fullscreenElement == pluginElement;
});
mm.addMessageListener("ppapi.js:setFullscreen", ({ data }) => {
if (data) {
pluginElement.requestFullscreen();
} else {
containerWindow.document.exitFullscreen();
}
});
mm.loadFrameScript("resource://ppapi.js/ppapi-instance.js", true);

Просмотреть файл

@ -0,0 +1,335 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "../ppapi/out/rpc.cc"
#include <dlfcn.h>
#define REAL_PLUGIN_PATH "/Applications/Google Chrome.app/Contents/Versions/42.0.2311.135/Google Chrome Framework.framework/Internet Plug-Ins/PepperFlash/PepperFlashPlayer.plugin/Contents/MacOS/PepperFlashPlayer"
//#define REAL_PLUGIN_PATH "/usr/lib/pepperflashplugin-nonfree/libpepflashplayer.so"
static PPB_GetInterface _real_PPB_GetInterface;
const void* RealGetInterface(const char* interfaceName) {
if (!strcmp(interfaceName, "PPB_Flash_File_FileRef;2.0")) {
interfaceName = "PPB_Flash_File_FileRef;2";
} else if (!strcmp(interfaceName, "PPB_Flash_File_ModuleLocal;3.0")) {
interfaceName = "PPB_Flash_File_ModuleLocal;3";
}
return _real_PPB_GetInterface(interfaceName);
}
const void* GetInterfaceForRPC(const char* interfaceName) {
const void* interface = gInterfaces[interfaceName];
//printf("GetInterfaceForRPC %s\n", interfaceName);
if (!interface) {
printf("MISSING INTERFACE %s\n", interfaceName);
}
return interface;
}
void
Fail(const char *reason, const char *data)
{
fprintf(stdout, reason, data);
fflush(stdout);
exit(-1);
}
void Logging_PP_CompletionCallback(void* user_data, int32_t result)
{
PP_CompletionCallback* _real_PP_CompletionCallback = static_cast<PP_CompletionCallback*>(user_data);
printf("callFromJSON: > {\"__callback\":\"PP_CompletionCallback\",\"__callbackStruct\":{\"func\":%lu,\"user_data\":%lu,\"flags\":%i},\"result\":%i}\n",
uintptr_t(_real_PP_CompletionCallback->func), uintptr_t(_real_PP_CompletionCallback->user_data), _real_PP_CompletionCallback->flags, result);
_real_PP_CompletionCallback->func(_real_PP_CompletionCallback->user_data, result);
printf("callFromJSON: < {\"__callback\":\"PP_CompletionCallback\",\"__callbackStruct\":{\"func\":%lu,\"user_data\":%lu,\"flags\":%i},\"result\":%i}\n",
uintptr_t(_real_PP_CompletionCallback->func), uintptr_t(_real_PP_CompletionCallback->user_data), _real_PP_CompletionCallback->flags, result);
delete _real_PP_CompletionCallback;
}
void Logging_PPB_Audio_Callback_1_0(void* sample_buffer,
uint32_t buffer_size_in_bytes,
void* user_data)
{
Logging_PPB_Audio_Callback_1_0_holder* holder = static_cast<Logging_PPB_Audio_Callback_1_0_holder*>(user_data);
printf("callFromJSON: > {\"__callback\":\"PPB_Audio_Callback_1_0\",\"__callbackStruct\":{\"func\":%lu,\"sample_buffer\":%lu,\"buffer_size_in_bytes\":%i},\"user_data\":%lu}\n",
uintptr_t(holder->func), uintptr_t(sample_buffer), buffer_size_in_bytes, uintptr_t(holder->user_data));
holder->func(sample_buffer, buffer_size_in_bytes, holder->user_data);
printf("callFromJSON: < {\"__callback\":\"PPB_Audio_Callback_1_0\",\"__callbackStruct\":{\"func\":%lu,\"sample_buffer\":%lu,\"buffer_size_in_bytes\":%i},\"user_data\":%lu}\n",
uintptr_t(holder->func), uintptr_t(sample_buffer), buffer_size_in_bytes, uintptr_t(holder->user_data));
}
static void *_real_PepperFlash = nullptr;
typedef int32_t (*PPP_InitializeBroker_Func)(PP_ConnectInstance_Func* connect_instance_func);
typedef void (*PPP_ShutdownBroker_Func)(void);
static PP_InitializeModule_Func _real_PPP_InitializeModule;
static PP_GetInterface_Func _real_PPP_GetInterface;
static PPP_InitializeBroker_Func _real_PPP_InitializeBroker;
static PPP_ShutdownBroker_Func _real_PPP_ShutdownBroker;
static void
LoadRealPepperFlash()
{
if (!_real_PepperFlash) {
_real_PepperFlash = dlopen(REAL_PLUGIN_PATH, RTLD_LAZY);
_real_PPP_InitializeModule = (PP_InitializeModule_Func)dlsym(_real_PepperFlash, "PPP_InitializeModule");
_real_PPP_GetInterface = (PP_GetInterface_Func)dlsym(_real_PepperFlash, "PPP_GetInterface");
_real_PPP_InitializeBroker = (PPP_InitializeBroker_Func)dlsym(_real_PepperFlash, "PPP_InitializeBroker");
_real_PPP_ShutdownBroker = (PPP_ShutdownBroker_Func)dlsym(_real_PepperFlash, "PPP_ShutdownBroker");
InitializeInterfaceList();
}
}
struct Logging_PPP_Class_Deprecated_holder;
PP_Bool
Logging_HasProperty(const void* object,
PP_Var name,
PP_Var* exception)
{
uint32_t varNameLength;
const char* varName = ((PPB_Var_Deprecated_0_3*)RealGetInterface("PPB_Var(Deprecated);0.3"))->VarToUtf8(name, &varNameLength);
printf("Logging_HasProperty for ");
for (uint32_t i = 0; i < varNameLength; ++i) {
printf("%c", varName[i]);
}
printf("\n");
const Logging_PPP_Class_Deprecated_holder* holder = static_cast<const Logging_PPP_Class_Deprecated_holder*>(object);
PP_Bool result = holder->_real_PPP_Class_Deprecated->HasProperty(holder->object, name, exception);
printf("Logging_HasProperty for ");
for (uint32_t i = 0; i < varNameLength; ++i) {
printf("%c", varName[i]);
}
printf(" returns %s\n", result == PP_TRUE ? "true" : "false");
return result;
}
PP_Bool
Logging_HasMethod(const void* object,
PP_Var name,
PP_Var* exception)
{
uint32_t varNameLength;
const char* varName = ((PPB_Var_Deprecated_0_3*)RealGetInterface("PPB_Var(Deprecated);0.3"))->VarToUtf8(name, &varNameLength);
printf("Logging_HasMethod for ");
for (uint32_t i = 0; i < varNameLength; ++i) {
printf("%c", varName[i]);
}
printf("\n");
const Logging_PPP_Class_Deprecated_holder* holder = static_cast<const Logging_PPP_Class_Deprecated_holder*>(object);
PP_Bool result = holder->_real_PPP_Class_Deprecated->HasMethod(holder->object, name, exception);
printf("Logging_HasMethod for ");
for (uint32_t i = 0; i < varNameLength; ++i) {
printf("%c", varName[i]);
}
printf(" returns %s\n", result == PP_TRUE ? "true" : "false");
return result;
}
PP_Var
Logging_GetProperty(const void* object,
PP_Var name,
PP_Var* exception)
{
printf("Logging_GetProperty\n");
const Logging_PPP_Class_Deprecated_holder* holder = static_cast<const Logging_PPP_Class_Deprecated_holder*>(object);
return holder->_real_PPP_Class_Deprecated->GetProperty(holder->object, name, exception);
}
void
Logging_GetAllPropertyNames(const void* object,
uint32_t* property_count,
PP_Var** properties,
PP_Var* exception)
{
printf("Logging_GetAllPropertyNames\n");
const Logging_PPP_Class_Deprecated_holder* holder = static_cast<const Logging_PPP_Class_Deprecated_holder*>(object);
holder->_real_PPP_Class_Deprecated->GetAllPropertyNames(holder->object, property_count, properties, exception);
}
void
Logging_SetProperty(const void* object,
PP_Var name,
PP_Var value,
PP_Var* exception)
{
printf("Logging_SetProperty\n");
const Logging_PPP_Class_Deprecated_holder* holder = static_cast<const Logging_PPP_Class_Deprecated_holder*>(object);
holder->_real_PPP_Class_Deprecated->SetProperty(holder->object, name, value, exception);
}
void
Logging_RemoveProperty(const void* object,
PP_Var name,
PP_Var* exception)
{
printf("Logging_RemoveProperty\n");
const Logging_PPP_Class_Deprecated_holder* holder = static_cast<const Logging_PPP_Class_Deprecated_holder*>(object);
holder->_real_PPP_Class_Deprecated->RemoveProperty(holder->object, name, exception);
}
PP_Var
Logging_Call(const void* object,
PP_Var method_name,
uint32_t argc,
const PP_Var argv[],
PP_Var* exception)
{
printf("Logging_Call\n");
const Logging_PPP_Class_Deprecated_holder* holder = static_cast<const Logging_PPP_Class_Deprecated_holder*>(object);
return holder->_real_PPP_Class_Deprecated->Call(holder->object, method_name, argc, argv, exception);
}
PP_Var
Logging_Construct(const void* object,
uint32_t argc,
const PP_Var argv[],
PP_Var* exception)
{
printf("Logging_Construct\n");
const Logging_PPP_Class_Deprecated_holder* holder = static_cast<const Logging_PPP_Class_Deprecated_holder*>(object);
return holder->_real_PPP_Class_Deprecated->Construct(holder->object, argc, argv, exception);
}
void
Logging_Deallocate(const void* object)
{
printf("Logging_Deallocate\n");
const Logging_PPP_Class_Deprecated_holder* holder = static_cast<const Logging_PPP_Class_Deprecated_holder*>(object);
holder->_real_PPP_Class_Deprecated->Deallocate(holder->object);
delete holder;
}
const PPP_Class_Deprecated _interpose_PPP_Class_Deprecated_1_0 = {
Logging_HasProperty,
Logging_HasMethod,
Logging_GetProperty,
Logging_GetAllPropertyNames,
Logging_SetProperty,
Logging_RemoveProperty,
Logging_Call,
Logging_Construct,
Logging_Deallocate,
};
#ifdef __cplusplus
extern "C" {
#endif
static PP_Bool
Logging_HandleInputEvent(PP_Instance instance, PP_Resource input_event)
{
const PPP_InputEvent_0_1* _real_PPP_InputEvent = static_cast<const PPP_InputEvent_0_1*>(_real_PPP_GetInterface("PPP_InputEvent;0.1"));
printf("callFromJSON: > {\"__interface\":\"PPP_InputEvent;0.1\",\"__member\":\"HandleInputEvent\",\"instance\":%i,\"input_event\":%i}\n", instance, input_event);
PP_Bool result = _real_PPP_InputEvent->HandleInputEvent(instance, input_event);
printf("callFromJSON: < \"%s\"\n", ToString_PP_Bool(result).c_str());
return result;
}
static const PPP_InputEvent_0_1 _interpose_PPP_InputEvent_0_1 = {
Logging_HandleInputEvent
};
static PP_Bool
Logging_DidCreate(PP_Instance instance,
uint32_t argc,
const char* argn[],
const char* argv[])
{
const PPP_Instance_1_1* _real_PPP_Instance = static_cast<const PPP_Instance_1_1*>(_real_PPP_GetInterface("PPP_Instance;1.1"));
printf("callFromJSON: > {\"__interface\":\"PPP_Instance;1.1\",\"__member\":\"DidCreate\",\"instance\":%i,\"argc\":%i,\"argn\":[", instance, argc);
for (uint32_t i = 0; i < argc; ++i) {
if (i > 0) {
printf(",");
}
printf("\"%s\"", argn[i]);
}
printf("],\"argv\":[");
for (uint32_t i = 0; i < argc; ++i) {
if (i > 0) {
printf(",");
}
printf("\"%s\"", argv[i]);
}
printf("]}\n");
PP_Bool result = _real_PPP_Instance->DidCreate(instance, argc, argn, argv);
printf("callFromJSON: < \"%s\"\n", ToString_PP_Bool(result).c_str());
return result;
}
static void
Logging_DidDestroy(PP_Instance instance)
{
const PPP_Instance_1_1* _real_PPP_Instance = static_cast<const PPP_Instance_1_1*>(_real_PPP_GetInterface("PPP_Instance;1.1"));
printf("callFromJSON: > {\"__interface\":\"PPP_Instance;1.1\",\"__member\":\"DidDestroy\",\"instance\":%i}\n", instance);
_real_PPP_Instance->DidDestroy(instance);
}
static void
Logging_DidChangeView(PP_Instance instance, PP_Resource view)
{
const PPP_Instance_1_1* _real_PPP_Instance = static_cast<const PPP_Instance_1_1*>(_real_PPP_GetInterface("PPP_Instance;1.1"));
printf("callFromJSON: > {\"__interface\":\"PPP_Instance;1.1\",\"__member\":\"DidChangeView\",\"instance\":%i,\"view\":%i}\n", instance, view);
_real_PPP_Instance->DidChangeView(instance, view);
}
static void
Logging_DidChangeFocus(PP_Instance instance, PP_Bool has_focus)
{
const PPP_Instance_1_1* _real_PPP_Instance = static_cast<const PPP_Instance_1_1*>(_real_PPP_GetInterface("PPP_Instance;1.1"));
printf("callFromJSON: > {\"__interface\":\"PPP_Instance;1.1\",\"__member\":\"DidChangeFocus\",\"instance\":%i,\"has_focus\":%s}\n", instance, has_focus ? "PP_TRUE" : "PP_FALSE");
_real_PPP_Instance->DidChangeFocus(instance, has_focus);
}
static PP_Bool
Logging_HandleDocumentLoad(PP_Instance instance, PP_Resource url_loader)
{
const PPP_Instance_1_1* _real_PPP_Instance = static_cast<const PPP_Instance_1_1*>(_real_PPP_GetInterface("PPP_Instance;1.1"));
printf("callFromJSON: > {\"__interface\":\"PPP_Instance;1.1\",\"__member\":\"HandleDocumentLoad\",\"instance\":%i,\"url_loader\":%i}\n", instance, url_loader);
PP_Bool result = _real_PPP_Instance->HandleDocumentLoad(instance, url_loader);
printf("callFromJSON: < \"%s\"\n", ToString_PP_Bool(result).c_str());
return result;
}
static const PPP_Instance_1_1 _interpose_PPP_Instance_1_1 = {
Logging_DidCreate,
Logging_DidDestroy,
Logging_DidChangeView,
Logging_DidChangeFocus,
Logging_HandleDocumentLoad
};
const void *
PPP_GetInterface(const char *interface_name)
{
//printf("PPP_GetInterface %s\n", interface_name);
LoadRealPepperFlash();
if (!strcmp(interface_name, "PPP_InputEvent;0.1")) {
return &_interpose_PPP_InputEvent_0_1;
}
if (!strcmp(interface_name, "PPP_Instance;1.1")) {
return &_interpose_PPP_Instance_1_1;
}
return _real_PPP_GetInterface(interface_name);
}
int32_t
PPP_InitializeModule(PP_Module module, PPB_GetInterface get_browser_interface)
{
LoadRealPepperFlash();
_real_PPB_GetInterface = get_browser_interface;
return _real_PPP_InitializeModule(module, GetInterfaceForRPC);
}
int32_t
PPP_InitializeBroker(PP_ConnectInstance_Func *connect_instance_func)
{
return _real_PPP_InitializeBroker(connect_instance_func);
}
void
PPP_ShutdownBroker()
{
return _real_PPP_ShutdownBroker();
}
#ifdef __cplusplus
} /* extern "C" */
#endif

69
browser/extensions/mortar/host/pdf/bootstrap.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,69 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
Cu.import("resource://gre/modules/Services.jsm");
function sandboxScript(sandbox)
{
dump("sandboxScript " + sandbox.pluginElement + "\n");
Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader).loadSubScript("resource://ppapipdf.js/ppapi-content-sandbox.js", sandbox);
}
let plugins;
function startup(data) {
dump(">>>STARTED!!!\n");
let root = data.installPath.parent.parent;
let rpclib = root.clone();
let pluginlib = root.clone();
let os = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS;
if (os == "Darwin") {
rpclib.appendRelativePath("ppapi/out/rpc.dylib");
pluginlib.appendRelativePath("plugin/libpepperpdfium.dylib");
} else if (os == "Linux") {
rpclib.appendRelativePath("ppapi/out/rpc.so");
pluginlib.appendRelativePath("plugin/libpepperpdfium.so");
} else if (os == "WINNT") {
rpclib.appendRelativePath("ppapi\\out\\rpc.dll");
pluginlib.appendRelativePath("plugin\\pepperpdfium.dll");
} else {
throw("Don't know the path to the libraries for this OS!");
}
rpclib = rpclib.path;
pluginlib = pluginlib.path;
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
let plugin = pluginHost.registerFakePlugin({
handlerURI: "chrome://ppapipdf.js/content/viewer.html",
mimeEntries: [
{ type: "application/pdf", extension: "pdf" },
{ type: "application/vnd.adobe.pdf", extension: "pdf" },
{ type: "application/vnd.adobe.pdfxml", extension: "pdfxml" },
{ type: "application/vnd.adobe.x-mars", extension: "mars" },
{ type: "application/vnd.adobe.xdp+xml", extension: "xdp" },
{ type: "application/vnd.adobe.xfdf", extension: "xfdf" },
{ type: "application/vnd.adobe.xfd+xml", extension: "xfd" },
{ type: "application/vnd.fdf", extension: "fdf" },
],
name: "PPAPI PDF plugin",
niceName: "PPAPI PDF plugin",
version: "1.0",
sandboxScript : `(${sandboxScript.toSource()})(this);`,
ppapiProcessArgs: [ rpclib, pluginlib ],
});
plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
let rng = Cc["@mozilla.org/security/random-generator;1"].createInstance(Ci.nsIRandomGenerator);
Services.ppmm.addMessageListener("ppapi.js:generateRandomBytes", ({ data }) => {
return rng.generateRandomBytes(data);
});
dump("<<<STARTED!!!\n");
}
function shutdown() {
dump("SHUTDOWN!!!\n");
}

Просмотреть файл

@ -0,0 +1,3 @@
resource ppapipdf.js .
content ppapipdf.js chrome/
resource ppapi.js ../common/

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,239 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
class PolyfillDropdown {
constructor(select) {
this._select = select;
this._currentValue = select.value;
this._visible = false;
this._scrollbarWidth = 0;
this._options = [];
this._onChangedHandler = [];
this._polyfill = document.createElement('div');
this._polyfill.classList.add('polyfillDropdown');
this._polyfill.classList.add('hidden');
for (let elem of this._select.getElementsByTagName('option')) {
this._options.push(elem.value);
if (!elem.hidden) {
let option = document.createElement('div');
option.classList.add('polyfillOption');
option.tabIndex = -1;
option.dataset.value = elem.value;
document.l10n.setAttributes(option,
elem.dataset.l10nId, JSON.parse(elem.dataset.l10nArgs || '{}'));
option.addEventListener('click',
this._onOptionClicked.bind(this, elem.value));
this._polyfill.appendChild(option);
}
}
document.body.appendChild(this._polyfill);
let dropdownStyle = getComputedStyle(this._polyfill);
this._defaultDropdownBorderWidth =
parseInt(dropdownStyle.getPropertyValue('border-left-width'), 10) +
parseInt(dropdownStyle.getPropertyValue('border-right-width'), 10);
let optionStyle = getComputedStyle(this._polyfill.childNodes[0]);
this._defaultOptionPaddingRight =
parseInt(optionStyle.getPropertyValue('padding-right'), 10);
this._select.addEventListener('click', this);
this._select.addEventListener('change', this);
this._select.addEventListener('blur', this);
this._select.addEventListener('keydown', this);
}
get value() {
return this._select.value;
}
set value(value) {
this._currentValue = value;
this._select.value = value;
}
_show() {
if (this._visible) {
return;
}
this._visible = true;
this._updateOptionStatus();
this._polyfill.classList.remove('hidden');
this._resize();
window.addEventListener('resize', this);
}
_hide() {
if (!this._visible) {
return;
}
window.removeEventListener('resize', this);
this._polyfill.classList.add('hidden');
this._visible = false;
if (this._select.value !== this._currentValue) {
this._triggerChangeEvent();
}
}
_updateOptionStatus() {
let currentValue = this._select.value;
for (let elem of this._polyfill.childNodes) {
elem.classList.toggle('toggled', elem.dataset.value === currentValue);
};
}
_resize() {
let rect = this._select.getBoundingClientRect();
this._polyfill.style.left = rect.left + 'px';
this._polyfill.style.top = rect.bottom + 'px';
let scrollbarWidth = this._polyfill.offsetWidth -
this._polyfill.clientWidth - this._defaultDropdownBorderWidth;
if (scrollbarWidth != this._scrollbarWidth) {
this._scrollbarWidth = scrollbarWidth;
Array.from(this._polyfill.getElementsByClassName('polyfillOption'))
.forEach(option => {
if (scrollbarWidth > 0) {
option.style.paddingRight =
(scrollbarWidth + this._defaultOptionPaddingRight) + 'px';
} else {
option.style.paddingRight = '';
}
});
}
}
_onOptionClicked(value) {
this._select.value = value;
this._hide();
}
_triggerChangeEvent() {
this._currentValue = this._select.value;
let event = {
type: 'change',
target: this._select
};
this._onChangedHandler.forEach(handler => {
if (typeof handler === 'function') {
handler.call(this._select, event);
} else if (typeof handler === 'object' &&
typeof handler.handleEvent === 'function') {
handler.handleEvent(event);
}
});
}
addEventListener(type, listener, useCapture) {
if (type == 'change') {
this._onChangedHandler.push(listener);
} else {
this._select.addEventListener(type, listener, useCapture);
}
}
querySelectorAll(selectors) {
return this._select.querySelectorAll(selectors);
}
handleEvent(evt) {
let handled = false;
switch(evt.type) {
case 'click':
if (this._visible) {
this._hide();
} else {
this._show();
}
handled = true;
break;
case 'change':
if (this._visible) {
this._updateOptionStatus();
} else if (this._select.value !== this._currentValue) {
this._triggerChangeEvent();
}
break;
case 'blur':
setTimeout(() => {
if (!this._polyfill.contains(document.activeElement)) {
this._hide();
}
});
break;
case 'resize':
this._resize();
break;
case 'keydown':
let isMac = navigator.platform.startsWith('Mac');
if (this._visible) {
let index;
switch(evt.keyCode) {
case KeyEvent.DOM_VK_ESCAPE:
case KeyEvent.DOM_VK_RETURN:
this._hide();
handled = true;
break;
case KeyEvent.DOM_VK_DOWN:
if (isMac) {
index = this._options.indexOf(this._select.value);
if (index < this._options.length - 1) {
this._select.value = this._options[index + 1];
this._updateOptionStatus();
}
handled = true;
}
break;
case KeyEvent.DOM_VK_UP:
if (isMac) {
index = this._options.indexOf(this._select.value);
if (index > 0) {
this._select.value = this._options[index - 1];
this._updateOptionStatus();
}
handled = true;
}
break;
}
} else if (document.activeElement == this._select) {
switch(evt.keyCode) {
case KeyEvent.DOM_VK_SPACE:
this._show();
handled = true;
break;
case KeyEvent.DOM_VK_DOWN:
case KeyEvent.DOM_VK_UP:
if (isMac) {
this._show();
handled = true;
}
break;
}
}
break;
}
if (handled) {
evt.stopPropagation();
evt.preventDefault();
}
}
}

Просмотреть файл

@ -0,0 +1,279 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
class ProgressBar {
constructor() {
this._container = document.getElementById('loadingBar');
this._percentage = this._container.querySelector('.progress');
}
show() {
this._container.classList.remove('hidden');
}
hide(waitForTransition) {
let percentage = this._percentage;
let doHide = () => {
this._container.classList.add('hidden');
percentage.style.width = '';
};
if (!waitForTransition) {
doHide();
} else {
percentage.addEventListener('transitionend', function handler() {
percentage.removeEventListener('transitionend', handler);
doHide();
});
}
}
setProgress(progress) {
if (isNaN(progress) || progress < 0 || progress > 100) {
this._percentage.classList.add('indeterminate');
return;
}
this._percentage.classList.remove('indeterminate');
this._percentage.style.width = Math.round(progress) + '%';
}
}
class SecondaryToolbar {
constructor() {
this._container = document.getElementById('secondaryToolbar');
this._toggleButton = document.getElementById('secondaryToolbarToggle');
}
toggle() {
this._toggleButton.classList.toggle('toggled');
this._container.classList.toggle('hidden');
if (this._container.classList.contains('hidden')) {
window.removeEventListener('click', this);
} else {
window.addEventListener('click', this);
}
}
handleEvent(evt) {
// Hide the secondary toolbar automatically when a user is not clicking the
// toggle button. (The handler of the toggle button will take care of hiding
// it instead.)
if (evt.target != this._toggleButton) {
this.toggle();
}
}
}
class ScaleSelect {
constructor(viewport) {
this._viewport = viewport;
this._select = new PolyfillDropdown(document.getElementById('scaleSelect'));
this._select.addEventListener('change', this);
this._customScaleOption = document.getElementById('customScaleOption');
this._customScale = 0;
this._predefinedOption =
Array.from(this._select.querySelectorAll('option:not([hidden])'))
.map(elem => elem.value);
}
setScale(scale) {
if (this._predefinedOption.includes(String(scale))) {
this._customScale = 0;
this._select.value = scale;
} else if (!isNaN(scale)) {
let customScale = Math.round(scale * 10000) / 100;
if (customScale != this._customScale) {
this._customScale = customScale;
document.l10n.formatValue('page_scale_percent', {scale: customScale})
.then(result => {
this._select.value = '';
this._customScaleOption.textContent = result;
this._select.value = 'custom';
});
}
}
}
handleEvent(evt) {
switch(evt.type) {
case 'change':
let scale = this._select.value;
if (!isNaN(scale)) {
// "viewport.fitting" will be set to "none" automatically once
// assigning a new "zoom".
this._viewport.zoom = scale;
} else if (scale != 'custom') {
this._viewport.fitting = scale;
}
break;
}
}
}
class Toolbar {
constructor(viewport) {
let elements = [
'zoomIn', 'zoomOut', 'previous', 'next', 'pageNumber', 'numPages',
'firstPage', 'lastPage', 'pageRotateCw', 'pageRotateCcw'
];
this.ZOOM_FACTORS = [
0.25, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.1, 1.3, 1.5, 1.7, 1.9, 2.1,
2.4, 2.7, 3, 3.3, 3.7, 4.1, 4.6, 5.1, 5.7, 6.3, 7, 7.7, 8.5, 9.4, 10
];
this._viewport = viewport;
this._secondaryToolbar = new SecondaryToolbar();
this._loadingBar = new ProgressBar();
this._scaleSelect = new ScaleSelect(viewport);
this._elements = {};
elements.forEach(id => {
this._elements[id] = document.getElementById(id);
});
let toolbarButtons =
document.querySelectorAll('.toolbarButton, .secondaryToolbarButton');
for (let button of toolbarButtons) {
button.addEventListener('click', this);
}
this._elements.pageNumber.addEventListener('focus', this);
this._elements.pageNumber.addEventListener('change', this);
this._viewport.onDimensionChanged = this._updateDimensions.bind(this);
this._viewport.onProgressChanged = this._updateProgress.bind(this);
this._viewport.onZoomChanged = this._updateToolbar.bind(this);
this._viewport.onPageChanged = this._updateToolbar.bind(this);
this._updateToolbar();
}
_zoomIn() {
let zoom = this._viewport.zoom;
let newZoom = this.ZOOM_FACTORS.find(factor => (factor - zoom) > 0.049);
if (!newZoom) {
newZoom = this.ZOOM_FACTORS[this.ZOOM_FACTORS.length - 1];
}
this._viewport.zoom = newZoom;
}
_zoomOut() {
let reversedFactors = Array.from(this.ZOOM_FACTORS);
reversedFactors.reverse();
let zoom = this._viewport.zoom;
let newZoom = reversedFactors.find(factor => (zoom - factor) > 0.049);
if (!newZoom) {
newZoom = this.ZOOM_FACTORS[0];
}
this._viewport.zoom = newZoom;
}
_buttonClicked(id) {
switch(id) {
case 'firstPage':
this._viewport.page = 0;
break;
case 'lastPage':
this._viewport.page = this._viewport.pageCount - 1;
break;
case 'previous':
this._viewport.page--;
break;
case 'next':
this._viewport.page++;
break;
case 'zoomIn':
this._zoomIn();
break;
case 'zoomOut':
this._zoomOut();
break;
case 'pageRotateCw':
this._viewport.rotateClockwise();
break;
case 'pageRotateCcw':
this._viewport.rotateCounterClockwise();
break;
case 'secondaryToolbarToggle':
this._secondaryToolbar.toggle();
break;
}
}
_pageNumberChanged() {
let newPage = parseFloat(this._elements.pageNumber.value);
if (!Number.isInteger(newPage) ||
newPage < 1 || newPage > this._viewport.pageCount) {
this._elements.pageNumber.value = this._viewport.page + 1;
return;
}
this._elements.pageNumber.value = newPage;
this._viewport.page = newPage - 1;
}
_updateDimensions() {
let pageCount = this._viewport.pageCount;
document.l10n.formatValue('page_of', { pageCount })
.then(page_of => this._elements.numPages.textContent = page_of);
this._elements.pageNumber.max = pageCount;
this._updateToolbar();
}
_updateToolbar() {
let page = this._viewport.page + 1;
let pageCount = this._viewport.pageCount;
this._elements.pageNumber.disabled =
this._elements.pageRotateCw.disabled =
this._elements.pageRotateCcw.disabled = (pageCount == 0);
this._elements.pageNumber.value = pageCount ? page : '';
this._elements.previous.disabled =
this._elements.firstPage.disabled = (!pageCount || page == 1);
this._elements.next.disabled =
this._elements.lastPage.disabled = (!pageCount || page == pageCount);
let zoom = this._viewport.zoom;
this._elements.zoomIn.disabled =
(zoom >= this.ZOOM_FACTORS[this.ZOOM_FACTORS.length - 1]);
this._elements.zoomOut.disabled = (zoom <= this.ZOOM_FACTORS[0]);
let fitting = this._viewport.fitting;
this._scaleSelect.setScale(fitting == 'none' ? zoom : fitting);
}
_updateProgress(progress) {
this._loadingBar.show();
this._loadingBar.setProgress(progress);
if (progress == 100) {
this._loadingBar.hide(true);
}
}
handleEvent(evt) {
let target = evt.target;
switch(evt.type) {
case 'change':
if (target === this._elements.pageNumber) {
this._pageNumberChanged();
}
break;
case 'focus':
if (target === this._elements.pageNumber) {
target.select();
}
break;
case 'click':
this._buttonClicked(target.id);
break;
}
}
}

Просмотреть файл

@ -0,0 +1,27 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
window.addEventListener('DOMContentLoaded', function() {
let viewport = new Viewport();
let toolbar = new Toolbar(viewport);
// Expose the custom viewport object to runtime
window.createCustomViewport = function(actionHandler) {
viewport.registerActionHandler(actionHandler);
return {
addView: viewport.addView.bind(viewport),
clearView: viewport.clearView.bind(viewport),
getBoundingClientRect: viewport.getBoundingClientRect.bind(viewport),
is: viewport.is.bind(viewport),
bindUIEvent: viewport.bindUIEvent.bind(viewport),
unbindUIEvent: viewport.unbindUIEvent.bind(viewport),
setCursor: viewport.setCursor.bind(viewport),
getScrollOffset: viewport.getScrollOffset.bind(viewport),
notify: viewport.notify.bind(viewport)
};
};
});

Просмотреть файл

@ -0,0 +1,501 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
class Viewport {
constructor() {
this._canvasContainer = document.getElementById('canvasContainer');
this._viewportController = document.getElementById('viewportController');
this._sizer = document.getElementById('sizer');
this._scrollbarWidth = this._getScrollbarWidth();
this._hasVisibleScrollbars = {
horizontal: false,
vertical: false
};
this._page = 0;
this._zoom = 1;
this._fitting = 'auto';
// Caches the next position set during a series of actions and will be set
// to scrollbar's position until calling "_refresh".
this._nextPosition = null;
// Indicates the last position that runtime knows. Will update runtime only
// if "scroll" event gives us a different value.
this._runtimePosition = this.getScrollOffset();
// Similar to above. Will notify runtime only if "_notifyRuntimeOfResized()"
// gets a different value.
this._runtimeSize = this.getBoundingClientRect();
this._runtimeOnResizedListener = [];
this.onProgressChanged = null;
this.onZoomChanged = null;
this.onDimensionChanged = null;
this.onPageChanged = null;
this._viewportController.addEventListener('scroll', this);
window.addEventListener('resize', this);
}
get zoom() {
return this._zoom;
}
set zoom(newZoom) {
newZoom = parseFloat(newZoom);
if (!isNaN(newZoom) &&
(newZoom != this._zoom || this._fitting != 'none')) {
this._fitting = 'none';
this._setZoom(newZoom);
this._refresh();
}
}
get fitting() {
return this._fitting;
}
set fitting(newFitting) {
let VALID_VALUE = ['none', 'auto', 'page-actual', 'page-width', 'page-fit'];
if (!VALID_VALUE.includes(newFitting)) {
return;
}
if (newFitting != this._fitting) {
this._fitting = newFitting;
this._setZoom(this._computeFittingZoom());
this._refresh();
}
}
get pageCount() {
if (!this._pageDimensions) {
return 0;
}
return this._pageDimensions.length;
}
get page() {
return this._page;
}
set page(newPage) {
newPage = parseFloat(newPage);
let pageCount = this.pageCount;
if (!pageCount || !Number.isInteger(newPage)) {
return;
}
newPage = Math.max(0, Math.min(pageCount - 1, newPage));
this._setPage(newPage);
this._refresh();
}
_getScrollbarWidth() {
var div = document.createElement('div');
div.style.visibility = 'hidden';
div.style.overflow = 'scroll';
div.style.width = '50px';
div.style.height = '50px';
div.style.position = 'absolute';
document.body.appendChild(div);
var result = div.offsetWidth - div.clientWidth;
div.remove();
return result;
}
_documentHasVisibleScrollbars(zoom) {
let zoomedDimensions = this._getZoomedDocumentDimensions(zoom);
if (!zoomedDimensions || !this._scrollbarWidth) {
return {
horizontal: false,
vertical: false
};
}
let outerRect = this._viewportController.getBoundingClientRect();
if (zoomedDimensions.width > outerRect.width) {
zoomedDimensions.height += this._scrollbarWidth;
} else if (zoomedDimensions.height > outerRect.height) {
zoomedDimensions.width += this._scrollbarWidth;
}
return {
horizontal: zoomedDimensions.width > outerRect.width,
vertical: zoomedDimensions.height > outerRect.height
};
}
_updateProgress(progress) {
if (typeof this.onProgressChanged === 'function') {
this.onProgressChanged(progress);
}
}
_setDocumentDimensions(documentDimensions) {
this._documentDimensions = documentDimensions;
this._pageDimensions = documentDimensions.pageDimensions;
this._setZoom(this._computeFittingZoom());
this._setPage(this._page);
if (typeof this.onDimensionChanged === 'function') {
this.onDimensionChanged();
}
this._refresh();
}
_computeFittingZoom() {
let newZoom = this._zoom;
let fitting = this._fitting;
if (fitting == 'none') {
return newZoom;
}
let FITTING_PADDING = 40;
let MAX_AUTO_ZOOM = 1.25;
let page = this._pageDimensions[this._page];
let viewportRect = this.getBoundingClientRect();
let pageWidthZoom = (viewportRect.width - FITTING_PADDING) / page.width;
let pageHeightZoom = viewportRect.height / page.height;
switch (fitting) {
case 'auto':
let isLandscape = (page.width > page.height);
// For pages in landscape mode, fit the page height to the viewer
// *unless* the page would thus become too wide to fit horizontally.
let horizontalZoom = isLandscape ?
Math.min(pageWidthZoom, pageHeightZoom) : pageWidthZoom;
newZoom = Math.min(MAX_AUTO_ZOOM, horizontalZoom);
break;
case 'page-actual':
newZoom = 1;
break;
case 'page-width':
newZoom = pageWidthZoom;
break;
case 'page-fit':
newZoom = Math.min(pageWidthZoom, pageHeightZoom);
break;
}
return newZoom;
}
_getMostVisiblePage() {
let firstVisiblePage = 0;
let pageCount = this.pageCount;
if (!pageCount) {
return firstVisiblePage;
}
let position = this.getScrollOffset();
let min = 0;
let max = pageCount - 1;
let y = position.y / this._zoom;
while (max >= min) {
let page = Math.floor(min + ((max - min) / 2));
// There might be a gap between the pages, in which case use the bottom
// of the previous page as the top for finding the page.
let top = 0;
if (page > 0) {
top = this._pageDimensions[page - 1].y +
this._pageDimensions[page - 1].height;
}
let bottom = this._pageDimensions[page].y +
this._pageDimensions[page].height;
if (top <= y && bottom > y) {
firstVisiblePage = page;
break;
} else if (top > y) {
max = page - 1;
} else {
min = page + 1;
}
}
if (firstVisiblePage == pageCount - 1) {
return firstVisiblePage;
}
let rect = this.getBoundingClientRect();
let viewportRect = {
x: position.x / this._zoom,
y: position.y / this._zoom,
width: rect.width / this._zoom,
height: rect.height / this._zoom
};
let getVisibleHeightRatio = rect => {
let intersectionHeight =
Math.min(rect.y + rect.height, viewportRect.y + viewportRect.height) -
Math.max(rect.y, viewportRect.y);
return Math.max(0, intersectionHeight) / rect.height;
};
let firstVisiblePageVisibility =
getVisibleHeightRatio(this._pageDimensions[firstVisiblePage]);
let nextPageVisibility =
getVisibleHeightRatio(this._pageDimensions[firstVisiblePage + 1]);
if (nextPageVisibility > firstVisiblePageVisibility) {
return firstVisiblePage + 1;
}
return firstVisiblePage;
}
_getZoomedDocumentDimensions(zoom) {
if (!this._documentDimensions) {
return null;
}
return {
width: Math.round(this._documentDimensions.width * zoom),
height: Math.round(this._documentDimensions.height * zoom)
};
}
_setPosition(x, y) {
this._nextPosition = {x, y};
}
_setZoom(newZoom) {
let currentPos = this._nextPosition || this.getScrollOffset();
currentPos.x /= this._zoom;
currentPos.y /= this._zoom;
this._zoom = newZoom;
this._contentSizeChanged();
this._setPosition(
currentPos.x * newZoom,
currentPos.y * newZoom
);
if (typeof this.onZoomChanged === 'function') {
this.onZoomChanged(this._zoom);
}
}
_setPage(newPage) {
if (newPage < 0 || newPage >= this.pageCount) {
return;
}
this._setPosition(
this._pageDimensions[newPage].x * this._zoom,
this._pageDimensions[newPage].y * this._zoom
);
}
_updateCanvasSize() {
let hasScrollbars = this._documentHasVisibleScrollbars(this._zoom);
if (hasScrollbars.horizontal == this._hasVisibleScrollbars.horizontal &&
hasScrollbars.vertical == this._hasVisibleScrollbars.vertical) {
return;
}
this._hasVisibleScrollbars = hasScrollbars;
this._canvasContainer.style.bottom =
hasScrollbars.horizontal ? this._scrollbarWidth + 'px' : 0;
this._canvasContainer.style.right =
hasScrollbars.vertical ? this._scrollbarWidth + 'px' : 0;
this._notifyRuntimeOfResized();
}
_contentSizeChanged() {
let zoomedDimensions = this._getZoomedDocumentDimensions(this._zoom);
if (zoomedDimensions) {
this._sizer.style.width = zoomedDimensions.width + 'px';
this._sizer.style.height = zoomedDimensions.height + 'px';
this._updateCanvasSize();
}
}
_resize() {
let newZoom = this._computeFittingZoom();
if (newZoom != this._zoom) {
this._setZoom(newZoom);
} else {
this._updateCanvasSize();
}
}
_notifyRuntimeOfResized() {
let rect = this.getBoundingClientRect();
if (rect.width == this._runtimeSize.width &&
rect.height == this._runtimeSize.height) {
return;
}
this._runtimeSize = rect;
this._runtimeOnResizedListener.forEach(listener => {
let evt = {
type: 'resize',
target: this._viewportController
};
if (typeof listener === 'function') {
listener(evt);
} else if (typeof listener.handleEvent === 'function') {
listener.handleEvent(evt);
}
});
}
_getEventTarget(type) {
switch(type) {
case 'keydown':
case 'keyup':
case 'keypress':
return window;
}
return this._viewportController;
}
_doAction(message) {
if (this._actionHandler) {
this._actionHandler(message);
}
}
_refresh() {
if (this._nextPosition) {
this._viewportController.scrollTo(
this._nextPosition.x, this._nextPosition.y);
this._nextPosition = null;
}
this._runtimePosition = this.getScrollOffset();
this._doAction({
type: 'viewport',
xOffset: this._runtimePosition.x,
yOffset: this._runtimePosition.y,
zoom: this._zoom
});
let newPage = this._getMostVisiblePage();
if (newPage != this._page) {
this._page = newPage;
if (typeof this.onPageChanged === 'function') {
this.onPageChanged(newPage);
}
}
}
handleEvent(evt) {
switch(evt.type) {
case 'resize':
this._resize();
this._notifyRuntimeOfResized();
this._refresh();
break;
case 'scroll':
this._nextPosition = null;
let position = this.getScrollOffset();
if (this._runtimePosition.x != position.x ||
this._runtimePosition.y != position.y) {
this._refresh();
}
break;
}
}
rotateClockwise() {
this._doAction({
type: 'rotateClockwise'
});
}
rotateCounterClockwise() {
this._doAction({
type: 'rotateCounterclockwise'
});
}
// A handler for delivering messages to runtime.
registerActionHandler(handler) {
if (typeof handler === 'function') {
this._actionHandler = handler;
}
}
/***************************/
/* PPAPIViewport Interface */
/***************************/
addView(canvas) {
this._canvasContainer.appendChild(canvas);
}
clearView() {
this._canvasContainer.innerHTML = '';
}
getBoundingClientRect() {
return this._canvasContainer.getBoundingClientRect();
}
is(element) {
return element == this._viewportController;
}
bindUIEvent(type, listener) {
if (type == 'fullscreenchange' || type == 'MozScrolledAreaChanged') {
// These two events won't be bound on a target because they should be
// fully controlled by UI layer, and we'll manually trigger the resize
// event once needed.
return;
}
switch(type) {
case 'resize':
this._runtimeOnResizedListener.push(listener);
break;
default:
this._getEventTarget(type).addEventListener(type, listener);
}
}
unbindUIEvent(type, listener) {
if (type == 'fullscreenchange' || type == 'MozScrolledAreaChanged') {
return;
}
switch(type) {
case 'resize':
this._runtimeOnResizedListener =
this._runtimeOnResizedListener.filter(item => item != listener);
break;
default:
this._getEventTarget(type).removeEventListener(type, listener);
}
}
setCursor(cursor) {
this._viewportController.style.cursor = cursor;
}
getScrollOffset() {
return {
x: this._viewportController.scrollLeft,
y: this._viewportController.scrollTop
};
}
// Notified by runtime.
notify(message) {
switch (message.type) {
case 'loadProgress':
this._updateProgress(message.progress);
break;
case 'documentDimensions':
this._setDocumentDimensions(message);
break;
}
}
}

Просмотреть файл

@ -0,0 +1,173 @@
# Copyright 2012 Mozilla Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Main toolbar buttons (tooltips and alt text for images)
previous.title=Previous Page
previous_label=Previous
next.title=Next Page
next_label=Next
# LOCALIZATION NOTE (page_label, page_of):
# These strings are concatenated to form the "Page: X of Y" string.
# Do not translate "{{pageCount}}", it will be substituted with a number
# representing the total number of pages.
page_label=Page:
page_of=of {{pageCount}}
zoom_out.title=Zoom Out
zoom_out_label=Zoom Out
zoom_in.title=Zoom In
zoom_in_label=Zoom In
zoom.title=Zoom
presentation_mode.title=Switch to Presentation Mode
presentation_mode_label=Presentation Mode
open_file.title=Open File
open_file_label=Open
print.title=Print
print_label=Print
download.title=Download
download_label=Download
bookmark.title=Current view (copy or open in new window)
bookmark_label=Current View
# Secondary toolbar and context menu
tools.title=Tools
tools_label=Tools
first_page.title=Go to First Page
first_page.label=Go to First Page
first_page_label=Go to First Page
last_page.title=Go to Last Page
last_page.label=Go to Last Page
last_page_label=Go to Last Page
page_rotate_cw.title=Rotate Clockwise
page_rotate_cw.label=Rotate Clockwise
page_rotate_cw_label=Rotate Clockwise
page_rotate_ccw.title=Rotate Counterclockwise
page_rotate_ccw.label=Rotate Counterclockwise
page_rotate_ccw_label=Rotate Counterclockwise
hand_tool_enable.title=Enable hand tool
hand_tool_enable_label=Enable hand tool
hand_tool_disable.title=Disable hand tool
hand_tool_disable_label=Disable hand tool
# Document properties dialog box
document_properties.title=Document Properties…
document_properties_label=Document Properties…
document_properties_file_name=File name:
document_properties_file_size=File size:
# LOCALIZATION NOTE (document_properties_kb): "{{size_kb}}" and "{{size_b}}"
# will be replaced by the PDF file size in kilobytes, respectively in bytes.
document_properties_kb={{size_kb}} KB ({{size_b}} bytes)
# LOCALIZATION NOTE (document_properties_mb): "{{size_mb}}" and "{{size_b}}"
# will be replaced by the PDF file size in megabytes, respectively in bytes.
document_properties_mb={{size_mb}} MB ({{size_b}} bytes)
document_properties_title=Title:
document_properties_author=Author:
document_properties_subject=Subject:
document_properties_keywords=Keywords:
document_properties_creation_date=Creation Date:
document_properties_modification_date=Modification Date:
# LOCALIZATION NOTE (document_properties_date_string): "{{date}}" and "{{time}}"
# will be replaced by the creation/modification date, and time, of the PDF file.
document_properties_date_string={{date}}, {{time}}
document_properties_creator=Creator:
document_properties_producer=PDF Producer:
document_properties_version=PDF Version:
document_properties_page_count=Page Count:
document_properties_close=Close
# Tooltips and alt text for side panel toolbar buttons
# (the _label strings are alt text for the buttons, the .title strings are
# tooltips)
toggle_sidebar.title=Toggle Sidebar
toggle_sidebar_label=Toggle Sidebar
outline.title=Show Document Outline
outline_label=Document Outline
attachments.title=Show Attachments
attachments_label=Attachments
thumbs.title=Show Thumbnails
thumbs_label=Thumbnails
findbar.title=Find in Document
findbar_label=Find
# Thumbnails panel item (tooltip and alt text for images)
# LOCALIZATION NOTE (thumb_page_title): "{{page}}" will be replaced by the page
# number.
thumb_page_title=Page {{page}}
# LOCALIZATION NOTE (thumb_page_canvas): "{{page}}" will be replaced by the page
# number.
thumb_page_canvas=Thumbnail of Page {{page}}
# Find panel button title and messages
find_label=Find:
find_previous.title=Find the previous occurrence of the phrase
find_previous_label=Previous
find_next.title=Find the next occurrence of the phrase
find_next_label=Next
find_highlight=Highlight all
find_match_case_label=Match case
find_reached_top=Reached top of document, continued from bottom
find_reached_bottom=Reached end of document, continued from top
find_not_found=Phrase not found
# Error panel labels
error_more_info=More Information
error_less_info=Less Information
error_close=Close
# LOCALIZATION NOTE (error_version_info): "{{version}}" and "{{build}}" will be
# replaced by the PDF.JS version and build ID.
error_version_info=PDF.js v{{version}} (build: {{build}})
# LOCALIZATION NOTE (error_message): "{{message}}" will be replaced by an
# english string describing the error.
error_message=Message: {{message}}
# LOCALIZATION NOTE (error_stack): "{{stack}}" will be replaced with a stack
# trace.
error_stack=Stack: {{stack}}
# LOCALIZATION NOTE (error_file): "{{file}}" will be replaced with a filename
error_file=File: {{file}}
# LOCALIZATION NOTE (error_line): "{{line}}" will be replaced with a line number
error_line=Line: {{line}}
rendering_error=An error occurred while rendering the page.
# Predefined zoom values
page_scale_width=Page Width
page_scale_fit=Page Fit
page_scale_auto=Automatic Zoom
page_scale_actual=Actual Size
# LOCALIZATION NOTE (page_scale_percent): "{{scale}}" will be replaced by a
# numerical scale value.
page_scale_percent={{scale}}%
# Loading indicator messages
loading_error_indicator=Error
loading_error=An error occurred while loading the PDF.
invalid_file_error=Invalid or corrupted PDF file.
missing_file_error=Missing PDF file.
unexpected_response_error=Unexpected server response.
# LOCALIZATION NOTE (text_annotation_type.alt): This is used as a tooltip.
# "{{type}}" will be replaced with an annotation type from a list defined in
# the PDF spec (32000-1:2008 Table 169 – Annotation types).
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
text_annotation_type.alt=[{{type}} Annotation]
password_label=Enter the password to open this PDF file.
password_invalid=Invalid password. Please try again.
password_ok=OK
password_cancel=Cancel
printing_not_supported=Warning: Printing is not fully supported by this browser.
printing_not_ready=Warning: The PDF is not fully loaded for printing.
web_fonts_disabled=Web fonts are disabled: unable to use embedded PDF fonts.
document_colors_not_allowed=PDF documents are not allowed to use their own colors: 'Allow pages to choose their own colors' is deactivated in the browser.

Просмотреть файл

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns="http://www.w3.org/2000/svg"
width="40"
height="40"
viewBox="0 0 40 40">
<path
d="M 1.5006714,23.536225 6.8925879,18.994244 14.585721,26.037937 34.019683,4.5410479 38.499329,9.2235032 14.585721,35.458952 z"
id="path4"
style="fill:#ffff00;fill-opacity:1;stroke:#000000;stroke-width:1.25402856;stroke-opacity:1" />
</svg>

После

Ширина:  |  Высота:  |  Размер: 415 B

Просмотреть файл

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns="http://www.w3.org/2000/svg"
height="40"
width="40"
viewBox="0 0 40 40">
<rect
style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
width="33.76017"
height="33.76017"
x="3.119915"
y="3.119915" />
<path
d="m 20.677967,8.54499 c -7.342801,0 -13.295293,4.954293 -13.295293,11.065751 0,2.088793 0.3647173,3.484376 1.575539,5.150563 L 6.0267418,31.45501 13.560595,29.011117 c 2.221262,1.387962 4.125932,1.665377 7.117372,1.665377 7.3428,0 13.295291,-4.954295 13.295291,-11.065753 0,-6.111458 -5.952491,-11.065751 -13.295291,-11.065751 z"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.93031836;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 883 B

Просмотреть файл

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns="http://www.w3.org/2000/svg"
width="40"
height="40"
viewBox="0 0 40 40">
<g
transform="translate(0,-60)"
id="layer1">
<rect
width="36.460953"
height="34.805603"
x="1.7695236"
y="62.597198"
style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.30826771;stroke-opacity:1" />
<g
transform="matrix(0.88763677,0,0,0.88763677,2.2472646,8.9890584)">
<path
d="M 20,64.526342 C 11.454135,64.526342 4.5263421,71.454135 4.5263421,80 4.5263421,88.545865 11.454135,95.473658 20,95.473658 28.545865,95.473658 35.473658,88.545865 35.473658,80 35.473658,71.454135 28.545865,64.526342 20,64.526342 z m -0.408738,9.488564 c 3.527079,0 6.393832,2.84061 6.393832,6.335441 0,3.494831 -2.866753,6.335441 -6.393832,6.335441 -3.527079,0 -6.393832,-2.84061 -6.393832,-6.335441 0,-3.494831 2.866753,-6.335441 6.393832,-6.335441 z"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.02768445;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
d="m 7.2335209,71.819938 4.9702591,4.161823 c -1.679956,2.581606 -1.443939,6.069592 0.159325,8.677725 l -5.1263071,3.424463 c 0.67516,1.231452 3.0166401,3.547686 4.2331971,4.194757 l 3.907728,-4.567277 c 2.541952,1.45975 5.730694,1.392161 8.438683,-0.12614 l 3.469517,6.108336 c 1.129779,-0.44367 4.742234,-3.449633 5.416358,-5.003859 l -5.46204,-4.415541 c 1.44319,-2.424098 1.651175,-5.267515 0.557303,-7.748623 l 5.903195,-3.833951 C 33.14257,71.704996 30.616217,69.018606 29.02952,67.99296 l -4.118813,4.981678 C 22.411934,71.205099 18.900853,70.937534 16.041319,72.32916 l -3.595408,-5.322091 c -1.345962,0.579488 -4.1293881,2.921233 -5.2123901,4.812869 z m 8.1010311,3.426672 c 2.75284,-2.446266 6.769149,-2.144694 9.048998,0.420874 2.279848,2.56557 2.113919,6.596919 -0.638924,9.043185 -2.752841,2.446267 -6.775754,2.13726 -9.055604,-0.428308 -2.279851,-2.565568 -2.107313,-6.589485 0.64553,-9.035751 z"
style="fill:#000000;fill-opacity:1;stroke:none" />
</g>
</g>
</svg>

После

Ширина:  |  Высота:  |  Размер: 2.1 KiB

Просмотреть файл

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns="http://www.w3.org/2000/svg"
width="64"
height="64"
viewBox="0 0 64 64">
<path
d="M 32.003143,1.4044602 57.432701,62.632577 6.5672991,62.627924 z"
style="fill:#ffff00;fill-opacity:0.94117647;fill-rule:nonzero;stroke:#000000;stroke-width:1.00493038;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
</svg>

После

Ширина:  |  Высота:  |  Размер: 408 B

Просмотреть файл

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns="http://www.w3.org/2000/svg"
width="64"
height="64"
viewBox="0 0 64 64">
<path
d="M 25.470843,9.4933766 C 25.30219,12.141818 30.139101,14.445969 34.704831,13.529144 40.62635,12.541995 41.398833,7.3856498 35.97505,5.777863 31.400921,4.1549155 25.157674,6.5445892 25.470843,9.4933766 z M 4.5246282,17.652051 C 4.068249,11.832873 9.2742983,5.9270407 18.437379,3.0977088 29.751911,-0.87185184 45.495663,1.4008022 53.603953,7.1104009 c 9.275765,6.1889221 7.158128,16.2079421 -3.171076,21.5939521 -1.784316,1.635815 -6.380222,1.21421 -7.068351,3.186186 -1.04003,0.972427 -1.288046,2.050158 -1.232864,3.168203 1.015111,2.000108 -3.831548,1.633216 -3.270553,3.759574 0.589477,5.264544 -0.179276,10.53738 -0.362842,15.806257 -0.492006,2.184998 1.163456,4.574232 -0.734888,6.610642 -2.482919,2.325184 -7.30604,2.189143 -9.193497,-0.274767 -2.733688,-1.740626 -8.254447,-3.615254 -6.104247,-6.339626 3.468112,-1.708686 -2.116197,-3.449897 0.431242,-5.080274 5.058402,-1.39256 -2.393215,-2.304318 -0.146889,-4.334645 3.069198,-0.977415 2.056986,-2.518352 -0.219121,-3.540397 1.876567,-1.807151 1.484149,-4.868919 -2.565455,-5.942205 0.150866,-1.805474 2.905737,-4.136876 -1.679967,-5.20493 C 10.260902,27.882167 4.6872697,22.95045 4.5245945,17.652051 z"
id="path604"
style="fill:#ffff00;fill-opacity:1;stroke:#000000;stroke-width:1.72665179;stroke-opacity:1" />
</svg>

После

Ширина:  |  Высота:  |  Размер: 1.4 KiB

Просмотреть файл

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns="http://www.w3.org/2000/svg"
width="64"
height="64"
viewBox="0 0 64 64">
<path
d="M 32.003143,10.913072 57.432701,53.086929 6.567299,53.083723 z"
id="path2985"
style="fill:#ffff00;fill-opacity:0.94117647;fill-rule:nonzero;stroke:#000000;stroke-width:0.83403099;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
</svg>

После

Ширина:  |  Высота:  |  Размер: 426 B

Просмотреть файл

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns="http://www.w3.org/2000/svg"
width="40"
height="40"
viewBox="0 0 40 40">
</svg>

После

Ширина:  |  Высота:  |  Размер: 158 B

Просмотреть файл

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns="http://www.w3.org/2000/svg"
width="40"
height="40"
viewBox="0 0 40 40">
<rect
width="36.075428"
height="31.096582"
x="1.962286"
y="4.4517088"
id="rect4"
style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.23004246;stroke-opacity:1" />
<rect
width="27.96859"
height="1.5012145"
x="6.0157046"
y="10.285"
id="rect6"
style="fill:#000000;fill-opacity:1;stroke:none" />
<rect
width="27.96859"
height="0.85783684"
x="6.0157056"
y="23.21689"
id="rect8"
style="fill:#000000;fill-opacity:1;stroke:none" />
<rect
width="27.96859"
height="0.85783684"
x="5.8130345"
y="28.964394"
id="rect10"
style="fill:#000000;fill-opacity:1;stroke:none" />
<rect
width="27.96859"
height="0.85783684"
x="6.0157046"
y="17.426493"
id="rect12"
style="fill:#000000;fill-opacity:1;stroke:none" />
</svg>

После

Ширина:  |  Высота:  |  Размер: 1.0 KiB

Просмотреть файл

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns="http://www.w3.org/2000/svg"
width="40"
height="40"
viewBox="0 0 40 40">
<rect
width="33.76017"
height="33.76017"
x="3.119915"
y="3.119915"
style="fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
d="m 17.692678,34.50206 0,-16.182224 c -1.930515,-0.103225 -3.455824,-0.730383 -4.57593,-1.881473 -1.12011,-1.151067 -1.680164,-2.619596 -1.680164,-4.405591 0,-1.992435 0.621995,-3.5796849 1.865988,-4.7617553 1.243989,-1.1820288 3.06352,-1.7730536 5.458598,-1.7730764 l 9.802246,0 0,2.6789711 -2.229895,0 0,26.3251486 -2.632515,0 0,-26.3251486 -3.45324,0 0,26.3251486 z"
style="font-size:29.42051125px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.07795751;stroke-opacity:1;font-family:Arial;-inkscape-font-specification:Arial" />
</svg>

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 199 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 304 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 193 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 296 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 193 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 296 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 199 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 304 B

Двоичные данные
browser/extensions/mortar/host/pdf/chrome/style/images/grab.cur Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 326 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 326 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.5 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.2 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 16 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 403 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 933 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 179 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 266 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 301 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 583 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 175 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 276 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 360 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 731 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 359 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 714 B

Двоичные данные
browser/extensions/mortar/host/pdf/chrome/style/images/shadow.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 290 B

Двоичные данные
browser/extensions/mortar/host/pdf/chrome/style/images/texture.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 174 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 260 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 259 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 425 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 107 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 152 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 295 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 550 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 242 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 398 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 238 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 396 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 245 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 405 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 246 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 403 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 321 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 586 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 257 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 464 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 309 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 653 B

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше