Skip to content

Commit

Permalink
[TIMOB-23185] TiAPI: Remove Ti.include and advertise workaround (#8569)
Browse files Browse the repository at this point in the history
  • Loading branch information
sgtcoolguy committed Oct 31, 2016
1 parent 0924040 commit b9af005
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 276 deletions.
108 changes: 0 additions & 108 deletions android/runtime/common/src/js/titanium.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,28 +51,6 @@ function TitaniumWrapper(context) {

// The "context" specific global object
this.global = context.global;
var self = this;

// Special version of include to handle relative paths based on sourceUrl.
this.include = function() {
var baseUrl, scopeVars;
var fileCount = arguments.length;
var info = arguments[fileCount - 1];

if (info instanceof Array) {
fileCount--;
baseUrl = info[0];
scopeVars = info[1];
} else {
baseUrl = sourceUrl;
scopeVars = context || {};
}

scopeVars.global = self.global;
for (var i = 0; i < fileCount; i++) {
TiInclude(arguments[i], baseUrl, scopeVars);
}
}

this.Android = new AndroidWrapper(context);
this.UI = new UIWrapper(context, this.Android);
Expand Down Expand Up @@ -118,31 +96,6 @@ AndroidWrapper.prototype = Titanium.Android;

// -----------------------------------------------------------------------

function createSandbox(ti, sourceUrl) {
var newSandbox = { Ti: ti, Titanium: ti };

// The require function we want to wrap for this context
var contextRequire = global.require;
if (ti.global) {
contextRequire = ti.global.require;
}

// Wrap require in Ti.include contexts so the relative sourceUrl is correct
newSandbox.require = function(path, context) {
if (context === undefined) {
context = {};
}

if (!context.sourceUrl) {
context.sourceUrl = sourceUrl;
}

return contextRequire(path, context, sourceUrl);
}

return newSandbox;
}

// Initializes a ScopeVars object with a
// passed in sourceURL (resolved from url.resolve)
function initScopeVars(scopeVars, sourceUrl) {
Expand All @@ -152,67 +105,6 @@ function initScopeVars(scopeVars, sourceUrl) {
}
Titanium.initScopeVars = initScopeVars;

// Gets the source string for a specified URL / filename combo
function getUrlSource(filename, sourceUrl) {
var source;

// Load the source code for the script.
if (!('protocol' in sourceUrl)) {
source = assets.readAsset(filename);
} else if (sourceUrl.filePath) {
var filepath = url.toFilePath(sourceUrl);
source = assets.readFile(filepath);
} else if (sourceUrl.assetPath) {
var assetPath = url.toAssetPath(sourceUrl);
source = assets.readAsset(assetPath);
} else {
throw new Error("Unable to load source for filename: " + filename);
}
return source;
}
Titanium.getUrlSource = getUrlSource;

// This is the implementation of Ti.include (and it's wrappers/delegates)
// Ti.include executes code in the current "context", and
// also supports relative paths based on the current file.
//
// We have some complicated code to get this working, namely:
// - Every "context" (i.e. window with a URL, or app.js) is actually a CommonJS module in disguise, with caching disabled
// - Every "context" has it's own top level / global object
// - Ti.include code is executed in the context that it's called from
// - Each "context" and each Ti.include file gets it's own version of Ti.include / require that wraps this implementation, passing a different baseUrl
// - We use TitaniumWrapper as the base for all context / scope-specific APIs
function TiInclude(filename, baseUrl, scopeVars) {
var sourceUrl = url.resolve(baseUrl, filename);
scopeVars = initScopeVars(scopeVars, sourceUrl.href);

// Create a context-bound Titanium module.
var ti = new TitaniumWrapper(scopeVars);

// This is called "localSandbox" so we don't overshadow the "sandbox" on global scope
var localSandbox = createSandbox(ti, scopeVars.sourceUrl);

var source = getUrlSource(filename, sourceUrl),
wrappedSource = "with(sandbox) { " + source + "\n }",
filePath = sourceUrl.href.replace("app://", "/"),
contextGlobal = ti.global;

if (contextGlobal) {
// We're running inside another window, so we run against it's context
contextGlobal.sandbox = localSandbox;
return Script.runInContext(wrappedSource, contextGlobal, filePath, true);

} else {
// We're running inside modules. Since we don't create a new context for modules
// due to TIMOB-11752, we use the global V8 Context directly.
// Put sandbox on the global scope
sandbox = localSandbox;
return Script.runInThisContext(wrappedSource, filePath, true);
}
}
TiInclude.prototype = global;
Titanium.include = TiInclude;

// This loops through all known APIs that require an
// Invocation object and wraps them so we can pass a
// source URL as the first argument
Expand Down
77 changes: 19 additions & 58 deletions apidoc/Titanium/Titanium.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,34 @@
name: Titanium
summary: The top-level Titanium module.
description: |
The Titanium module provides the Titanium Mobile API, allowing developers to access native
features of each target environment. Currently, the Android, iOS and Mobile Web (beta)
The Titanium module provides the Titanium Mobile API, allowing developers to access native
features of each target environment. Currently, the Android, iOS and Mobile Web (beta)
environments are supported.
#### Titanium Namespace
The complete Titanium API is accessible from the `Titanium` namespace but, for convenience and
brevity, the alias `Ti` is also provided. As the `Titanium` namespace is functionally-identical
The complete Titanium API is accessible from the `Titanium` namespace but, for convenience and
brevity, the alias `Ti` is also provided. As the `Titanium` namespace is functionally-identical
to its `Ti` alias, it is always recommended to use `Ti` in your code.
For example, the following pairs of Titanium calls behave exactly the same.
Titanium.API.info('Hello Titanium!');
Ti.API.info('Hello Titanium!');
Titanium.Utils.sha256('Hello Titanium!');
Ti.Utils.sha256('Hello Titanium!');
Titanium.App.Properties.setString('hello_msg','Hello Titanium!');
Ti.App.Properties.setString('hello_msg','Hello Titanium!');
Titanium.Database.open('mydb');
Ti.Database.open('mydb');
#### Global APIs
Titanium includes a number of built-in JavaScript objects that are not part of the Titanium
namespace, including JSON parsing, String formatting, timers, and the CommonJS `require` function.
Titanium includes a number of built-in JavaScript objects that are not part of the Titanium
namespace, including JSON parsing, String formatting, timers, and the CommonJS `require` function.
See [Global APIs](Global) for details.
since: "0.1"
Expand All @@ -41,7 +41,7 @@ properties:
type: String
summary: User-agent string used by Titanium.
description: |
On Mobile Web, the browser's user agent cannot be overridden. Writing to this property has no
On Mobile Web, the browser's user agent cannot be overridden. Writing to this property has no
effect and reading the property will always return the browser's user agent.
- name: version
type: String
Expand All @@ -58,44 +58,6 @@ properties:
summary: Git hash of the Titanium build.
permission: read-only
methods:
- name: include
summary: Includes JavaScript code from one or more files.
deprecated:
since: 3.3.0
notes: Create a CommonJS module and use the `require()` method to include external JavaScript code.
description: |
Note that this mechanism is not supported with Alloy projects.
The `include` method has several interesting quirks:
- The included JavaScript is interpreted in the current root execution
context -- that is, either `app.js` or in the root context of a window
opened with the `url` property. For example, in the following code
snippet, the included code in `some_module.js` has access to
`globalVar`, but *not* to the local variable, `localVar`:
var globalVar = {};
function loadModule() {
var localVar = "A local value.";
Ti.include('some_module.js');
};
loadModule();
- The included filename is interpreted *local to the current file*. For
example, suppose `a.js` includes `dir/b.js.` If `b.js` includes another file,
`c.js`, this is interpreted as `dir/c.js`.
- Calling `include` from an event handler does not work consistently across
platforms.
- Calling `include` on a non-existent file causes a runtime error.
See also [CommonJS Require](Global.require).
parameters:
- name: name
summary: Filename(s) to include.
type: String

- name: createBuffer
summary: Creates a new buffer based on the params.
parameters:
Expand All @@ -109,18 +71,18 @@ methods:
examples:
- title: Create a buffer with 1K bytes
example: |
var buffer = Ti.createBuffer({ length: 1024 });
- title: Create a buffer with string
example: |
Create a buffer with the string "hello world" encoded in UTF-8
var buffer = Ti.createBuffer({ value: "hello world" });
- title: Create a buffer with encoded float
example: |
Create a buffer with the encoded value of the double-precision floating point
Create a buffer with the encoded value of the double-precision floating point
number 1.234567 in Big Endian (network) byte order
var buffer = Ti.createBuffer({ value: 1.234567, type: Ti.Codec.TYPE_DOUBLE, byteOrder: Ti.Codec.BIG_ENDIAN });
Expand Down Expand Up @@ -150,4 +112,3 @@ properties:
summary: The byte order of this buffer.
optional: true
default: The OS native byte order is used by default. See <Titanium.Codec.getNativeByteOrder>

56 changes: 9 additions & 47 deletions iphone/Classes/TopTiModule.m
Original file line number Diff line number Diff line change
Expand Up @@ -53,44 +53,6 @@ -(NSString*)apiName
return @"Ti";
}

-(void)include:(NSArray*)jsfiles
{
id<TiEvaluator> context = [self executionContext];
NSURL * oldUrl = [context currentURL];
NSURL * rootURL = (oldUrl != nil)?oldUrl:[self _baseURL];

for (id file in jsfiles)
{
// only allow includes that are local to our execution context url
// for security, refuse to load non-compiled in Javascript code
NSURL *url = [TiUtils toURL:file relativeToURL:rootURL];
DebugLog(@"[DEBUG] Include url: %@",[url absoluteString]);
[context setCurrentURL:url];
[context evalFile:[url absoluteString]];
}

[context setCurrentURL:oldUrl];
}

#ifdef DEBUG
// an internal include that works with absolute URLs (debug mode only)
-(void)includeAbsolute:(NSArray*)jsfiles
{
for (id file in jsfiles)
{
DebugLog(@"[DEBUG] Absolute url: %@", file);

NSURL *url = nil;
if (![file hasPrefix:@"file:"]) {
url = [NSURL URLWithString:file];
} else {
url = [[NSURL fileURLWithPath:file] standardizedURL];
}
[[self executionContext] evalFile:[url absoluteString]];
}
}
#endif

-(TiBuffer*)createBuffer:(id)arg
{
ENSURE_SINGLE_ARG_OR_NIL(arg, NSDictionary);
Expand All @@ -101,24 +63,24 @@ -(TiBuffer*)createBuffer:(id)arg
NSString* type;
CFByteOrder byteOrder;
BOOL hasByteOrder;

ENSURE_INT_OR_NIL_FOR_KEY(length, arg, @"length", hasLength);
ENSURE_ARG_OR_NIL_FOR_KEY(data, arg, @"value", NSObject);
ENSURE_ARG_OR_NIL_FOR_KEY(type, arg, @"type", NSString);
ENSURE_INT_OR_NIL_FOR_KEY(byteOrder, arg, @"byteOrder", hasByteOrder);

TiBuffer* buffer = [[[TiBuffer alloc] _initWithPageContext:[self executionContext]] autorelease];
if (hasLength) {
[buffer setLength:[NSNumber numberWithInt:length]];
}

// NOTE: We use the length of the buffer as a hint when encoding strings. In this case, if [string length] > length,
// we only encode up to 'length' of the string.
if ([data isKindOfClass:[NSString class]]) {
NSUInteger encodeLength = (hasLength) ? length : [data length];

NSString* charset = (type != nil) ? type : kTiUTF8Encoding;

// Just put the string data directly into the buffer, if we can.
if (!hasLength){
NSStringEncoding encoding = [TiUtils charsetToEncoding:charset];
Expand All @@ -133,8 +95,8 @@ -(TiBuffer*)createBuffer:(id)arg
}
case BAD_ENCODING: {
[self throwException:[NSString stringWithFormat:@"Invalid string encoding type '%@'",charset]
subreason:nil
location:CODELOCATION];
subreason:nil
location:CODELOCATION];
break;
}
}
Expand All @@ -146,12 +108,12 @@ -(TiBuffer*)createBuffer:(id)arg
subreason:nil
location:CODELOCATION];
}

if (!hasLength) {
length = [TiUtils dataSize:[TiUtils constantToType:type]];
[buffer setLength:NUMINT(length)];
}

byteOrder = (hasByteOrder) ? byteOrder : CFByteOrderGetCurrent();
[buffer setByteOrder:NUMLONG(byteOrder)];
switch ([TiUtils encodeNumber:data toBuffer:buffer offset:0 type:type endianness:byteOrder]) {
Expand Down Expand Up @@ -187,7 +149,7 @@ -(TiBuffer*)createBuffer:(id)arg
subreason:nil
location:CODELOCATION];
}

return buffer;
}

Expand Down
11 changes: 2 additions & 9 deletions mobileweb/titanium/Ti.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*/

define(
["Ti/_", "Ti/API", "Ti/_/analytics", "Ti/App", "Ti/_/Evented", "Ti/_/has", "Ti/_/lang", "Ti/_/ready", "Ti/_/style", "Ti/Buffer", "Ti/Platform", "Ti/UI", "Ti/Locale", "Ti/_/include"],
["Ti/_", "Ti/API", "Ti/_/analytics", "Ti/App", "Ti/_/Evented", "Ti/_/has", "Ti/_/lang", "Ti/_/ready", "Ti/_/style", "Ti/Buffer", "Ti/Platform", "Ti/UI", "Ti/Locale"],
function(_, API, analytics, App, Evented, has, lang, ready, style, Buffer, Platform, UI) {

var global = window,
Expand Down Expand Up @@ -44,13 +44,6 @@ define(
return new Buffer(args);
},

include: function(files) {
typeof files === "array" || (files = [].concat(Array.prototype.slice.call(arguments, 0)));
files.forEach(function(f) {
require("Ti/_/include!" + f);
});
},

deferStart: function() {
if (loaded) {
API.warn("app.js already loaded!");
Expand Down Expand Up @@ -265,4 +258,4 @@ define(

return Ti;

});
});

0 comments on commit b9af005

Please sign in to comment.